scissor stack fixes, proper render & event transformations
This commit is contained in:
@@ -36,6 +36,7 @@
|
|||||||
flex_wrap="wrap"
|
flex_wrap="wrap"
|
||||||
justify_content="stretch"
|
justify_content="stretch"
|
||||||
gap="4"
|
gap="4"
|
||||||
|
overflow_y="scroll"
|
||||||
/>
|
/>
|
||||||
</elements>
|
</elements>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
use std::{collections::HashMap, rc::Rc};
|
use std::{collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
use wgui::{
|
use wgui::{
|
||||||
components::{self, button::ComponentButton},
|
components::button::ComponentButton,
|
||||||
layout::WidgetPair,
|
layout::WidgetPair,
|
||||||
parser::{Fetchable, ParseDocumentParams, ParserData, ParserState},
|
parser::{Fetchable, ParseDocumentParams, ParserData, ParserState},
|
||||||
taffy::{self, Dimension, prelude::length},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -16,7 +15,9 @@ pub struct TabApps {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub state: ParserState,
|
pub state: ParserState,
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
entries: Vec<DesktopEntry>,
|
entries: Vec<DesktopEntry>,
|
||||||
|
#[allow(dead_code)]
|
||||||
app_list: AppList,
|
app_list: AppList,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +106,7 @@ impl AppList {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
let button = data.fetch_component_as::<ComponentButton>("button")?;
|
let button = data.fetch_component_as::<ComponentButton>("button")?;
|
||||||
button.on_click(Box::new(move |common, evt| {
|
button.on_click(Box::new(move |_common, _evt| {
|
||||||
log::info!("click");
|
log::info!("click");
|
||||||
Ok(())
|
Ok(())
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use glam::{FloatExt, Vec2};
|
use glam::FloatExt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
drawing::Boundary,
|
||||||
event::{CallbackDataCommon, EventAlterables},
|
event::{CallbackDataCommon, EventAlterables},
|
||||||
layout::{LayoutState, WidgetID},
|
layout::{LayoutState, WidgetID},
|
||||||
widget::{WidgetData, WidgetObj},
|
widget::{WidgetData, WidgetObj},
|
||||||
@@ -46,7 +47,7 @@ pub struct CallbackData<'a> {
|
|||||||
pub obj: &'a mut dyn WidgetObj,
|
pub obj: &'a mut dyn WidgetObj,
|
||||||
pub data: &'a mut WidgetData,
|
pub data: &'a mut WidgetData,
|
||||||
pub widget_id: WidgetID,
|
pub widget_id: WidgetID,
|
||||||
pub widget_size: Vec2,
|
pub widget_boundary: Boundary,
|
||||||
pub pos: f32, // 0.0 (start of animation) - 1.0 (end of animation)
|
pub pos: f32, // 0.0 (start of animation) - 1.0 (end of animation)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,14 +99,13 @@ impl Animation {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let widget_node = *state.nodes.get(self.target_widget).unwrap();
|
let widget_node = *state.nodes.get(self.target_widget).unwrap();
|
||||||
let layout = state.tree.layout(widget_node).unwrap(); // should always succeed
|
|
||||||
|
|
||||||
let mut widget_state = widget.state();
|
let mut widget_state = widget.state();
|
||||||
let (data, obj) = widget_state.get_data_obj_mut();
|
let (data, obj) = widget_state.get_data_obj_mut();
|
||||||
|
|
||||||
let data = &mut CallbackData {
|
let data = &mut CallbackData {
|
||||||
widget_id: self.target_widget,
|
widget_id: self.target_widget,
|
||||||
widget_size: Vec2::new(layout.size.width, layout.size.height),
|
widget_boundary: state.get_widget_boundary(widget_node),
|
||||||
obj,
|
obj,
|
||||||
data,
|
data,
|
||||||
pos,
|
pos,
|
||||||
|
|||||||
@@ -1,21 +1,25 @@
|
|||||||
use std::{cell::RefCell, rc::Rc};
|
|
||||||
use taffy::{AlignItems, JustifyContent};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
animation::{Animation, AnimationEasing},
|
animation::{Animation, AnimationEasing},
|
||||||
components::{Component, ComponentBase, ComponentTrait, InitData},
|
components::{Component, ComponentBase, ComponentTrait, InitData},
|
||||||
drawing::{self, Color},
|
drawing::{self, Boundary, Color},
|
||||||
event::{CallbackDataCommon, EventListenerCollection, EventListenerKind, ListenerHandleVec},
|
event::{CallbackDataCommon, EventListenerCollection, EventListenerKind, ListenerHandleVec},
|
||||||
globals::Globals,
|
globals::Globals,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{Layout, WidgetID},
|
layout::{Layout, WidgetID, WidgetPair},
|
||||||
renderer_vk::text::{FontWeight, TextStyle},
|
renderer_vk::{
|
||||||
|
text::{FontWeight, TextStyle},
|
||||||
|
util::centered_matrix,
|
||||||
|
},
|
||||||
widget::{
|
widget::{
|
||||||
|
WidgetData,
|
||||||
label::{WidgetLabel, WidgetLabelParams},
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
util::WLength,
|
util::WLength,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use glam::{Mat4, Vec3};
|
||||||
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
use taffy::{AlignItems, JustifyContent};
|
||||||
|
|
||||||
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
|
||||||
@@ -93,24 +97,43 @@ fn get_color2(color: &drawing::Color) -> drawing::Color {
|
|||||||
color.lerp(&Color::new(0.0, 0.0, 0.0, color.a), 0.2)
|
color.lerp(&Color::new(0.0, 0.0, 0.0, color.a), 0.2)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn anim_hover(rect: &mut WidgetRectangle, data: &Data, pos: f32, pressed: bool) {
|
fn anim_hover(
|
||||||
|
rect: &mut WidgetRectangle,
|
||||||
|
widget_data: &mut WidgetData,
|
||||||
|
data: &Data,
|
||||||
|
widget_boundary: Boundary,
|
||||||
|
pos: f32,
|
||||||
|
pressed: bool,
|
||||||
|
) {
|
||||||
let mult = pos * if pressed { 1.5 } else { 1.0 };
|
let mult = pos * if pressed { 1.5 } else { 1.0 };
|
||||||
let bgcolor = data.initial_color.lerp(&data.initial_hover_color, mult);
|
let bgcolor = data.initial_color.lerp(&data.initial_hover_color, mult);
|
||||||
|
|
||||||
|
//let t = Mat4::from_scale(Vec3::splat(1.0 + pos * 0.5)) * Mat4::from_rotation_z(pos * 1.0);
|
||||||
|
|
||||||
|
let t = Mat4::from_scale(Vec3::splat(1.0 + pos * 0.05));
|
||||||
|
widget_data.transform = centered_matrix(widget_boundary.size, &t);
|
||||||
|
|
||||||
rect.params.color = bgcolor;
|
rect.params.color = bgcolor;
|
||||||
rect.params.color2 = get_color2(&bgcolor);
|
rect.params.color2 = get_color2(&bgcolor);
|
||||||
rect.params.border_color = data.initial_border_color.lerp(&data.initial_hover_border_color, mult);
|
rect.params.border_color = data.initial_border_color.lerp(&data.initial_hover_border_color, mult);
|
||||||
rect.params.border = 2.0;
|
rect.params.border = 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn anim_hover_out(data: Rc<Data>, state: Rc<RefCell<State>>, widget_id: WidgetID) -> Animation {
|
fn anim_hover_create(data: Rc<Data>, state: Rc<RefCell<State>>, widget_id: WidgetID, fade_in: bool) -> Animation {
|
||||||
Animation::new(
|
Animation::new(
|
||||||
widget_id,
|
widget_id,
|
||||||
15,
|
if fade_in { 5 } else { 10 },
|
||||||
AnimationEasing::OutCubic,
|
AnimationEasing::OutCubic,
|
||||||
Box::new(move |common, anim_data| {
|
Box::new(move |common, anim_data| {
|
||||||
let rect = anim_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
let rect = anim_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
anim_hover(rect, &data, 1.0 - anim_data.pos, state.borrow().down);
|
anim_hover(
|
||||||
|
rect,
|
||||||
|
anim_data.data,
|
||||||
|
&data,
|
||||||
|
anim_data.widget_boundary,
|
||||||
|
if fade_in { anim_data.pos } else { 1.0 - anim_data.pos },
|
||||||
|
state.borrow().down,
|
||||||
|
);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@@ -129,10 +152,13 @@ fn register_event_mouse_enter<U1, U2>(
|
|||||||
Box::new(move |common, event_data, _, _| {
|
Box::new(move |common, event_data, _, _| {
|
||||||
common.alterables.trigger_haptics();
|
common.alterables.trigger_haptics();
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
let rect = event_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
common.alterables.animate(anim_hover_create(
|
||||||
let mut state = state.borrow_mut();
|
data.clone(),
|
||||||
anim_hover(rect, &data, 1.0, state.down);
|
state.clone(),
|
||||||
state.hovered = true;
|
event_data.widget_id,
|
||||||
|
true,
|
||||||
|
));
|
||||||
|
state.borrow_mut().hovered = true;
|
||||||
Ok(())
|
Ok(())
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -150,9 +176,12 @@ fn register_event_mouse_leave<U1, U2>(
|
|||||||
EventListenerKind::MouseLeave,
|
EventListenerKind::MouseLeave,
|
||||||
Box::new(move |common, event_data, _, _| {
|
Box::new(move |common, event_data, _, _| {
|
||||||
common.alterables.trigger_haptics();
|
common.alterables.trigger_haptics();
|
||||||
common
|
common.alterables.animate(anim_hover_create(
|
||||||
.alterables
|
data.clone(),
|
||||||
.animate(anim_hover_out(data.clone(), state.clone(), event_data.widget_id));
|
state.clone(),
|
||||||
|
event_data.widget_id,
|
||||||
|
false,
|
||||||
|
));
|
||||||
state.borrow_mut().hovered = false;
|
state.borrow_mut().hovered = false;
|
||||||
Ok(())
|
Ok(())
|
||||||
}),
|
}),
|
||||||
@@ -173,7 +202,14 @@ fn register_event_mouse_press<U1, U2>(
|
|||||||
let mut state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
|
|
||||||
let rect = event_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
let rect = event_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
anim_hover(rect, &data, 1.0, true);
|
anim_hover(
|
||||||
|
rect,
|
||||||
|
event_data.widget_data,
|
||||||
|
&data,
|
||||||
|
common.state.get_widget_boundary(event_data.node_id),
|
||||||
|
1.0,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
if state.hovered {
|
if state.hovered {
|
||||||
state.down = true;
|
state.down = true;
|
||||||
@@ -199,7 +235,14 @@ fn register_event_mouse_release<U1, U2>(
|
|||||||
EventListenerKind::MouseRelease,
|
EventListenerKind::MouseRelease,
|
||||||
Box::new(move |common, event_data, _, _| {
|
Box::new(move |common, event_data, _, _| {
|
||||||
let rect = event_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
let rect = event_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
anim_hover(rect, &data, 1.0, false);
|
anim_hover(
|
||||||
|
rect,
|
||||||
|
event_data.widget_data,
|
||||||
|
&data,
|
||||||
|
common.state.get_widget_boundary(event_data.node_id),
|
||||||
|
1.0,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
let mut state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
if state.down {
|
if state.down {
|
||||||
@@ -226,7 +269,7 @@ pub fn construct<U1, U2>(
|
|||||||
listeners: &mut EventListenerCollection<U1, U2>,
|
listeners: &mut EventListenerCollection<U1, U2>,
|
||||||
parent: WidgetID,
|
parent: WidgetID,
|
||||||
params: Params,
|
params: Params,
|
||||||
) -> anyhow::Result<(WidgetID, Rc<ComponentButton>)> {
|
) -> anyhow::Result<(WidgetPair, Rc<ComponentButton>)> {
|
||||||
let mut style = params.style;
|
let mut style = params.style;
|
||||||
|
|
||||||
// force-override style
|
// force-override style
|
||||||
@@ -260,7 +303,7 @@ pub fn construct<U1, U2>(
|
|||||||
Color::new(color.r + 0.5, color.g + 0.5, color.g + 0.5, color.a + 0.5)
|
Color::new(color.r + 0.5, color.g + 0.5, color.g + 0.5, color.a + 0.5)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (id_root, _) = layout.add_child(
|
let (root, _) = layout.add_child(
|
||||||
parent,
|
parent,
|
||||||
WidgetRectangle::create(WidgetRectangleParams {
|
WidgetRectangle::create(WidgetRectangleParams {
|
||||||
color,
|
color,
|
||||||
@@ -272,12 +315,13 @@ pub fn construct<U1, U2>(
|
|||||||
}),
|
}),
|
||||||
style,
|
style,
|
||||||
)?;
|
)?;
|
||||||
let id_rect = id_root;
|
|
||||||
|
let id_rect = root.id;
|
||||||
|
|
||||||
let light_text = (color.r + color.g + color.b) < 1.5;
|
let light_text = (color.r + color.g + color.b) < 1.5;
|
||||||
|
|
||||||
let id_label = if let Some(content) = params.text {
|
let id_label = if let Some(content) = params.text {
|
||||||
let (id_label, _node_label) = layout.add_child(
|
let (label, _node_label) = layout.add_child(
|
||||||
id_rect,
|
id_rect,
|
||||||
WidgetLabel::create(
|
WidgetLabel::create(
|
||||||
globals,
|
globals,
|
||||||
@@ -296,7 +340,7 @@ pub fn construct<U1, U2>(
|
|||||||
),
|
),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)?;
|
)?;
|
||||||
id_label
|
label.id
|
||||||
} else {
|
} else {
|
||||||
WidgetID::default()
|
WidgetID::default()
|
||||||
};
|
};
|
||||||
@@ -326,5 +370,5 @@ pub fn construct<U1, U2>(
|
|||||||
let button = Rc::new(ComponentButton { base, data, state });
|
let button = Rc::new(ComponentButton { base, data, state });
|
||||||
|
|
||||||
layout.defer_component_init(Component(button.clone()));
|
layout.defer_component_init(Component(button.clone()));
|
||||||
Ok((id_root, button))
|
Ok((root, button))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
drawing::Color,
|
drawing::Color,
|
||||||
event::{CallbackDataCommon, EventAlterables, EventListenerCollection, EventListenerKind, ListenerHandleVec},
|
event::{CallbackDataCommon, EventAlterables, EventListenerCollection, EventListenerKind, ListenerHandleVec},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{self, Layout, LayoutState, WidgetID},
|
layout::{self, Layout, LayoutState, WidgetID, WidgetPair},
|
||||||
renderer_vk::text::{FontWeight, TextStyle},
|
renderer_vk::text::{FontWeight, TextStyle},
|
||||||
widget::{
|
widget::{
|
||||||
label::{WidgetLabel, WidgetLabelParams},
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
@@ -249,7 +249,7 @@ pub fn construct<U1, U2>(
|
|||||||
listeners: &mut EventListenerCollection<U1, U2>,
|
listeners: &mut EventListenerCollection<U1, U2>,
|
||||||
parent: WidgetID,
|
parent: WidgetID,
|
||||||
params: Params,
|
params: Params,
|
||||||
) -> anyhow::Result<(WidgetID, Rc<ComponentCheckbox>)> {
|
) -> anyhow::Result<(WidgetPair, Rc<ComponentCheckbox>)> {
|
||||||
let mut style = params.style;
|
let mut style = params.style;
|
||||||
|
|
||||||
// force-override style
|
// force-override style
|
||||||
@@ -267,7 +267,7 @@ pub fn construct<U1, U2>(
|
|||||||
|
|
||||||
let globals = layout.state.globals.clone();
|
let globals = layout.state.globals.clone();
|
||||||
|
|
||||||
let (id_root, _) = layout.add_child(
|
let (root, _) = layout.add_child(
|
||||||
parent,
|
parent,
|
||||||
WidgetRectangle::create(WidgetRectangleParams {
|
WidgetRectangle::create(WidgetRectangleParams {
|
||||||
color: Color::new(1.0, 1.0, 1.0, 0.0),
|
color: Color::new(1.0, 1.0, 1.0, 0.0),
|
||||||
@@ -277,14 +277,15 @@ pub fn construct<U1, U2>(
|
|||||||
}),
|
}),
|
||||||
style,
|
style,
|
||||||
)?;
|
)?;
|
||||||
let id_container = id_root;
|
|
||||||
|
let id_container = root.id;
|
||||||
|
|
||||||
let box_size = taffy::Size {
|
let box_size = taffy::Size {
|
||||||
width: length(params.box_size),
|
width: length(params.box_size),
|
||||||
height: length(params.box_size),
|
height: length(params.box_size),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (id_outer_box, _) = layout.add_child(
|
let (outer_box, _) = layout.add_child(
|
||||||
id_container,
|
id_container,
|
||||||
WidgetRectangle::create(WidgetRectangleParams {
|
WidgetRectangle::create(WidgetRectangleParams {
|
||||||
border: 2.0,
|
border: 2.0,
|
||||||
@@ -302,8 +303,8 @@ pub fn construct<U1, U2>(
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let (id_inner_box, _) = layout.add_child(
|
let (inner_box, _) = layout.add_child(
|
||||||
id_outer_box,
|
outer_box.id,
|
||||||
WidgetRectangle::create(WidgetRectangleParams {
|
WidgetRectangle::create(WidgetRectangleParams {
|
||||||
round: WLength::Units(5.0),
|
round: WLength::Units(5.0),
|
||||||
color: if params.checked { COLOR_CHECKED } else { COLOR_UNCHECKED },
|
color: if params.checked { COLOR_CHECKED } else { COLOR_UNCHECKED },
|
||||||
@@ -318,7 +319,7 @@ pub fn construct<U1, U2>(
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let (id_label, _node_label) = layout.add_child(
|
let (label, _node_label) = layout.add_child(
|
||||||
id_container,
|
id_container,
|
||||||
WidgetLabel::create(
|
WidgetLabel::create(
|
||||||
&mut globals.get(),
|
&mut globals.get(),
|
||||||
@@ -335,8 +336,8 @@ pub fn construct<U1, U2>(
|
|||||||
|
|
||||||
let data = Rc::new(Data {
|
let data = Rc::new(Data {
|
||||||
id_container,
|
id_container,
|
||||||
id_inner_box,
|
id_inner_box: inner_box.id,
|
||||||
id_label,
|
id_label: label.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
let state = Rc::new(RefCell::new(State {
|
let state = Rc::new(RefCell::new(State {
|
||||||
@@ -356,5 +357,5 @@ pub fn construct<U1, U2>(
|
|||||||
let checkbox = Rc::new(ComponentCheckbox { base, data, state });
|
let checkbox = Rc::new(ComponentCheckbox { base, data, state });
|
||||||
|
|
||||||
layout.defer_component_init(Component(checkbox.clone()));
|
layout.defer_component_init(Component(checkbox.clone()));
|
||||||
Ok((id_root, checkbox))
|
Ok((root, checkbox))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use crate::{
|
|||||||
drawing::{self},
|
drawing::{self},
|
||||||
event::{self, CallbackDataCommon, EventListenerCollection, EventListenerKind, ListenerHandleVec},
|
event::{self, CallbackDataCommon, EventListenerCollection, EventListenerKind, ListenerHandleVec},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::{Layout, WidgetID},
|
layout::{Layout, WidgetID, WidgetPair},
|
||||||
renderer_vk::{
|
renderer_vk::{
|
||||||
text::{FontWeight, HorizontalAlign, TextStyle},
|
text::{FontWeight, HorizontalAlign, TextStyle},
|
||||||
util,
|
util,
|
||||||
@@ -175,7 +175,7 @@ fn on_enter_anim(common: &mut event::CallbackDataCommon, handle_id: WidgetID) {
|
|||||||
AnimationEasing::OutBack,
|
AnimationEasing::OutBack,
|
||||||
Box::new(move |common, data| {
|
Box::new(move |common, data| {
|
||||||
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
data.data.transform = get_anim_transform(data.pos, data.widget_size);
|
data.data.transform = get_anim_transform(data.pos, data.widget_boundary.size);
|
||||||
anim_rect(rect, data.pos);
|
anim_rect(rect, data.pos);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
}),
|
}),
|
||||||
@@ -189,7 +189,7 @@ fn on_leave_anim(common: &mut event::CallbackDataCommon, handle_id: WidgetID) {
|
|||||||
AnimationEasing::OutQuad,
|
AnimationEasing::OutQuad,
|
||||||
Box::new(move |common, data| {
|
Box::new(move |common, data| {
|
||||||
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||||
data.data.transform = get_anim_transform(1.0 - data.pos, data.widget_size);
|
data.data.transform = get_anim_transform(1.0 - data.pos, data.widget_boundary.size);
|
||||||
anim_rect(rect, 1.0 - data.pos);
|
anim_rect(rect, 1.0 - data.pos);
|
||||||
common.alterables.mark_redraw();
|
common.alterables.mark_redraw();
|
||||||
}),
|
}),
|
||||||
@@ -308,14 +308,14 @@ pub fn construct<U1, U2>(
|
|||||||
listeners: &mut EventListenerCollection<U1, U2>,
|
listeners: &mut EventListenerCollection<U1, U2>,
|
||||||
parent: WidgetID,
|
parent: WidgetID,
|
||||||
params: Params,
|
params: Params,
|
||||||
) -> anyhow::Result<(WidgetID, Rc<ComponentSlider>)> {
|
) -> anyhow::Result<(WidgetPair, Rc<ComponentSlider>)> {
|
||||||
let mut style = params.style;
|
let mut style = params.style;
|
||||||
style.position = taffy::Position::Relative;
|
style.position = taffy::Position::Relative;
|
||||||
style.min_size = style.size;
|
style.min_size = style.size;
|
||||||
style.max_size = style.size;
|
style.max_size = style.size;
|
||||||
|
|
||||||
let (root_id, slider_body_node) = layout.add_child(parent, WidgetDiv::create(), style)?;
|
let (root, slider_body_node) = layout.add_child(parent, WidgetDiv::create(), style)?;
|
||||||
let body_id = root_id;
|
let body_id = root.id;
|
||||||
|
|
||||||
let (_background_id, _) = layout.add_child(
|
let (_background_id, _) = layout.add_child(
|
||||||
body_id,
|
body_id,
|
||||||
@@ -350,10 +350,10 @@ pub fn construct<U1, U2>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// invisible outer handle body
|
// invisible outer handle body
|
||||||
let (slider_handle_id, slider_handle_node) = layout.add_child(body_id, WidgetDiv::create(), slider_handle_style)?;
|
let (slider_handle, slider_handle_node) = layout.add_child(body_id, WidgetDiv::create(), slider_handle_style)?;
|
||||||
|
|
||||||
let (slider_handle_rect_id, _) = layout.add_child(
|
let (slider_handle_rect, _) = layout.add_child(
|
||||||
slider_handle_id,
|
slider_handle.id,
|
||||||
WidgetRectangle::create(WidgetRectangleParams {
|
WidgetRectangle::create(WidgetRectangleParams {
|
||||||
color: HANDLE_COLOR,
|
color: HANDLE_COLOR,
|
||||||
border_color: HANDLE_BORDER_COLOR,
|
border_color: HANDLE_BORDER_COLOR,
|
||||||
@@ -379,8 +379,8 @@ pub fn construct<U1, U2>(
|
|||||||
|
|
||||||
let globals = layout.state.globals.clone();
|
let globals = layout.state.globals.clone();
|
||||||
|
|
||||||
let (slider_text_id, _) = layout.add_child(
|
let (slider_text, _) = layout.add_child(
|
||||||
slider_handle_id,
|
slider_handle.id,
|
||||||
WidgetLabel::create(
|
WidgetLabel::create(
|
||||||
&mut globals.get(),
|
&mut globals.get(),
|
||||||
WidgetLabelParams {
|
WidgetLabelParams {
|
||||||
@@ -399,9 +399,9 @@ pub fn construct<U1, U2>(
|
|||||||
let data = Rc::new(Data {
|
let data = Rc::new(Data {
|
||||||
body: body_id,
|
body: body_id,
|
||||||
slider_handle_node,
|
slider_handle_node,
|
||||||
slider_handle_rect_id,
|
slider_handle_rect_id: slider_handle_rect.id,
|
||||||
slider_body_node,
|
slider_body_node,
|
||||||
slider_text_id,
|
slider_text_id: slider_text.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
let state = Rc::new(RefCell::new(state));
|
let state = Rc::new(RefCell::new(state));
|
||||||
@@ -418,5 +418,5 @@ pub fn construct<U1, U2>(
|
|||||||
let slider = Rc::new(ComponentSlider { base, data, state });
|
let slider = Rc::new(ComponentSlider { base, data, state });
|
||||||
|
|
||||||
layout.defer_component_init(Component(slider.clone()));
|
layout.defer_component_init(Component(slider.clone()));
|
||||||
Ok((root_id, slider))
|
Ok((root, slider))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ use taffy::TraversePartialTree;
|
|||||||
use crate::{
|
use crate::{
|
||||||
drawing,
|
drawing,
|
||||||
layout::Widget,
|
layout::Widget,
|
||||||
renderer_vk::text::{custom_glyph::CustomGlyph, TextShadow},
|
renderer_vk::text::{TextShadow, custom_glyph::CustomGlyph},
|
||||||
stack::{self, ScissorStack, TransformStack},
|
stack::{self, ScissorBoundary, ScissorStack, TransformStack},
|
||||||
widget::{self},
|
widget::{self},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -29,11 +29,22 @@ impl Boundary {
|
|||||||
Self { pos, size }
|
Self { pos, size }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn construct(transform_stack: &TransformStack) -> Self {
|
/// top-left is an absolute position
|
||||||
|
pub const fn construct_absolute(transform_stack: &TransformStack) -> Self {
|
||||||
let transform = transform_stack.get();
|
let transform = transform_stack.get();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
pos: Vec2::new(transform.pos.x, transform.pos.y),
|
pos: Vec2::new(transform.abs_pos.x, transform.abs_pos.y),
|
||||||
|
size: Vec2::new(transform.dim.x, transform.dim.y),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// top-left is zero
|
||||||
|
pub const fn construct_relative(transform_stack: &TransformStack) -> Self {
|
||||||
|
let transform = transform_stack.get();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
pos: Vec2::ZERO,
|
||||||
size: Vec2::new(transform.dim.x, transform.dim.y),
|
size: Vec2::new(transform.dim.x, transform.dim.y),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,8 +148,7 @@ pub enum RenderPrimitive {
|
|||||||
Rectangle(PrimitiveExtent, Rectangle),
|
Rectangle(PrimitiveExtent, Rectangle),
|
||||||
Text(PrimitiveExtent, Rc<RefCell<Buffer>>, Option<TextShadow>),
|
Text(PrimitiveExtent, Rc<RefCell<Buffer>>, Option<TextShadow>),
|
||||||
Sprite(PrimitiveExtent, Option<CustomGlyph>), //option because we want as_slice
|
Sprite(PrimitiveExtent, Option<CustomGlyph>), //option because we want as_slice
|
||||||
ScissorEnable(Boundary),
|
ScissorSet(ScissorBoundary),
|
||||||
ScissorDisable,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DrawParams<'a> {
|
pub struct DrawParams<'a> {
|
||||||
@@ -146,7 +156,7 @@ pub struct DrawParams<'a> {
|
|||||||
pub debug_draw: bool,
|
pub debug_draw: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_overflow_clip(style: &taffy::Style) -> bool {
|
pub fn has_overflow_clip(style: &taffy::Style) -> bool {
|
||||||
style.overflow.x != taffy::Overflow::Visible || style.overflow.y != taffy::Overflow::Visible
|
style.overflow.x != taffy::Overflow::Visible || style.overflow.y != taffy::Overflow::Visible
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +181,6 @@ fn draw_widget(
|
|||||||
node_id: taffy::NodeId,
|
node_id: taffy::NodeId,
|
||||||
style: &taffy::Style,
|
style: &taffy::Style,
|
||||||
widget: &Widget,
|
widget: &Widget,
|
||||||
parent_transform: &glam::Mat4,
|
|
||||||
) {
|
) {
|
||||||
let Ok(l) = params.layout.state.tree.layout(node_id) else {
|
let Ok(l) = params.layout.state.tree.layout(node_id) else {
|
||||||
debug_assert!(false);
|
debug_assert!(false);
|
||||||
@@ -180,24 +189,23 @@ fn draw_widget(
|
|||||||
|
|
||||||
let mut widget_state = widget.state();
|
let mut widget_state = widget.state();
|
||||||
|
|
||||||
let transform = widget_state.data.transform * *parent_transform;
|
let (scroll_shift, info) = match widget::get_scrollbar_info(l) {
|
||||||
|
|
||||||
let (shift, info) = match widget::get_scrollbar_info(l) {
|
|
||||||
Some(info) => (widget_state.get_scroll_shift(&info, l), Some(info)),
|
Some(info) => (widget_state.get_scroll_shift(&info, l), Some(info)),
|
||||||
None => (Vec2::default(), None),
|
None => (Vec2::default(), None),
|
||||||
};
|
};
|
||||||
|
|
||||||
state.transform_stack.push(stack::Transform {
|
state.transform_stack.push(stack::Transform {
|
||||||
pos: Vec2::new(l.location.x, l.location.y) - shift,
|
rel_pos: Vec2::new(l.location.x, l.location.y) - scroll_shift,
|
||||||
transform,
|
transform: widget_state.data.transform,
|
||||||
dim: Vec2::new(l.size.width, l.size.height),
|
dim: Vec2::new(l.size.width, l.size.height),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
if params.debug_draw {
|
if params.debug_draw {
|
||||||
let boundary = drawing::Boundary::construct(state.transform_stack);
|
let boundary = drawing::Boundary::construct_relative(state.transform_stack);
|
||||||
state.primitives.push(primitive_debug_rect(
|
state.primitives.push(primitive_debug_rect(
|
||||||
&boundary,
|
&boundary,
|
||||||
&transform,
|
&state.transform_stack.get().transform,
|
||||||
Color::new(0.0, 1.0, 1.0, 0.5),
|
Color::new(0.0, 1.0, 1.0, 0.5),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -205,17 +213,23 @@ fn draw_widget(
|
|||||||
let scissor_pushed = info.is_some() && has_overflow_clip(style);
|
let scissor_pushed = info.is_some() && has_overflow_clip(style);
|
||||||
|
|
||||||
if scissor_pushed {
|
if scissor_pushed {
|
||||||
let boundary = drawing::Boundary::construct(state.transform_stack);
|
let mut boundary_absolute = drawing::Boundary::construct_absolute(state.transform_stack);
|
||||||
state.scissor_stack.push(boundary);
|
boundary_absolute.pos += scroll_shift;
|
||||||
|
state.scissor_stack.push(ScissorBoundary(boundary_absolute));
|
||||||
|
|
||||||
if params.debug_draw {
|
if params.debug_draw {
|
||||||
|
let mut boundary_relative = drawing::Boundary::construct_relative(state.transform_stack);
|
||||||
|
boundary_relative.pos += scroll_shift;
|
||||||
state.primitives.push(primitive_debug_rect(
|
state.primitives.push(primitive_debug_rect(
|
||||||
&boundary,
|
&boundary_relative,
|
||||||
&transform,
|
&state.transform_stack.get().transform,
|
||||||
Color::new(1.0, 0.0, 1.0, 1.0),
|
Color::new(1.0, 0.0, 1.0, 1.0),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
state.primitives.push(drawing::RenderPrimitive::ScissorEnable(boundary));
|
state
|
||||||
|
.primitives
|
||||||
|
.push(drawing::RenderPrimitive::ScissorSet(*state.scissor_stack.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let draw_params = widget::DrawParams {
|
let draw_params = widget::DrawParams {
|
||||||
@@ -226,11 +240,13 @@ fn draw_widget(
|
|||||||
|
|
||||||
widget_state.draw_all(state, &draw_params);
|
widget_state.draw_all(state, &draw_params);
|
||||||
|
|
||||||
draw_children(params, state, node_id, &transform);
|
draw_children(params, state, node_id);
|
||||||
|
|
||||||
if scissor_pushed {
|
if scissor_pushed {
|
||||||
state.primitives.push(drawing::RenderPrimitive::ScissorDisable);
|
|
||||||
state.scissor_stack.pop();
|
state.scissor_stack.pop();
|
||||||
|
state
|
||||||
|
.primitives
|
||||||
|
.push(drawing::RenderPrimitive::ScissorSet(*state.scissor_stack.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
state.transform_stack.pop();
|
state.transform_stack.pop();
|
||||||
@@ -240,7 +256,7 @@ fn draw_widget(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_children(params: &DrawParams, state: &mut DrawState, parent_node_id: taffy::NodeId, model: &glam::Mat4) {
|
fn draw_children(params: &DrawParams, state: &mut DrawState, parent_node_id: taffy::NodeId) {
|
||||||
let layout = ¶ms.layout;
|
let layout = ¶ms.layout;
|
||||||
|
|
||||||
for node_id in layout.state.tree.child_ids(parent_node_id) {
|
for node_id in layout.state.tree.child_ids(parent_node_id) {
|
||||||
@@ -259,7 +275,7 @@ fn draw_children(params: &DrawParams, state: &mut DrawState, parent_node_id: taf
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
draw_widget(params, state, node_id, style, widget, model);
|
draw_widget(params, state, node_id, style, widget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +283,6 @@ pub fn draw(params: &DrawParams) -> anyhow::Result<Vec<RenderPrimitive>> {
|
|||||||
let mut primitives = Vec::<RenderPrimitive>::new();
|
let mut primitives = Vec::<RenderPrimitive>::new();
|
||||||
let mut transform_stack = TransformStack::new();
|
let mut transform_stack = TransformStack::new();
|
||||||
let mut scissor_stack = ScissorStack::new();
|
let mut scissor_stack = ScissorStack::new();
|
||||||
let model = glam::Mat4::IDENTITY;
|
|
||||||
|
|
||||||
let Some(root_widget) = params.layout.state.widgets.get(params.layout.root_widget) else {
|
let Some(root_widget) = params.layout.state.widgets.get(params.layout.root_widget) else {
|
||||||
panic!();
|
panic!();
|
||||||
@@ -277,11 +292,6 @@ pub fn draw(params: &DrawParams) -> anyhow::Result<Vec<RenderPrimitive>> {
|
|||||||
panic!();
|
panic!();
|
||||||
};
|
};
|
||||||
|
|
||||||
scissor_stack.push(Boundary {
|
|
||||||
pos: Default::default(),
|
|
||||||
size: Vec2::splat(1.0e12),
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut state = DrawState {
|
let mut state = DrawState {
|
||||||
primitives: &mut primitives,
|
primitives: &mut primitives,
|
||||||
transform_stack: &mut transform_stack,
|
transform_stack: &mut transform_stack,
|
||||||
@@ -289,7 +299,7 @@ pub fn draw(params: &DrawParams) -> anyhow::Result<Vec<RenderPrimitive>> {
|
|||||||
layout: params.layout,
|
layout: params.layout,
|
||||||
};
|
};
|
||||||
|
|
||||||
draw_widget(params, &mut state, params.layout.root_node, style, root_widget, &model);
|
draw_widget(params, &mut state, params.layout.root_node, style, root_widget);
|
||||||
|
|
||||||
Ok(primitives)
|
Ok(primitives)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
animation::{self, Animation},
|
animation::{self, Animation},
|
||||||
i18n::I18n,
|
i18n::I18n,
|
||||||
layout::{LayoutState, WidgetID},
|
layout::{LayoutState, WidgetID},
|
||||||
stack::{Transform, TransformStack},
|
stack::{ScissorStack, Transform, TransformStack},
|
||||||
widget::{WidgetData, WidgetObj},
|
widget::{WidgetData, WidgetObj},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -74,10 +74,10 @@ pub enum Event {
|
|||||||
|
|
||||||
impl Event {
|
impl Event {
|
||||||
fn test_transform_pos(transform: &Transform, pos: Vec2) -> bool {
|
fn test_transform_pos(transform: &Transform, pos: Vec2) -> bool {
|
||||||
pos.x >= transform.pos.x
|
pos.x >= transform.abs_pos.x
|
||||||
&& pos.x < transform.pos.x + transform.dim.x
|
&& pos.x < transform.abs_pos.x + transform.dim.x
|
||||||
&& pos.y >= transform.pos.y
|
&& pos.y >= transform.abs_pos.y
|
||||||
&& pos.y < transform.pos.y + transform.dim.y
|
&& pos.y < transform.abs_pos.y + transform.dim.y
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_mouse_within_transform(&self, transform: &Transform) -> bool {
|
pub fn test_mouse_within_transform(&self, transform: &Transform) -> bool {
|
||||||
@@ -97,6 +97,7 @@ pub struct EventAlterables {
|
|||||||
pub style_set_requests: Vec<(taffy::NodeId, taffy::Style)>,
|
pub style_set_requests: Vec<(taffy::NodeId, taffy::Style)>,
|
||||||
pub animations: Vec<animation::Animation>,
|
pub animations: Vec<animation::Animation>,
|
||||||
pub transform_stack: TransformStack,
|
pub transform_stack: TransformStack,
|
||||||
|
pub scissor_stack: ScissorStack,
|
||||||
pub needs_redraw: bool,
|
pub needs_redraw: bool,
|
||||||
pub trigger_haptics: bool,
|
pub trigger_haptics: bool,
|
||||||
}
|
}
|
||||||
@@ -170,7 +171,7 @@ impl CallbackMetadata {
|
|||||||
|
|
||||||
pub fn get_mouse_pos_relative(&self, transform_stack: &TransformStack) -> Option<Vec2> {
|
pub fn get_mouse_pos_relative(&self, transform_stack: &TransformStack) -> Option<Vec2> {
|
||||||
let mouse_pos_abs = self.get_mouse_pos_absolute()?;
|
let mouse_pos_abs = self.get_mouse_pos_absolute()?;
|
||||||
Some(mouse_pos_abs - transform_stack.get().pos)
|
Some(mouse_pos_abs - transform_stack.get().abs_pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
use std::{
|
use std::{
|
||||||
cell::{RefCell, RefMut},
|
cell::{RefCell, RefMut},
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
rc::Rc,
|
rc::{Rc, Weak},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
animation::Animations,
|
animation::Animations,
|
||||||
components::{Component, InitData},
|
components::{Component, InitData},
|
||||||
|
drawing::{self, Boundary, has_overflow_clip},
|
||||||
event::{self, CallbackDataCommon, EventAlterables, EventListenerCollection},
|
event::{self, CallbackDataCommon, EventAlterables, EventListenerCollection},
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
stack::Transform,
|
stack::{self, ScissorBoundary, Transform},
|
||||||
widget::{self, EventParams, WidgetObj, WidgetState, div::WidgetDiv},
|
widget::{self, EventParams, WidgetObj, WidgetState, div::WidgetDiv},
|
||||||
};
|
};
|
||||||
|
|
||||||
use glam::{Vec2, vec2};
|
use glam::{Vec2, vec2};
|
||||||
use slotmap::{HopSlotMap, SecondaryMap, new_key_type};
|
use slotmap::{HopSlotMap, SecondaryMap, new_key_type};
|
||||||
use taffy::{TaffyTree, TraversePartialTree};
|
use taffy::{NodeId, TaffyTree, TraversePartialTree};
|
||||||
|
|
||||||
new_key_type! {
|
new_key_type! {
|
||||||
pub struct WidgetID;
|
pub struct WidgetID;
|
||||||
@@ -23,6 +24,7 @@ new_key_type! {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Widget(Rc<RefCell<WidgetState>>);
|
pub struct Widget(Rc<RefCell<WidgetState>>);
|
||||||
|
pub struct WeakWidget(Weak<RefCell<WidgetState>>);
|
||||||
|
|
||||||
impl Widget {
|
impl Widget {
|
||||||
pub fn new(widget_state: WidgetState) -> Self {
|
pub fn new(widget_state: WidgetState) -> Self {
|
||||||
@@ -33,11 +35,21 @@ impl Widget {
|
|||||||
RefMut::filter_map(self.0.borrow_mut(), |w| w.obj.get_as_mut::<T>()).ok()
|
RefMut::filter_map(self.0.borrow_mut(), |w| w.obj.get_as_mut::<T>()).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn downgrade(&self) -> WeakWidget {
|
||||||
|
WeakWidget(Rc::downgrade(&self.0))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn state(&self) -> RefMut<'_, WidgetState> {
|
pub fn state(&self) -> RefMut<'_, WidgetState> {
|
||||||
self.0.borrow_mut()
|
self.0.borrow_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl WeakWidget {
|
||||||
|
pub fn upgrade(&self) -> Option<Widget> {
|
||||||
|
self.0.upgrade().map(Widget)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WidgetMap(HopSlotMap<WidgetID, Widget>);
|
pub struct WidgetMap(HopSlotMap<WidgetID, Widget>);
|
||||||
pub type WidgetNodeMap = SecondaryMap<WidgetID, taffy::NodeId>;
|
pub type WidgetNodeMap = SecondaryMap<WidgetID, taffy::NodeId>;
|
||||||
|
|
||||||
@@ -128,9 +140,10 @@ fn add_child_internal(
|
|||||||
parent_node: Option<taffy::NodeId>,
|
parent_node: Option<taffy::NodeId>,
|
||||||
widget_state: WidgetState,
|
widget_state: WidgetState,
|
||||||
style: taffy::Style,
|
style: taffy::Style,
|
||||||
) -> anyhow::Result<(WidgetID, taffy::NodeId)> {
|
) -> anyhow::Result<(WidgetPair, taffy::NodeId)> {
|
||||||
#[allow(clippy::arc_with_non_send_sync)]
|
let new_widget = Widget::new(widget_state);
|
||||||
let child_id = widgets.insert(Widget::new(widget_state));
|
|
||||||
|
let child_id = widgets.insert(new_widget.clone());
|
||||||
let child_node = tree.new_leaf_with_context(style, child_id)?;
|
let child_node = tree.new_leaf_with_context(style, child_id)?;
|
||||||
|
|
||||||
if let Some(parent_node) = parent_node {
|
if let Some(parent_node) = parent_node {
|
||||||
@@ -139,7 +152,13 @@ fn add_child_internal(
|
|||||||
|
|
||||||
nodes.insert(child_id, child_node);
|
nodes.insert(child_id, child_node);
|
||||||
|
|
||||||
Ok((child_id, child_node))
|
Ok((
|
||||||
|
WidgetPair {
|
||||||
|
id: child_id,
|
||||||
|
widget: new_widget,
|
||||||
|
},
|
||||||
|
child_node,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Layout {
|
impl Layout {
|
||||||
@@ -152,7 +171,7 @@ impl Layout {
|
|||||||
parent_widget_id: WidgetID,
|
parent_widget_id: WidgetID,
|
||||||
widget: WidgetState,
|
widget: WidgetState,
|
||||||
style: taffy::Style,
|
style: taffy::Style,
|
||||||
) -> anyhow::Result<(WidgetID, taffy::NodeId)> {
|
) -> anyhow::Result<(WidgetPair, taffy::NodeId)> {
|
||||||
let parent_node = *self.state.nodes.get(parent_widget_id).unwrap();
|
let parent_node = *self.state.nodes.get(parent_widget_id).unwrap();
|
||||||
|
|
||||||
self.mark_redraw();
|
self.mark_redraw();
|
||||||
@@ -255,13 +274,26 @@ impl Layout {
|
|||||||
anyhow::bail!("invalid widget");
|
anyhow::bail!("invalid widget");
|
||||||
};
|
};
|
||||||
|
|
||||||
let transform = Transform {
|
let mut widget = widget.0.borrow_mut();
|
||||||
pos: Vec2::new(l.location.x, l.location.y),
|
let (scroll_shift, info) = match widget::get_scrollbar_info(l) {
|
||||||
dim: Vec2::new(l.size.width, l.size.height),
|
Some(info) => (widget.get_scroll_shift(&info, l), Some(info)),
|
||||||
transform: glam::Mat4::IDENTITY, // TODO: event transformations? Not needed for now
|
None => (Vec2::default(), None),
|
||||||
};
|
};
|
||||||
|
|
||||||
alterables.transform_stack.push(transform);
|
alterables.transform_stack.push(stack::Transform {
|
||||||
|
rel_pos: Vec2::new(l.location.x, l.location.y) - scroll_shift,
|
||||||
|
transform: widget.data.transform,
|
||||||
|
dim: Vec2::new(l.size.width, l.size.height),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
// see drawing.rs too
|
||||||
|
let scissor_pushed = info.is_some() && has_overflow_clip(style);
|
||||||
|
if scissor_pushed {
|
||||||
|
let mut boundary_absolute = drawing::Boundary::construct_absolute(&alterables.transform_stack);
|
||||||
|
boundary_absolute.pos += scroll_shift;
|
||||||
|
alterables.scissor_stack.push(ScissorBoundary(boundary_absolute));
|
||||||
|
}
|
||||||
|
|
||||||
let mut iter_children = true;
|
let mut iter_children = true;
|
||||||
|
|
||||||
@@ -275,8 +307,6 @@ impl Layout {
|
|||||||
|
|
||||||
let listeners_vec = listeners.get(widget_id);
|
let listeners_vec = listeners.get(widget_id);
|
||||||
|
|
||||||
let mut widget = widget.0.borrow_mut();
|
|
||||||
|
|
||||||
match widget.process_event(widget_id, listeners_vec, node_id, event, user_data, &mut params)? {
|
match widget.process_event(widget_id, listeners_vec, node_id, event, user_data, &mut params)? {
|
||||||
widget::EventResult::Pass => {
|
widget::EventResult::Pass => {
|
||||||
// go on
|
// go on
|
||||||
@@ -292,6 +322,10 @@ impl Layout {
|
|||||||
self.push_event_children(listeners, node_id, event, alterables, user_data)?;
|
self.push_event_children(listeners, node_id, event, alterables, user_data)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if scissor_pushed {
|
||||||
|
alterables.scissor_stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
alterables.transform_stack.pop();
|
alterables.transform_stack.pop();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -361,7 +395,7 @@ impl Layout {
|
|||||||
prev_size: Vec2::default(),
|
prev_size: Vec2::default(),
|
||||||
content_size: Vec2::default(),
|
content_size: Vec2::default(),
|
||||||
root_node,
|
root_node,
|
||||||
root_widget,
|
root_widget: root_widget.id,
|
||||||
needs_redraw: true,
|
needs_redraw: true,
|
||||||
haptics_triggered: false,
|
haptics_triggered: false,
|
||||||
animations: Animations::default(),
|
animations: Animations::default(),
|
||||||
@@ -468,3 +502,24 @@ impl Layout {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LayoutState {
|
||||||
|
pub fn get_widget_boundary(&self, id: NodeId) -> Boundary {
|
||||||
|
let Ok(layout) = self.tree.layout(id) else {
|
||||||
|
return Boundary::default();
|
||||||
|
};
|
||||||
|
|
||||||
|
Boundary {
|
||||||
|
pos: Vec2::new(layout.location.x, layout.location.y),
|
||||||
|
size: Vec2::new(layout.size.width, layout.size.height),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_widget_size(&self, id: NodeId) -> Vec2 {
|
||||||
|
let Ok(layout) = self.tree.layout(id) else {
|
||||||
|
return Vec2::ZERO;
|
||||||
|
};
|
||||||
|
|
||||||
|
Vec2::new(layout.size.width, layout.size.height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
components::{button, Component},
|
components::{Component, button},
|
||||||
drawing::Color,
|
drawing::Color,
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{
|
parser::{
|
||||||
parse_children, process_component,
|
AttribPair, ParserContext, ParserFile, parse_children, process_component,
|
||||||
style::{parse_color_opt, parse_round, parse_style, parse_text_style},
|
style::{parse_color_opt, parse_round, parse_style, parse_text_style},
|
||||||
AttribPair, ParserContext, ParserFile,
|
|
||||||
},
|
},
|
||||||
widget::util::WLength,
|
widget::util::WLength,
|
||||||
};
|
};
|
||||||
@@ -30,27 +29,27 @@ pub fn parse_component_button<'a, U1, U2>(
|
|||||||
|
|
||||||
for pair in attribs {
|
for pair in attribs {
|
||||||
let (key, value) = (pair.attrib.as_ref(), pair.value.as_ref());
|
let (key, value) = (pair.attrib.as_ref(), pair.value.as_ref());
|
||||||
match key.as_ref() {
|
match key {
|
||||||
"text" => {
|
"text" => {
|
||||||
translation = Some(Translation::from_raw_text(&value));
|
translation = Some(Translation::from_raw_text(value));
|
||||||
}
|
}
|
||||||
"translation" => {
|
"translation" => {
|
||||||
translation = Some(Translation::from_translation_key(&value));
|
translation = Some(Translation::from_translation_key(value));
|
||||||
}
|
}
|
||||||
"round" => {
|
"round" => {
|
||||||
parse_round(&value, &mut round);
|
parse_round(value, &mut round);
|
||||||
}
|
}
|
||||||
"color" => {
|
"color" => {
|
||||||
parse_color_opt(&value, &mut color);
|
parse_color_opt(value, &mut color);
|
||||||
}
|
}
|
||||||
"border_color" => {
|
"border_color" => {
|
||||||
parse_color_opt(&value, &mut border_color);
|
parse_color_opt(value, &mut border_color);
|
||||||
}
|
}
|
||||||
"hover_color" => {
|
"hover_color" => {
|
||||||
parse_color_opt(&value, &mut hover_color);
|
parse_color_opt(value, &mut hover_color);
|
||||||
}
|
}
|
||||||
"hover_border_color" => {
|
"hover_border_color" => {
|
||||||
parse_color_opt(&value, &mut hover_border_color);
|
parse_color_opt(value, &mut hover_border_color);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@@ -58,7 +57,7 @@ pub fn parse_component_button<'a, U1, U2>(
|
|||||||
|
|
||||||
let globals = ctx.layout.state.globals.clone();
|
let globals = ctx.layout.state.globals.clone();
|
||||||
|
|
||||||
let (new_id, component) = button::construct(
|
let (widget, component) = button::construct(
|
||||||
&mut globals.get(),
|
&mut globals.get(),
|
||||||
ctx.layout,
|
ctx.layout,
|
||||||
ctx.listeners,
|
ctx.listeners,
|
||||||
@@ -75,8 +74,8 @@ pub fn parse_component_button<'a, U1, U2>(
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
process_component(ctx, Component(component), new_id, attribs);
|
process_component(ctx, Component(component), widget.id, attribs);
|
||||||
parse_children(file, ctx, node, new_id)?;
|
parse_children(file, ctx, node, widget.id)?;
|
||||||
|
|
||||||
Ok(new_id)
|
Ok(widget.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
components::{checkbox, Component},
|
components::{Component, checkbox},
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{parse_check_f32, parse_check_i32, process_component, style::parse_style, AttribPair, ParserContext},
|
parser::{AttribPair, ParserContext, parse_check_f32, parse_check_i32, process_component, style::parse_style},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parse_component_checkbox<'a, U1, U2>(
|
pub fn parse_component_checkbox<U1, U2>(
|
||||||
ctx: &mut ParserContext<U1, U2>,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
attribs: &[AttribPair],
|
attribs: &[AttribPair],
|
||||||
@@ -35,7 +35,7 @@ pub fn parse_component_checkbox<'a, U1, U2>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (new_id, component) = checkbox::construct(
|
let (widget, component) = checkbox::construct(
|
||||||
ctx.layout,
|
ctx.layout,
|
||||||
ctx.listeners,
|
ctx.listeners,
|
||||||
parent_id,
|
parent_id,
|
||||||
@@ -47,7 +47,7 @@ pub fn parse_component_checkbox<'a, U1, U2>(
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
process_component(ctx, Component(component), new_id, attribs);
|
process_component(ctx, Component(component), widget.id, attribs);
|
||||||
|
|
||||||
Ok(new_id)
|
Ok(widget.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
components::{slider, Component},
|
components::{Component, slider},
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{parse_check_f32, process_component, style::parse_style, AttribPair, ParserContext},
|
parser::{AttribPair, ParserContext, parse_check_f32, process_component, style::parse_style},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parse_component_slider<'a, U1, U2>(
|
pub fn parse_component_slider<U1, U2>(
|
||||||
ctx: &mut ParserContext<U1, U2>,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
attribs: &[AttribPair],
|
attribs: &[AttribPair],
|
||||||
@@ -31,7 +31,7 @@ pub fn parse_component_slider<'a, U1, U2>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (new_id, component) = slider::construct(
|
let (widget, component) = slider::construct(
|
||||||
ctx.layout,
|
ctx.layout,
|
||||||
ctx.listeners,
|
ctx.listeners,
|
||||||
parent_id,
|
parent_id,
|
||||||
@@ -45,7 +45,7 @@ pub fn parse_component_slider<'a, U1, U2>(
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
process_component(ctx, Component(component), new_id, attribs);
|
process_component(ctx, Component(component), widget.id, attribs);
|
||||||
|
|
||||||
Ok(new_id)
|
Ok(widget.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -530,9 +530,9 @@ fn parse_widget_other_internal<U1, U2>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_widget_other<'a, U1, U2>(
|
fn parse_widget_other<U1, U2>(
|
||||||
xml_tag_name: &str,
|
xml_tag_name: &str,
|
||||||
file: &'a ParserFile,
|
file: &ParserFile,
|
||||||
ctx: &mut ParserContext<U1, U2>,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
attribs: &[AttribPair],
|
attribs: &[AttribPair],
|
||||||
@@ -548,7 +548,7 @@ fn parse_widget_other<'a, U1, U2>(
|
|||||||
parse_widget_other_internal(&template, template_parameters, file, ctx, parent_id)
|
parse_widget_other_internal(&template, template_parameters, file, ctx, parent_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_tag_include<'a, U1, U2>(
|
fn parse_tag_include<U1, U2>(
|
||||||
file: &ParserFile,
|
file: &ParserFile,
|
||||||
ctx: &mut ParserContext<U1, U2>,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
@@ -641,7 +641,7 @@ fn process_attrib<'a, U1, U2>(
|
|||||||
let name = &value[1..];
|
let name = &value[1..];
|
||||||
|
|
||||||
match ctx.get_var(name) {
|
match ctx.get_var(name) {
|
||||||
Some(name) => AttribPair::new(key, name.clone()),
|
Some(name) => AttribPair::new(key, name),
|
||||||
None => AttribPair::new(key, "undefined"),
|
None => AttribPair::new(key, "undefined"),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -655,7 +655,7 @@ fn raw_attribs<'a>(node: &'a roxmltree::Node<'a, 'a>) -> Vec<AttribPair> {
|
|||||||
let (key, value) = (attrib.name(), attrib.value());
|
let (key, value) = (attrib.name(), attrib.value());
|
||||||
res.push(AttribPair::new(key, value));
|
res.push(AttribPair::new(key, value));
|
||||||
}
|
}
|
||||||
return res;
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_attribs<'a, U1, U2>(
|
fn process_attribs<'a, U1, U2>(
|
||||||
@@ -761,7 +761,7 @@ fn parse_tag_macro<U1, U2>(file: &ParserFile, ctx: &mut ParserContext<U1, U2>, n
|
|||||||
ctx.insert_macro_attrib(name, MacroAttribs { attribs: macro_attribs });
|
ctx.insert_macro_attrib(name, MacroAttribs { attribs: macro_attribs });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_component<'a, U1, U2>(
|
fn process_component<U1, U2>(
|
||||||
ctx: &mut ParserContext<U1, U2>,
|
ctx: &mut ParserContext<U1, U2>,
|
||||||
component: Component,
|
component: Component,
|
||||||
widget_id: WidgetID,
|
widget_id: WidgetID,
|
||||||
@@ -782,7 +782,7 @@ fn process_component<'a, U1, U2>(
|
|||||||
ctx.insert_component(widget_id, component, component_id);
|
ctx.insert_component(widget_id, component, component_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_widget_universal<'a, U1, U2>(ctx: &mut ParserContext<U1, U2>, widget_id: WidgetID, attribs: &[AttribPair]) {
|
fn parse_widget_universal<U1, U2>(ctx: &mut ParserContext<U1, U2>, widget_id: WidgetID, attribs: &[AttribPair]) {
|
||||||
for pair in attribs {
|
for pair in attribs {
|
||||||
#[allow(clippy::single_match)]
|
#[allow(clippy::single_match)]
|
||||||
match pair.attrib.as_ref() {
|
match pair.attrib.as_ref() {
|
||||||
@@ -957,7 +957,7 @@ impl CustomAttribsInfo<'_> {
|
|||||||
CustomAttribsInfoOwned {
|
CustomAttribsInfoOwned {
|
||||||
parent_id: self.parent_id,
|
parent_id: self.parent_id,
|
||||||
widget_id: self.widget_id,
|
widget_id: self.widget_id,
|
||||||
pairs: self.pairs.iter().cloned().collect(),
|
pairs: self.pairs.to_vec(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use taffy::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
drawing,
|
drawing,
|
||||||
parser::{
|
parser::{
|
||||||
is_percent, parse_color_hex, parse_f32, parse_percent, parse_size_unit, parse_val, print_invalid_attrib,
|
AttribPair, is_percent, parse_color_hex, parse_f32, parse_percent, parse_size_unit, parse_val,
|
||||||
print_invalid_value, AttribPair,
|
print_invalid_attrib, print_invalid_value,
|
||||||
},
|
},
|
||||||
renderer_vk::text::{FontWeight, HorizontalAlign, TextStyle},
|
renderer_vk::text::{FontWeight, HorizontalAlign, TextStyle},
|
||||||
widget::util::WLength,
|
widget::util::WLength,
|
||||||
@@ -54,7 +54,7 @@ pub fn parse_text_style(attribs: &[AttribPair]) -> TextStyle {
|
|||||||
style.color = Some(color);
|
style.color = Some(color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"align" => match value.as_ref() {
|
"align" => match value {
|
||||||
"left" => style.align = Some(HorizontalAlign::Left),
|
"left" => style.align = Some(HorizontalAlign::Left),
|
||||||
"right" => style.align = Some(HorizontalAlign::Right),
|
"right" => style.align = Some(HorizontalAlign::Right),
|
||||||
"center" => style.align = Some(HorizontalAlign::Center),
|
"center" => style.align = Some(HorizontalAlign::Center),
|
||||||
@@ -64,7 +64,7 @@ pub fn parse_text_style(attribs: &[AttribPair]) -> TextStyle {
|
|||||||
print_invalid_attrib(key, value);
|
print_invalid_attrib(key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"weight" => match value.as_ref() {
|
"weight" => match value {
|
||||||
"normal" => style.weight = Some(FontWeight::Normal),
|
"normal" => style.weight = Some(FontWeight::Normal),
|
||||||
"bold" => style.weight = Some(FontWeight::Bold),
|
"bold" => style.weight = Some(FontWeight::Bold),
|
||||||
_ => {
|
_ => {
|
||||||
@@ -111,8 +111,8 @@ pub fn parse_style(attribs: &[AttribPair]) -> taffy::Style {
|
|||||||
|
|
||||||
for pair in attribs {
|
for pair in attribs {
|
||||||
let (key, value) = (pair.attrib.as_ref(), pair.value.as_ref());
|
let (key, value) = (pair.attrib.as_ref(), pair.value.as_ref());
|
||||||
match key.as_ref() {
|
match key {
|
||||||
"display" => match value.as_ref() {
|
"display" => match value {
|
||||||
"flex" => style.display = Display::Flex,
|
"flex" => style.display = Display::Flex,
|
||||||
"block" => style.display = Display::Block,
|
"block" => style.display = Display::Block,
|
||||||
"grid" => style.display = Display::Grid,
|
"grid" => style.display = Display::Grid,
|
||||||
@@ -176,7 +176,7 @@ pub fn parse_style(attribs: &[AttribPair]) -> taffy::Style {
|
|||||||
style.padding.bottom = dim;
|
style.padding.bottom = dim;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"overflow" => match value.as_ref() {
|
"overflow" => match value {
|
||||||
"hidden" => {
|
"hidden" => {
|
||||||
style.overflow.x = Overflow::Hidden;
|
style.overflow.x = Overflow::Hidden;
|
||||||
style.overflow.y = Overflow::Hidden;
|
style.overflow.y = Overflow::Hidden;
|
||||||
@@ -197,7 +197,7 @@ pub fn parse_style(attribs: &[AttribPair]) -> taffy::Style {
|
|||||||
print_invalid_attrib(key, value);
|
print_invalid_attrib(key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"overflow_x" => match value.as_ref() {
|
"overflow_x" => match value {
|
||||||
"hidden" => style.overflow.x = Overflow::Hidden,
|
"hidden" => style.overflow.x = Overflow::Hidden,
|
||||||
"visible" => style.overflow.x = Overflow::Visible,
|
"visible" => style.overflow.x = Overflow::Visible,
|
||||||
"clip" => style.overflow.x = Overflow::Clip,
|
"clip" => style.overflow.x = Overflow::Clip,
|
||||||
@@ -206,7 +206,7 @@ pub fn parse_style(attribs: &[AttribPair]) -> taffy::Style {
|
|||||||
print_invalid_attrib(key, value);
|
print_invalid_attrib(key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"overflow_y" => match value.as_ref() {
|
"overflow_y" => match value {
|
||||||
"hidden" => style.overflow.y = Overflow::Hidden,
|
"hidden" => style.overflow.y = Overflow::Hidden,
|
||||||
"visible" => style.overflow.y = Overflow::Visible,
|
"visible" => style.overflow.y = Overflow::Visible,
|
||||||
"clip" => style.overflow.y = Overflow::Clip,
|
"clip" => style.overflow.y = Overflow::Clip,
|
||||||
@@ -265,21 +265,21 @@ pub fn parse_style(attribs: &[AttribPair]) -> taffy::Style {
|
|||||||
style.flex_shrink = val;
|
style.flex_shrink = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"position" => match value.as_ref() {
|
"position" => match value {
|
||||||
"absolute" => style.position = taffy::Position::Absolute,
|
"absolute" => style.position = taffy::Position::Absolute,
|
||||||
"relative" => style.position = taffy::Position::Relative,
|
"relative" => style.position = taffy::Position::Relative,
|
||||||
_ => {
|
_ => {
|
||||||
print_invalid_attrib(key, value);
|
print_invalid_attrib(key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"box_sizing" => match value.as_ref() {
|
"box_sizing" => match value {
|
||||||
"border_box" => style.box_sizing = BoxSizing::BorderBox,
|
"border_box" => style.box_sizing = BoxSizing::BorderBox,
|
||||||
"content_box" => style.box_sizing = BoxSizing::ContentBox,
|
"content_box" => style.box_sizing = BoxSizing::ContentBox,
|
||||||
_ => {
|
_ => {
|
||||||
print_invalid_attrib(key, value);
|
print_invalid_attrib(key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"align_self" => match value.as_ref() {
|
"align_self" => match value {
|
||||||
"baseline" => style.align_self = Some(AlignSelf::Baseline),
|
"baseline" => style.align_self = Some(AlignSelf::Baseline),
|
||||||
"center" => style.align_self = Some(AlignSelf::Center),
|
"center" => style.align_self = Some(AlignSelf::Center),
|
||||||
"end" => style.align_self = Some(AlignSelf::End),
|
"end" => style.align_self = Some(AlignSelf::End),
|
||||||
@@ -291,7 +291,7 @@ pub fn parse_style(attribs: &[AttribPair]) -> taffy::Style {
|
|||||||
print_invalid_attrib(key, value);
|
print_invalid_attrib(key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"justify_self" => match value.as_ref() {
|
"justify_self" => match value {
|
||||||
"center" => style.justify_self = Some(JustifySelf::Center),
|
"center" => style.justify_self = Some(JustifySelf::Center),
|
||||||
"end" => style.justify_self = Some(JustifySelf::End),
|
"end" => style.justify_self = Some(JustifySelf::End),
|
||||||
"flex_end" => style.justify_self = Some(JustifySelf::FlexEnd),
|
"flex_end" => style.justify_self = Some(JustifySelf::FlexEnd),
|
||||||
@@ -302,7 +302,7 @@ pub fn parse_style(attribs: &[AttribPair]) -> taffy::Style {
|
|||||||
print_invalid_attrib(key, value);
|
print_invalid_attrib(key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"align_items" => match value.as_ref() {
|
"align_items" => match value {
|
||||||
"baseline" => style.align_items = Some(AlignItems::Baseline),
|
"baseline" => style.align_items = Some(AlignItems::Baseline),
|
||||||
"center" => style.align_items = Some(AlignItems::Center),
|
"center" => style.align_items = Some(AlignItems::Center),
|
||||||
"end" => style.align_items = Some(AlignItems::End),
|
"end" => style.align_items = Some(AlignItems::End),
|
||||||
@@ -314,7 +314,7 @@ pub fn parse_style(attribs: &[AttribPair]) -> taffy::Style {
|
|||||||
print_invalid_attrib(key, value);
|
print_invalid_attrib(key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"align_content" => match value.as_ref() {
|
"align_content" => match value {
|
||||||
"center" => style.align_content = Some(AlignContent::Center),
|
"center" => style.align_content = Some(AlignContent::Center),
|
||||||
"end" => style.align_content = Some(AlignContent::End),
|
"end" => style.align_content = Some(AlignContent::End),
|
||||||
"flex_end" => style.align_content = Some(AlignContent::FlexEnd),
|
"flex_end" => style.align_content = Some(AlignContent::FlexEnd),
|
||||||
@@ -328,7 +328,7 @@ pub fn parse_style(attribs: &[AttribPair]) -> taffy::Style {
|
|||||||
print_invalid_attrib(key, value);
|
print_invalid_attrib(key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"justify_content" => match value.as_ref() {
|
"justify_content" => match value {
|
||||||
"center" => style.justify_content = Some(JustifyContent::Center),
|
"center" => style.justify_content = Some(JustifyContent::Center),
|
||||||
"end" => style.justify_content = Some(JustifyContent::End),
|
"end" => style.justify_content = Some(JustifyContent::End),
|
||||||
"flex_end" => style.justify_content = Some(JustifyContent::FlexEnd),
|
"flex_end" => style.justify_content = Some(JustifyContent::FlexEnd),
|
||||||
@@ -342,13 +342,13 @@ pub fn parse_style(attribs: &[AttribPair]) -> taffy::Style {
|
|||||||
print_invalid_attrib(key, value);
|
print_invalid_attrib(key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flex_wrap" => match value.as_ref() {
|
"flex_wrap" => match value {
|
||||||
"wrap" => style.flex_wrap = FlexWrap::Wrap,
|
"wrap" => style.flex_wrap = FlexWrap::Wrap,
|
||||||
"no_wrap" => style.flex_wrap = FlexWrap::NoWrap,
|
"no_wrap" => style.flex_wrap = FlexWrap::NoWrap,
|
||||||
"wrap_reverse" => style.flex_wrap = FlexWrap::WrapReverse,
|
"wrap_reverse" => style.flex_wrap = FlexWrap::WrapReverse,
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
"flex_direction" => match value.as_ref() {
|
"flex_direction" => match value {
|
||||||
"column_reverse" => style.flex_direction = FlexDirection::ColumnReverse,
|
"column_reverse" => style.flex_direction = FlexDirection::ColumnReverse,
|
||||||
"column" => style.flex_direction = FlexDirection::Column,
|
"column" => style.flex_direction = FlexDirection::Column,
|
||||||
"row_reverse" => style.flex_direction = FlexDirection::RowReverse,
|
"row_reverse" => style.flex_direction = FlexDirection::RowReverse,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{parse_children, parse_widget_universal, style::parse_style, AttribPair, ParserContext, ParserFile},
|
parser::{AttribPair, ParserContext, ParserFile, parse_children, parse_widget_universal, style::parse_style},
|
||||||
widget::div::WidgetDiv,
|
widget::div::WidgetDiv,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -13,10 +13,10 @@ pub fn parse_widget_div<'a, U1, U2>(
|
|||||||
) -> anyhow::Result<WidgetID> {
|
) -> anyhow::Result<WidgetID> {
|
||||||
let style = parse_style(attribs);
|
let style = parse_style(attribs);
|
||||||
|
|
||||||
let (new_id, _) = ctx.layout.add_child(parent_id, WidgetDiv::create(), style)?;
|
let (widget, _) = ctx.layout.add_child(parent_id, WidgetDiv::create(), style)?;
|
||||||
|
|
||||||
parse_widget_universal(ctx, new_id, attribs);
|
parse_widget_universal(ctx, widget.id, attribs);
|
||||||
parse_children(file, ctx, node, new_id)?;
|
parse_children(file, ctx, node, widget.id)?;
|
||||||
|
|
||||||
Ok(new_id)
|
Ok(widget.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ use crate::{
|
|||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{
|
parser::{
|
||||||
parse_children, parse_widget_universal,
|
AttribPair, ParserContext, ParserFile, parse_children, parse_widget_universal,
|
||||||
style::{parse_style, parse_text_style},
|
style::{parse_style, parse_text_style},
|
||||||
AttribPair, ParserContext, ParserFile,
|
|
||||||
},
|
},
|
||||||
widget::label::{WidgetLabel, WidgetLabelParams},
|
widget::label::{WidgetLabel, WidgetLabelParams},
|
||||||
};
|
};
|
||||||
@@ -40,12 +39,12 @@ pub fn parse_widget_label<'a, U1, U2>(
|
|||||||
|
|
||||||
let globals = ctx.layout.state.globals.clone();
|
let globals = ctx.layout.state.globals.clone();
|
||||||
|
|
||||||
let (new_id, _) = ctx
|
let (widget, _) = ctx
|
||||||
.layout
|
.layout
|
||||||
.add_child(parent_id, WidgetLabel::create(&mut globals.get(), params), style)?;
|
.add_child(parent_id, WidgetLabel::create(&mut globals.get(), params), style)?;
|
||||||
|
|
||||||
parse_widget_universal(ctx, new_id, attribs);
|
parse_widget_universal(ctx, widget.id, attribs);
|
||||||
parse_children(file, ctx, node, new_id)?;
|
parse_children(file, ctx, node, widget.id)?;
|
||||||
|
|
||||||
Ok(new_id)
|
Ok(widget.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ use crate::{
|
|||||||
drawing::GradientMode,
|
drawing::GradientMode,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{
|
parser::{
|
||||||
parse_children, parse_widget_universal, print_invalid_attrib,
|
AttribPair, ParserContext, ParserFile, parse_children, parse_widget_universal, print_invalid_attrib,
|
||||||
style::{parse_color, parse_round, parse_style},
|
style::{parse_color, parse_round, parse_style},
|
||||||
AttribPair, ParserContext, ParserFile,
|
|
||||||
},
|
},
|
||||||
widget::rectangle::{WidgetRectangle, WidgetRectangleParams},
|
widget::rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
};
|
};
|
||||||
@@ -17,7 +16,7 @@ pub fn parse_widget_rectangle<'a, U1, U2>(
|
|||||||
attribs: &[AttribPair],
|
attribs: &[AttribPair],
|
||||||
) -> anyhow::Result<WidgetID> {
|
) -> anyhow::Result<WidgetID> {
|
||||||
let mut params = WidgetRectangleParams::default();
|
let mut params = WidgetRectangleParams::default();
|
||||||
let style = parse_style(&attribs);
|
let style = parse_style(attribs);
|
||||||
|
|
||||||
for pair in attribs {
|
for pair in attribs {
|
||||||
let (key, value) = (pair.attrib.as_ref(), pair.value.as_ref());
|
let (key, value) = (pair.attrib.as_ref(), pair.value.as_ref());
|
||||||
@@ -56,12 +55,12 @@ pub fn parse_widget_rectangle<'a, U1, U2>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (new_id, _) = ctx
|
let (widget, _) = ctx
|
||||||
.layout
|
.layout
|
||||||
.add_child(parent_id, WidgetRectangle::create(params), style)?;
|
.add_child(parent_id, WidgetRectangle::create(params), style)?;
|
||||||
|
|
||||||
parse_widget_universal(ctx, new_id, attribs);
|
parse_widget_universal(ctx, widget.id, attribs);
|
||||||
parse_children(file, ctx, node, new_id)?;
|
parse_children(file, ctx, node, widget.id)?;
|
||||||
|
|
||||||
Ok(new_id)
|
Ok(widget.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{parse_children, parse_widget_universal, style::parse_style, AttribPair, ParserContext, ParserFile},
|
parser::{AttribPair, ParserContext, ParserFile, parse_children, parse_widget_universal, style::parse_style},
|
||||||
renderer_vk::text::custom_glyph::{CustomGlyphContent, CustomGlyphData},
|
renderer_vk::text::custom_glyph::{CustomGlyphContent, CustomGlyphData},
|
||||||
widget::sprite::{WidgetSprite, WidgetSpriteParams},
|
widget::sprite::{WidgetSprite, WidgetSpriteParams},
|
||||||
};
|
};
|
||||||
@@ -15,7 +15,7 @@ pub fn parse_widget_sprite<'a, U1, U2>(
|
|||||||
attribs: &[AttribPair],
|
attribs: &[AttribPair],
|
||||||
) -> anyhow::Result<WidgetID> {
|
) -> anyhow::Result<WidgetID> {
|
||||||
let mut params = WidgetSpriteParams::default();
|
let mut params = WidgetSpriteParams::default();
|
||||||
let style = parse_style(&attribs);
|
let style = parse_style(attribs);
|
||||||
|
|
||||||
let mut glyph = None;
|
let mut glyph = None;
|
||||||
for pair in attribs {
|
for pair in attribs {
|
||||||
@@ -54,10 +54,10 @@ pub fn parse_widget_sprite<'a, U1, U2>(
|
|||||||
log::warn!("No source for sprite node!");
|
log::warn!("No source for sprite node!");
|
||||||
}
|
}
|
||||||
|
|
||||||
let (new_id, _) = ctx.layout.add_child(parent_id, WidgetSprite::create(params), style)?;
|
let (widget, _) = ctx.layout.add_child(parent_id, WidgetSprite::create(params), style)?;
|
||||||
|
|
||||||
parse_widget_universal(ctx, new_id, attribs);
|
parse_widget_universal(ctx, widget.id, attribs);
|
||||||
parse_children(file, ctx, node, new_id)?;
|
parse_children(file, ctx, node, widget.id)?;
|
||||||
|
|
||||||
Ok(new_id)
|
Ok(widget.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,20 +2,20 @@ use std::{cell::RefCell, rc::Rc, sync::Arc};
|
|||||||
|
|
||||||
use cosmic_text::Buffer;
|
use cosmic_text::Buffer;
|
||||||
use glam::{Mat4, Vec2, Vec3};
|
use glam::{Mat4, Vec2, Vec3};
|
||||||
use slotmap::{new_key_type, SlotMap};
|
use slotmap::{SlotMap, new_key_type};
|
||||||
use vulkano::pipeline::graphics::viewport;
|
use vulkano::pipeline::graphics::viewport;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drawing::{self},
|
drawing::{self},
|
||||||
gfx::{cmd::GfxCommandBuffer, WGfx},
|
gfx::{WGfx, cmd::GfxCommandBuffer},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
rect::{RectPipeline, RectRenderer},
|
rect::{RectPipeline, RectRenderer},
|
||||||
text::{
|
text::{
|
||||||
|
DEFAULT_METRICS, FONT_SYSTEM, SWASH_CACHE, TextArea, TextBounds,
|
||||||
text_atlas::{TextAtlas, TextPipeline},
|
text_atlas::{TextAtlas, TextPipeline},
|
||||||
text_renderer::TextRenderer,
|
text_renderer::TextRenderer,
|
||||||
TextArea, TextBounds, DEFAULT_METRICS, FONT_SYSTEM, SWASH_CACHE,
|
|
||||||
},
|
},
|
||||||
viewport::Viewport,
|
viewport::Viewport,
|
||||||
};
|
};
|
||||||
@@ -287,12 +287,8 @@ impl Context {
|
|||||||
transform: extent.transform,
|
transform: extent.transform,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
drawing::RenderPrimitive::ScissorEnable(boundary) => {
|
drawing::RenderPrimitive::ScissorSet(boundary) => {
|
||||||
next_scissor = Some(*boundary);
|
next_scissor = Some(boundary.0);
|
||||||
needs_new_pass = true;
|
|
||||||
}
|
|
||||||
drawing::RenderPrimitive::ScissorDisable => {
|
|
||||||
next_scissor = None;
|
|
||||||
needs_new_pass = true;
|
needs_new_pass = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use glam::Vec2;
|
use glam::{Mat4, Vec2, Vec3};
|
||||||
|
|
||||||
use crate::drawing;
|
use crate::drawing;
|
||||||
|
|
||||||
@@ -50,18 +50,40 @@ impl<T: StackItem<T>, const STACK_MAX: usize> Default for GenericStack<T, STACK_
|
|||||||
// Transform stack
|
// Transform stack
|
||||||
// ########################################
|
// ########################################
|
||||||
|
|
||||||
#[derive(Default, Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Transform {
|
pub struct Transform {
|
||||||
pub pos: Vec2,
|
pub rel_pos: Vec2,
|
||||||
pub transform: glam::Mat4,
|
|
||||||
pub dim: Vec2, // for convenience
|
pub dim: Vec2, // for convenience
|
||||||
|
pub abs_pos: Vec2, // for convenience, will be set after pushing
|
||||||
|
pub transform: glam::Mat4,
|
||||||
|
pub transform_rel: glam::Mat4,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Transform {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
abs_pos: Default::default(),
|
||||||
|
rel_pos: Default::default(),
|
||||||
|
dim: Default::default(),
|
||||||
|
transform: Mat4::IDENTITY,
|
||||||
|
transform_rel: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> StackItem<T> for Transform where Transform: Pushable<T> {}
|
impl<T> StackItem<T> for Transform where Transform: Pushable<T> {}
|
||||||
|
|
||||||
impl Pushable<Transform> for Transform {
|
impl Pushable<Transform> for Transform {
|
||||||
fn push(&mut self, upper: &Transform) {
|
fn push(&mut self, upper: &Transform) {
|
||||||
self.pos += upper.pos;
|
// fixme: there is definitely a better way to do these operations
|
||||||
|
let translation_matrix = Mat4::from_translation(Vec3::new(self.rel_pos.x, self.rel_pos.y, 0.0));
|
||||||
|
|
||||||
|
self.abs_pos = upper.abs_pos + self.rel_pos;
|
||||||
|
let absolute_shift_matrix = Mat4::from_translation(Vec3::new(self.abs_pos.x, self.abs_pos.y, 0.0));
|
||||||
|
let absolute_shift_matrix_neg = Mat4::from_translation(Vec3::new(-self.abs_pos.x, -self.abs_pos.y, 0.0));
|
||||||
|
|
||||||
|
self.transform =
|
||||||
|
(absolute_shift_matrix * self.transform * absolute_shift_matrix_neg) * upper.transform * translation_matrix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,12 +93,26 @@ pub type TransformStack = GenericStack<Transform, 64>;
|
|||||||
// Scissor stack
|
// Scissor stack
|
||||||
// ########################################
|
// ########################################
|
||||||
|
|
||||||
impl<T> StackItem<T> for drawing::Boundary where drawing::Boundary: Pushable<T> {}
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct ScissorBoundary(pub drawing::Boundary);
|
||||||
|
|
||||||
impl Pushable<drawing::Boundary> for drawing::Boundary {
|
impl Default for ScissorBoundary {
|
||||||
fn push(&mut self, upper: &drawing::Boundary) {
|
fn default() -> Self {
|
||||||
let mut display_pos = self.pos;
|
Self(drawing::Boundary {
|
||||||
let mut display_size = self.size;
|
pos: Default::default(),
|
||||||
|
size: Vec2::splat(1.0e12),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> StackItem<T> for ScissorBoundary where ScissorBoundary: Pushable<T> {}
|
||||||
|
|
||||||
|
impl Pushable<ScissorBoundary> for ScissorBoundary {
|
||||||
|
fn push(&mut self, upper: &ScissorBoundary) {
|
||||||
|
let mut display_pos = self.0.pos;
|
||||||
|
let mut display_size = self.0.size;
|
||||||
|
|
||||||
|
let upper = &upper.0;
|
||||||
|
|
||||||
// limit in x-coord
|
// limit in x-coord
|
||||||
if display_pos.x < upper.left() {
|
if display_pos.x < upper.left() {
|
||||||
@@ -100,9 +136,9 @@ impl Pushable<drawing::Boundary> for drawing::Boundary {
|
|||||||
display_size.y = upper.bottom() - display_pos.y;
|
display_size.y = upper.bottom() - display_pos.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pos = display_pos;
|
self.0.pos = display_pos;
|
||||||
self.size = display_size;
|
self.0.size = display_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ScissorStack = GenericStack<drawing::Boundary, 64>;
|
pub type ScissorStack = GenericStack<ScissorBoundary, 64>;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
globals::Globals,
|
globals::Globals,
|
||||||
i18n::{I18n, Translation},
|
i18n::{I18n, Translation},
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
renderer_vk::text::{TextStyle, FONT_SYSTEM},
|
renderer_vk::text::{FONT_SYSTEM, TextStyle},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{WidgetObj, WidgetState};
|
use super::{WidgetObj, WidgetState};
|
||||||
@@ -109,7 +109,7 @@ impl WidgetLabel {
|
|||||||
|
|
||||||
impl WidgetObj for WidgetLabel {
|
impl WidgetObj for WidgetLabel {
|
||||||
fn draw(&mut self, state: &mut super::DrawState, _params: &super::DrawParams) {
|
fn draw(&mut self, state: &mut super::DrawState, _params: &super::DrawParams) {
|
||||||
let boundary = drawing::Boundary::construct(state.transform_stack);
|
let boundary = drawing::Boundary::construct_relative(state.transform_stack);
|
||||||
|
|
||||||
if self.last_boundary != boundary {
|
if self.last_boundary != boundary {
|
||||||
self.last_boundary = boundary;
|
self.last_boundary = boundary;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
layout::{Layout, LayoutState, WidgetID},
|
layout::{Layout, LayoutState, WidgetID},
|
||||||
stack::{ScissorStack, TransformStack},
|
stack::{ScissorStack, TransformStack},
|
||||||
|
widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod div;
|
pub mod div;
|
||||||
@@ -248,8 +249,8 @@ impl WidgetState {
|
|||||||
PrimitiveExtent {
|
PrimitiveExtent {
|
||||||
boundary: drawing::Boundary::from_pos_size(
|
boundary: drawing::Boundary::from_pos_size(
|
||||||
Vec2::new(
|
Vec2::new(
|
||||||
transform.pos.x + transform.dim.x * (1.0 - info.handle_size.x) * self.data.scrolling.x,
|
transform.abs_pos.x + transform.dim.x * (1.0 - info.handle_size.x) * self.data.scrolling.x,
|
||||||
transform.pos.y + transform.dim.y - thickness - margin,
|
transform.abs_pos.y + transform.dim.y - thickness - margin,
|
||||||
),
|
),
|
||||||
Vec2::new(transform.dim.x * info.handle_size.x, thickness),
|
Vec2::new(transform.dim.x * info.handle_size.x, thickness),
|
||||||
),
|
),
|
||||||
@@ -265,8 +266,8 @@ impl WidgetState {
|
|||||||
PrimitiveExtent {
|
PrimitiveExtent {
|
||||||
boundary: drawing::Boundary::from_pos_size(
|
boundary: drawing::Boundary::from_pos_size(
|
||||||
Vec2::new(
|
Vec2::new(
|
||||||
transform.pos.x + transform.dim.x - thickness - margin,
|
transform.abs_pos.x + transform.dim.x - thickness - margin,
|
||||||
transform.pos.y + transform.dim.y * (1.0 - info.handle_size.y) * self.data.scrolling.y,
|
transform.abs_pos.y + transform.dim.y * (1.0 - info.handle_size.y) * self.data.scrolling.y,
|
||||||
),
|
),
|
||||||
Vec2::new(thickness, transform.dim.y * info.handle_size.y),
|
Vec2::new(thickness, transform.dim.y * info.handle_size.y),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ impl WidgetRectangle {
|
|||||||
|
|
||||||
impl WidgetObj for WidgetRectangle {
|
impl WidgetObj for WidgetRectangle {
|
||||||
fn draw(&mut self, state: &mut super::DrawState, _params: &super::DrawParams) {
|
fn draw(&mut self, state: &mut super::DrawState, _params: &super::DrawParams) {
|
||||||
let boundary = drawing::Boundary::construct(state.transform_stack);
|
let boundary = drawing::Boundary::construct_relative(state.transform_stack);
|
||||||
|
|
||||||
let round_units = match self.params.round {
|
let round_units = match self.params.round {
|
||||||
WLength::Units(units) => units as u8,
|
WLength::Units(units) => units as u8,
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ use crate::{
|
|||||||
drawing::{self, PrimitiveExtent},
|
drawing::{self, PrimitiveExtent},
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
renderer_vk::text::{
|
renderer_vk::text::{
|
||||||
custom_glyph::{CustomGlyph, CustomGlyphData},
|
|
||||||
DEFAULT_METRICS, FONT_SYSTEM,
|
DEFAULT_METRICS, FONT_SYSTEM,
|
||||||
|
custom_glyph::{CustomGlyph, CustomGlyphData},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ impl WidgetSprite {
|
|||||||
|
|
||||||
impl WidgetObj for WidgetSprite {
|
impl WidgetObj for WidgetSprite {
|
||||||
fn draw(&mut self, state: &mut super::DrawState, _params: &super::DrawParams) {
|
fn draw(&mut self, state: &mut super::DrawState, _params: &super::DrawParams) {
|
||||||
let boundary = drawing::Boundary::construct(state.transform_stack);
|
let boundary = drawing::Boundary::construct_relative(state.transform_stack);
|
||||||
|
|
||||||
if let Some(glyph_data) = self.params.glyph_data.as_ref() {
|
if let Some(glyph_data) = self.params.glyph_data.as_ref() {
|
||||||
let glyph = CustomGlyph {
|
let glyph = CustomGlyph {
|
||||||
|
|||||||
Reference in New Issue
Block a user