various_widgets: add visibility test, minor refactoring
This commit is contained in:
@@ -1,31 +1,40 @@
|
|||||||
<layout>
|
<layout>
|
||||||
|
<macro name="rect"
|
||||||
|
color="#000000aa"
|
||||||
|
round="4" border="2"
|
||||||
|
border_color="#ffffffaa"
|
||||||
|
flex_direction="column"
|
||||||
|
gap="4"
|
||||||
|
padding="8"
|
||||||
|
align_self="baseline"
|
||||||
|
align_items="baseline" />
|
||||||
|
|
||||||
<elements>
|
<elements>
|
||||||
<rectangle
|
<rectangle position="absolute" width="100%" height="100%" color="#1e3a3eee" />
|
||||||
width="1000" height="1000" min_width="1000" min_height="500"
|
<div
|
||||||
gap="4" flex_direction="column"
|
margin="16"
|
||||||
color="#444444ee"
|
gap="4"
|
||||||
|
flex_direction="column"
|
||||||
overflow_y="scroll">
|
overflow_y="scroll">
|
||||||
|
|
||||||
|
<rectangle macro="rect">
|
||||||
<label text="Raw text" color="#FFFFFF" />
|
<label text="Raw text" color="#FFFFFF" />
|
||||||
<label translation="TESTBED.HELLO_WORLD" color="#FFFFFF" />
|
<label translation="TESTBED.HELLO_WORLD" color="#FFFFFF" />
|
||||||
|
</rectangle>
|
||||||
|
|
||||||
<div margin_left="16" gap="8" flex_direction="column">
|
<rectangle macro="rect">
|
||||||
<label id="label_current_option" text="Click any of these buttons" size="20" weight="bold" />
|
<label id="label_current_option" text="Click any of these buttons" size="20" weight="bold" />
|
||||||
<Button id="button_popup" text="Show pop-up" width="200" height="32" color="#777777" />
|
|
||||||
<div gap="4">
|
<div gap="4">
|
||||||
<Button id="button_red" text="Red button" width="150" height="32" color="#FF0000" tooltip="I'm at the top" tooltip_side="top" />
|
<Button id="button_red" text="Red button" width="150" height="32" color="#FF0000" tooltip="I'm at the top" tooltip_side="top" />
|
||||||
<Button id="button_aqua" text="Aqua button" width="150" height="32" color="#00FFFF" tooltip="I'm at the bottom" tooltip_side="bottom" />
|
<Button id="button_aqua" text="Aqua button" width="150" height="32" color="#00FFFF" tooltip="I'm at the bottom" tooltip_side="bottom" />
|
||||||
<Button id="button_yellow" text="Yellow button" width="150" height="32" color="#FFFF00" tooltip="TESTBED.HELLO_WORLD" tooltip_side="right" />
|
<Button id="button_yellow" text="Yellow button" width="150" height="32" color="#FFFF00" tooltip="TESTBED.HELLO_WORLD" tooltip_side="right" />
|
||||||
</div>
|
</div>
|
||||||
|
<div gap="4">
|
||||||
<Button id="button_click_me" text="Click me" width="128" height="24" color="#FFFFFF" />
|
<Button id="button_click_me" text="Click me" width="128" height="24" color="#FFFFFF" />
|
||||||
|
<Button id="button_popup" text="Show pop-up" width="200" height="32" color="#777777" />
|
||||||
<div gap="8" align_items="center">
|
|
||||||
<CheckBox id="cb_first" text="I'm a checkbox!" />
|
|
||||||
<CheckBox text="and me too!" />
|
|
||||||
<CheckBox text="i'm tall" box_size="32" />
|
|
||||||
<CheckBox text="i'm checked by default" checked="1" />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label text="custom attrib test, you should see size rectangles below, each of them in R, G and B (if TESTBED is not set)" />
|
<label text="custom attrib test" />
|
||||||
<div flex_direction="row" gap="8">
|
<div flex_direction="row" gap="8">
|
||||||
<label text="lighter:" />
|
<label text="lighter:" />
|
||||||
|
|
||||||
@@ -39,13 +48,29 @@
|
|||||||
<rectangle _my_custom="green" _mult="0.5" width="16" height="16" />
|
<rectangle _my_custom="green" _mult="0.5" width="16" height="16" />
|
||||||
<rectangle _my_custom="blue" _mult="0.5" width="16" height="16" />
|
<rectangle _my_custom="blue" _mult="0.5" width="16" height="16" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</rectangle>
|
||||||
|
|
||||||
<div flex_direction="row" gap="16">
|
<rectangle macro="rect">
|
||||||
|
<label text="visibility test" weight="bold" />
|
||||||
|
<CheckBox id="cb_visible" height="24" text="visible" />
|
||||||
|
<div id="div_visibility" flex_direction="column" gap="8" margin_top="8" align_items="baseline" display="none">
|
||||||
|
<Button text="button" width="128" height="24" />
|
||||||
|
<Button text="button" width="128" height="24" />
|
||||||
|
<Button text="button" width="128" height="24" />
|
||||||
|
<CheckBox height="32" text="foobar" />
|
||||||
|
<Slider width="200" height="24" min_value="42" max_value="2137" value="100" />
|
||||||
|
</div>
|
||||||
|
</rectangle>
|
||||||
|
|
||||||
|
<rectangle macro="rect" flex_direction="row" gap="16">
|
||||||
|
<CheckBox id="cb_first" text="I'm a checkbox!" />
|
||||||
|
<CheckBox text="and me too!" />
|
||||||
|
<CheckBox text="i'm checked by default" checked="1" />
|
||||||
|
</rectangle>
|
||||||
|
|
||||||
|
<rectangle macro="rect" flex_direction="row" align_items="start">
|
||||||
<div flex_direction="column" gap="8">
|
<div flex_direction="column" gap="8">
|
||||||
<rectangle width="128" height="2" />
|
<label text="height 16" weight="bold" />
|
||||||
<label text="height 16" />
|
|
||||||
<rectangle width="128" height="2" />
|
|
||||||
|
|
||||||
<label text="range 0-100 value 25" />
|
<label text="range 0-100 value 25" />
|
||||||
<Slider width="200" height="16" min_value="0" max_value="100" value="25" />
|
<Slider width="200" height="16" min_value="0" max_value="100" value="25" />
|
||||||
@@ -57,10 +82,10 @@
|
|||||||
<Slider width="200" height="16" min_value="-10" max_value="42" value="0" />
|
<Slider width="200" height="16" min_value="-10" max_value="42" value="0" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<rectangle color="#ffffff44" width="2" height="100%" margin_left="4" margin_right="4" />
|
||||||
|
|
||||||
<div flex_direction="column" gap="8">
|
<div flex_direction="column" gap="8">
|
||||||
<rectangle width="128" height="2" />
|
<label text="height 24" weight="bold" />
|
||||||
<label text="height 24" />
|
|
||||||
<rectangle width="128" height="2" />
|
|
||||||
|
|
||||||
<label text="range 0-100 value 25" />
|
<label text="range 0-100 value 25" />
|
||||||
<Slider width="200" height="24" min_value="0" max_value="100" value="25" />
|
<Slider width="200" height="24" min_value="0" max_value="100" value="25" />
|
||||||
@@ -71,22 +96,7 @@
|
|||||||
<label text="range -10-42 value 0" />
|
<label text="range -10-42 value 0" />
|
||||||
<Slider width="200" height="24" min_value="-10" max_value="42" value="0" />
|
<Slider width="200" height="24" min_value="-10" max_value="42" value="0" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div flex_direction="column" gap="8">
|
|
||||||
<rectangle width="128" height="2" />
|
|
||||||
<label text="height 32" />
|
|
||||||
<rectangle width="128" height="2" />
|
|
||||||
|
|
||||||
<label text="range 0-100 value 25" />
|
|
||||||
<Slider width="200" height="32" min_value="0" max_value="100" value="25" />
|
|
||||||
|
|
||||||
<label text="range 10-20 value 15" />
|
|
||||||
<Slider width="200" height="32" min_value="10" max_value="20" value="15" />
|
|
||||||
|
|
||||||
<label text="range -10-42 value 0" />
|
|
||||||
<Slider width="200" height="32" min_value="-10" max_value="42" value="0" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</rectangle>
|
</rectangle>
|
||||||
|
</div>
|
||||||
</elements>
|
</elements>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -18,6 +18,7 @@ use wgui::{
|
|||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{Layout, LayoutParams, RcLayout, Widget},
|
layout::{Layout, LayoutParams, RcLayout, Widget},
|
||||||
parser::{Fetchable, ParseDocumentExtra, ParseDocumentParams, ParserState},
|
parser::{Fetchable, ParseDocumentExtra, ParseDocumentParams, ParserState},
|
||||||
|
taffy,
|
||||||
widget::{label::WidgetLabel, rectangle::WidgetRectangle},
|
widget::{label::WidgetLabel, rectangle::WidgetRectangle},
|
||||||
windowing::{WguiWindow, WguiWindowParams},
|
windowing::{WguiWindow, WguiWindowParams},
|
||||||
};
|
};
|
||||||
@@ -118,6 +119,24 @@ impl TestbedGeneric {
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let cb_visible = state.fetch_component_as::<ComponentCheckbox>("cb_visible")?;
|
||||||
|
let div_visibility = state.fetch_widget(&layout.state, "div_visibility")?;
|
||||||
|
|
||||||
|
cb_visible.on_toggle(Box::new(move |common, evt| {
|
||||||
|
let mut style = common
|
||||||
|
.state
|
||||||
|
.get_widget_style(div_visibility.id)
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
style.display = if evt.checked {
|
||||||
|
taffy::Display::Flex
|
||||||
|
} else {
|
||||||
|
taffy::Display::None
|
||||||
|
};
|
||||||
|
common.alterables.set_style(div_visibility.id, style);
|
||||||
|
Ok(())
|
||||||
|
}));
|
||||||
|
|
||||||
let label_cur_option = state.fetch_widget(&layout.state, "label_current_option")?;
|
let label_cur_option = state.fetch_widget(&layout.state, "label_current_option")?;
|
||||||
|
|
||||||
let button_click_me = state.fetch_component_as::<ComponentButton>("button_click_me")?;
|
let button_click_me = state.fetch_component_as::<ComponentButton>("button_click_me")?;
|
||||||
|
|||||||
@@ -196,6 +196,10 @@ _Tooltip text on hover, translated by key_
|
|||||||
|
|
||||||
`tooltip_side`: "top" | "bottom" | "left" | "right" (default: top)
|
`tooltip_side`: "top" | "bottom" | "left" | "right" (default: top)
|
||||||
|
|
||||||
|
`sticky`: "1" | "0" (default: "0")
|
||||||
|
|
||||||
|
_make button act as a toggle (visual only)_
|
||||||
|
|
||||||
#### Info
|
#### Info
|
||||||
|
|
||||||
Child widgets are supported and can be added directly in XML.
|
Child widgets are supported and can be added directly in XML.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
components::{self, tooltip::ComponentTooltip, Component, ComponentBase, ComponentTrait, InitData},
|
components::{self, Component, ComponentBase, ComponentTrait, RefreshData, tooltip::ComponentTooltip},
|
||||||
drawing::{self, Boundary, Color},
|
drawing::{self, Boundary, Color},
|
||||||
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
@@ -10,15 +10,15 @@ use crate::{
|
|||||||
util::centered_matrix,
|
util::centered_matrix,
|
||||||
},
|
},
|
||||||
widget::{
|
widget::{
|
||||||
|
ConstructEssentials, EventResult, WidgetData,
|
||||||
label::{WidgetLabel, WidgetLabelParams},
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
util::WLength,
|
util::WLength,
|
||||||
ConstructEssentials, EventResult, WidgetData,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use glam::{Mat4, Vec3};
|
use glam::{Mat4, Vec3};
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
use taffy::{prelude::length, AlignItems, JustifyContent};
|
use taffy::{AlignItems, JustifyContent, prelude::length};
|
||||||
|
|
||||||
pub struct Params {
|
pub struct Params {
|
||||||
pub text: Option<Translation>, // if unset, label will not be populated
|
pub text: Option<Translation>, // if unset, label will not be populated
|
||||||
@@ -83,11 +83,15 @@ pub struct ComponentButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentTrait for ComponentButton {
|
impl ComponentTrait for ComponentButton {
|
||||||
fn base(&mut self) -> &mut ComponentBase {
|
fn base(&self) -> &ComponentBase {
|
||||||
|
&self.base
|
||||||
|
}
|
||||||
|
|
||||||
|
fn base_mut(&mut self) -> &mut ComponentBase {
|
||||||
&mut self.base
|
&mut self.base
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&self, _data: &mut InitData) {}
|
fn refresh(&self, _data: &mut RefreshData) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentButton {
|
impl ComponentButton {
|
||||||
@@ -339,6 +343,7 @@ fn register_event_mouse_release(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Result<(WidgetPair, Rc<ComponentButton>)> {
|
pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Result<(WidgetPair, Rc<ComponentButton>)> {
|
||||||
let globals = ess.layout.state.globals.clone();
|
let globals = ess.layout.state.globals.clone();
|
||||||
let mut style = params.style;
|
let mut style = params.style;
|
||||||
@@ -390,7 +395,14 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
|
|
||||||
let id_rect = root.id;
|
let id_rect = root.id;
|
||||||
|
|
||||||
let light_text = (color.r + color.g + color.b) < 1.5;
|
let light_text = {
|
||||||
|
let mult = if globals.get().defaults.dark_mode {
|
||||||
|
color.a
|
||||||
|
} else {
|
||||||
|
1.0 - color.a
|
||||||
|
};
|
||||||
|
(color.r + color.g + color.b) * mult < 1.5
|
||||||
|
};
|
||||||
|
|
||||||
let id_label = if let Some(content) = params.text {
|
let id_label = if let Some(content) = params.text {
|
||||||
let (label, _node_label) = ess.layout.add_child(
|
let (label, _node_label) = ess.layout.add_child(
|
||||||
@@ -436,6 +448,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
let base = ComponentBase {
|
let base = ComponentBase {
|
||||||
|
id: root.id,
|
||||||
lhandles: {
|
lhandles: {
|
||||||
let mut widget = ess.layout.state.widgets.get(id_rect).unwrap().state();
|
let mut widget = ess.layout.state.widgets.get(id_rect).unwrap().state();
|
||||||
vec![
|
vec![
|
||||||
@@ -449,6 +462,6 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
|
|
||||||
let button = Rc::new(ComponentButton { base, data, state });
|
let button = Rc::new(ComponentButton { base, data, state });
|
||||||
|
|
||||||
ess.layout.defer_component_init(Component(button.clone()));
|
ess.layout.defer_component_refresh(Component(button.clone()));
|
||||||
Ok((root, button))
|
Ok((root, button))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
use taffy::{
|
use taffy::{
|
||||||
prelude::{length, percent},
|
|
||||||
AlignItems, JustifyContent,
|
AlignItems, JustifyContent,
|
||||||
|
prelude::{length, percent},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
components::{Component, ComponentBase, ComponentTrait, InitData},
|
components::{Component, ComponentBase, ComponentTrait, RefreshData},
|
||||||
drawing::Color,
|
drawing::Color,
|
||||||
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
event::{CallbackDataCommon, EventListenerCollection, EventListenerID, EventListenerKind},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{self, WidgetID, WidgetPair},
|
layout::{self, WidgetID, WidgetPair},
|
||||||
renderer_vk::text::{FontWeight, TextStyle},
|
renderer_vk::text::{FontWeight, TextStyle},
|
||||||
widget::{
|
widget::{
|
||||||
|
ConstructEssentials, EventResult,
|
||||||
label::{WidgetLabel, WidgetLabelParams},
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
util::WLength,
|
util::WLength,
|
||||||
ConstructEssentials, EventResult,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -68,11 +68,15 @@ pub struct ComponentCheckbox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentTrait for ComponentCheckbox {
|
impl ComponentTrait for ComponentCheckbox {
|
||||||
fn base(&mut self) -> &mut ComponentBase {
|
fn base(&self) -> &ComponentBase {
|
||||||
|
&self.base
|
||||||
|
}
|
||||||
|
|
||||||
|
fn base_mut(&mut self) -> &mut ComponentBase {
|
||||||
&mut self.base
|
&mut self.base
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&self, _data: &mut InitData) {}
|
fn refresh(&self, _data: &mut RefreshData) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const COLOR_CHECKED: Color = Color::new(0.1, 0.5, 1.0, 1.0);
|
const COLOR_CHECKED: Color = Color::new(0.1, 0.5, 1.0, 1.0);
|
||||||
@@ -333,6 +337,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
let base = ComponentBase {
|
let base = ComponentBase {
|
||||||
|
id: root.id,
|
||||||
lhandles: {
|
lhandles: {
|
||||||
let mut widget = ess.layout.state.widgets.get(id_container).unwrap().state();
|
let mut widget = ess.layout.state.widgets.get(id_container).unwrap().state();
|
||||||
vec![
|
vec![
|
||||||
@@ -346,6 +351,6 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
|
|
||||||
let checkbox = Rc::new(ComponentCheckbox { base, data, state });
|
let checkbox = Rc::new(ComponentCheckbox { base, data, state });
|
||||||
|
|
||||||
ess.layout.defer_component_init(Component(checkbox.clone()));
|
ess.layout.defer_component_refresh(Component(checkbox.clone()));
|
||||||
Ok((root, checkbox))
|
Ok((root, checkbox))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::rc::Rc;
|
|||||||
use crate::{
|
use crate::{
|
||||||
any::AnyTrait,
|
any::AnyTrait,
|
||||||
event::{CallbackDataCommon, EventListenerID},
|
event::{CallbackDataCommon, EventListenerID},
|
||||||
|
layout::WidgetID,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod button;
|
pub mod button;
|
||||||
@@ -10,7 +11,7 @@ pub mod checkbox;
|
|||||||
pub mod slider;
|
pub mod slider;
|
||||||
pub mod tooltip;
|
pub mod tooltip;
|
||||||
|
|
||||||
pub struct InitData<'a> {
|
pub struct RefreshData<'a> {
|
||||||
pub common: &'a mut CallbackDataCommon<'a>,
|
pub common: &'a mut CallbackDataCommon<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,11 +20,19 @@ pub struct InitData<'a> {
|
|||||||
pub struct ComponentBase {
|
pub struct ComponentBase {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
lhandles: Vec<EventListenerID>,
|
lhandles: Vec<EventListenerID>,
|
||||||
|
id: WidgetID,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ComponentBase {
|
||||||
|
pub const fn get_id(&self) -> WidgetID {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ComponentTrait: AnyTrait {
|
pub trait ComponentTrait: AnyTrait {
|
||||||
fn base(&mut self) -> &mut ComponentBase;
|
fn base(&self) -> &ComponentBase;
|
||||||
fn init(&self, data: &mut InitData);
|
fn base_mut(&mut self) -> &mut ComponentBase;
|
||||||
|
fn refresh(&self, data: &mut RefreshData);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use taffy::prelude::{length, percent};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
components::{Component, ComponentBase, ComponentTrait, InitData},
|
components::{Component, ComponentBase, ComponentTrait, RefreshData},
|
||||||
drawing::{self},
|
drawing::{self},
|
||||||
event::{self, CallbackDataCommon, EventListenerCollection, EventListenerKind},
|
event::{self, CallbackDataCommon, EventListenerCollection, EventListenerKind},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
@@ -15,11 +15,11 @@ use crate::{
|
|||||||
util,
|
util,
|
||||||
},
|
},
|
||||||
widget::{
|
widget::{
|
||||||
|
ConstructEssentials, EventResult,
|
||||||
div::WidgetDiv,
|
div::WidgetDiv,
|
||||||
label::{WidgetLabel, WidgetLabelParams},
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
util::WLength,
|
util::WLength,
|
||||||
ConstructEssentials, EventResult,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -80,7 +80,8 @@ struct Data {
|
|||||||
body: WidgetID, // Div
|
body: WidgetID, // Div
|
||||||
slider_handle_rect_id: WidgetID, // Rectangle
|
slider_handle_rect_id: WidgetID, // Rectangle
|
||||||
slider_text_id: WidgetID, // Text
|
slider_text_id: WidgetID, // Text
|
||||||
slider_handle_node: taffy::NodeId,
|
slider_handle: WidgetPair,
|
||||||
|
slider_handle_node_id: taffy::NodeId,
|
||||||
slider_body_node: taffy::NodeId,
|
slider_body_node: taffy::NodeId,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,13 +99,17 @@ pub struct ComponentSlider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentTrait for ComponentSlider {
|
impl ComponentTrait for ComponentSlider {
|
||||||
fn init(&self, init_data: &mut InitData) {
|
fn refresh(&self, init_data: &mut RefreshData) {
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
let value = state.values.value;
|
let value = state.values.value;
|
||||||
state.set_value(init_data.common, &self.data, value);
|
state.set_value(init_data.common, &self.data, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn base(&mut self) -> &mut ComponentBase {
|
fn base(&self) -> &ComponentBase {
|
||||||
|
&self.base
|
||||||
|
}
|
||||||
|
|
||||||
|
fn base_mut(&mut self) -> &mut ComponentBase {
|
||||||
&mut self.base
|
&mut self.base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,17 +192,15 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_value(&mut self, common: &mut CallbackDataCommon, data: &Data, value: f32) {
|
fn set_value(&mut self, common: &mut CallbackDataCommon, data: &Data, value: f32) {
|
||||||
//common.call_on_widget(data.slider_handle_id, |_div: &mut Div| {});
|
|
||||||
|
|
||||||
let before = self.values.value;
|
let before = self.values.value;
|
||||||
self.values.set_value(value);
|
self.values.set_value(value);
|
||||||
|
|
||||||
let changed = self.values.value != before;
|
let changed = self.values.value != before;
|
||||||
let mut style = common.state.tree.style(data.slider_handle_node).unwrap().clone();
|
let mut style = common.state.tree.style(data.slider_handle_node_id).unwrap().clone();
|
||||||
conf_handle_style(&self.values, data.slider_body_node, &mut style, &common.state.tree);
|
conf_handle_style(&self.values, data.slider_body_node, &mut style, &common.state.tree);
|
||||||
common.alterables.mark_dirty(data.slider_handle_node);
|
common.alterables.mark_dirty(data.slider_handle_node_id);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
common.alterables.set_style(data.slider_handle_node, style);
|
common.alterables.set_style(data.slider_handle.id, style);
|
||||||
|
|
||||||
if let Some(mut label) = common.state.widgets.get_as::<WidgetLabel>(data.slider_text_id) {
|
if let Some(mut label) = common.state.widgets.get_as::<WidgetLabel>(data.slider_text_id) {
|
||||||
Self::update_text(common, &mut label, self.values.value);
|
Self::update_text(common, &mut label, self.values.value);
|
||||||
@@ -401,7 +404,8 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
};
|
};
|
||||||
|
|
||||||
// invisible outer handle body
|
// invisible outer handle body
|
||||||
let (slider_handle, slider_handle_node) = ess
|
let (slider_handle, slider_handle_node_id) =
|
||||||
|
ess
|
||||||
.layout
|
.layout
|
||||||
.add_child(body_id, WidgetDiv::create(), slider_handle_style)?;
|
.add_child(body_id, WidgetDiv::create(), slider_handle_style)?;
|
||||||
|
|
||||||
@@ -452,15 +456,17 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
|
|
||||||
let data = Rc::new(Data {
|
let data = Rc::new(Data {
|
||||||
body: body_id,
|
body: body_id,
|
||||||
slider_handle_node,
|
slider_handle,
|
||||||
slider_handle_rect_id: slider_handle_rect.id,
|
slider_handle_rect_id: slider_handle_rect.id,
|
||||||
slider_body_node,
|
slider_body_node,
|
||||||
|
slider_handle_node_id,
|
||||||
slider_text_id: slider_text.id,
|
slider_text_id: slider_text.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
let state = Rc::new(RefCell::new(state));
|
let state = Rc::new(RefCell::new(state));
|
||||||
|
|
||||||
let base = ComponentBase {
|
let base = ComponentBase {
|
||||||
|
id: root.id,
|
||||||
lhandles: {
|
lhandles: {
|
||||||
let mut widget = ess.layout.state.widgets.get(body_id).unwrap().state();
|
let mut widget = ess.layout.state.widgets.get(body_id).unwrap().state();
|
||||||
vec![
|
vec![
|
||||||
@@ -476,6 +482,6 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
|
|
||||||
let slider = Rc::new(ComponentSlider { base, data, state });
|
let slider = Rc::new(ComponentSlider { base, data, state });
|
||||||
|
|
||||||
ess.layout.defer_component_init(Component(slider.clone()));
|
ess.layout.defer_component_refresh(Component(slider.clone()));
|
||||||
Ok((root, slider))
|
Ok((root, slider))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::{cell::RefCell, rc::Rc};
|
|||||||
use taffy::prelude::length;
|
use taffy::prelude::length;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
components::{self, Component, ComponentBase, ComponentTrait, InitData},
|
components::{self, Component, ComponentBase, ComponentTrait, RefreshData},
|
||||||
drawing::Color,
|
drawing::Color,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{self, LayoutTask, LayoutTasks, WidgetID, WidgetPair},
|
layout::{self, LayoutTask, LayoutTasks, WidgetID, WidgetPair},
|
||||||
@@ -65,11 +65,15 @@ pub struct ComponentTooltip {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentTrait for ComponentTooltip {
|
impl ComponentTrait for ComponentTooltip {
|
||||||
fn base(&mut self) -> &mut ComponentBase {
|
fn base_mut(&mut self) -> &mut ComponentBase {
|
||||||
&mut self.base
|
&mut self.base
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&self, _data: &mut InitData) {}
|
fn base(&self) -> &ComponentBase {
|
||||||
|
&self.base
|
||||||
|
}
|
||||||
|
|
||||||
|
fn refresh(&self, _data: &mut RefreshData) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentTooltip {}
|
impl ComponentTooltip {}
|
||||||
@@ -200,7 +204,7 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
|||||||
tasks: ess.layout.tasks.clone(),
|
tasks: ess.layout.tasks.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
ess.layout.defer_component_init(Component(tooltip.clone()));
|
ess.layout.defer_component_refresh(Component(tooltip.clone()));
|
||||||
Ok((div, tooltip))
|
Ok((div, tooltip))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ impl Event {
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct EventAlterables {
|
pub struct EventAlterables {
|
||||||
pub dirty_nodes: Vec<taffy::NodeId>,
|
pub dirty_nodes: Vec<taffy::NodeId>,
|
||||||
pub style_set_requests: Vec<(taffy::NodeId, taffy::Style)>,
|
pub style_set_requests: Vec<(WidgetID, taffy::Style)>,
|
||||||
pub animations: Vec<animation::Animation>,
|
pub animations: Vec<animation::Animation>,
|
||||||
pub widgets_to_tick: HashSet<WidgetID>, // widgets which needs to be ticked in the next `Layout::update()` fn
|
pub widgets_to_tick: HashSet<WidgetID>, // widgets which needs to be ticked in the next `Layout::update()` fn
|
||||||
pub transform_stack: TransformStack,
|
pub transform_stack: TransformStack,
|
||||||
@@ -112,8 +112,8 @@ impl EventAlterables {
|
|||||||
self.needs_redraw = true;
|
self.needs_redraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_style(&mut self, node_id: taffy::NodeId, style: taffy::Style) {
|
pub fn set_style(&mut self, widget_id: WidgetID, style: taffy::Style) {
|
||||||
self.style_set_requests.push((node_id, style));
|
self.style_set_requests.push((widget_id, style));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mark_dirty(&mut self, node_id: taffy::NodeId) {
|
pub fn mark_dirty(&mut self, node_id: taffy::NodeId) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
animation::Animations,
|
animation::Animations,
|
||||||
components::{Component, InitData},
|
components::{Component, RefreshData},
|
||||||
drawing::{self, ANSI_BOLD_CODE, ANSI_RESET_CODE, Boundary, push_scissor_stack, push_transform_stack},
|
drawing::{self, ANSI_BOLD_CODE, ANSI_RESET_CODE, Boundary, push_scissor_stack, push_transform_stack},
|
||||||
event::{self, CallbackDataCommon, EventAlterables},
|
event::{self, CallbackDataCommon, EventAlterables},
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
@@ -139,7 +139,8 @@ pub struct Layout {
|
|||||||
|
|
||||||
pub tasks: LayoutTasks,
|
pub tasks: LayoutTasks,
|
||||||
|
|
||||||
pub components_to_init: Vec<Component>,
|
components_to_refresh: Vec<Component>,
|
||||||
|
|
||||||
pub widgets_to_tick: Vec<WidgetID>,
|
pub widgets_to_tick: Vec<WidgetID>,
|
||||||
|
|
||||||
// *Main root*
|
// *Main root*
|
||||||
@@ -311,15 +312,19 @@ impl Layout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn process_pending_components(&mut self, alterables: &mut EventAlterables) {
|
fn process_pending_components(&mut self, alterables: &mut EventAlterables) {
|
||||||
for comp in &self.components_to_init {
|
for comp in &self.components_to_refresh {
|
||||||
let mut common = CallbackDataCommon {
|
let mut common = CallbackDataCommon {
|
||||||
state: &self.state,
|
state: &self.state,
|
||||||
alterables,
|
alterables,
|
||||||
};
|
};
|
||||||
|
|
||||||
comp.0.init(&mut InitData { common: &mut common });
|
/* todo
|
||||||
|
let widget_id = comp.0.base().get_id();
|
||||||
|
*/
|
||||||
|
|
||||||
|
comp.0.refresh(&mut RefreshData { common: &mut common });
|
||||||
}
|
}
|
||||||
self.components_to_init.clear();
|
self.components_to_refresh.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_pending_widget_ticks(&mut self, alterables: &mut EventAlterables) {
|
fn process_pending_widget_ticks(&mut self, alterables: &mut EventAlterables) {
|
||||||
@@ -333,8 +338,8 @@ impl Layout {
|
|||||||
self.widgets_to_tick.clear();
|
self.widgets_to_tick.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn defer_component_init(&mut self, component: Component) {
|
pub fn defer_component_refresh(&mut self, component: Component) {
|
||||||
self.components_to_init.push(component);
|
self.components_to_refresh.push(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function to avoid repeated `WidgetID` → `WidgetState` lookups.
|
/// Convenience function to avoid repeated `WidgetID` → `WidgetState` lookups.
|
||||||
@@ -552,7 +557,7 @@ impl Layout {
|
|||||||
needs_redraw: true,
|
needs_redraw: true,
|
||||||
haptics_triggered: false,
|
haptics_triggered: false,
|
||||||
animations: Animations::default(),
|
animations: Animations::default(),
|
||||||
components_to_init: Vec::new(),
|
components_to_refresh: Vec::new(),
|
||||||
widgets_to_tick: Vec::new(),
|
widgets_to_tick: Vec::new(),
|
||||||
tasks: LayoutTasks::new(),
|
tasks: LayoutTasks::new(),
|
||||||
})
|
})
|
||||||
@@ -680,9 +685,11 @@ impl Layout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for request in alterables.style_set_requests {
|
for (widget_id, style) in alterables.style_set_requests {
|
||||||
if let Err(e) = self.state.tree.set_style(request.0, request.1) {
|
if let Some(node_id) = self.state.nodes.get(widget_id) {
|
||||||
log::error!("failed to set style for taffy widget ID {:?}: {:?}", request.0, e);
|
if let Err(e) = self.state.tree.set_style(*node_id, style) {
|
||||||
|
log::error!("failed to set style for taffy widget ID {node_id:?}: {e:?}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -763,6 +770,14 @@ impl LayoutState {
|
|||||||
Vec2::new(layout.size.width, layout.size.height)
|
Vec2::new(layout.size.width, layout.size.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_node_style(&self, id: NodeId) -> Option<&taffy::Style> {
|
||||||
|
let Ok(style) = self.tree.style(id) else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(style)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_widget_boundary(&self, id: WidgetID) -> Boundary {
|
pub fn get_widget_boundary(&self, id: WidgetID) -> Boundary {
|
||||||
let Some(node_id) = self.nodes.get(id) else {
|
let Some(node_id) = self.nodes.get(id) else {
|
||||||
return Boundary::default();
|
return Boundary::default();
|
||||||
@@ -778,4 +793,8 @@ impl LayoutState {
|
|||||||
|
|
||||||
self.get_node_size(*node_id)
|
self.get_node_size(*node_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_widget_style(&self, id: WidgetID) -> Option<&taffy::Style> {
|
||||||
|
self.get_node_style(*self.nodes.get(id)?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ impl ButtonPaneTabSwitcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_tab_active(common: &mut CallbackDataCommon, data: &TabData, active: bool) {
|
fn set_tab_active(common: &mut CallbackDataCommon, data: &TabData, active: bool) {
|
||||||
let pane_node = common.state.nodes[data.pane];
|
|
||||||
let style = Style {
|
let style = Style {
|
||||||
display: if active {
|
display: if active {
|
||||||
Display::Block
|
Display::Block
|
||||||
@@ -89,7 +88,7 @@ fn set_tab_active(common: &mut CallbackDataCommon, data: &TabData, active: bool)
|
|||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
common.alterables.set_style(pane_node, style);
|
common.alterables.set_style(data.pane, style);
|
||||||
if let Some(button) = data.button.as_ref() {
|
if let Some(button) = data.button.as_ref() {
|
||||||
button.set_sticky_state(common, active);
|
button.set_sticky_state(common, active);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user