diff --git a/.gitignore b/.gitignore
index ea8c4bf..c0ed7d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
/target
+/logs
\ No newline at end of file
diff --git a/logs/latest.log b/logs/latest.log
deleted file mode 100644
index 522524a..0000000
--- a/logs/latest.log
+++ /dev/null
@@ -1,110 +0,0 @@
-2024-10-18T22:01:48.001029Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:48.001150Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:48.474890Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:48.474947Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:48.495298Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:48.495345Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:48.618136Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:48.659732Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:48.659792Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:48.743791Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:48.743851Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:49.058470Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:49.058527Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:49.099680Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:49.099736Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:49.579664Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:49.579721Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:50.259909Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:50.259973Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:50.259992Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:50.657504Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
-2024-10-18T22:01:50.657561Z INFO src/gamepad_manager.rs:33: Selected gamepad changed to: Some(
- GamepadId(
- 0,
- ),
-)
diff --git a/src/app.rs b/src/app.rs
index ced0eee..af1138d 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -1,6 +1,6 @@
use std::time::{Duration, Instant};
-use color_eyre::{owo_colors::OwoColorize, Result};
+use color_eyre::{eyre::eyre, owo_colors::OwoColorize, Result};
use gilrs::{Gamepad, Gilrs};
use ratatui::{
buffer::Buffer,
@@ -78,6 +78,8 @@ impl App {
self.manager.scan_gamepads();
return Ok(());
}
+ KeyCode::Char('v') => self.manager.test_weak_ff(),
+ KeyCode::Char('V') => self.manager.test_strong_ff(),
KeyCode::Char('q') | KeyCode::Char('Q') | KeyCode::Esc => self.quit(),
_ => {}
}
@@ -94,33 +96,35 @@ impl App {
self.state = AppState::Quitting;
}
- fn render_title(area: Rect, buf: &mut Buffer) {
- Paragraph::new("App Example Title")
- .block(
- Block::bordered()
- .border_type(BorderType::Rounded)
- .padding(Padding::top(1)),
- )
- .alignment(Alignment::Center)
- .render(area, buf);
- }
+ // fn render_title(area: Rect, buf: &mut Buffer) {
+ // Paragraph::new("App Example Title")
+ // .block(
+ // Block::bordered()
+ // .border_type(BorderType::Rounded)
+ // .padding(Padding::top(1)),
+ // )
+ // .alignment(Alignment::Center)
+ // .render(area, buf);
+ // }
+ //
+ // fn render_connected_gamepad(&self, area: Rect, buf: &mut Buffer) {
+ // Paragraph::new(format!(
+ // "{} connected gamepads",
+ // self.manager.connected_gamepads()
+ // ))
+ // .block(
+ // Block::bordered()
+ // .border_type(BorderType::Rounded)
+ // .padding(Padding::top(1)),
+ // )
+ // .alignment(Alignment::Center)
+ // .bold()
+ // .render(area, buf);
+ // }
- fn render_connected_gamepad(&self, area: Rect, buf: &mut Buffer) {
- Paragraph::new(format!(
- "{} connected gamepads",
- self.manager.connected_gamepads()
- ))
- .block(
- Block::bordered()
- .border_type(BorderType::Rounded)
- .padding(Padding::top(1)),
- )
- .alignment(Alignment::Center)
- .bold()
- .render(area, buf);
- }
+ fn render_action_buttons(&self, area: Rect, buf: &mut Buffer) {
+ Block::bordered().render(area, buf);
- fn render_right_buttons(&self, area: Rect, buf: &mut Buffer) {
let north_button = self.create_action_button_ui(gilrs::Button::North);
let east_button = self.create_action_button_ui(gilrs::Button::East);
let south_button = self.create_action_button_ui(gilrs::Button::South);
@@ -144,13 +148,113 @@ impl App {
west_button.render(west, buf);
}
+ fn render_dpad_buttons(&self, area: Rect, buf: &mut Buffer) {
+ Block::bordered().render(area, buf);
+
+ let up_button = self.create_action_button_ui(gilrs::Button::DPadUp);
+ let right_button = self.create_action_button_ui(gilrs::Button::DPadRight);
+ let down_button = self.create_action_button_ui(gilrs::Button::DPadDown);
+ let left_button = self.create_action_button_ui(gilrs::Button::DPadLeft);
+
+ let layers = Layout::vertical([Fill(1), Fill(1), Fill(1)]);
+ let [top, mid, bot] = layers.areas(area);
+
+ let top_layer = Layout::horizontal([Fill(1), Fill(1), Fill(1)]);
+ let [_, up, _] = top_layer.areas(top);
+
+ let mid_layer = Layout::horizontal([Fill(1), Fill(1), Fill(1)]);
+ let [left, _, right] = mid_layer.areas(mid);
+
+ let bot_layer = Layout::horizontal([Fill(1), Fill(1), Fill(1)]);
+ let [_, down, _] = bot_layer.areas(bot);
+
+ up_button.render(up, buf);
+ right_button.render(right, buf);
+ down_button.render(down, buf);
+ left_button.render(left, buf);
+ }
+
+ fn render_setting_buttons(&self, area: Rect, buf: &mut Buffer) {
+ Block::bordered().render(area, buf);
+
+ let select_button = self.create_action_button_ui(gilrs::Button::Select);
+ let start_button = self.create_action_button_ui(gilrs::Button::Start);
+
+ let layers = Layout::horizontal([Fill(1), Fill(1), Fill(1), Fill(1), Fill(1)]);
+ let [_, select_area, _, start_area, _] = layers.areas(area);
+
+ let select_layer = Layout::vertical([Fill(1), Fill(1), Fill(1), Fill(1)]);
+ let [_, select, _, _] = select_layer.areas(select_area);
+
+ let start_layer = Layout::vertical([Fill(1), Fill(1), Fill(1), Fill(1)]);
+ let [_, start, _, _] = start_layer.areas(start_area);
+
+ select_button.render(select, buf);
+ start_button.render(start, buf);
+ }
+
+ fn render_trigger_buttons(&self, area: Rect, buf: &mut Buffer) {
+ Block::bordered().render(area, buf);
+
+ let r1_button = self.create_action_button_ui(gilrs::Button::RightTrigger);
+ let r2_button = self.create_action_button_ui(gilrs::Button::RightTrigger2);
+ let l1_button = self.create_action_button_ui(gilrs::Button::LeftTrigger);
+ let l2_button = self.create_action_button_ui(gilrs::Button::LeftTrigger2);
+
+ let layers = Layout::horizontal([
+ Fill(2),
+ Fill(1),
+ Fill(1),
+ Fill(1),
+ Fill(4),
+ Fill(1),
+ Fill(1),
+ Fill(1),
+ Fill(2),
+ ]);
+ let [_, l2_area, _, l1_area, _, r1_area, _, r2_area, _] = layers.areas(area);
+
+ let r1_layer = Layout::vertical([Fill(2), Fill(1), Fill(2)]);
+ let [_, r1, _] = r1_layer.areas(r1_area);
+
+ let r2_layer = Layout::vertical([Fill(1), Fill(3), Fill(1)]);
+ let [_, r2, _] = r2_layer.areas(r2_area);
+
+ let l1_layer = Layout::vertical([Fill(2), Fill(1), Fill(2)]);
+ let [_, l1, _] = l1_layer.areas(l1_area);
+
+ let l2_layer = Layout::vertical([Fill(1), Fill(3), Fill(1)]);
+ let [_, l2, _] = l2_layer.areas(l2_area);
+
+ r1_button.render(r1, buf);
+ r2_button.render(r2, buf);
+ l1_button.render(l1, buf);
+ l2_button.render(l2, buf);
+
+ //TODO: For PS4+ controllers doesn't have dedicated trigger push force
+ // let gauge_percentage = match self.manager.active_gamepad() {
+ // Ok(gamepad) => match gamepad.axis_data(gilrs::Axis::Unknown) {
+ // Some(ad) => ad.value(),
+ // None => 0.0,
+ // },
+ // Err(_) => 0.0,
+ // };
+ // let gauge_percentage = 0;
+
+ // Gauge::default()
+ // .gauge_style(Color::Green)
+ // .bg(Color::DarkGray)
+ // .ratio(gauge_percentage.into())
+ // .render(r2, buf);
+ }
+
fn create_action_button_ui(&self, dir: gilrs::Button) -> Block {
let color = match self.manager.active_gamepad() {
Ok(gamepad) => match gamepad.is_pressed(dir) {
true => Color::Green,
- false => Color::Gray,
+ false => Color::DarkGray,
},
- Err(_) => Color::Gray,
+ Err(_) => Color::DarkGray,
};
Block::new().style(Style::default().bg(color))
@@ -159,29 +263,26 @@ impl App {
impl Widget for &App {
fn render(self, area: Rect, buf: &mut Buffer) {
- let layout = Layout::vertical([Length(5), Min(0), Length(5)]);
- let [header_area, inner_area, footer_area] = layout.areas(area);
+ let layout = Layout::vertical([Percentage(100)]);
+ let [inner_area] = layout.areas(area);
- let header_layout = Layout::horizontal([Fill(1), Fill(4)]);
- let [tabs_area, title_area] = header_layout.areas(header_area);
+ let gamepad_layout = Layout::vertical([Fill(2), Fill(4), Fill(3)]);
+ let [triggers, buttons, joysticks] = gamepad_layout.areas(inner_area);
- let gamepad_layout = Layout::vertical([
- Percentage(10),
- Percentage(50),
- Percentage(30),
- Percentage(10),
- ]);
- let [_, buttons, joysticks, _] = gamepad_layout.areas(inner_area);
-
- let buttons_layout = Layout::horizontal([Fill(1), Fill(2), Fill(2), Fill(2), Fill(1)]);
- let [_, left_buttons, mid_buttons, right_buttons, _] = buttons_layout.areas(buttons);
+ let buttons_layout = Layout::horizontal([Fill(2), Fill(2), Fill(2)]);
+ let [left_buttons, mid_buttons, right_buttons] = buttons_layout.areas(buttons);
// let details_layout = Layout::horizontal([Fill(2), Fill(2)]);
// let [right_details_area, left_details_area] = details_layout.areas(details_area);
- App::render_title(title_area, buf);
- self.render_connected_gamepad(tabs_area, buf);
- Block::bordered().render(inner_area, buf);
+ let mut title_label = Block::bordered();
+ title_label = match self.manager.active_gamepad() {
+ Ok(gp) => title_label
+ .title(gp.name().to_string())
+ .title_style(Color::Rgb(255, 165, 35)),
+ Err(_) => title_label.title("No active device".to_string()),
+ };
+ title_label.render(inner_area, buf);
// Block::bordered()
// .style(Style::default().bg(tailwind::GREEN.c900))
@@ -191,7 +292,10 @@ impl Widget for &App {
// .style(Style::default().bg(tailwind::YELLOW.c300))
// .render(details_area, buf);
- self.render_right_buttons(right_buttons, buf);
+ self.render_dpad_buttons(left_buttons, buf);
+ self.render_setting_buttons(mid_buttons, buf);
+ self.render_action_buttons(right_buttons, buf);
+ self.render_trigger_buttons(triggers, buf);
// Block::bordered()
// .style(Style::default().bg(tailwind::TEAL.c300))
diff --git a/src/gamepad_manager.rs b/src/gamepad_manager.rs
index 5d1339e..a55ab82 100644
--- a/src/gamepad_manager.rs
+++ b/src/gamepad_manager.rs
@@ -1,3 +1,5 @@
+use std::{thread, time::Duration};
+
use color_eyre::{eyre::eyre, Result};
use gilrs::{
ff::{BaseEffect, BaseEffectType, EffectBuilder, Replay, Ticks},
@@ -24,13 +26,9 @@ impl GamepadManager {
})
}
- pub fn select_gamepad(&mut self, id: impl Into