sliders (wip), fix wlx build
This commit is contained in:
@@ -2,13 +2,61 @@
|
|||||||
<elements>
|
<elements>
|
||||||
<rectangle
|
<rectangle
|
||||||
color="#AAAAAA"
|
color="#AAAAAA"
|
||||||
width="500" height="500" min_width="500" min_height="500"
|
width="1000" height="500" min_width="1000" min_height="500"
|
||||||
gap="4" flex_direction="column">
|
gap="4" flex_direction="column"
|
||||||
|
overflow_y="scroll">
|
||||||
<label text="aaa" color="#FFFFFF" />
|
<label text="aaa" color="#FFFFFF" />
|
||||||
|
|
||||||
<button text="Red button" width="128" height="32" color="#FF0000" />
|
<button text="Red button" width="128" height="32" color="#FF0000" />
|
||||||
<button text="Aqua button" width="128" height="32" color="#00FFFF" />
|
<button text="Aqua button" width="128" height="32" color="#00FFFF" />
|
||||||
<button text="Yellow button" width="128" height="32" color="#FFFF00" />
|
<button text="Yellow button" width="128" height="32" color="#FFFF00" />
|
||||||
|
|
||||||
|
<div flex_direction="row" gap="16">
|
||||||
|
<div flex_direction="column" gap="8">
|
||||||
|
<rectangle width="128" height="2" />
|
||||||
|
<label text="height 16" />
|
||||||
|
<rectangle width="128" height="2" />
|
||||||
|
|
||||||
|
<label text="range 0-100 value 25" />
|
||||||
|
<slider width="200" height="16" min_value="0" max_value="100" value="25" />
|
||||||
|
|
||||||
|
<label text="range 10-20 value 15" />
|
||||||
|
<slider width="200" height="16" min_value="10" max_value="20" value="15" />
|
||||||
|
|
||||||
|
<label text="range -10-42 value 0" />
|
||||||
|
<slider width="200" height="16" min_value="-10" max_value="42" value="0" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div flex_direction="column" gap="8">
|
||||||
|
<rectangle width="128" height="2" />
|
||||||
|
<label text="height 24" />
|
||||||
|
<rectangle width="128" height="2" />
|
||||||
|
|
||||||
|
<label text="range 0-100 value 25" />
|
||||||
|
<slider width="200" height="24" min_value="0" max_value="100" value="25" />
|
||||||
|
|
||||||
|
<label text="range 10-20 value 15" />
|
||||||
|
<slider width="200" height="24" min_value="10" max_value="20" value="15" />
|
||||||
|
|
||||||
|
<label text="range -10-42 value 0" />
|
||||||
|
<slider width="200" height="24" min_value="-10" max_value="42" value="0" />
|
||||||
|
</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>
|
||||||
</elements>
|
</elements>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -2,7 +2,7 @@ use std::sync::Arc;
|
|||||||
use taffy::{AlignItems, JustifyContent, prelude::length};
|
use taffy::{AlignItems, JustifyContent, prelude::length};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
animation::{self, Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
components::Component,
|
components::Component,
|
||||||
drawing::{self, Color},
|
drawing::{self, Color},
|
||||||
event::{EventListenerCollection, EventListenerKind, WidgetCallback},
|
event::{EventListenerCollection, EventListenerKind, WidgetCallback},
|
||||||
@@ -98,9 +98,9 @@ fn anim_hover_out(button: Arc<Button>, widget_id: WidgetID) -> Animation {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn construct(
|
pub fn construct<U1, U2>(
|
||||||
layout: &mut Layout,
|
layout: &mut Layout,
|
||||||
listeners: &mut EventListenerCollection<(), ()>,
|
listeners: &mut EventListenerCollection<U1, U2>,
|
||||||
parent: WidgetID,
|
parent: WidgetID,
|
||||||
params: Params,
|
params: Params,
|
||||||
) -> anyhow::Result<Arc<Button>> {
|
) -> anyhow::Result<Arc<Button>> {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::any::AnyTrait;
|
use crate::any::AnyTrait;
|
||||||
|
|
||||||
pub mod button;
|
pub mod button;
|
||||||
|
pub mod slider;
|
||||||
|
|
||||||
pub trait Component: AnyTrait {}
|
pub trait Component: AnyTrait {}
|
||||||
|
|||||||
125
wgui/src/components/slider.rs
Normal file
125
wgui/src/components/slider.rs
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use taffy::prelude::{length, percent};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
components::Component,
|
||||||
|
drawing::{self},
|
||||||
|
event::{EventListenerCollection, EventListenerKind, WidgetCallback},
|
||||||
|
layout::{Layout, WidgetID},
|
||||||
|
widget::{
|
||||||
|
rectangle::{Rectangle, RectangleParams},
|
||||||
|
util::WLength,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Params {
|
||||||
|
pub style: taffy::Style,
|
||||||
|
pub initial_value: f32,
|
||||||
|
pub min_value: f32,
|
||||||
|
pub max_value: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Params {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
style: Default::default(),
|
||||||
|
initial_value: 0.5,
|
||||||
|
min_value: 0.0,
|
||||||
|
max_value: 1.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Slider {
|
||||||
|
pub body: WidgetID, // Outer rectangle
|
||||||
|
pub slider_handle_id: WidgetID, // Inner rectangle
|
||||||
|
pub slider_handle_node: taffy::NodeId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for Slider {}
|
||||||
|
|
||||||
|
impl Slider {
|
||||||
|
pub fn set_value<'a, C>(&self, callback_data: &mut C, _value: f32)
|
||||||
|
where
|
||||||
|
C: WidgetCallback<'a>,
|
||||||
|
{
|
||||||
|
callback_data.mark_redraw();
|
||||||
|
callback_data.mark_dirty(self.slider_handle_node);
|
||||||
|
callback_data.call_on_widget(self.slider_handle_id, |_rect: &mut Rectangle| {
|
||||||
|
// todo
|
||||||
|
});
|
||||||
|
callback_data.mark_redraw();
|
||||||
|
callback_data.mark_dirty(self.slider_handle_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn construct<U1, U2>(
|
||||||
|
layout: &mut Layout,
|
||||||
|
listeners: &mut EventListenerCollection<U1, U2>,
|
||||||
|
parent: WidgetID,
|
||||||
|
params: Params,
|
||||||
|
) -> anyhow::Result<Arc<Slider>> {
|
||||||
|
let mut style = params.style;
|
||||||
|
style.position = taffy::Position::Relative;
|
||||||
|
style.min_size = style.size;
|
||||||
|
style.max_size = style.size;
|
||||||
|
|
||||||
|
let body_color = drawing::Color::new(0.2, 0.3, 0.4, 1.0);
|
||||||
|
let body_border_color = drawing::Color::new(0.1, 0.2, 0.3, 1.0);
|
||||||
|
let handle_color = drawing::Color::new(1.0, 1.0, 1.0, 1.0);
|
||||||
|
|
||||||
|
let (body_id, _) = layout.add_child(
|
||||||
|
parent,
|
||||||
|
Rectangle::create(RectangleParams {
|
||||||
|
color: body_color,
|
||||||
|
round: WLength::Percent(1.0),
|
||||||
|
border_color: body_border_color,
|
||||||
|
border: 2.0,
|
||||||
|
..Default::default()
|
||||||
|
})?,
|
||||||
|
style,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut handle_style = taffy::Style::default();
|
||||||
|
handle_style.size.width = length(32.0);
|
||||||
|
handle_style.size.height = percent(1.0);
|
||||||
|
|
||||||
|
let (slider_handle_id, slider_handle_node) = layout.add_child(
|
||||||
|
body_id,
|
||||||
|
Rectangle::create(RectangleParams {
|
||||||
|
color: handle_color,
|
||||||
|
round: WLength::Percent(1.0),
|
||||||
|
..Default::default()
|
||||||
|
})?,
|
||||||
|
handle_style,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let slider = Arc::new(Slider {
|
||||||
|
body: body_id,
|
||||||
|
slider_handle_node,
|
||||||
|
slider_handle_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
//let mut widget = layout.widget_map.get(rect_id).unwrap().lock().unwrap();
|
||||||
|
|
||||||
|
listeners.add(
|
||||||
|
body_id,
|
||||||
|
EventListenerKind::MouseEnter,
|
||||||
|
Box::new(move |_data, _, _| {}),
|
||||||
|
);
|
||||||
|
|
||||||
|
listeners.add(
|
||||||
|
body_id,
|
||||||
|
EventListenerKind::MouseMotion,
|
||||||
|
Box::new(move |_data, _, _| {}),
|
||||||
|
);
|
||||||
|
|
||||||
|
listeners.add(
|
||||||
|
body_id,
|
||||||
|
EventListenerKind::MouseLeave,
|
||||||
|
Box::new(move |_data, _, _| {}),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(slider)
|
||||||
|
}
|
||||||
@@ -134,6 +134,7 @@ pub enum EventListenerKind {
|
|||||||
MousePress,
|
MousePress,
|
||||||
MouseRelease,
|
MouseRelease,
|
||||||
MouseEnter,
|
MouseEnter,
|
||||||
|
MouseMotion,
|
||||||
MouseLeave,
|
MouseLeave,
|
||||||
InternalStateChange,
|
InternalStateChange,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ use crate::{
|
|||||||
widget::util::WLength,
|
widget::util::WLength,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parse_component_button<'a>(
|
pub fn parse_component_button<'a, U1, U2>(
|
||||||
file: &'a ParserFile,
|
file: &'a ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
node: roxmltree::Node<'a, 'a>,
|
node: roxmltree::Node<'a, 'a>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
@@ -43,7 +43,7 @@ pub fn parse_component_button<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let button = button::construct(
|
let _button = button::construct(
|
||||||
ctx.layout,
|
ctx.layout,
|
||||||
ctx.listeners,
|
ctx.listeners,
|
||||||
parent_id,
|
parent_id,
|
||||||
|
|||||||
48
wgui/src/parser/component_slider.rs
Normal file
48
wgui/src/parser/component_slider.rs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
use crate::{
|
||||||
|
components::slider,
|
||||||
|
layout::WidgetID,
|
||||||
|
parser::{ParserContext, ParserFile, iter_attribs, parse_check_f32, style::parse_style},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn parse_component_slider<'a, U1, U2>(
|
||||||
|
file: &'a ParserFile,
|
||||||
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
|
node: roxmltree::Node<'a, 'a>,
|
||||||
|
parent_id: WidgetID,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let mut min_value = 0.0;
|
||||||
|
let mut max_value = 1.0;
|
||||||
|
let mut initial_value = 0.5;
|
||||||
|
|
||||||
|
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
|
||||||
|
let style = parse_style(&attribs);
|
||||||
|
|
||||||
|
for (key, value) in attribs {
|
||||||
|
match key.as_ref() {
|
||||||
|
"min_value" => {
|
||||||
|
parse_check_f32(value.as_ref(), &mut min_value);
|
||||||
|
}
|
||||||
|
"max_value" => {
|
||||||
|
parse_check_f32(value.as_ref(), &mut max_value);
|
||||||
|
}
|
||||||
|
"value" => {
|
||||||
|
parse_check_f32(value.as_ref(), &mut initial_value);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let slider = slider::construct(
|
||||||
|
ctx.layout,
|
||||||
|
ctx.listeners,
|
||||||
|
parent_id,
|
||||||
|
slider::Params {
|
||||||
|
min_value,
|
||||||
|
max_value,
|
||||||
|
initial_value,
|
||||||
|
style,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
mod component_button;
|
mod component_button;
|
||||||
|
mod component_slider;
|
||||||
mod style;
|
mod style;
|
||||||
mod widget_div;
|
mod widget_div;
|
||||||
mod widget_label;
|
mod widget_label;
|
||||||
@@ -11,9 +12,9 @@ use crate::{
|
|||||||
event::EventListenerCollection,
|
event::EventListenerCollection,
|
||||||
layout::{Layout, WidgetID},
|
layout::{Layout, WidgetID},
|
||||||
parser::{
|
parser::{
|
||||||
component_button::parse_component_button, widget_div::parse_widget_div,
|
component_button::parse_component_button, component_slider::parse_component_slider,
|
||||||
widget_label::parse_widget_label, widget_rectangle::parse_widget_rectangle,
|
widget_div::parse_widget_div, widget_label::parse_widget_label,
|
||||||
widget_sprite::parse_widget_sprite,
|
widget_rectangle::parse_widget_rectangle, widget_sprite::parse_widget_sprite,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use ouroboros::self_referencing;
|
use ouroboros::self_referencing;
|
||||||
@@ -59,11 +60,11 @@ impl ParserResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_template(
|
pub fn process_template<U1, U2>(
|
||||||
&mut self,
|
&mut self,
|
||||||
template_name: &str,
|
template_name: &str,
|
||||||
layout: &mut Layout,
|
layout: &mut Layout,
|
||||||
listeners: &mut EventListenerCollection<(), ()>,
|
listeners: &mut EventListenerCollection<U1, U2>,
|
||||||
widget_id: WidgetID,
|
widget_id: WidgetID,
|
||||||
template_parameters: HashMap<Rc<str>, Rc<str>>,
|
template_parameters: HashMap<Rc<str>, Rc<str>>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
@@ -108,9 +109,9 @@ struct MacroAttribs {
|
|||||||
attribs: HashMap<Rc<str>, Rc<str>>,
|
attribs: HashMap<Rc<str>, Rc<str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ParserContext<'a> {
|
struct ParserContext<'a, U1, U2> {
|
||||||
layout: &'a mut Layout,
|
layout: &'a mut Layout,
|
||||||
listeners: &'a mut EventListenerCollection<(), ()>,
|
listeners: &'a mut EventListenerCollection<U1, U2>,
|
||||||
var_map: HashMap<Rc<str>, Rc<str>>,
|
var_map: HashMap<Rc<str>, Rc<str>>,
|
||||||
macro_attribs: HashMap<Rc<str>, MacroAttribs>,
|
macro_attribs: HashMap<Rc<str>, MacroAttribs>,
|
||||||
ids: HashMap<Rc<str>, WidgetID>,
|
ids: HashMap<Rc<str>, WidgetID>,
|
||||||
@@ -208,6 +209,16 @@ fn parse_f32(value: &str) -> Option<f32> {
|
|||||||
value.parse::<f32>().ok()
|
value.parse::<f32>().ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_check_f32(value: &str, num: &mut f32) -> bool {
|
||||||
|
if let Some(value) = parse_f32(value) {
|
||||||
|
*num = value;
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
print_invalid_value(value);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_size_unit<T>(value: &str) -> Option<T>
|
fn parse_size_unit<T>(value: &str) -> Option<T>
|
||||||
where
|
where
|
||||||
T: taffy::prelude::FromPercent + taffy::prelude::FromLength,
|
T: taffy::prelude::FromPercent + taffy::prelude::FromLength,
|
||||||
@@ -219,11 +230,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_widget_other_internal(
|
fn parse_widget_other_internal<U1, U2>(
|
||||||
template: Rc<Template>,
|
template: Rc<Template>,
|
||||||
template_parameters: HashMap<Rc<str>, Rc<str>>,
|
template_parameters: HashMap<Rc<str>, Rc<str>>,
|
||||||
file: &ParserFile,
|
file: &ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let template_file = ParserFile {
|
let template_file = ParserFile {
|
||||||
@@ -244,10 +255,10 @@ fn parse_widget_other_internal(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_widget_other<'a>(
|
fn parse_widget_other<'a, U1, U2>(
|
||||||
xml_tag_name: &str,
|
xml_tag_name: &str,
|
||||||
file: &'a ParserFile,
|
file: &'a ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
node: roxmltree::Node<'a, 'a>,
|
node: roxmltree::Node<'a, 'a>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
@@ -262,9 +273,9 @@ fn parse_widget_other<'a>(
|
|||||||
parse_widget_other_internal(template.clone(), template_parameters, file, ctx, parent_id)
|
parse_widget_other_internal(template.clone(), template_parameters, file, ctx, parent_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_tag_include<'a>(
|
fn parse_tag_include<'a, U1, U2>(
|
||||||
file: &ParserFile,
|
file: &ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
node: roxmltree::Node<'a, 'a>,
|
node: roxmltree::Node<'a, 'a>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
@@ -291,7 +302,10 @@ fn parse_tag_include<'a>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_tag_var<'a>(ctx: &mut ParserContext, node: roxmltree::Node<'a, 'a>) -> anyhow::Result<()> {
|
fn parse_tag_var<'a, U1, U2>(
|
||||||
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
|
node: roxmltree::Node<'a, 'a>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
let mut out_key: Option<&str> = None;
|
let mut out_key: Option<&str> = None;
|
||||||
let mut out_value: Option<&str> = None;
|
let mut out_value: Option<&str> = None;
|
||||||
|
|
||||||
@@ -349,9 +363,9 @@ pub fn replace_vars(input: &str, vars: &HashMap<Rc<str>, Rc<str>>) -> Rc<str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::manual_strip)]
|
#[allow(clippy::manual_strip)]
|
||||||
fn process_attrib<'a>(
|
fn process_attrib<'a, U1, U2>(
|
||||||
file: &'a ParserFile,
|
file: &'a ParserFile,
|
||||||
ctx: &'a ParserContext,
|
ctx: &'a ParserContext<U1, U2>,
|
||||||
key: &str,
|
key: &str,
|
||||||
value: &str,
|
value: &str,
|
||||||
) -> (Rc<str>, Rc<str>) {
|
) -> (Rc<str>, Rc<str>) {
|
||||||
@@ -373,9 +387,9 @@ fn process_attrib<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_attribs<'a>(
|
fn iter_attribs<'a, U1, U2>(
|
||||||
file: &'a ParserFile,
|
file: &'a ParserFile,
|
||||||
ctx: &'a ParserContext,
|
ctx: &'a ParserContext<U1, U2>,
|
||||||
node: &'a roxmltree::Node<'a, 'a>,
|
node: &'a roxmltree::Node<'a, 'a>,
|
||||||
is_tag_macro: bool,
|
is_tag_macro: bool,
|
||||||
) -> impl Iterator<Item = (/*key*/ Rc<str>, /*value*/ Rc<str>)> + 'a {
|
) -> impl Iterator<Item = (/*key*/ Rc<str>, /*value*/ Rc<str>)> + 'a {
|
||||||
@@ -409,8 +423,8 @@ fn iter_attribs<'a>(
|
|||||||
res.into_iter()
|
res.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_tag_theme<'a>(
|
fn parse_tag_theme<'a, U1, U2>(
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
node: roxmltree::Node<'a, 'a>,
|
node: roxmltree::Node<'a, 'a>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
for child_node in node.children() {
|
for child_node in node.children() {
|
||||||
@@ -429,9 +443,9 @@ fn parse_tag_theme<'a>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_tag_template(
|
fn parse_tag_template<U1, U2>(
|
||||||
file: &ParserFile,
|
file: &ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
node: roxmltree::Node<'_, '_>,
|
node: roxmltree::Node<'_, '_>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut template_name: Option<Rc<str>> = None;
|
let mut template_name: Option<Rc<str>> = None;
|
||||||
@@ -465,9 +479,9 @@ fn parse_tag_template(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_tag_macro(
|
fn parse_tag_macro<U1, U2>(
|
||||||
file: &ParserFile,
|
file: &ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
node: roxmltree::Node<'_, '_>,
|
node: roxmltree::Node<'_, '_>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut macro_name: Option<Rc<str>> = None;
|
let mut macro_name: Option<Rc<str>> = None;
|
||||||
@@ -503,9 +517,9 @@ fn parse_tag_macro(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_universal<'a>(
|
fn parse_universal<'a, U1, U2>(
|
||||||
file: &'a ParserFile,
|
file: &'a ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
node: roxmltree::Node<'a, 'a>,
|
node: roxmltree::Node<'a, 'a>,
|
||||||
widget_id: WidgetID,
|
widget_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
@@ -526,9 +540,9 @@ fn parse_universal<'a>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_children<'a>(
|
fn parse_children<'a, U1, U2>(
|
||||||
file: &ParserFile,
|
file: &ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
node: roxmltree::Node<'a, 'a>,
|
node: roxmltree::Node<'a, 'a>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
@@ -552,6 +566,9 @@ fn parse_children<'a>(
|
|||||||
"button" => {
|
"button" => {
|
||||||
parse_component_button(file, ctx, child_node, parent_id)?;
|
parse_component_button(file, ctx, child_node, parent_id)?;
|
||||||
}
|
}
|
||||||
|
"slider" => {
|
||||||
|
parse_component_slider(file, ctx, child_node, parent_id)?;
|
||||||
|
}
|
||||||
"" => { /* ignore */ }
|
"" => { /* ignore */ }
|
||||||
other_tag_name => {
|
other_tag_name => {
|
||||||
parse_widget_other(other_tag_name, file, ctx, child_node, parent_id)?;
|
parse_widget_other(other_tag_name, file, ctx, child_node, parent_id)?;
|
||||||
@@ -561,10 +578,10 @@ fn parse_children<'a>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_default_context<'a>(
|
fn create_default_context<'a, U1, U2>(
|
||||||
layout: &'a mut Layout,
|
layout: &'a mut Layout,
|
||||||
listeners: &'a mut EventListenerCollection<(), ()>,
|
listeners: &'a mut EventListenerCollection<U1, U2>,
|
||||||
) -> ParserContext<'a> {
|
) -> ParserContext<'a, U1, U2> {
|
||||||
ParserContext {
|
ParserContext {
|
||||||
layout,
|
layout,
|
||||||
listeners,
|
listeners,
|
||||||
@@ -575,9 +592,9 @@ fn create_default_context<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_from_assets(
|
pub fn parse_from_assets<U1, U2>(
|
||||||
layout: &mut Layout,
|
layout: &mut Layout,
|
||||||
listeners: &mut EventListenerCollection<(), ()>,
|
listeners: &mut EventListenerCollection<U1, U2>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
path: &str,
|
path: &str,
|
||||||
) -> anyhow::Result<ParserResult> {
|
) -> anyhow::Result<ParserResult> {
|
||||||
@@ -602,9 +619,9 @@ pub fn parse_from_assets(
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_layout_from_assets(
|
pub fn new_layout_from_assets<U1, U2>(
|
||||||
assets: Box<dyn AssetProvider>,
|
assets: Box<dyn AssetProvider>,
|
||||||
listeners: &mut EventListenerCollection<(), ()>,
|
listeners: &mut EventListenerCollection<U1, U2>,
|
||||||
path: &str,
|
path: &str,
|
||||||
) -> anyhow::Result<(Layout, ParserResult)> {
|
) -> anyhow::Result<(Layout, ParserResult)> {
|
||||||
let mut layout = Layout::new(assets)?;
|
let mut layout = Layout::new(assets)?;
|
||||||
@@ -618,8 +635,8 @@ fn assets_path_to_xml(assets: &mut Box<dyn AssetProvider>, path: &Path) -> anyho
|
|||||||
Ok(String::from_utf8(data)?)
|
Ok(String::from_utf8(data)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_doc_from_path(
|
fn get_doc_from_path<U1, U2>(
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
) -> anyhow::Result<(ParserFile, roxmltree::NodeId)> {
|
) -> anyhow::Result<(ParserFile, roxmltree::NodeId)> {
|
||||||
let xml = assets_path_to_xml(&mut ctx.layout.assets, path)?;
|
let xml = assets_path_to_xml(&mut ctx.layout.assets, path)?;
|
||||||
@@ -643,9 +660,9 @@ fn get_doc_from_path(
|
|||||||
Ok((file, tag_layout.id()))
|
Ok((file, tag_layout.id()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_document_root(
|
fn parse_document_root<U1, U2>(
|
||||||
file: ParserFile,
|
file: ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
node_layout: roxmltree::NodeId,
|
node_layout: roxmltree::NodeId,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ use crate::{
|
|||||||
widget,
|
widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parse_widget_div<'a>(
|
pub fn parse_widget_div<'a, U1, U2>(
|
||||||
file: &ParserFile,
|
file: &ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
node: roxmltree::Node<'a, 'a>,
|
node: roxmltree::Node<'a, 'a>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ use crate::{
|
|||||||
widget::text::{TextLabel, TextParams},
|
widget::text::{TextLabel, TextParams},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parse_widget_label<'a>(
|
pub fn parse_widget_label<'a, U1, U2>(
|
||||||
file: &'a ParserFile,
|
file: &'a ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
node: roxmltree::Node<'a, 'a>,
|
node: roxmltree::Node<'a, 'a>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ use crate::{
|
|||||||
widget::{self, rectangle::RectangleParams},
|
widget::{self, rectangle::RectangleParams},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parse_widget_rectangle<'a>(
|
pub fn parse_widget_rectangle<'a, U1, U2>(
|
||||||
file: &ParserFile,
|
file: &ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
node: roxmltree::Node<'a, 'a>,
|
node: roxmltree::Node<'a, 'a>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ use crate::{
|
|||||||
|
|
||||||
use super::{parse_color_hex, print_invalid_attrib};
|
use super::{parse_color_hex, print_invalid_attrib};
|
||||||
|
|
||||||
pub fn parse_widget_sprite<'a>(
|
pub fn parse_widget_sprite<'a, U1, U2>(
|
||||||
file: &'a ParserFile,
|
file: &'a ParserFile,
|
||||||
ctx: &mut ParserContext,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
node: roxmltree::Node<'a, 'a>,
|
node: roxmltree::Node<'a, 'a>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
|||||||
@@ -390,6 +390,17 @@ impl WidgetState {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
call_event!(
|
||||||
|
self,
|
||||||
|
listeners,
|
||||||
|
widget_id,
|
||||||
|
node_id,
|
||||||
|
params,
|
||||||
|
MouseMotion,
|
||||||
|
user_data,
|
||||||
|
CallbackMetadata::None
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Event::MouseLeave(e) => {
|
Event::MouseLeave(e) => {
|
||||||
if self.data.set_device_hovered(e.device, false) {
|
if self.data.set_device_hovered(e.device, false) {
|
||||||
|
|||||||
@@ -42,8 +42,13 @@ impl<S> GuiPanel<S> {
|
|||||||
path: &str,
|
path: &str,
|
||||||
state: S,
|
state: S,
|
||||||
) -> anyhow::Result<(Self, ParserResult)> {
|
) -> anyhow::Result<(Self, ParserResult)> {
|
||||||
let (layout, parser_result) =
|
let mut listeners = EventListenerCollection::<AppState, S>::default();
|
||||||
wgui::parser::new_layout_from_assets(Box::new(gui::asset::GuiAsset {}), path)?;
|
|
||||||
|
let (layout, parser_result) = wgui::parser::new_layout_from_assets(
|
||||||
|
Box::new(gui::asset::GuiAsset {}),
|
||||||
|
&mut listeners,
|
||||||
|
path,
|
||||||
|
)?;
|
||||||
|
|
||||||
let context = WguiContext::new(&mut app.wgui_shared, 1.0)?;
|
let context = WguiContext::new(&mut app.wgui_shared, 1.0)?;
|
||||||
let mut timestep = Timestep::new();
|
let mut timestep = Timestep::new();
|
||||||
@@ -56,7 +61,7 @@ impl<S> GuiPanel<S> {
|
|||||||
timestep,
|
timestep,
|
||||||
state,
|
state,
|
||||||
timers: vec![],
|
timers: vec![],
|
||||||
listeners: EventListenerCollection::default(),
|
listeners,
|
||||||
},
|
},
|
||||||
parser_result,
|
parser_result,
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ where
|
|||||||
|
|
||||||
let (_, mut gui_state_key) = wgui::parser::new_layout_from_assets(
|
let (_, mut gui_state_key) = wgui::parser::new_layout_from_assets(
|
||||||
Box::new(gui::asset::GuiAsset {}),
|
Box::new(gui::asset::GuiAsset {}),
|
||||||
|
&mut panel.listeners,
|
||||||
"gui/keyboard.xml",
|
"gui/keyboard.xml",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@@ -156,7 +157,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let template_key = format!("Key{:?}", key.cap_type);
|
let template_key = format!("Key{:?}", key.cap_type);
|
||||||
gui_state_key.process_template(&template_key, &mut panel.layout, div, params)?;
|
gui_state_key.process_template(
|
||||||
|
&template_key,
|
||||||
|
&mut panel.layout,
|
||||||
|
&mut panel.listeners,
|
||||||
|
div,
|
||||||
|
params,
|
||||||
|
)?;
|
||||||
|
|
||||||
if let Some(widget_id) = gui_state_key.ids.get(&*my_id) {
|
if let Some(widget_id) = gui_state_key.ids.get(&*my_id) {
|
||||||
let key_state = {
|
let key_state = {
|
||||||
|
|||||||
Reference in New Issue
Block a user