Merge pull request #382 from wlx-team/feat-dash-tabbed-settings
dash-frontend: Tabbed settings, minor fixes
This commit is contained in:
@@ -66,11 +66,12 @@ impl Default for Params<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ButtonClickEvent {
|
||||
pub mouse_pos_absolute: Option<Vec2>,
|
||||
pub boundary: Boundary,
|
||||
}
|
||||
pub type ButtonClickCallback = Box<dyn Fn(&mut CallbackDataCommon, ButtonClickEvent) -> anyhow::Result<()>>;
|
||||
pub type ButtonClickCallback = Rc<dyn Fn(&mut CallbackDataCommon, ButtonClickEvent) -> anyhow::Result<()>>;
|
||||
|
||||
pub struct Colors {
|
||||
pub color: drawing::Color,
|
||||
@@ -111,7 +112,6 @@ impl ComponentTrait for ComponentButton {
|
||||
}
|
||||
|
||||
fn refresh(&self, data: &mut RefreshData) {
|
||||
// nothing to do
|
||||
let mut state = self.state.borrow_mut();
|
||||
|
||||
if state.active_tooltip.is_some() {
|
||||
@@ -362,7 +362,6 @@ fn register_event_mouse_release(
|
||||
Box::new(move |common, event_data, (), ()| {
|
||||
let rect = event_data.obj.get_as_mut::<WidgetRectangle>().unwrap();
|
||||
let mut state = state.borrow_mut();
|
||||
|
||||
if data.sticky {
|
||||
state.sticky_down = !state.sticky_down;
|
||||
}
|
||||
@@ -384,17 +383,18 @@ fn register_event_mouse_release(
|
||||
state.sticky_down,
|
||||
);
|
||||
|
||||
if let Some(on_click) = &state.on_click {
|
||||
on_click(
|
||||
common,
|
||||
ButtonClickEvent {
|
||||
mouse_pos_absolute: event_data.metadata.get_mouse_pos_absolute(),
|
||||
boundary: event_data.widget_data.cached_absolute_boundary,
|
||||
},
|
||||
)?;
|
||||
if let Some(on_click) = state.on_click.clone() {
|
||||
let evt = ButtonClickEvent {
|
||||
mouse_pos_absolute: event_data.metadata.get_mouse_pos_absolute(),
|
||||
boundary: event_data.widget_data.cached_absolute_boundary,
|
||||
};
|
||||
|
||||
common.alterables.dispatch(Box::new(move |common| {
|
||||
(*on_click)(common, evt)?;
|
||||
Ok(())
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(EventResult::Consumed)
|
||||
} else {
|
||||
Ok(EventResult::Pass)
|
||||
@@ -403,14 +403,15 @@ fn register_event_mouse_release(
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Result<(WidgetPair, Rc<ComponentButton>)> {
|
||||
let globals = ess.layout.state.globals.clone();
|
||||
let mut style = params.style;
|
||||
|
||||
// force-override style
|
||||
style.align_items = Some(AlignItems::Center);
|
||||
style.justify_content = Some(JustifyContent::Center);
|
||||
if style.justify_content.is_none() {
|
||||
style.justify_content = Some(JustifyContent::Center);
|
||||
}
|
||||
style.overflow.x = taffy::Overflow::Hidden;
|
||||
style.overflow.y = taffy::Overflow::Hidden;
|
||||
|
||||
|
||||
@@ -284,7 +284,6 @@ fn register_event_mouse_release(
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Result<(WidgetPair, Rc<ComponentCheckbox>)> {
|
||||
let mut style = params.style;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ pub mod button;
|
||||
pub mod checkbox;
|
||||
pub mod radio_group;
|
||||
pub mod slider;
|
||||
pub mod tabs;
|
||||
pub mod tooltip;
|
||||
|
||||
pub struct RefreshData<'a> {
|
||||
|
||||
@@ -84,7 +84,6 @@ struct Data {
|
||||
slider_handle_rect_id: WidgetID, // Rectangle
|
||||
slider_text_id: Option<WidgetID>, // Text
|
||||
slider_handle_id: WidgetID,
|
||||
slider_handle_node_id: taffy::NodeId,
|
||||
}
|
||||
|
||||
pub struct SliderValueChangedEvent {
|
||||
@@ -212,7 +211,14 @@ impl State {
|
||||
self.values.set_value(value);
|
||||
|
||||
let changed = self.values.value != before;
|
||||
let style = common.state.tree.style(data.slider_handle_node_id).unwrap();
|
||||
|
||||
let Some(slider_handle_node_id) = common.state.nodes.get(data.slider_handle_id) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(style) = common.state.tree.style(*slider_handle_node_id) else {
|
||||
return;
|
||||
};
|
||||
if !conf_handle_style(
|
||||
common.alterables,
|
||||
&self.values,
|
||||
@@ -398,7 +404,6 @@ fn register_event_mouse_release(
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Result<(WidgetPair, Rc<ComponentSlider>)> {
|
||||
let mut style = params.style;
|
||||
style.position = taffy::Position::Relative;
|
||||
@@ -441,10 +446,9 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
||||
};
|
||||
|
||||
// invisible outer handle body
|
||||
let (slider_handle, slider_handle_node_id) =
|
||||
ess
|
||||
.layout
|
||||
.add_child(body_id, WidgetDiv::create(), slider_handle_style)?;
|
||||
let (slider_handle, _) = ess
|
||||
.layout
|
||||
.add_child(body_id, WidgetDiv::create(), slider_handle_style)?;
|
||||
|
||||
let (slider_handle_rect, _) = ess.layout.add_child(
|
||||
slider_handle.id,
|
||||
@@ -500,7 +504,6 @@ pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Resul
|
||||
slider_handle_rect_id: slider_handle_rect.id,
|
||||
body_node: slider_body_node,
|
||||
slider_handle_id: slider_handle.id,
|
||||
slider_handle_node_id,
|
||||
slider_text_id: slider_text.map(|s| s.0.id),
|
||||
});
|
||||
|
||||
|
||||
176
wgui/src/components/tabs.rs
Normal file
176
wgui/src/components/tabs.rs
Normal file
@@ -0,0 +1,176 @@
|
||||
use crate::{
|
||||
assets::AssetPath,
|
||||
components::{
|
||||
Component, ComponentBase, ComponentTrait, RefreshData,
|
||||
button::{self, ComponentButton},
|
||||
},
|
||||
event::CallbackDataCommon,
|
||||
i18n::Translation,
|
||||
layout::WidgetPair,
|
||||
widget::{ConstructEssentials, div::WidgetDiv},
|
||||
};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
rc::{Rc, Weak},
|
||||
sync::Arc,
|
||||
};
|
||||
use taffy::{
|
||||
AlignItems,
|
||||
prelude::{auto, length, percent},
|
||||
};
|
||||
|
||||
pub struct Entry<'a> {
|
||||
pub sprite_src: Option<AssetPath<'a>>,
|
||||
pub text: Translation,
|
||||
pub name: &'a str,
|
||||
}
|
||||
|
||||
pub struct Params<'a> {
|
||||
pub style: taffy::Style,
|
||||
pub entries: Vec<Entry<'a>>,
|
||||
pub selected_entry_name: &'a str, // default: ""
|
||||
pub on_select: Option<TabSelectCallback>,
|
||||
}
|
||||
|
||||
struct MountedEntry {
|
||||
name: Rc<str>,
|
||||
button: Rc<ComponentButton>,
|
||||
}
|
||||
|
||||
pub struct TabSelectEvent {
|
||||
pub name: Rc<str>,
|
||||
}
|
||||
|
||||
pub type TabSelectCallback = Rc<dyn Fn(&mut CallbackDataCommon, TabSelectEvent) -> anyhow::Result<()>>;
|
||||
|
||||
struct State {
|
||||
mounted_entries: Vec<MountedEntry>,
|
||||
selected_entry_name: Rc<str>,
|
||||
on_select: Option<TabSelectCallback>,
|
||||
}
|
||||
|
||||
struct Data {}
|
||||
|
||||
pub struct ComponentTabs {
|
||||
base: ComponentBase,
|
||||
data: Rc<Data>,
|
||||
state: Rc<RefCell<State>>,
|
||||
}
|
||||
|
||||
impl ComponentTrait for ComponentTabs {
|
||||
fn base(&self) -> &ComponentBase {
|
||||
&self.base
|
||||
}
|
||||
|
||||
fn base_mut(&mut self) -> &mut ComponentBase {
|
||||
&mut self.base
|
||||
}
|
||||
|
||||
fn refresh(&self, _data: &mut RefreshData) {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn select_entry(&mut self, common: &mut CallbackDataCommon, name: &Rc<str>) {
|
||||
let (color_accent, color_button) = {
|
||||
let def = common.state.globals.defaults();
|
||||
(def.accent_color, def.button_color)
|
||||
};
|
||||
|
||||
for entry in &self.mounted_entries {
|
||||
if *entry.name == **name {
|
||||
entry.button.set_color(common, color_accent);
|
||||
} else {
|
||||
entry.button.set_color(common, color_button);
|
||||
}
|
||||
}
|
||||
self.selected_entry_name = name.clone();
|
||||
|
||||
if let Some(on_select) = self.on_select.clone() {
|
||||
let evt = TabSelectEvent { name: name.clone() };
|
||||
common.alterables.dispatch(Box::new(move |common| {
|
||||
(*on_select)(common, evt)?;
|
||||
Ok(())
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentTabs {
|
||||
pub fn on_select(&self, callback: TabSelectCallback) {
|
||||
self.state.borrow_mut().on_select = Some(callback);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Result<(WidgetPair, Rc<ComponentTabs>)> {
|
||||
let mut style = params.style;
|
||||
|
||||
// force-override style
|
||||
style.overflow.y = taffy::Overflow::Scroll;
|
||||
style.flex_direction = taffy::FlexDirection::Column;
|
||||
style.flex_wrap = taffy::FlexWrap::NoWrap;
|
||||
style.align_items = Some(AlignItems::Center);
|
||||
style.gap = length(4.0);
|
||||
|
||||
let (root, _) = ess.layout.add_child(ess.parent, WidgetDiv::create(), style)?;
|
||||
|
||||
let mut mounted_entries = Vec::<MountedEntry>::new();
|
||||
|
||||
// Mount entries
|
||||
for entry in params.entries {
|
||||
let (_, button) = button::construct(
|
||||
&mut ConstructEssentials {
|
||||
layout: ess.layout,
|
||||
parent: root.id,
|
||||
},
|
||||
button::Params {
|
||||
text: Some(entry.text),
|
||||
sprite_src: entry.sprite_src,
|
||||
style: taffy::Style {
|
||||
min_size: taffy::Size {
|
||||
width: percent(1.0),
|
||||
height: length(32.0),
|
||||
},
|
||||
justify_content: Some(taffy::JustifyContent::Start),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
|
||||
mounted_entries.push(MountedEntry {
|
||||
name: Rc::from(entry.name),
|
||||
button,
|
||||
});
|
||||
}
|
||||
|
||||
let data = Rc::new(Data {});
|
||||
let state = Rc::new(RefCell::new(State {
|
||||
selected_entry_name: Rc::from(params.selected_entry_name),
|
||||
mounted_entries,
|
||||
on_select: params.on_select,
|
||||
}));
|
||||
|
||||
// handle button clicks
|
||||
for entry in &state.borrow().mounted_entries {
|
||||
entry.button.on_click({
|
||||
let entry_name = entry.name.clone();
|
||||
let state = state.clone();
|
||||
Rc::new(move |common, _| {
|
||||
state.borrow_mut().select_entry(common, &entry_name);
|
||||
Ok(())
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
let base = ComponentBase {
|
||||
id: root.id,
|
||||
lhandles: Default::default(),
|
||||
};
|
||||
|
||||
let tabs = Rc::new(ComponentTabs { base, data, state });
|
||||
|
||||
ess.layout.defer_component_refresh(Component(tabs.clone()));
|
||||
Ok((root, tabs))
|
||||
}
|
||||
@@ -89,7 +89,6 @@ impl Drop for ComponentTooltip {
|
||||
pub const TOOLTIP_COLOR: Color = Color::new(0.02, 0.02, 0.02, 0.95);
|
||||
pub const TOOLTIP_BORDER_COLOR: Color = Color::new(0.4, 0.4, 0.4, 1.0);
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn construct(ess: &mut ConstructEssentials, params: Params) -> anyhow::Result<(WidgetPair, Rc<ComponentTooltip>)> {
|
||||
let absolute_boundary = {
|
||||
let widget_to_watch = ess
|
||||
|
||||
@@ -9,6 +9,7 @@ use slotmap::{DenseSlotMap, new_key_type};
|
||||
|
||||
use crate::{
|
||||
animation::{self, Animation},
|
||||
components::Component,
|
||||
i18n::I18n,
|
||||
layout::{LayoutState, LayoutTask, WidgetID},
|
||||
sound::WguiSoundType,
|
||||
@@ -145,6 +146,10 @@ impl EventAlterables {
|
||||
pub fn play_sound(&mut self, sound_type: WguiSoundType) {
|
||||
self.tasks.push(LayoutTask::PlaySound(sound_type));
|
||||
}
|
||||
|
||||
pub fn dispatch(&mut self, func: Box<dyn FnOnce(&mut CallbackDataCommon) -> anyhow::Result<()>>) {
|
||||
self.tasks.push(LayoutTask::Dispatch(func))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CallbackDataCommon<'a> {
|
||||
|
||||
@@ -136,6 +136,7 @@ pub enum LayoutTask {
|
||||
RemoveWidget(WidgetID),
|
||||
ModifyLayoutState(ModifyLayoutStateFunc),
|
||||
PlaySound(WguiSoundType),
|
||||
Dispatch(Box<dyn FnOnce(&mut CallbackDataCommon) -> anyhow::Result<()>>),
|
||||
}
|
||||
|
||||
pub type LayoutTasks = Tasks<LayoutTask>;
|
||||
@@ -696,6 +697,11 @@ impl Layout {
|
||||
self.sounds_to_play_once.push(sound);
|
||||
}
|
||||
}
|
||||
LayoutTask::Dispatch(func) => {
|
||||
let mut c = self.start_common();
|
||||
func(&mut c.common())?;
|
||||
c.finish()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
clippy::float_cmp,
|
||||
clippy::needless_pass_by_ref_mut,
|
||||
clippy::use_self,
|
||||
clippy::match_same_arms
|
||||
clippy::match_same_arms,
|
||||
clippy::too_many_lines
|
||||
)]
|
||||
|
||||
pub mod animation;
|
||||
|
||||
@@ -5,13 +5,12 @@ use crate::{
|
||||
i18n::Translation,
|
||||
layout::WidgetID,
|
||||
parser::{
|
||||
AttribPair, ParserContext, ParserFile, parse_children, parse_f32, process_component,
|
||||
AttribPair, ParserContext, ParserFile, get_asset_path_from_kv, parse_children, parse_f32, process_component,
|
||||
style::{parse_color_opt, parse_round, parse_style, parse_text_style},
|
||||
},
|
||||
widget::util::WLength,
|
||||
};
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn parse_component_button<'a>(
|
||||
file: &'a ParserFile,
|
||||
ctx: &mut ParserContext,
|
||||
@@ -76,13 +75,7 @@ pub fn parse_component_button<'a>(
|
||||
parse_color_opt(ctx, tag_name, key, value, &mut hover_border_color);
|
||||
}
|
||||
"sprite_src" | "sprite_src_ext" | "sprite_src_builtin" | "sprite_src_internal" => {
|
||||
let asset_path = match key {
|
||||
"sprite_src" => AssetPath::FileOrBuiltIn(value),
|
||||
"sprite_src_ext" => AssetPath::File(value),
|
||||
"sprite_src_builtin" => AssetPath::BuiltIn(value),
|
||||
"sprite_src_internal" => AssetPath::WguiInternal(value),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let asset_path = get_asset_path_from_kv("sprite_", key, value);
|
||||
|
||||
if !value.is_empty() {
|
||||
sprite_src = Some(asset_path);
|
||||
|
||||
71
wgui/src/parser/component_tabs.rs
Normal file
71
wgui/src/parser/component_tabs.rs
Normal file
@@ -0,0 +1,71 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::{
|
||||
assets::AssetPath,
|
||||
components::{Component, tabs},
|
||||
i18n::Translation,
|
||||
layout::WidgetID,
|
||||
parser::{AttribPair, ParserContext, ParserFile, get_asset_path_from_kv, process_component, style::parse_style},
|
||||
};
|
||||
|
||||
pub fn parse_component_tabs<'a>(
|
||||
file: &'a ParserFile,
|
||||
ctx: &mut ParserContext,
|
||||
node: roxmltree::Node<'a, 'a>,
|
||||
parent_id: WidgetID,
|
||||
attribs: &[AttribPair],
|
||||
tag_name: &str,
|
||||
) -> anyhow::Result<WidgetID> {
|
||||
let style = parse_style(ctx, attribs, tag_name);
|
||||
|
||||
let mut entries = Vec::<tabs::Entry>::new();
|
||||
|
||||
for child in node.children() {
|
||||
match child.tag_name().name() {
|
||||
"" => { /* ignore */ }
|
||||
"Tab" => {
|
||||
let mut name: Option<&str> = None;
|
||||
let mut text: Option<Translation> = None;
|
||||
let mut sprite_src: Option<AssetPath> = None;
|
||||
|
||||
for attrib in child.attributes() {
|
||||
let (key, value) = (attrib.name(), attrib.value());
|
||||
match key {
|
||||
"name" => name = Some(value),
|
||||
"text" => text = Some(Translation::from_raw_text(value)),
|
||||
"translation" => text = Some(Translation::from_translation_key(value)),
|
||||
"sprite_src" | "sprite_src_ext" | "sprite_src_builtin" | "sprite_src_internal" => {
|
||||
sprite_src = Some(get_asset_path_from_kv("sprite_", key, value));
|
||||
}
|
||||
other_key => {
|
||||
ctx.print_invalid_attrib("Tab", other_key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(name) = name
|
||||
&& let Some(text) = text
|
||||
{
|
||||
entries.push(tabs::Entry { sprite_src, text, name });
|
||||
}
|
||||
}
|
||||
other_tag_name => {
|
||||
ctx.print_invalid_tag(tag_name, other_tag_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (widget, component) = tabs::construct(
|
||||
&mut ctx.get_construct_essentials(parent_id),
|
||||
tabs::Params {
|
||||
style,
|
||||
selected_entry_name: "first",
|
||||
entries,
|
||||
on_select: None,
|
||||
},
|
||||
)?;
|
||||
|
||||
process_component(ctx, Component(component), widget.id, attribs);
|
||||
|
||||
Ok(widget.id)
|
||||
}
|
||||
@@ -2,6 +2,7 @@ mod component_button;
|
||||
mod component_checkbox;
|
||||
mod component_radio_group;
|
||||
mod component_slider;
|
||||
mod component_tabs;
|
||||
mod style;
|
||||
mod widget_div;
|
||||
mod widget_image;
|
||||
@@ -22,6 +23,7 @@ use crate::{
|
||||
component_checkbox::{CheckboxKind, parse_component_checkbox},
|
||||
component_radio_group::parse_component_radio_group,
|
||||
component_slider::parse_component_slider,
|
||||
component_tabs::parse_component_tabs,
|
||||
widget_div::parse_widget_div,
|
||||
widget_image::parse_widget_image,
|
||||
widget_label::parse_widget_label,
|
||||
@@ -480,6 +482,7 @@ impl ParserContext<'_> {
|
||||
insert_color_vars!(self, "faded", def.faded_color, def.translucent_alpha);
|
||||
insert_color_vars!(self, "bg", def.bg_color, def.translucent_alpha);
|
||||
}
|
||||
|
||||
fn print_invalid_attrib(&self, tag_name: &str, key: &str, value: &str) {
|
||||
log::warn!(
|
||||
"{}: <{tag_name}> value for \"{key}\" is invalid: \"{value}\"",
|
||||
@@ -487,6 +490,13 @@ impl ParserContext<'_> {
|
||||
);
|
||||
}
|
||||
|
||||
fn print_invalid_tag(&self, tag_name: &str, invalid_tag_name: &str) {
|
||||
log::warn!(
|
||||
"{}: <{tag_name}> has an invalid tag named <{invalid_tag_name}>",
|
||||
self.doc_params.path.get_str()
|
||||
);
|
||||
}
|
||||
|
||||
fn print_missing_attrib(&self, tag_name: &str, attr: &str) {
|
||||
log::warn!(
|
||||
"{}: <{tag_name}> is missing \"{attr}\".",
|
||||
@@ -1042,6 +1052,11 @@ fn parse_child<'a>(
|
||||
file, ctx, child_node, parent_id, &attribs, tag_name,
|
||||
)?);
|
||||
}
|
||||
"Tabs" => {
|
||||
new_widget_id = Some(parse_component_tabs(
|
||||
file, ctx, child_node, parent_id, &attribs, tag_name,
|
||||
)?);
|
||||
}
|
||||
"" => { /* ignore */ }
|
||||
other_tag_name => {
|
||||
parse_widget_other(other_tag_name, file, ctx, parent_id, &attribs)?;
|
||||
@@ -1283,3 +1298,22 @@ fn parse_document_root(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_asset_path_from_kv<'a>(prefix: &'static str, key: &'a str, value: &'a str) -> AssetPath<'a> {
|
||||
let key_split = match key.find(prefix) {
|
||||
Some(pos) => {
|
||||
assert!(pos == 0, "invalid split");
|
||||
key.get(prefix.len()..).unwrap()
|
||||
}
|
||||
None => key,
|
||||
};
|
||||
match key_split {
|
||||
"src" => AssetPath::FileOrBuiltIn(value),
|
||||
"src_ext" => AssetPath::File(value),
|
||||
"src_builtin" => AssetPath::BuiltIn(value),
|
||||
"src_internal" => AssetPath::WguiInternal(value),
|
||||
other => {
|
||||
panic!("unexpected attrib {other}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,6 @@ pub fn parse_text_style(ctx: &ParserContext<'_>, attribs: &[AttribPair], tag_nam
|
||||
style
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
pub fn parse_style(ctx: &ParserContext<'_>, attribs: &[AttribPair], tag_name: &str) -> taffy::Style {
|
||||
let mut style = taffy::Style::default();
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
assets::AssetPath,
|
||||
layout::WidgetID,
|
||||
parser::{
|
||||
AttribPair, ParserContext, ParserFile, parse_children, parse_widget_universal,
|
||||
AttribPair, ParserContext, ParserFile, get_asset_path_from_kv, parse_children, parse_widget_universal,
|
||||
style::{parse_color, parse_round, parse_style},
|
||||
},
|
||||
renderer_vk::text::custom_glyph::CustomGlyphData,
|
||||
@@ -25,16 +25,9 @@ pub fn parse_widget_image<'a>(
|
||||
let (key, value) = (pair.attrib.as_ref(), pair.value.as_ref());
|
||||
match key {
|
||||
"src" | "src_ext" | "src_builtin" | "src_internal" => {
|
||||
let asset_path = match key {
|
||||
"src" => AssetPath::FileOrBuiltIn(value),
|
||||
"src_ext" => AssetPath::File(value),
|
||||
"src_builtin" => AssetPath::BuiltIn(value),
|
||||
"src_internal" => AssetPath::WguiInternal(value),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if !value.is_empty() {
|
||||
glyph = match CustomGlyphData::from_assets(&mut ctx.layout.state.globals, asset_path) {
|
||||
glyph = match CustomGlyphData::from_assets(&ctx.layout.state.globals, get_asset_path_from_kv("", key, value))
|
||||
{
|
||||
Ok(glyph) => Some(glyph),
|
||||
Err(e) => {
|
||||
log::warn!("failed to load {value}: {e}");
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
use crate::{
|
||||
assets::AssetPath,
|
||||
layout::WidgetID,
|
||||
parser::{AttribPair, ParserContext, ParserFile, parse_children, parse_widget_universal, style::parse_style},
|
||||
parser::{
|
||||
AttribPair, ParserContext, ParserFile, get_asset_path_from_kv, parse_children, parse_widget_universal,
|
||||
style::parse_style,
|
||||
},
|
||||
renderer_vk::text::custom_glyph::CustomGlyphData,
|
||||
widget::sprite::{WidgetSprite, WidgetSpriteParams},
|
||||
};
|
||||
@@ -24,13 +27,7 @@ pub fn parse_widget_sprite<'a>(
|
||||
let (key, value) = (pair.attrib.as_ref(), pair.value.as_ref());
|
||||
match key {
|
||||
"src" | "src_ext" | "src_builtin" | "src_internal" => {
|
||||
let asset_path = match key {
|
||||
"src" => AssetPath::FileOrBuiltIn(value),
|
||||
"src_ext" => AssetPath::File(value),
|
||||
"src_builtin" => AssetPath::BuiltIn(value),
|
||||
"src_internal" => AssetPath::WguiInternal(value),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let asset_path = get_asset_path_from_kv("", key, value);
|
||||
|
||||
if !value.is_empty() {
|
||||
glyph = match CustomGlyphData::from_assets(&ctx.layout.state.globals, asset_path) {
|
||||
|
||||
@@ -54,7 +54,6 @@ impl TextRenderer {
|
||||
}
|
||||
|
||||
/// Prepares all of the provided text areas for rendering.
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn prepare<'a>(
|
||||
&mut self,
|
||||
font_system: &mut FontSystem,
|
||||
@@ -324,7 +323,6 @@ struct PrepareGlyphParams<'a> {
|
||||
bounds_max_y: i32,
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn prepare_glyph(
|
||||
par: &mut PrepareGlyphParams,
|
||||
get_glyph_image: impl FnOnce(&mut SwashCache, &mut FontSystem) -> Option<GetGlyphImageResult>,
|
||||
|
||||
@@ -34,7 +34,7 @@ impl<TaskType: Clone + 'static> Tasks<TaskType> {
|
||||
pub fn handle_button(&self, button: &Rc<ComponentButton>, task: TaskType) {
|
||||
button.on_click({
|
||||
let this = self.clone();
|
||||
Box::new(move |_, _| {
|
||||
Rc::new(move |_, _| {
|
||||
this.push(task.clone());
|
||||
Ok(())
|
||||
})
|
||||
|
||||
@@ -100,7 +100,6 @@ impl WguiWindow {
|
||||
self.0.borrow_mut().opened_window = None;
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn open(&mut self, params: &mut WguiWindowParams) -> anyhow::Result<()> {
|
||||
// close previous one if it's already open
|
||||
self.close();
|
||||
@@ -233,7 +232,7 @@ impl WguiWindow {
|
||||
let but_close = state.fetch_component_as::<ComponentButton>("but_close").unwrap();
|
||||
but_close.on_click({
|
||||
let this = self.clone();
|
||||
Box::new(move |_common, _e| {
|
||||
Rc::new(move |_common, _e| {
|
||||
this.close();
|
||||
Ok(())
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user