wgui: prevent data copy, parser data
This commit is contained in:
@@ -9,7 +9,7 @@ mod widget_sprite;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assets::AssetProvider,
|
assets::AssetProvider,
|
||||||
components::{Component, ComponentTrait, ComponentWeak},
|
components::{Component, ComponentWeak},
|
||||||
drawing::{self},
|
drawing::{self},
|
||||||
event::EventListenerCollection,
|
event::EventListenerCollection,
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
@@ -49,25 +49,55 @@ struct ParserFile {
|
|||||||
template_parameters: HashMap<Rc<str>, Rc<str>>,
|
template_parameters: HashMap<Rc<str>, Rc<str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub struct ParserData {
|
||||||
|
pub components_by_id: HashMap<Rc<str>, ComponentWeak>,
|
||||||
|
pub components_by_widget_id: HashMap<WidgetID, ComponentWeak>,
|
||||||
|
pub components: Vec<Component>,
|
||||||
|
pub ids: HashMap<Rc<str>, WidgetID>,
|
||||||
|
pub templates: HashMap<Rc<str>, Rc<Template>>,
|
||||||
|
pub var_map: HashMap<Rc<str>, Rc<str>>,
|
||||||
|
macro_attribs: HashMap<Rc<str>, MacroAttribs>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParserData {
|
||||||
|
fn take_results_from(&mut self, from: &mut Self) {
|
||||||
|
let ids = std::mem::take(&mut from.ids);
|
||||||
|
let components = std::mem::take(&mut from.components);
|
||||||
|
let components_by_id = std::mem::take(&mut from.components_by_id);
|
||||||
|
let components_by_widget_id = std::mem::take(&mut from.components_by_widget_id);
|
||||||
|
|
||||||
|
for (id, key) in ids {
|
||||||
|
self.ids.insert(id, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
for c in components {
|
||||||
|
self.components.push(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k, v) in components_by_id {
|
||||||
|
self.components_by_id.insert(k, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k, v) in components_by_widget_id {
|
||||||
|
self.components_by_widget_id.insert(k, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
WARNING: this struct could contain valid components with already bound listener handles.
|
WARNING: this struct could contain valid components with already bound listener handles.
|
||||||
Make sure to store them somewhere in your code.
|
Make sure to store them somewhere in your code.
|
||||||
*/
|
*/
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ParserState {
|
pub struct ParserState {
|
||||||
pub ids: HashMap<Rc<str>, WidgetID>,
|
pub data: ParserData,
|
||||||
macro_attribs: HashMap<Rc<str>, MacroAttribs>,
|
|
||||||
pub var_map: HashMap<Rc<str>, Rc<str>>,
|
|
||||||
pub components: Vec<Component>,
|
|
||||||
pub components_by_id: HashMap<Rc<str>, std::rc::Weak<dyn ComponentTrait>>,
|
|
||||||
pub components_by_widget_id: HashMap<WidgetID, std::rc::Weak<dyn ComponentTrait>>,
|
|
||||||
pub templates: HashMap<Rc<str>, Rc<Template>>,
|
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParserState {
|
impl ParserState {
|
||||||
pub fn fetch_component_by_id(&self, id: &str) -> anyhow::Result<Component> {
|
pub fn fetch_component_by_id(&self, id: &str) -> anyhow::Result<Component> {
|
||||||
let Some(weak) = self.components_by_id.get(id) else {
|
let Some(weak) = self.data.components_by_id.get(id) else {
|
||||||
anyhow::bail!("Component by ID \"{id}\" doesn't exist");
|
anyhow::bail!("Component by ID \"{id}\" doesn't exist");
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,7 +109,7 @@ impl ParserState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_component_by_widget_id(&self, widget_id: WidgetID) -> anyhow::Result<Component> {
|
pub fn fetch_component_by_widget_id(&self, widget_id: WidgetID) -> anyhow::Result<Component> {
|
||||||
let Some(weak) = self.components_by_widget_id.get(&widget_id) else {
|
let Some(weak) = self.data.components_by_widget_id.get(&widget_id) else {
|
||||||
anyhow::bail!("Component by widget ID \"{widget_id:?}\" doesn't exist");
|
anyhow::bail!("Component by widget ID \"{widget_id:?}\" doesn't exist");
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -113,7 +143,7 @@ impl ParserState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_widget_id(&self, id: &str) -> anyhow::Result<WidgetID> {
|
pub fn get_widget_id(&self, id: &str) -> anyhow::Result<WidgetID> {
|
||||||
match self.ids.get(id) {
|
match self.data.ids.get(id) {
|
||||||
Some(id) => Ok(*id),
|
Some(id) => Ok(*id),
|
||||||
None => anyhow::bail!("Widget by ID \"{id}\" doesn't exist"),
|
None => anyhow::bail!("Widget by ID \"{id}\" doesn't exist"),
|
||||||
}
|
}
|
||||||
@@ -155,20 +185,15 @@ impl ParserState {
|
|||||||
widget_id: WidgetID,
|
widget_id: WidgetID,
|
||||||
template_parameters: HashMap<Rc<str>, Rc<str>>,
|
template_parameters: HashMap<Rc<str>, Rc<str>>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let Some(template) = self.templates.get(template_name) else {
|
let Some(template) = self.data.templates.get(template_name) else {
|
||||||
anyhow::bail!("no template named \"{template_name}\" found");
|
anyhow::bail!("no template named \"{template_name}\" found");
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ctx = ParserContext {
|
let mut ctx = ParserContext {
|
||||||
layout,
|
layout,
|
||||||
listeners,
|
listeners,
|
||||||
ids: Default::default(),
|
data_global: &self.data,
|
||||||
macro_attribs: self.macro_attribs.clone(), // FIXME: prevent copying
|
data_local: ParserData::default(),
|
||||||
var_map: self.var_map.clone(), // FIXME: prevent copying
|
|
||||||
components: self.components.clone(), // FIXME: prevent copying
|
|
||||||
components_by_id: self.components_by_id.clone(), // FIXME: prevent copying
|
|
||||||
components_by_widget_id: self.components_by_widget_id.clone(), // FIXME: prevent copying
|
|
||||||
templates: Default::default(),
|
|
||||||
doc_params,
|
doc_params,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -180,10 +205,7 @@ impl ParserState {
|
|||||||
|
|
||||||
parse_widget_other_internal(&template.clone(), template_parameters, &file, &mut ctx, widget_id)?;
|
parse_widget_other_internal(&template.clone(), template_parameters, &file, &mut ctx, widget_id)?;
|
||||||
|
|
||||||
// FIXME?
|
self.data.take_results_from(&mut ctx.data_local);
|
||||||
ctx.ids.into_iter().for_each(|(id, key)| {
|
|
||||||
self.ids.insert(id, key);
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -198,14 +220,89 @@ struct ParserContext<'a, U1, U2> {
|
|||||||
doc_params: &'a ParseDocumentParams<'a>,
|
doc_params: &'a ParseDocumentParams<'a>,
|
||||||
layout: &'a mut Layout,
|
layout: &'a mut Layout,
|
||||||
listeners: &'a mut EventListenerCollection<U1, U2>,
|
listeners: &'a mut EventListenerCollection<U1, U2>,
|
||||||
var_map: HashMap<Rc<str>, Rc<str>>,
|
data_global: &'a ParserData, // current parser state at a given moment
|
||||||
macro_attribs: HashMap<Rc<str>, MacroAttribs>,
|
data_local: ParserData, // newly processed items in a given template
|
||||||
ids: HashMap<Rc<str>, WidgetID>,
|
}
|
||||||
templates: HashMap<Rc<str>, Rc<Template>>,
|
|
||||||
|
|
||||||
components: Vec<Component>,
|
impl<U1, U2> ParserContext<'_, U1, U2> {
|
||||||
components_by_id: HashMap<Rc<str>, ComponentWeak>,
|
fn get_template(&self, name: &str) -> Option<Rc<Template>> {
|
||||||
components_by_widget_id: HashMap<WidgetID, ComponentWeak>,
|
// find in local
|
||||||
|
if let Some(template) = self.data_local.templates.get(name) {
|
||||||
|
return Some(template.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// find in global
|
||||||
|
if let Some(template) = self.data_global.templates.get(name) {
|
||||||
|
return Some(template.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_var(&self, name: &str) -> Option<Rc<str>> {
|
||||||
|
// find in local
|
||||||
|
if let Some(value) = self.data_local.var_map.get(name) {
|
||||||
|
return Some(value.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// find in global
|
||||||
|
if let Some(value) = self.data_global.var_map.get(name) {
|
||||||
|
return Some(value.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_macro_attrib(&self, value: &str) -> Option<&MacroAttribs> {
|
||||||
|
// find in local
|
||||||
|
if let Some(macro_attribs) = self.data_local.macro_attribs.get(value) {
|
||||||
|
return Some(macro_attribs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// find in global
|
||||||
|
if let Some(macro_attribs) = self.data_global.macro_attribs.get(value) {
|
||||||
|
return Some(macro_attribs);
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_template(&mut self, name: Rc<str>, template: Rc<Template>) {
|
||||||
|
self.data_local.templates.insert(name, template);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_var(&mut self, key: &str, value: &str) {
|
||||||
|
self.data_local.var_map.insert(Rc::from(key), Rc::from(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_macro_attrib(&mut self, name: Rc<str>, attribs: MacroAttribs) {
|
||||||
|
self.data_local.macro_attribs.insert(name, attribs);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_component(&mut self, widget_id: WidgetID, component: Component, id: Option<Rc<str>>) {
|
||||||
|
self
|
||||||
|
.data_local
|
||||||
|
.components_by_widget_id
|
||||||
|
.insert(widget_id, component.weak());
|
||||||
|
|
||||||
|
if let Some(id) = id
|
||||||
|
&& self
|
||||||
|
.data_local
|
||||||
|
.components_by_id
|
||||||
|
.insert(id.clone(), component.weak())
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
log::warn!("duplicate component ID \"{id}\" in the same layout file!");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.data_local.components.push(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_id(&mut self, id: &Rc<str>, widget_id: WidgetID) {
|
||||||
|
if self.data_local.ids.insert(id.clone(), widget_id).is_some() {
|
||||||
|
log::warn!("duplicate widget ID \"{id}\" in the same layout file!");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses a color from a HTML hex string
|
// Parses a color from a HTML hex string
|
||||||
@@ -357,14 +454,14 @@ fn parse_widget_other<'a, U1, U2>(
|
|||||||
node: roxmltree::Node<'a, 'a>,
|
node: roxmltree::Node<'a, 'a>,
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let Some(template) = ctx.templates.get(xml_tag_name) else {
|
let Some(template) = ctx.get_template(xml_tag_name) else {
|
||||||
log::error!("Undefined tag named \"{xml_tag_name}\"");
|
log::error!("Undefined tag named \"{xml_tag_name}\"");
|
||||||
return Ok(()); // not critical
|
return Ok(()); // not critical
|
||||||
};
|
};
|
||||||
|
|
||||||
let template_parameters: HashMap<Rc<str>, Rc<str>> = iter_attribs(file, ctx, &node, false).collect();
|
let template_parameters: HashMap<Rc<str>, Rc<str>> = iter_attribs(file, ctx, &node, false).collect();
|
||||||
|
|
||||||
parse_widget_other_internal(&template.clone(), 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<'a, U1, U2>(
|
||||||
@@ -426,7 +523,7 @@ fn parse_tag_var<'a, U1, U2>(ctx: &mut ParserContext<U1, U2>, node: roxmltree::N
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.var_map.insert(Rc::from(key), Rc::from(value));
|
ctx.insert_var(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replace_vars(input: &str, vars: &HashMap<Rc<str>, Rc<str>>) -> Rc<str> {
|
pub fn replace_vars(input: &str, vars: &HashMap<Rc<str>, Rc<str>>) -> Rc<str> {
|
||||||
@@ -462,8 +559,8 @@ fn process_attrib<'a, U1, U2>(
|
|||||||
|
|
||||||
(
|
(
|
||||||
Rc::from(key),
|
Rc::from(key),
|
||||||
match ctx.var_map.get(name) {
|
match ctx.get_var(name) {
|
||||||
Some(name) => name.clone(),
|
Some(name) => name,
|
||||||
None => Rc::from("undefined"),
|
None => Rc::from("undefined"),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -493,7 +590,7 @@ fn iter_attribs<'a, U1, U2>(
|
|||||||
let (key, value) = (attrib.name(), attrib.value());
|
let (key, value) = (attrib.name(), attrib.value());
|
||||||
|
|
||||||
if key == "macro" {
|
if key == "macro" {
|
||||||
if let Some(macro_attrib) = ctx.macro_attribs.get(value) {
|
if let Some(macro_attrib) = ctx.get_macro_attrib(value) {
|
||||||
for (macro_key, macro_value) in ¯o_attrib.attribs {
|
for (macro_key, macro_value) in ¯o_attrib.attribs {
|
||||||
res.push(process_attrib(file, ctx, macro_key, macro_value));
|
res.push(process_attrib(file, ctx, macro_key, macro_value));
|
||||||
}
|
}
|
||||||
@@ -544,7 +641,7 @@ fn parse_tag_template<U1, U2>(file: &ParserFile, ctx: &mut ParserContext<U1, U2>
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.templates.insert(
|
ctx.insert_template(
|
||||||
name,
|
name,
|
||||||
Rc::new(Template {
|
Rc::new(Template {
|
||||||
node: node.id(),
|
node: node.id(),
|
||||||
@@ -577,7 +674,7 @@ fn parse_tag_macro<U1, U2>(file: &ParserFile, ctx: &mut ParserContext<U1, U2>, n
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.macro_attribs.insert(name, MacroAttribs { attribs: macro_attribs });
|
ctx.insert_macro_attrib(name, MacroAttribs { attribs: macro_attribs });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_component<'a, U1, U2>(
|
fn process_component<'a, U1, U2>(
|
||||||
@@ -587,23 +684,21 @@ fn process_component<'a, U1, U2>(
|
|||||||
component: Component,
|
component: Component,
|
||||||
widget_id: WidgetID,
|
widget_id: WidgetID,
|
||||||
) {
|
) {
|
||||||
ctx.components_by_widget_id.insert(widget_id, component.weak());
|
|
||||||
|
|
||||||
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
|
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
|
||||||
|
|
||||||
|
let mut component_id: Option<Rc<str>> = None;
|
||||||
|
|
||||||
for (key, value) in attribs {
|
for (key, value) in attribs {
|
||||||
#[allow(clippy::single_match)]
|
#[allow(clippy::single_match)]
|
||||||
match key.as_ref() {
|
match key.as_ref() {
|
||||||
"id" => {
|
"id" => {
|
||||||
if ctx.components_by_id.insert(value.clone(), component.weak()).is_some() {
|
component_id = Some(value);
|
||||||
log::warn!("duplicate component ID \"{value}\" in the same layout file!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.components.push(component);
|
ctx.insert_component(widget_id, component, component_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_widget_universal<'a, U1, U2>(
|
fn parse_widget_universal<'a, U1, U2>(
|
||||||
@@ -619,9 +714,7 @@ fn parse_widget_universal<'a, U1, U2>(
|
|||||||
match key.as_ref() {
|
match key.as_ref() {
|
||||||
"id" => {
|
"id" => {
|
||||||
// Attach a specific widget to name-ID map (just like getElementById)
|
// Attach a specific widget to name-ID map (just like getElementById)
|
||||||
if ctx.ids.insert(value.clone(), widget_id).is_some() {
|
ctx.insert_id(&value, widget_id);
|
||||||
log::warn!("duplicate widget ID \"{value}\" in the same layout file!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@@ -733,18 +826,14 @@ fn create_default_context<'a, U1, U2>(
|
|||||||
doc_params: &'a ParseDocumentParams,
|
doc_params: &'a ParseDocumentParams,
|
||||||
layout: &'a mut Layout,
|
layout: &'a mut Layout,
|
||||||
listeners: &'a mut EventListenerCollection<U1, U2>,
|
listeners: &'a mut EventListenerCollection<U1, U2>,
|
||||||
|
data_global: &'a ParserData,
|
||||||
) -> ParserContext<'a, U1, U2> {
|
) -> ParserContext<'a, U1, U2> {
|
||||||
ParserContext {
|
ParserContext {
|
||||||
doc_params,
|
doc_params,
|
||||||
layout,
|
layout,
|
||||||
listeners,
|
listeners,
|
||||||
ids: Default::default(),
|
data_local: ParserData::default(),
|
||||||
var_map: Default::default(),
|
data_global,
|
||||||
templates: Default::default(),
|
|
||||||
macro_attribs: Default::default(),
|
|
||||||
components: Default::default(),
|
|
||||||
components_by_id: Default::default(),
|
|
||||||
components_by_widget_id: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -844,20 +933,15 @@ pub fn parse_from_assets<U1, U2>(
|
|||||||
) -> anyhow::Result<ParserState> {
|
) -> anyhow::Result<ParserState> {
|
||||||
let path = PathBuf::from(doc_params.path);
|
let path = PathBuf::from(doc_params.path);
|
||||||
|
|
||||||
let mut ctx = create_default_context(doc_params, layout, listeners);
|
let parser_data = ParserData::default();
|
||||||
|
let mut ctx = create_default_context(doc_params, layout, listeners, &parser_data);
|
||||||
|
|
||||||
let (file, node_layout) = get_doc_from_path(&ctx, &path)?;
|
let (file, node_layout) = get_doc_from_path(&ctx, &path)?;
|
||||||
parse_document_root(&file, &mut ctx, parent_id, node_layout)?;
|
parse_document_root(&file, &mut ctx, parent_id, node_layout)?;
|
||||||
|
|
||||||
// move everything essential to the result
|
// move everything essential to the result
|
||||||
let result = ParserState {
|
let result = ParserState {
|
||||||
ids: std::mem::take(&mut ctx.ids),
|
data: std::mem::take(&mut ctx.data_local),
|
||||||
templates: std::mem::take(&mut ctx.templates),
|
|
||||||
macro_attribs: std::mem::take(&mut ctx.macro_attribs),
|
|
||||||
var_map: std::mem::take(&mut ctx.var_map),
|
|
||||||
components: std::mem::take(&mut ctx.components),
|
|
||||||
components_by_id: std::mem::take(&mut ctx.components_by_id),
|
|
||||||
components_by_widget_id: std::mem::take(&mut ctx.components_by_widget_id),
|
|
||||||
path,
|
path,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
use button::setup_custom_button;
|
use button::setup_custom_button;
|
||||||
use glam::{vec2, Affine2, Vec2};
|
use glam::{Affine2, Vec2, vec2};
|
||||||
use label::setup_custom_label;
|
use label::setup_custom_label;
|
||||||
use vulkano::{command_buffer::CommandBufferUsage, image::view::ImageView};
|
use vulkano::{command_buffer::CommandBufferUsage, image::view::ImageView};
|
||||||
use wgui::{
|
use wgui::{
|
||||||
@@ -20,7 +20,7 @@ use wgui::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
input::{Haptics, PointerHit, PointerMode},
|
input::{Haptics, PointerHit, PointerMode},
|
||||||
overlay::{ui_transform, FrameMeta, OverlayBackend, ShouldRender},
|
overlay::{FrameMeta, OverlayBackend, ShouldRender, ui_transform},
|
||||||
},
|
},
|
||||||
graphics::{CommandBuffers, ExtentExt},
|
graphics::{CommandBuffers, ExtentExt},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
@@ -93,7 +93,7 @@ impl<S> GuiPanel<S> {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
if let Some(on_element_id) = on_custom_id {
|
if let Some(on_element_id) = on_custom_id {
|
||||||
let ids = parser_state.ids.clone();
|
let ids = parser_state.data.ids.clone(); // FIXME: copying all ids?
|
||||||
|
|
||||||
for (id, widget) in ids {
|
for (id, widget) in ids {
|
||||||
on_element_id(
|
on_element_id(
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ where
|
|||||||
let state = BarState {};
|
let state = BarState {};
|
||||||
let mut panel = GuiPanel::new_from_template(app, "gui/bar.xml", state, None)?;
|
let mut panel = GuiPanel::new_from_template(app, "gui/bar.xml", state, None)?;
|
||||||
|
|
||||||
for (id, _widget_id) in &panel.parser_state.ids {
|
for (id, _widget_id) in &panel.parser_state.data.ids {
|
||||||
match id.as_ref() {
|
match id.as_ref() {
|
||||||
"lock" => {}
|
"lock" => {}
|
||||||
"anchor" => {}
|
"anchor" => {}
|
||||||
|
|||||||
@@ -172,13 +172,13 @@ where
|
|||||||
params,
|
params,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if let Some(widget_id) = gui_state_key.ids.get(&*my_id) {
|
if let Some(widget_id) = gui_state_key.get_widget_id(&*my_id).ok() {
|
||||||
let key_state = {
|
let key_state = {
|
||||||
let rect = panel
|
let rect = panel
|
||||||
.layout
|
.layout
|
||||||
.state
|
.state
|
||||||
.widgets
|
.widgets
|
||||||
.get_as::<WidgetRectangle>(*widget_id)
|
.get_as::<WidgetRectangle>(widget_id)
|
||||||
.unwrap(); // want panic
|
.unwrap(); // want panic
|
||||||
|
|
||||||
Rc::new(KeyState {
|
Rc::new(KeyState {
|
||||||
@@ -192,7 +192,7 @@ where
|
|||||||
|
|
||||||
panel.listeners.register(
|
panel.listeners.register(
|
||||||
&mut panel.listener_handles,
|
&mut panel.listener_handles,
|
||||||
*widget_id,
|
widget_id,
|
||||||
EventListenerKind::MouseEnter,
|
EventListenerKind::MouseEnter,
|
||||||
Box::new({
|
Box::new({
|
||||||
let k = key_state.clone();
|
let k = key_state.clone();
|
||||||
@@ -205,7 +205,7 @@ where
|
|||||||
);
|
);
|
||||||
panel.listeners.register(
|
panel.listeners.register(
|
||||||
&mut panel.listener_handles,
|
&mut panel.listener_handles,
|
||||||
*widget_id,
|
widget_id,
|
||||||
EventListenerKind::MouseLeave,
|
EventListenerKind::MouseLeave,
|
||||||
Box::new({
|
Box::new({
|
||||||
let k = key_state.clone();
|
let k = key_state.clone();
|
||||||
@@ -218,7 +218,7 @@ where
|
|||||||
);
|
);
|
||||||
panel.listeners.register(
|
panel.listeners.register(
|
||||||
&mut panel.listener_handles,
|
&mut panel.listener_handles,
|
||||||
*widget_id,
|
widget_id,
|
||||||
EventListenerKind::MousePress,
|
EventListenerKind::MousePress,
|
||||||
Box::new({
|
Box::new({
|
||||||
let k = key_state.clone();
|
let k = key_state.clone();
|
||||||
@@ -235,7 +235,7 @@ where
|
|||||||
);
|
);
|
||||||
panel.listeners.register(
|
panel.listeners.register(
|
||||||
&mut panel.listener_handles,
|
&mut panel.listener_handles,
|
||||||
*widget_id,
|
widget_id,
|
||||||
EventListenerKind::MouseRelease,
|
EventListenerKind::MouseRelease,
|
||||||
Box::new({
|
Box::new({
|
||||||
let k = key_state.clone();
|
let k = key_state.clone();
|
||||||
@@ -251,7 +251,7 @@ where
|
|||||||
if let Some(modifier) = my_modifier {
|
if let Some(modifier) = my_modifier {
|
||||||
panel.listeners.register(
|
panel.listeners.register(
|
||||||
&mut panel.listener_handles,
|
&mut panel.listener_handles,
|
||||||
*widget_id,
|
widget_id,
|
||||||
EventListenerKind::InternalStateChange,
|
EventListenerKind::InternalStateChange,
|
||||||
Box::new({
|
Box::new({
|
||||||
let k = key_state.clone();
|
let k = key_state.clone();
|
||||||
|
|||||||
Reference in New Issue
Block a user