diff --git a/wgui/src/components/button.rs b/wgui/src/components/button.rs index 4c99064..fb7acf0 100644 --- a/wgui/src/components/button.rs +++ b/wgui/src/components/button.rs @@ -1,6 +1,6 @@ use crate::{ animation::{Animation, AnimationEasing}, - components::{self, Component, ComponentBase, ComponentTrait, InitData, tooltip::ComponentTooltip}, + components::{self, tooltip::ComponentTooltip, Component, ComponentBase, ComponentTrait, InitData}, drawing::{self, Boundary, Color}, event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind}, i18n::Translation, @@ -10,15 +10,15 @@ use crate::{ util::centered_matrix, }, widget::{ - ConstructEssentials, EventResult, WidgetData, label::{WidgetLabel, WidgetLabelParams}, rectangle::{WidgetRectangle, WidgetRectangleParams}, util::WLength, + ConstructEssentials, EventResult, WidgetData, }, }; use glam::{Mat4, Vec3}; use std::{cell::RefCell, rc::Rc}; -use taffy::{AlignItems, JustifyContent, prelude::length}; +use taffy::{prelude::length, AlignItems, JustifyContent}; pub struct Params { pub text: Option, // if unset, label will not be populated @@ -31,6 +31,10 @@ pub struct Params { pub style: taffy::Style, pub text_style: TextStyle, pub tooltip: Option, + /// make this a toggle-style button that stays depressed + /// until "un-clicked". this is visual only. + /// set the initial state using `set_sticky_state` + pub sticky: bool, } impl Default for Params { @@ -46,6 +50,7 @@ impl Default for Params { style: Default::default(), text_style: TextStyle::default(), tooltip: None, + sticky: false, } } } @@ -56,6 +61,7 @@ pub type ButtonClickCallback = Box, active_tooltip: Option>, } @@ -67,6 +73,7 @@ struct Data { initial_hover_border_color: drawing::Color, id_label: WidgetID, // Label id_rect: WidgetID, // Rectangle + sticky: bool, } pub struct ComponentButton { @@ -95,6 +102,45 @@ impl ComponentButton { pub fn on_click(&self, func: ButtonClickCallback) { self.state.borrow_mut().on_click = Some(func); } + + /// Sets the sticky state of the button. + /// + /// On buttons where sticky is false, sticky state won't automatically clear. + pub fn set_sticky_state(&self, common: &mut CallbackDataCommon, sticky_down: bool) { + let mut state = self.state.borrow_mut(); + + // only play anim if we're not changing the border highlight + let dirty = !state.hovered && !state.down && state.sticky_down != sticky_down; + + state.sticky_down = sticky_down; + + if !dirty { + return; + } + + let data = self.data.clone(); + let anim = Animation::new( + self.data.id_rect, + if sticky_down { 5 } else { 10 }, + AnimationEasing::OutCubic, + Box::new(move |common, anim_data| { + let rect = anim_data.obj.get_as_mut::().unwrap(); + let mult = if sticky_down { + anim_data.pos + } else { + 1.0 - anim_data.pos + }; + + let bgcolor = data.initial_color.lerp(&data.initial_hover_color, mult * 0.5); + rect.params.color = bgcolor; + rect.params.color2 = get_color2(&bgcolor); + rect.params.border_color = data.initial_border_color.lerp(&data.initial_hover_border_color, mult); + common.alterables.mark_redraw(); + }), + ); + + common.alterables.animations.push(anim); + } } fn get_color2(color: &drawing::Color) -> drawing::Color { @@ -108,9 +154,20 @@ fn anim_hover( widget_boundary: Boundary, pos: f32, pressed: bool, + sticky_down: bool, ) { let mult = pos * if pressed { 1.5 } else { 1.0 }; - let bgcolor = data.initial_color.lerp(&data.initial_hover_color, mult); + + let (init_border_color, init_color) = if sticky_down { + ( + data.initial_hover_border_color, + data.initial_color.lerp(&data.initial_hover_color, 0.5), + ) + } else { + (data.initial_border_color, data.initial_color) + }; + + let bgcolor = init_color.lerp(&data.initial_hover_color, mult); //let t = Mat4::from_scale(Vec3::splat(1.0 + pos * 0.5)) * Mat4::from_rotation_z(pos * 1.0); @@ -119,7 +176,8 @@ fn anim_hover( rect.params.color = bgcolor; rect.params.color2 = get_color2(&bgcolor); - rect.params.border_color = data.initial_border_color.lerp(&data.initial_hover_border_color, mult); + + rect.params.border_color = init_border_color.lerp(&data.initial_hover_border_color, mult); } fn anim_hover_create(data: Rc, state: Rc>, widget_id: WidgetID, fade_in: bool) -> Animation { @@ -129,13 +187,15 @@ fn anim_hover_create(data: Rc, state: Rc>, widget_id: Widge AnimationEasing::OutCubic, Box::new(move |common, anim_data| { let rect = anim_data.obj.get_as_mut::().unwrap(); + let state = state.borrow(); anim_hover( rect, anim_data.data, &data, anim_data.widget_boundary, if fade_in { anim_data.pos } else { 1.0 - anim_data.pos }, - state.borrow().down, + state.down, + state.sticky_down, ); common.alterables.mark_redraw(); }), @@ -219,6 +279,7 @@ fn register_event_mouse_press( common.state.get_node_boundary(event_data.node_id), 1.0, true, + state.sticky_down, ); common.alterables.trigger_haptics(); @@ -243,6 +304,12 @@ fn register_event_mouse_release( EventListenerKind::MouseRelease, Box::new(move |common, event_data, (), ()| { let rect = event_data.obj.get_as_mut::().unwrap(); + let mut state = state.borrow_mut(); + + if data.sticky { + state.sticky_down = !state.sticky_down; + } + anim_hover( rect, event_data.widget_data, @@ -250,12 +317,12 @@ fn register_event_mouse_release( common.state.get_node_boundary(event_data.node_id), 1.0, false, + state.sticky_down, ); common.alterables.trigger_haptics(); common.alterables.mark_redraw(); - let mut state = state.borrow_mut(); if state.down { state.down = false; @@ -357,6 +424,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul initial_border_color: border_color, initial_hover_color: hover_color, initial_hover_border_color: hover_border_color, + sticky: params.sticky, }); let state = Rc::new(RefCell::new(State { @@ -364,6 +432,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul hovered: false, on_click: None, active_tooltip: None, + sticky_down: false, })); let base = ComponentBase { diff --git a/wgui/src/parser/component_button.rs b/wgui/src/parser/component_button.rs index aba6088..17c971d 100644 --- a/wgui/src/parser/component_button.rs +++ b/wgui/src/parser/component_button.rs @@ -1,11 +1,12 @@ use crate::{ - components::{Component, button, tooltip}, + components::{button, tooltip, Component}, drawing::Color, i18n::Translation, layout::WidgetID, parser::{ - AttribPair, ParserContext, ParserFile, parse_check_f32, parse_children, print_invalid_attrib, process_component, + parse_check_f32, parse_check_i32, parse_children, print_invalid_attrib, process_component, style::{parse_color_opt, parse_round, parse_style, parse_text_style}, + AttribPair, ParserContext, ParserFile, }, widget::util::WLength, }; @@ -25,6 +26,7 @@ pub fn parse_component_button<'a>( let mut round = WLength::Units(4.0); let mut tooltip: Option = None; let mut tooltip_side: Option = None; + let mut sticky: bool = false; let mut translation: Option = None; @@ -71,6 +73,10 @@ pub fn parse_component_button<'a>( } } } + "sticky" => { + let mut sticky_i32 = 0; + sticky = parse_check_i32(value, &mut sticky_i32) && sticky_i32 == 1; + } _ => {} } } @@ -91,6 +97,7 @@ pub fn parse_component_button<'a>( side: tooltip_side.map_or(tooltip::TooltipSide::Bottom, |f| f), text: Translation::from_translation_key(&t), }), + sticky, }, )?; diff --git a/wgui/src/widget/sprite.rs b/wgui/src/widget/sprite.rs index f1efce4..df79394 100644 --- a/wgui/src/widget/sprite.rs +++ b/wgui/src/widget/sprite.rs @@ -8,8 +8,8 @@ use crate::{ globals::Globals, layout::WidgetID, renderer_vk::text::{ - DEFAULT_METRICS, custom_glyph::{CustomGlyph, CustomGlyphData}, + DEFAULT_METRICS, }, }; @@ -23,7 +23,7 @@ pub struct WidgetSpriteParams { #[derive(Debug, Default)] pub struct WidgetSprite { - params: WidgetSpriteParams, + pub params: WidgetSpriteParams, id: WidgetID, } diff --git a/wlx-overlay-s/src/assets/bar/add.svg b/wlx-overlay-s/src/assets/edit/add.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/add.svg rename to wlx-overlay-s/src/assets/edit/add.svg diff --git a/wlx-overlay-s/src/assets/bar/anchor.svg b/wlx-overlay-s/src/assets/edit/anchor.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/anchor.svg rename to wlx-overlay-s/src/assets/edit/anchor.svg diff --git a/wlx-overlay-s/src/assets/bar/background-off.svg b/wlx-overlay-s/src/assets/edit/background-off.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/background-off.svg rename to wlx-overlay-s/src/assets/edit/background-off.svg diff --git a/wlx-overlay-s/src/assets/bar/background.svg b/wlx-overlay-s/src/assets/edit/background.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/background.svg rename to wlx-overlay-s/src/assets/edit/background.svg diff --git a/wlx-overlay-s/src/assets/bar/cancel.svg b/wlx-overlay-s/src/assets/edit/cancel.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/cancel.svg rename to wlx-overlay-s/src/assets/edit/cancel.svg diff --git a/wlx-overlay-s/src/assets/bar/checkbox-checked.svg b/wlx-overlay-s/src/assets/edit/checkbox-checked.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/checkbox-checked.svg rename to wlx-overlay-s/src/assets/edit/checkbox-checked.svg diff --git a/wlx-overlay-s/src/assets/bar/checkbox.svg b/wlx-overlay-s/src/assets/edit/checkbox.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/checkbox.svg rename to wlx-overlay-s/src/assets/edit/checkbox.svg diff --git a/wlx-overlay-s/src/assets/bar/curve.svg b/wlx-overlay-s/src/assets/edit/curve.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/curve.svg rename to wlx-overlay-s/src/assets/edit/curve.svg diff --git a/wlx-overlay-s/src/assets/bar/delete.svg b/wlx-overlay-s/src/assets/edit/delete.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/delete.svg rename to wlx-overlay-s/src/assets/edit/delete.svg diff --git a/wlx-overlay-s/src/assets/bar/fade.svg b/wlx-overlay-s/src/assets/edit/fade.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/fade.svg rename to wlx-overlay-s/src/assets/edit/fade.svg diff --git a/wlx-overlay-s/src/assets/edit/float.svg b/wlx-overlay-s/src/assets/edit/float.svg new file mode 100644 index 0000000..ad18caf --- /dev/null +++ b/wlx-overlay-s/src/assets/edit/float.svg @@ -0,0 +1 @@ + diff --git a/wlx-overlay-s/src/assets/edit/grid.svg b/wlx-overlay-s/src/assets/edit/grid.svg new file mode 100644 index 0000000..4380ca6 --- /dev/null +++ b/wlx-overlay-s/src/assets/edit/grid.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/wlx-overlay-s/src/assets/bar/inout.svg b/wlx-overlay-s/src/assets/edit/inout.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/inout.svg rename to wlx-overlay-s/src/assets/edit/inout.svg diff --git a/wlx-overlay-s/src/assets/bar/lock.svg b/wlx-overlay-s/src/assets/edit/lock.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/lock.svg rename to wlx-overlay-s/src/assets/edit/lock.svg diff --git a/wlx-overlay-s/src/assets/bar/lock_open.svg b/wlx-overlay-s/src/assets/edit/lock_open.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/lock_open.svg rename to wlx-overlay-s/src/assets/edit/lock_open.svg diff --git a/wlx-overlay-s/src/assets/bar/mouse.svg b/wlx-overlay-s/src/assets/edit/mouse.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/mouse.svg rename to wlx-overlay-s/src/assets/edit/mouse.svg diff --git a/wlx-overlay-s/src/assets/bar/mouse_lock.svg b/wlx-overlay-s/src/assets/edit/mouse_lock.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/mouse_lock.svg rename to wlx-overlay-s/src/assets/edit/mouse_lock.svg diff --git a/wlx-overlay-s/src/assets/bar/move-all.svg b/wlx-overlay-s/src/assets/edit/move-all.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/move-all.svg rename to wlx-overlay-s/src/assets/edit/move-all.svg diff --git a/wlx-overlay-s/src/assets/bar/move-horizontal.svg b/wlx-overlay-s/src/assets/edit/move-horizontal.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/move-horizontal.svg rename to wlx-overlay-s/src/assets/edit/move-horizontal.svg diff --git a/wlx-overlay-s/src/assets/edit/pin.svg b/wlx-overlay-s/src/assets/edit/pin.svg new file mode 100644 index 0000000..96f6bef --- /dev/null +++ b/wlx-overlay-s/src/assets/edit/pin.svg @@ -0,0 +1 @@ + diff --git a/wlx-overlay-s/src/assets/bar/resize.svg b/wlx-overlay-s/src/assets/edit/resize.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/resize.svg rename to wlx-overlay-s/src/assets/edit/resize.svg diff --git a/wlx-overlay-s/src/assets/bar/screen-add.svg b/wlx-overlay-s/src/assets/edit/screen-add.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/screen-add.svg rename to wlx-overlay-s/src/assets/edit/screen-add.svg diff --git a/wlx-overlay-s/src/assets/bar/screen-options.svg b/wlx-overlay-s/src/assets/edit/screen-options.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/screen-options.svg rename to wlx-overlay-s/src/assets/edit/screen-options.svg diff --git a/wlx-overlay-s/src/assets/bar/screen-remove.svg b/wlx-overlay-s/src/assets/edit/screen-remove.svg similarity index 100% rename from wlx-overlay-s/src/assets/bar/screen-remove.svg rename to wlx-overlay-s/src/assets/edit/screen-remove.svg diff --git a/wlx-overlay-s/src/assets/gui/bar.xml b/wlx-overlay-s/src/assets/gui/bar.xml deleted file mode 100644 index 7d4f316..0000000 --- a/wlx-overlay-s/src/assets/gui/bar.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - -
- - - - - - - - - - - - -
-
-
\ No newline at end of file diff --git a/wlx-overlay-s/src/assets/gui/edit.xml b/wlx-overlay-s/src/assets/gui/edit.xml index 2eeacb6..ff35be6 100644 --- a/wlx-overlay-s/src/assets/gui/edit.xml +++ b/wlx-overlay-s/src/assets/gui/edit.xml @@ -6,49 +6,84 @@ border="2" round="50%" padding="8" gradient="vertical" tooltip_side="bottom" /> + +
-