@@ -37,18 +37,18 @@
|
|||||||
<Separator />
|
<Separator />
|
||||||
<label translation="APP_LAUNCHER.ASPECT_TITLE" />
|
<label translation="APP_LAUNCHER.ASPECT_TITLE" />
|
||||||
<RadioGroup id="radio_orientation" flex_direction="row" gap="16">
|
<RadioGroup id="radio_orientation" flex_direction="row" gap="16">
|
||||||
<RadioBox translation="APP_LAUNCHER.ASPECT.WIDE" value="Wide" tooltip="16:9" checked="1" />
|
<RadioBox translation="APP_LAUNCHER.ASPECT.WIDE" value="Wide" tooltip_str="16:9" checked="1" />
|
||||||
<RadioBox translation="APP_LAUNCHER.ASPECT.SEMI_WIDE" value="SemiWide" tooltip="3:2" />
|
<RadioBox translation="APP_LAUNCHER.ASPECT.SEMI_WIDE" value="SemiWide" tooltip_str="3:2" />
|
||||||
<RadioBox translation="APP_LAUNCHER.ASPECT.SQUARE" value="Square" tooltip="1:1" />
|
<RadioBox translation="APP_LAUNCHER.ASPECT.SQUARE" value="Square" tooltip_str="1:1" />
|
||||||
<RadioBox translation="APP_LAUNCHER.ASPECT.SEMI_TALL" value="SemiTall" tooltip="2:3" />
|
<RadioBox translation="APP_LAUNCHER.ASPECT.SEMI_TALL" value="SemiTall" tooltip_str="2:3" />
|
||||||
<RadioBox translation="APP_LAUNCHER.ASPECT.TALL" value="Tall" tooltip="9:16" />
|
<RadioBox translation="APP_LAUNCHER.ASPECT.TALL" value="Tall" tooltip_str="9:16" />
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
<!-- Separator /> // saved settings override this, so let's hide it for now
|
<!-- Separator /> // saved settings override this, so let's hide it for now
|
||||||
<label translation="APP_LAUNCHER.POS_TITLE" />
|
<label translation="APP_LAUNCHER.POS_TITLE" />
|
||||||
<RadioGroup id="radio_pos" flex_direction="row" gap="16">
|
<RadioGroup id="radio_pos" flex_direction="row" gap="16">
|
||||||
<RadioBox translation="APP_LAUNCHER.POS.FLOATING" value="Floating" tooltip="APP_LAUNCHER.POS.FLOATING_HELP" />
|
<RadioBox translation="APP_LAUNCHER.POS.FLOATING" value="Floating" tooltip_str="APP_LAUNCHER.POS.FLOATING_HELP" />
|
||||||
<RadioBox translation="APP_LAUNCHER.POS.ANCHORED" value="Anchored" tooltip="APP_LAUNCHER.POS.ANCHORED_HELP" checked="1" />
|
<RadioBox translation="APP_LAUNCHER.POS.ANCHORED" value="Anchored" tooltip_str="APP_LAUNCHER.POS.ANCHORED_HELP" checked="1" />
|
||||||
<RadioBox translation="APP_LAUNCHER.POS.STATIC" value="Static" tooltip="APP_LAUNCHER.POS.STATIC_HELP" />
|
<RadioBox translation="APP_LAUNCHER.POS.STATIC" value="Static" tooltip_str="APP_LAUNCHER.POS.STATIC_HELP" />
|
||||||
</RadioGroup -->
|
</RadioGroup -->
|
||||||
<Separator />
|
<Separator />
|
||||||
<div flex_direction="row" justify_content="space_between" gap="16">
|
<div flex_direction="row" justify_content="space_between" gap="16">
|
||||||
@@ -61,4 +61,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</elements>
|
</elements>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
components::{self, Component, ComponentBase, ComponentTrait, RefreshData, tooltip::ComponentTooltip},
|
components::{
|
||||||
|
self, Component, ComponentBase, ComponentTrait, RefreshData,
|
||||||
|
tooltip::{ComponentTooltip, TooltipTrait},
|
||||||
|
},
|
||||||
drawing::{self, Boundary, Color},
|
drawing::{self, Boundary, Color},
|
||||||
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{LayoutTask, WidgetID, WidgetPair},
|
layout::{WidgetID, WidgetPair},
|
||||||
renderer_vk::{
|
renderer_vk::{
|
||||||
text::{FontWeight, TextStyle, custom_glyph::CustomGlyphData},
|
text::{FontWeight, TextStyle, custom_glyph::CustomGlyphData},
|
||||||
util::centered_matrix,
|
util::centered_matrix,
|
||||||
@@ -90,6 +93,12 @@ struct State {
|
|||||||
last_pressed: Instant,
|
last_pressed: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TooltipTrait for State {
|
||||||
|
fn get(&mut self) -> &mut Option<Rc<ComponentTooltip>> {
|
||||||
|
&mut self.active_tooltip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Data {
|
struct Data {
|
||||||
id_label: WidgetID, // Label
|
id_label: WidgetID, // Label
|
||||||
id_rect: WidgetID, // Rectangle
|
id_rect: WidgetID, // Rectangle
|
||||||
@@ -268,7 +277,7 @@ fn register_event_mouse_enter(
|
|||||||
data: Rc<Data>,
|
data: Rc<Data>,
|
||||||
state: Rc<RefCell<State>>,
|
state: Rc<RefCell<State>>,
|
||||||
listeners: &mut EventListenerCollection,
|
listeners: &mut EventListenerCollection,
|
||||||
info: Option<components::tooltip::TooltipInfo>,
|
tooltip_info: Option<components::tooltip::TooltipInfo>,
|
||||||
anim_mult: f32,
|
anim_mult: f32,
|
||||||
) -> EventListenerID {
|
) -> EventListenerID {
|
||||||
listeners.register(
|
listeners.register(
|
||||||
@@ -281,17 +290,7 @@ fn register_event_mouse_enter(
|
|||||||
.alterables
|
.alterables
|
||||||
.animate(anim_hover_create(state.clone(), event_data.widget_id, true, anim_mult));
|
.animate(anim_hover_create(state.clone(), event_data.widget_id, true, anim_mult));
|
||||||
|
|
||||||
if let Some(info) = info.clone() {
|
ComponentTooltip::register_hover_in(common, &tooltip_info, data.id_rect, state.clone());
|
||||||
common.alterables.tasks.push(LayoutTask::ModifyLayoutState({
|
|
||||||
let widget_to_watch = data.id_rect;
|
|
||||||
let state = state.clone();
|
|
||||||
Box::new(move |m| {
|
|
||||||
state.borrow_mut().active_tooltip =
|
|
||||||
Some(components::tooltip::show(m.layout, widget_to_watch, info.clone())?);
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
state.borrow_mut().hovered = true;
|
state.borrow_mut().hovered = true;
|
||||||
Ok(EventResult::Pass)
|
Ok(EventResult::Pass)
|
||||||
|
|||||||
@@ -9,7 +9,11 @@ use taffy::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
components::{Component, ComponentBase, ComponentTrait, RefreshData, radio_group::ComponentRadioGroup},
|
components::{
|
||||||
|
Component, ComponentBase, ComponentTrait, RefreshData,
|
||||||
|
radio_group::ComponentRadioGroup,
|
||||||
|
tooltip::{self, ComponentTooltip, TooltipTrait},
|
||||||
|
},
|
||||||
drawing::Color,
|
drawing::Color,
|
||||||
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
@@ -31,6 +35,7 @@ pub struct Params {
|
|||||||
pub checked: bool,
|
pub checked: bool,
|
||||||
pub radio_group: Option<Rc<ComponentRadioGroup>>,
|
pub radio_group: Option<Rc<ComponentRadioGroup>>,
|
||||||
pub value: Option<Rc<str>>,
|
pub value: Option<Rc<str>>,
|
||||||
|
pub tooltip: Option<tooltip::TooltipInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Params {
|
impl Default for Params {
|
||||||
@@ -42,6 +47,7 @@ impl Default for Params {
|
|||||||
checked: false,
|
checked: false,
|
||||||
radio_group: None,
|
radio_group: None,
|
||||||
value: None,
|
value: None,
|
||||||
|
tooltip: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,6 +65,13 @@ struct State {
|
|||||||
down: bool,
|
down: bool,
|
||||||
on_toggle: Option<CheckboxToggleCallback>,
|
on_toggle: Option<CheckboxToggleCallback>,
|
||||||
self_ref: Weak<ComponentCheckbox>,
|
self_ref: Weak<ComponentCheckbox>,
|
||||||
|
active_tooltip: Option<Rc<ComponentTooltip>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TooltipTrait for State {
|
||||||
|
fn get(&mut self) -> &mut Option<Rc<ComponentTooltip>> {
|
||||||
|
&mut self.active_tooltip
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::struct_field_names)]
|
#[allow(clippy::struct_field_names)]
|
||||||
@@ -181,6 +194,7 @@ fn anim_hover_out(state: Rc<RefCell<State>>, widget_id: WidgetID, anim_mult: f32
|
|||||||
fn register_event_mouse_enter(
|
fn register_event_mouse_enter(
|
||||||
state: Rc<RefCell<State>>,
|
state: Rc<RefCell<State>>,
|
||||||
listeners: &mut EventListenerCollection,
|
listeners: &mut EventListenerCollection,
|
||||||
|
tooltip_info: Option<tooltip::TooltipInfo>,
|
||||||
anim_mult: f32,
|
anim_mult: f32,
|
||||||
) -> EventListenerID {
|
) -> EventListenerID {
|
||||||
listeners.register(
|
listeners.register(
|
||||||
@@ -190,6 +204,9 @@ fn register_event_mouse_enter(
|
|||||||
common
|
common
|
||||||
.alterables
|
.alterables
|
||||||
.animate(anim_hover_in(state.clone(), event_data.widget_id, anim_mult));
|
.animate(anim_hover_in(state.clone(), event_data.widget_id, anim_mult));
|
||||||
|
|
||||||
|
ComponentTooltip::register_hover_in(common, &tooltip_info, event_data.widget_id, state.clone());
|
||||||
|
|
||||||
state.borrow_mut().hovered = true;
|
state.borrow_mut().hovered = true;
|
||||||
Ok(EventResult::Pass)
|
Ok(EventResult::Pass)
|
||||||
}),
|
}),
|
||||||
@@ -208,7 +225,13 @@ fn register_event_mouse_leave(
|
|||||||
common
|
common
|
||||||
.alterables
|
.alterables
|
||||||
.animate(anim_hover_out(state.clone(), event_data.widget_id, anim_mult));
|
.animate(anim_hover_out(state.clone(), event_data.widget_id, anim_mult));
|
||||||
state.borrow_mut().hovered = false;
|
|
||||||
|
{
|
||||||
|
let mut state = state.borrow_mut();
|
||||||
|
state.hovered = false;
|
||||||
|
state.active_tooltip = None;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(EventResult::Pass)
|
Ok(EventResult::Pass)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@@ -402,6 +425,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
hovered: false,
|
hovered: false,
|
||||||
on_toggle: None,
|
on_toggle: None,
|
||||||
self_ref: Weak::new(),
|
self_ref: Weak::new(),
|
||||||
|
active_tooltip: None,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let base = ComponentBase {
|
let base = ComponentBase {
|
||||||
@@ -410,7 +434,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
let mut widget = ess.layout.state.widgets.get(id_container).unwrap().state();
|
let mut widget = ess.layout.state.widgets.get(id_container).unwrap().state();
|
||||||
let anim_mult = ess.layout.state.globals.defaults().animation_mult;
|
let anim_mult = ess.layout.state.globals.defaults().animation_mult;
|
||||||
vec![
|
vec![
|
||||||
register_event_mouse_enter(state.clone(), &mut widget.event_listeners, anim_mult),
|
register_event_mouse_enter(state.clone(), &mut widget.event_listeners, params.tooltip, anim_mult),
|
||||||
register_event_mouse_leave(state.clone(), &mut widget.event_listeners, anim_mult),
|
register_event_mouse_leave(state.clone(), &mut widget.event_listeners, anim_mult),
|
||||||
register_event_mouse_press(state.clone(), &mut widget.event_listeners),
|
register_event_mouse_press(state.clone(), &mut widget.event_listeners),
|
||||||
register_event_mouse_release(data.clone(), state.clone(), &mut widget.event_listeners),
|
register_event_mouse_release(data.clone(), state.clone(), &mut widget.event_listeners),
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ use taffy::prelude::{length, percent};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
components::{Component, ComponentBase, ComponentTrait, RefreshData},
|
components::{
|
||||||
|
Component, ComponentBase, ComponentTrait, RefreshData,
|
||||||
|
tooltip::{self, ComponentTooltip, TooltipTrait},
|
||||||
|
},
|
||||||
drawing::{self},
|
drawing::{self},
|
||||||
event::{
|
event::{
|
||||||
self, CallbackDataCommon, CallbackMetadata, EventAlterables, EventListenerCollection, EventListenerKind,
|
self, CallbackDataCommon, CallbackMetadata, EventAlterables, EventListenerCollection, EventListenerKind,
|
||||||
@@ -70,6 +73,7 @@ pub struct Params {
|
|||||||
pub style: taffy::Style,
|
pub style: taffy::Style,
|
||||||
pub values: ValuesMinMax,
|
pub values: ValuesMinMax,
|
||||||
pub show_value: bool,
|
pub show_value: bool,
|
||||||
|
pub tooltip: Option<tooltip::TooltipInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
@@ -77,6 +81,13 @@ struct State {
|
|||||||
hovered: bool,
|
hovered: bool,
|
||||||
values: ValuesMinMax,
|
values: ValuesMinMax,
|
||||||
on_value_changed: Option<SliderValueChangedCallback>,
|
on_value_changed: Option<SliderValueChangedCallback>,
|
||||||
|
active_tooltip: Option<Rc<ComponentTooltip>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TooltipTrait for State {
|
||||||
|
fn get(&mut self) -> &mut Option<Rc<ComponentTooltip>> {
|
||||||
|
&mut self.active_tooltip
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Data {
|
struct Data {
|
||||||
@@ -304,14 +315,18 @@ fn register_event_mouse_enter(
|
|||||||
data: Rc<Data>,
|
data: Rc<Data>,
|
||||||
state: Rc<RefCell<State>>,
|
state: Rc<RefCell<State>>,
|
||||||
listeners: &mut EventListenerCollection,
|
listeners: &mut EventListenerCollection,
|
||||||
|
tooltip_info: Option<tooltip::TooltipInfo>,
|
||||||
anim_mult: f32,
|
anim_mult: f32,
|
||||||
) -> event::EventListenerID {
|
) -> event::EventListenerID {
|
||||||
listeners.register(
|
listeners.register(
|
||||||
EventListenerKind::MouseEnter,
|
EventListenerKind::MouseEnter,
|
||||||
Box::new(move |common, _data, (), ()| {
|
Box::new(move |common, event_data, (), ()| {
|
||||||
common.alterables.trigger_haptics();
|
common.alterables.trigger_haptics();
|
||||||
state.borrow_mut().hovered = true;
|
state.borrow_mut().hovered = true;
|
||||||
on_enter_anim(common, data.slider_handle_rect_id, anim_mult);
|
on_enter_anim(common, data.slider_handle_rect_id, anim_mult);
|
||||||
|
|
||||||
|
ComponentTooltip::register_hover_in(common, &tooltip_info, event_data.widget_id, state.clone());
|
||||||
|
|
||||||
Ok(EventResult::Pass)
|
Ok(EventResult::Pass)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@@ -327,8 +342,14 @@ fn register_event_mouse_leave(
|
|||||||
EventListenerKind::MouseLeave,
|
EventListenerKind::MouseLeave,
|
||||||
Box::new(move |common, _data, (), ()| {
|
Box::new(move |common, _data, (), ()| {
|
||||||
common.alterables.trigger_haptics();
|
common.alterables.trigger_haptics();
|
||||||
state.borrow_mut().hovered = false;
|
|
||||||
|
{
|
||||||
|
let mut state = state.borrow_mut();
|
||||||
|
state.hovered = false;
|
||||||
|
state.active_tooltip = None;
|
||||||
|
}
|
||||||
on_leave_anim(common, data.slider_handle_rect_id, anim_mult);
|
on_leave_anim(common, data.slider_handle_rect_id, anim_mult);
|
||||||
|
|
||||||
Ok(EventResult::Pass)
|
Ok(EventResult::Pass)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@@ -474,6 +495,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
hovered: false,
|
hovered: false,
|
||||||
values: params.values,
|
values: params.values,
|
||||||
on_value_changed: None,
|
on_value_changed: None,
|
||||||
|
active_tooltip: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let globals = ess.layout.state.globals.clone();
|
let globals = ess.layout.state.globals.clone();
|
||||||
@@ -515,7 +537,13 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
let mut widget = ess.layout.state.widgets.get(body_id).unwrap().state();
|
let mut widget = ess.layout.state.widgets.get(body_id).unwrap().state();
|
||||||
let anim_mult = ess.layout.state.globals.defaults().animation_mult;
|
let anim_mult = ess.layout.state.globals.defaults().animation_mult;
|
||||||
vec![
|
vec![
|
||||||
register_event_mouse_enter(data.clone(), state.clone(), &mut widget.event_listeners, anim_mult),
|
register_event_mouse_enter(
|
||||||
|
data.clone(),
|
||||||
|
state.clone(),
|
||||||
|
&mut widget.event_listeners,
|
||||||
|
params.tooltip,
|
||||||
|
anim_mult,
|
||||||
|
),
|
||||||
register_event_mouse_leave(data.clone(), state.clone(), &mut widget.event_listeners, anim_mult),
|
register_event_mouse_leave(data.clone(), state.clone(), &mut widget.event_listeners, anim_mult),
|
||||||
register_event_mouse_motion(data.clone(), state.clone(), &mut widget.event_listeners),
|
register_event_mouse_motion(data.clone(), state.clone(), &mut widget.event_listeners),
|
||||||
register_event_mouse_press(data.clone(), state.clone(), &mut widget.event_listeners),
|
register_event_mouse_press(data.clone(), state.clone(), &mut widget.event_listeners),
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
use glam::{Mat4, Vec3};
|
use glam::{Mat4, Vec2, Vec3};
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
use taffy::prelude::length;
|
use taffy::prelude::length;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
animation::{Animation, AnimationEasing},
|
||||||
components::{self, Component, ComponentBase, ComponentTrait, RefreshData},
|
components::{self, Component, ComponentBase, ComponentTrait, RefreshData},
|
||||||
drawing::Color,
|
drawing::Color,
|
||||||
|
event::CallbackDataCommon,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{self, LayoutTask, LayoutTasks, WidgetID, WidgetPair},
|
layout::{self, LayoutTask, LayoutTasks, WidgetID, WidgetPair},
|
||||||
renderer_vk::text::{FontWeight, TextStyle},
|
renderer_vk::text::{FontWeight, TextStyle},
|
||||||
@@ -17,6 +19,30 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub trait TooltipTrait {
|
||||||
|
fn get(&mut self) -> &mut Option<Rc<ComponentTooltip>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ComponentTooltip {
|
||||||
|
pub fn register_hover_in(
|
||||||
|
common: &mut CallbackDataCommon,
|
||||||
|
tooltip_info: &Option<TooltipInfo>,
|
||||||
|
widget_to_watch: WidgetID,
|
||||||
|
state: Rc<RefCell<dyn TooltipTrait>>,
|
||||||
|
) {
|
||||||
|
let Some(info) = tooltip_info.clone() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
common.alterables.tasks.push(LayoutTask::ModifyLayoutState({
|
||||||
|
Box::new(move |m| {
|
||||||
|
let mut state = state.borrow_mut();
|
||||||
|
*state.get() = Some(components::tooltip::show(m.layout, widget_to_watch, info.clone())?);
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub enum TooltipSide {
|
pub enum TooltipSide {
|
||||||
Left,
|
Left,
|
||||||
@@ -78,8 +104,6 @@ impl ComponentTrait for ComponentTooltip {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentTooltip {}
|
|
||||||
|
|
||||||
impl Drop for ComponentTooltip {
|
impl Drop for ComponentTooltip {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.tasks.push(LayoutTask::RemoveWidget(self.data.id_root));
|
self.tasks.push(LayoutTask::RemoveWidget(self.data.id_root));
|
||||||
@@ -180,7 +204,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let (_label, _) = ess.layout.add_child(
|
let (label, _) = ess.layout.add_child(
|
||||||
rect.id,
|
rect.id,
|
||||||
WidgetLabel::create(
|
WidgetLabel::create(
|
||||||
&mut globals.get(),
|
&mut globals.get(),
|
||||||
@@ -208,6 +232,35 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
tasks: ess.layout.tasks.clone(),
|
tasks: ess.layout.tasks.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let direction = match params.info.side {
|
||||||
|
TooltipSide::Left => Vec2::new(-1.0, 0.0),
|
||||||
|
TooltipSide::Right => Vec2::new(1.0, 0.0),
|
||||||
|
TooltipSide::Top => Vec2::new(0.0, -1.0),
|
||||||
|
TooltipSide::Bottom => Vec2::new(0.0, 1.0),
|
||||||
|
};
|
||||||
|
|
||||||
|
let anim_mult = ess.layout.state.globals.defaults().animation_mult;
|
||||||
|
ess.layout.animations.add(Animation::new(
|
||||||
|
rect.id,
|
||||||
|
(10.0 * anim_mult) as u32,
|
||||||
|
AnimationEasing::OutQuad,
|
||||||
|
Box::new(move |common, data| {
|
||||||
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap(); /* safe */
|
||||||
|
let alpha = data.pos;
|
||||||
|
rect.params.color.a = alpha;
|
||||||
|
rect.params.border_color.a = alpha;
|
||||||
|
|
||||||
|
let dir_mult = (1.0 - data.pos) * 5.0;
|
||||||
|
data.data.transform = Mat4::from_translation(Vec3::new(direction.x * dir_mult, direction.y * dir_mult, 0.0));
|
||||||
|
|
||||||
|
if let Some(mut label) = common.state.widgets.get_as::<WidgetLabel>(label.id) {
|
||||||
|
label.set_color(common, Color::new(1.0, 1.0, 1.0, alpha), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
common.alterables.mark_redraw();
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
|
||||||
ess.layout.defer_component_refresh(Component(tooltip.clone()));
|
ess.layout.defer_component_refresh(Component(tooltip.clone()));
|
||||||
Ok((div, tooltip))
|
Ok((div, tooltip))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ pub struct LayoutUpdateResult {
|
|||||||
pub sounds_to_play: Vec<WguiSoundType>,
|
pub sounds_to_play: Vec<WguiSoundType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ModifyLayoutStateFunc = Box<dyn Fn(ModifyLayoutStateData) -> anyhow::Result<()>>;
|
pub type ModifyLayoutStateFunc = Box<dyn FnOnce(ModifyLayoutStateData) -> anyhow::Result<()>>;
|
||||||
|
|
||||||
pub enum LayoutTask {
|
pub enum LayoutTask {
|
||||||
RemoveWidget(WidgetID),
|
RemoveWidget(WidgetID),
|
||||||
@@ -690,7 +690,7 @@ impl Layout {
|
|||||||
self.remove_widget(widget_id);
|
self.remove_widget(widget_id);
|
||||||
}
|
}
|
||||||
LayoutTask::ModifyLayoutState(callback) => {
|
LayoutTask::ModifyLayoutState(callback) => {
|
||||||
(*callback)(ModifyLayoutStateData { layout: self })?;
|
callback(ModifyLayoutStateData { layout: self })?;
|
||||||
}
|
}
|
||||||
LayoutTask::PlaySound(sound) => {
|
LayoutTask::PlaySound(sound) => {
|
||||||
if !self.sounds_to_play_once.contains(&sound) {
|
if !self.sounds_to_play_once.contains(&sound) {
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ use crate::{
|
|||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{
|
parser::{
|
||||||
AttribPair, ParserContext, ParserFile, get_asset_path_from_kv, parse_children, parse_f32, process_component,
|
AttribPair, ParserContext, ParserFile, get_asset_path_from_kv,
|
||||||
|
helpers::{TooltipAttribs, parse_attrib_tooltip},
|
||||||
|
parse_children, parse_f32, process_component,
|
||||||
style::{parse_color_opt, parse_round, parse_style, parse_text_style},
|
style::{parse_color_opt, parse_round, parse_style, parse_text_style},
|
||||||
},
|
},
|
||||||
widget::util::WLength,
|
widget::util::WLength,
|
||||||
@@ -25,8 +27,7 @@ pub fn parse_component_button<'a>(
|
|||||||
let mut hover_color: Option<Color> = None;
|
let mut hover_color: Option<Color> = None;
|
||||||
let mut hover_border_color: Option<Color> = None;
|
let mut hover_border_color: Option<Color> = None;
|
||||||
let mut round = WLength::Units(4.0);
|
let mut round = WLength::Units(4.0);
|
||||||
let mut tooltip: Option<Translation> = None;
|
let mut tooltip = TooltipAttribs::default();
|
||||||
let mut tooltip_side: Option<tooltip::TooltipSide> = None;
|
|
||||||
let mut sticky: bool = false;
|
let mut sticky: bool = false;
|
||||||
let mut long_press_time = 0.0;
|
let mut long_press_time = 0.0;
|
||||||
let mut sprite_src: Option<AssetPath> = None;
|
let mut sprite_src: Option<AssetPath> = None;
|
||||||
@@ -81,20 +82,6 @@ pub fn parse_component_button<'a>(
|
|||||||
sprite_src = Some(asset_path);
|
sprite_src = Some(asset_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"tooltip" if !value.is_empty() => tooltip = Some(Translation::from_translation_key(value)),
|
|
||||||
"tooltip_str" if !value.is_empty() => tooltip = Some(Translation::from_raw_text(value)),
|
|
||||||
"tooltip_side" => {
|
|
||||||
tooltip_side = match value {
|
|
||||||
"left" => Some(tooltip::TooltipSide::Left),
|
|
||||||
"right" => Some(tooltip::TooltipSide::Right),
|
|
||||||
"top" => Some(tooltip::TooltipSide::Top),
|
|
||||||
"bottom" => Some(tooltip::TooltipSide::Bottom),
|
|
||||||
_ => {
|
|
||||||
ctx.print_invalid_attrib(tag_name, key, value);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"sticky" => {
|
"sticky" => {
|
||||||
let mut sticky_i32 = 0;
|
let mut sticky_i32 = 0;
|
||||||
sticky = ctx.parse_check_i32(tag_name, key, value, &mut sticky_i32) && sticky_i32 == 1;
|
sticky = ctx.parse_check_i32(tag_name, key, value, &mut sticky_i32) && sticky_i32 == 1;
|
||||||
@@ -102,7 +89,9 @@ pub fn parse_component_button<'a>(
|
|||||||
"long_press_time" => {
|
"long_press_time" => {
|
||||||
long_press_time = parse_f32(value).unwrap_or(long_press_time);
|
long_press_time = parse_f32(value).unwrap_or(long_press_time);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {
|
||||||
|
parse_attrib_tooltip(ctx, tag_name, pair, &mut tooltip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,10 +107,7 @@ pub fn parse_component_button<'a>(
|
|||||||
style,
|
style,
|
||||||
text_style,
|
text_style,
|
||||||
round,
|
round,
|
||||||
tooltip: tooltip.map(|text| tooltip::TooltipInfo {
|
tooltip: tooltip.get_info(),
|
||||||
side: tooltip_side.map_or(tooltip::TooltipSide::Top, |f| f),
|
|
||||||
text,
|
|
||||||
}),
|
|
||||||
sticky,
|
sticky,
|
||||||
long_press_time,
|
long_press_time,
|
||||||
sprite_src,
|
sprite_src,
|
||||||
|
|||||||
@@ -2,9 +2,15 @@ use crate::{
|
|||||||
components::{Component, checkbox, radio_group::ComponentRadioGroup},
|
components::{Component, checkbox, radio_group::ComponentRadioGroup},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{AttribPair, Fetchable, ParserContext, process_component, style::parse_style},
|
parser::{
|
||||||
|
AttribPair, Fetchable, ParserContext,
|
||||||
|
helpers::{TooltipAttribs, parse_attrib_tooltip},
|
||||||
|
process_component,
|
||||||
|
style::parse_style,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub enum CheckboxKind {
|
pub enum CheckboxKind {
|
||||||
CheckBox,
|
CheckBox,
|
||||||
RadioBox,
|
RadioBox,
|
||||||
@@ -21,6 +27,7 @@ pub fn parse_component_checkbox(
|
|||||||
let mut translation = Translation::default();
|
let mut translation = Translation::default();
|
||||||
let mut checked = 0;
|
let mut checked = 0;
|
||||||
let mut component_value = None;
|
let mut component_value = None;
|
||||||
|
let mut tooltip = TooltipAttribs::default();
|
||||||
|
|
||||||
let style = parse_style(ctx, attribs, tag_name);
|
let style = parse_style(ctx, attribs, tag_name);
|
||||||
|
|
||||||
@@ -46,7 +53,9 @@ pub fn parse_component_checkbox(
|
|||||||
"checked" => {
|
"checked" => {
|
||||||
ctx.parse_check_i32(tag_name, key, value, &mut checked);
|
ctx.parse_check_i32(tag_name, key, value, &mut checked);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {
|
||||||
|
parse_attrib_tooltip(ctx, tag_name, pair, &mut tooltip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,6 +90,7 @@ pub fn parse_component_checkbox(
|
|||||||
style,
|
style,
|
||||||
radio_group,
|
radio_group,
|
||||||
value: component_value,
|
value: component_value,
|
||||||
|
tooltip: tooltip.get_info(),
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
components::{Component, slider},
|
components::{Component, slider},
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{AttribPair, ParserContext, process_component, style::parse_style},
|
parser::{
|
||||||
|
AttribPair, ParserContext,
|
||||||
|
helpers::{TooltipAttribs, parse_attrib_tooltip},
|
||||||
|
process_component,
|
||||||
|
style::parse_style,
|
||||||
|
},
|
||||||
widget::ConstructEssentials,
|
widget::ConstructEssentials,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -16,6 +21,7 @@ pub fn parse_component_slider(
|
|||||||
let mut initial_value = 0.5;
|
let mut initial_value = 0.5;
|
||||||
let mut step = 1.0;
|
let mut step = 1.0;
|
||||||
let mut show_value = 1;
|
let mut show_value = 1;
|
||||||
|
let mut tooltip = TooltipAttribs::default();
|
||||||
|
|
||||||
let style = parse_style(ctx, attribs, tag_name);
|
let style = parse_style(ctx, attribs, tag_name);
|
||||||
|
|
||||||
@@ -37,7 +43,9 @@ pub fn parse_component_slider(
|
|||||||
"show_value" => {
|
"show_value" => {
|
||||||
ctx.parse_check_i32(tag_name, key, value, &mut show_value);
|
ctx.parse_check_i32(tag_name, key, value, &mut show_value);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {
|
||||||
|
parse_attrib_tooltip(ctx, tag_name, pair, &mut tooltip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +63,7 @@ pub fn parse_component_slider(
|
|||||||
step,
|
step,
|
||||||
},
|
},
|
||||||
show_value: show_value != 0,
|
show_value: show_value != 0,
|
||||||
|
tooltip: tooltip.get_info(),
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|||||||
40
wgui/src/parser/helpers.rs
Normal file
40
wgui/src/parser/helpers.rs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
use crate::{
|
||||||
|
components::tooltip,
|
||||||
|
i18n::Translation,
|
||||||
|
parser::{AttribPair, ParserContext},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct TooltipAttribs {
|
||||||
|
tooltip: Option<Translation>,
|
||||||
|
tooltip_side: Option<tooltip::TooltipSide>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TooltipAttribs {
|
||||||
|
pub fn get_info(self) -> Option<tooltip::TooltipInfo> {
|
||||||
|
self.tooltip.map(|text| tooltip::TooltipInfo {
|
||||||
|
text,
|
||||||
|
side: self.tooltip_side.map_or(tooltip::TooltipSide::Top, |f| f),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_attrib_tooltip(ctx: &mut ParserContext, tag_name: &str, pair: &AttribPair, tooltip: &mut TooltipAttribs) {
|
||||||
|
match pair.attrib.as_ref() {
|
||||||
|
"tooltip" if !pair.value.is_empty() => tooltip.tooltip = Some(Translation::from_translation_key(&pair.value)),
|
||||||
|
"tooltip_str" if !pair.value.is_empty() => tooltip.tooltip = Some(Translation::from_raw_text(&pair.value)),
|
||||||
|
"tooltip_side" => {
|
||||||
|
tooltip.tooltip_side = match pair.value.as_ref() {
|
||||||
|
"left" => Some(tooltip::TooltipSide::Left),
|
||||||
|
"right" => Some(tooltip::TooltipSide::Right),
|
||||||
|
"top" => Some(tooltip::TooltipSide::Top),
|
||||||
|
"bottom" => Some(tooltip::TooltipSide::Bottom),
|
||||||
|
_ => {
|
||||||
|
ctx.print_invalid_attrib(tag_name, &pair.attrib, &pair.value);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ mod component_checkbox;
|
|||||||
mod component_radio_group;
|
mod component_radio_group;
|
||||||
mod component_slider;
|
mod component_slider;
|
||||||
mod component_tabs;
|
mod component_tabs;
|
||||||
|
mod helpers;
|
||||||
mod style;
|
mod style;
|
||||||
mod widget_div;
|
mod widget_div;
|
||||||
mod widget_image;
|
mod widget_image;
|
||||||
|
|||||||
Reference in New Issue
Block a user