summaryrefslogtreecommitdiff
path: root/pixel-client/src/ui.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-07-25 14:34:18 +0200
committermetamuffin <metamuffin@disroot.org>2024-07-25 14:34:18 +0200
commit16dbbba23e3534105707fbb861a1dce5d9ef2f0e (patch)
tree44b2f81349e22ff12ad9e36db1893a02455548c8 /pixel-client/src/ui.rs
parentecb6ff15c24841dc08ab8f5c3b347c8080720ac4 (diff)
downloadhurrycurry-16dbbba23e3534105707fbb861a1dce5d9ef2f0e.tar
hurrycurry-16dbbba23e3534105707fbb861a1dce5d9ef2f0e.tar.bz2
hurrycurry-16dbbba23e3534105707fbb861a1dce5d9ef2f0e.tar.zst
button interact behavior
Diffstat (limited to 'pixel-client/src/ui.rs')
-rw-r--r--pixel-client/src/ui.rs107
1 files changed, 102 insertions, 5 deletions
diff --git a/pixel-client/src/ui.rs b/pixel-client/src/ui.rs
index 557800aa..5ac1a79f 100644
--- a/pixel-client/src/ui.rs
+++ b/pixel-client/src/ui.rs
@@ -1,29 +1,91 @@
-use crate::render::Renderer;
-use hurrycurry_protocol::glam::Vec2;
+use crate::render::{sprite::SpriteDraw, Renderer};
+use hurrycurry_protocol::glam::{IVec2, Vec2};
+use sdl2::{
+ keyboard::{KeyboardState, Keycode, Scancode},
+ mouse::MouseState,
+};
+
+#[derive(Debug, Default)]
+pub struct FocusDevice {
+ focus: usize,
+ pressing: Option<usize>,
+ interact_just_pressed: bool,
+ interact_just_released: bool,
+ interact_down: bool,
+}
#[derive(Default, Debug)]
pub struct UiState {
- focus: usize,
+ mouse_position: Vec2,
+ ui_scale: Vec2,
+
+ keyboard_focus: FocusDevice,
+ mouse_focus: FocusDevice,
}
pub struct Ui<'a, 'b> {
cursor: Vec2,
cross_height: f32,
+ index: usize,
direction_horizontal: bool,
renderer: &'a mut Renderer<'b>,
state: &'a mut UiState,
}
impl UiState {
+ pub fn update(&mut self, keyboard: &KeyboardState, mouse: &MouseState, _dt: f32) {
+ self.mouse_position = IVec2::new(mouse.x(), mouse.y()).as_vec2() / self.ui_scale;
+
+ self.mouse_focus.update(mouse.left());
+ self.keyboard_focus
+ .update(keyboard.is_scancode_pressed(Scancode::Space));
+ }
+ pub fn keyboard_event(&mut self, keycode: Keycode, down: bool) {
+ if down {
+ match keycode {
+ Keycode::DOWN => self.keyboard_focus.focus += 1,
+ Keycode::UP if self.keyboard_focus.focus > 0 => self.keyboard_focus.focus -= 1,
+ _ => (),
+ }
+ }
+ }
+
pub fn draw(&mut self, renderer: &mut Renderer, ui: impl FnOnce(&mut Ui)) {
+ self.ui_scale = renderer.ui_scale;
+ self.mouse_focus.focus = usize::MAX;
let mut u = Ui {
cursor: Vec2::ZERO,
direction_horizontal: false,
renderer,
state: self,
cross_height: 0.,
+ index: 0,
};
ui(&mut u);
+
+ if self.mouse_focus.interact_just_released {
+ self.mouse_focus.pressing = None;
+ }
+ if self.keyboard_focus.interact_just_released {
+ self.keyboard_focus.pressing = None;
+ }
+ }
+}
+
+impl FocusDevice {
+ pub fn update(&mut self, interact: bool) {
+ self.interact_just_pressed = interact && !self.interact_down;
+ self.interact_just_released = !interact && self.interact_down;
+ self.interact_down = interact;
+ }
+ pub fn element(&mut self, index: usize) -> (bool, bool, bool) {
+ let focus = self.focus == index;
+ if focus && self.interact_just_pressed {
+ self.pressing = Some(index)
+ };
+ let pressing = self.pressing == Some(index);
+ let released = self.interact_just_released && pressing && focus;
+ (focus, pressing, released)
}
}
@@ -33,9 +95,44 @@ impl<'a, 'b> Ui<'a, 'b> {
self.advance(size);
}
pub fn button(&mut self, label: &str) -> bool {
- let size = self.renderer.draw_text(self.cursor, label);
+ let c = self.cursor;
+ let margin = Vec2::splat(2.);
+ let size = self.renderer.draw_text(self.cursor + margin, label) + margin + margin;
+
+ self.index += 1;
+
+ let mouse_rel = self.state.mouse_position - c;
+ if mouse_rel.x >= 0. && mouse_rel.y >= 0. && mouse_rel.x < size.x && mouse_rel.y < size.y {
+ self.state.mouse_focus.focus = self.index;
+ }
+
+ let (focus, pressing, released) = {
+ let (mfocus, mpressing, mreleased) = self.state.mouse_focus.element(self.index);
+ let (kfocus, kpressing, kreleased) = self.state.keyboard_focus.element(self.index);
+ (
+ mfocus || kfocus,
+ mpressing || kpressing,
+ mreleased || kreleased,
+ )
+ };
+
+ let l = if pressing {
+ 100
+ } else if focus {
+ 50
+ } else {
+ 30
+ };
+ self.renderer.draw_ui(SpriteDraw::screen(
+ self.renderer.misc_textures.solid,
+ i32::MAX - 1,
+ c,
+ size,
+ Some([l, l, l, 200]),
+ ));
+
self.advance(size);
- false
+ released
}
pub fn advance(&mut self, size: Vec2) {