wgui: Simplify Popup usage

This commit is contained in:
Aleksander 2026-04-11 19:48:48 +02:00 committed by galister
parent 62881c08b3
commit aee5bf69da
12 changed files with 136 additions and 129 deletions

View File

@ -23,12 +23,10 @@ use crate::{
}; };
#[derive(Clone)] #[derive(Clone)]
enum Task { enum Task {}
CloseLauncher,
}
struct State { struct State {
view_launcher: Option<PopupHolder<views::app_launcher::View>>, view_launcher: PopupHolder<views::app_launcher::View>,
} }
pub struct TabApps<T> { pub struct TabApps<T> {
@ -47,21 +45,17 @@ impl<T> Tab<T> for TabApps<T> {
} }
fn update(&mut self, frontend: &mut Frontend<T>, _time_ms: u32, data: &mut T) -> anyhow::Result<()> { fn update(&mut self, frontend: &mut Frontend<T>, _time_ms: u32, data: &mut T) -> anyhow::Result<()> {
let mut state = self.state.borrow_mut(); let state = self.state.borrow_mut();
for task in self.tasks.drain() { for task in self.tasks.drain() {
match task { match task {}
Task::CloseLauncher => state.view_launcher = None,
}
} }
self self.app_list.tick(frontend, &self.state, &mut self.parser_state)?;
.app_list
.tick(frontend, &self.state, &self.tasks, &mut self.parser_state)?;
if let Some((_, launcher)) = &mut state.view_launcher { state
launcher.update(&mut frontend.interface, data)?; .view_launcher
} .with_view_res(|view| view.update(&mut frontend.interface, data))?;
Ok(()) Ok(())
} }
} }
@ -79,18 +73,13 @@ fn on_app_click(
globals: WguiGlobals, globals: WguiGlobals,
entry: DesktopEntry, entry: DesktopEntry,
state: Rc<RefCell<State>>, state: Rc<RefCell<State>>,
tasks: Tasks<Task>,
) -> ButtonClickCallback { ) -> ButtonClickCallback {
Rc::new(move |_common, _evt| { Rc::new(move |_common, _evt| {
views::app_launcher::mount_popup( views::app_launcher::mount_popup(
frontend_tasks.clone(), frontend_tasks.clone(),
globals.clone(), globals.clone(),
entry.clone(), entry.clone(),
tasks.make_callback_box(Task::CloseLauncher), state.borrow_mut().view_launcher.clone(),
Box::new({
let state = state.clone();
move |popup| state.borrow_mut().view_launcher = Some(popup)
}),
); );
Ok(()) Ok(())
}) })
@ -108,7 +97,9 @@ impl<T> TabApps<T> {
pub fn new(frontend: &mut Frontend<T>, parent_id: WidgetID, data: &mut T) -> anyhow::Result<Self> { pub fn new(frontend: &mut Frontend<T>, parent_id: WidgetID, data: &mut T) -> anyhow::Result<Self> {
let globals = frontend.layout.state.globals.clone(); let globals = frontend.layout.state.globals.clone();
let tasks = Tasks::new(); let tasks = Tasks::new();
let state = Rc::new(RefCell::new(State { view_launcher: None })); let state = Rc::new(RefCell::new(State {
view_launcher: Default::default(),
}));
let parser_state = wgui::parser::parse_from_assets(&doc_params(globals.clone()), &mut frontend.layout, parent_id)?; let parser_state = wgui::parser::parse_from_assets(&doc_params(globals.clone()), &mut frontend.layout, parent_id)?;
let app_list_parent = parser_state.fetch_widget(&frontend.layout.state, "app_list_parent")?; let app_list_parent = parser_state.fetch_widget(&frontend.layout.state, "app_list_parent")?;
@ -313,7 +304,6 @@ impl AppList {
&mut self, &mut self,
frontend: &mut Frontend<T>, frontend: &mut Frontend<T>,
state: &Rc<RefCell<State>>, state: &Rc<RefCell<State>>,
tasks: &Tasks<Task>,
parser_state: &mut ParserState, parser_state: &mut ParserState,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
// load 4 entries for a single frame at most // load 4 entries for a single frame at most
@ -327,7 +317,6 @@ impl AppList {
globals.clone(), globals.clone(),
entry.clone(), entry.clone(),
state.clone(), state.clone(),
tasks.clone(),
)); ));
} else { } else {
break; break;

View File

@ -34,16 +34,105 @@ pub struct MountedPopup {
frontend_tasks: FrontendTasks, frontend_tasks: FrontendTasks,
} }
#[derive(Default)]
struct MountedPopupState { struct MountedPopupState {
mounted_popup: Option<MountedPopup>, mounted_popup: Option<MountedPopup>,
} }
#[derive(Clone)] #[derive(Default, Clone)]
pub struct PopupHandle { pub struct PopupHandle {
state: Rc<RefCell<MountedPopupState>>, state: Rc<RefCell<MountedPopupState>>,
} }
pub type PopupHolder<ViewType> = (PopupHandle, ViewType); struct PopupHolderState<ViewType> {
popup_handle: PopupHandle,
view: Option<ViewType>,
}
// we can't use #[derive(Default)] due to the fact that ViewType can't be Default.
impl<ViewType> Default for PopupHolderState<ViewType> {
fn default() -> Self {
Self {
popup_handle: Default::default(),
view: Default::default(),
}
}
}
pub struct PopupHolder<ViewType> {
state: Rc<RefCell<PopupHolderState<ViewType>>>,
}
impl<ViewType> Default for PopupHolder<ViewType> {
fn default() -> Self {
Self {
state: Rc::new(RefCell::new(PopupHolderState::default())),
}
}
}
// we can't derive(Clone) due to the fact that ViewType is non-cloneable
impl<ViewType> Clone for PopupHolder<ViewType> {
fn clone(&self) -> Self {
Self {
state: self.state.clone(),
}
}
}
impl<ViewType> PopupHolder<ViewType> {
pub fn close(&self) {
let mut state = self.state.borrow_mut();
state.view = None;
state.popup_handle.close();
}
pub fn set_view(&self, handle: PopupHandle, view: ViewType) {
let mut state = self.state.borrow_mut();
state.view = Some(view);
state.popup_handle = handle;
}
// Get underlying ViewType object in a closure and return its value
// example usage:
//
// ```rs
// holder.with_view(|view| {
// view.foo();
// })
// ```
//
pub fn with_view<F, R>(&self, f: F) -> Option<R>
where
F: FnOnce(&mut ViewType) -> R,
{
let mut state = self.state.borrow_mut();
if let Some(view) = state.view.as_mut() {
Some(f(view))
} else {
None
}
}
// Same as with_view, but the closure expects a simple anyhow::Result<()> type
pub fn with_view_res<F>(&self, f: F) -> anyhow::Result<()>
where
F: FnOnce(&mut ViewType) -> anyhow::Result<()>,
{
if let Some(res) = self.with_view(f) {
return res;
}
Ok(())
}
pub fn get_close_callback(&self) -> Box<dyn Fn()>
where
ViewType: 'static,
{
let this = self.clone();
Box::new(move || this.close())
}
}
impl PopupHandle { impl PopupHandle {
pub fn close(&self) { pub fn close(&self) {

View File

@ -424,13 +424,7 @@ impl View {
} }
} }
pub fn mount_popup( pub fn mount_popup(frontend_tasks: FrontendTasks, globals: WguiGlobals, entry: DesktopEntry, popup: PopupHolder<View>) {
frontend_tasks: FrontendTasks,
globals: WguiGlobals,
entry: DesktopEntry,
on_close_request: Box<dyn Fn()>,
set_holder: Box<dyn FnOnce(PopupHolder<View>)>,
) {
frontend_tasks frontend_tasks
.clone() .clone()
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new( .push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
@ -443,10 +437,10 @@ pub fn mount_popup(
parent_id: data.id_content, parent_id: data.id_content,
frontend_tasks: &frontend_tasks, frontend_tasks: &frontend_tasks,
config: data.config, config: data.config,
on_launched: on_close_request, on_launched: popup.get_close_callback(),
})?; })?;
set_holder((data.handle, view)); popup.set_view(data.handle, view);
Ok(()) Ok(())
}), }),
))); )));

View File

@ -198,8 +198,7 @@ pub fn mount_popup(
executor: AsyncExecutor, executor: AsyncExecutor,
globals: WguiGlobals, globals: WguiGlobals,
manifest: AppManifest, manifest: AppManifest,
on_close_request: Box<dyn Fn()>, popup: PopupHolder<View>,
set_holder: Box<dyn FnOnce(PopupHolder<View>)>,
) { ) {
frontend_tasks frontend_tasks
.clone() .clone()
@ -213,10 +212,10 @@ pub fn mount_popup(
layout: data.layout, layout: data.layout,
parent_id: data.id_content, parent_id: data.id_content,
frontend_tasks: &frontend_tasks, frontend_tasks: &frontend_tasks,
on_launched: on_close_request, on_launched: popup.get_close_callback(),
})?; })?;
set_holder((data.handle, view)); popup.set_view(data.handle, view);
Ok(()) Ok(())
}), }),
))); )));

View File

@ -1,4 +1,4 @@
use std::{cell::RefCell, collections::HashMap, rc::Rc}; use std::{collections::HashMap, rc::Rc};
use wgui::{ use wgui::{
assets::AssetPath, assets::AssetPath,
@ -29,7 +29,6 @@ use crate::{
enum Task { enum Task {
AppManifestClicked(steam_utils::AppManifest), AppManifestClicked(steam_utils::AppManifest),
SetCoverArt(AppID, Rc<CoverArt>), SetCoverArt(AppID, Rc<CoverArt>),
CloseLauncher,
LoadManifests, LoadManifests,
FillPage(u32), FillPage(u32),
PrevPage, PrevPage,
@ -50,10 +49,6 @@ pub struct GameCoverCell {
view_cover: game_cover::View, view_cover: game_cover::View,
} }
struct State {
view_launcher: Option<PopupHolder<views::game_launcher::View>>,
}
pub struct View { pub struct View {
#[allow(dead_code)] #[allow(dead_code)]
parser_state: ParserState, parser_state: ParserState,
@ -63,12 +58,12 @@ pub struct View {
id_list_parent: WidgetID, id_list_parent: WidgetID,
game_cover_view_common: game_cover::ViewCommon, game_cover_view_common: game_cover::ViewCommon,
executor: AsyncExecutor, executor: AsyncExecutor,
state: Rc<RefCell<State>>,
mounted_game_covers: HashMap<AppID, GameCoverCell>, mounted_game_covers: HashMap<AppID, GameCoverCell>,
all_manifests: Vec<steam_utils::AppManifest>, all_manifests: Vec<steam_utils::AppManifest>,
cur_page: u32, cur_page: u32,
page_count: u32, page_count: u32,
id_label_page: WidgetID, id_label_page: WidgetID,
view_launcher: PopupHolder<views::game_launcher::View>,
} }
impl View { impl View {
@ -105,12 +100,12 @@ impl View {
id_list_parent: list_parent.id, id_list_parent: list_parent.id,
mounted_game_covers: HashMap::new(), mounted_game_covers: HashMap::new(),
game_cover_view_common: game_cover::ViewCommon::new(params.globals.clone()), game_cover_view_common: game_cover::ViewCommon::new(params.globals.clone()),
state: Rc::new(RefCell::new(State { view_launcher: None })),
executor: params.executor, executor: params.executor,
all_manifests: Vec::new(), all_manifests: Vec::new(),
cur_page: 0, cur_page: 0,
page_count: 0, page_count: 0,
id_label_page, id_label_page,
view_launcher: Default::default(),
}) })
} }
@ -131,17 +126,13 @@ impl View {
Task::FillPage(page_idx) => self.fill_page(layout, executor, page_idx)?, Task::FillPage(page_idx) => self.fill_page(layout, executor, page_idx)?,
Task::AppManifestClicked(manifest) => self.action_app_manifest_clicked(manifest)?, Task::AppManifestClicked(manifest) => self.action_app_manifest_clicked(manifest)?,
Task::SetCoverArt(app_id, cover_art) => self.set_cover_art(layout, app_id, cover_art), Task::SetCoverArt(app_id, cover_art) => self.set_cover_art(layout, app_id, cover_art),
Task::CloseLauncher => self.state.borrow_mut().view_launcher = None,
Task::PrevPage => self.page_prev(), Task::PrevPage => self.page_prev(),
Task::NextPage => self.page_next(), Task::NextPage => self.page_next(),
} }
} }
} }
let mut state = self.state.borrow_mut(); self.view_launcher.with_view_res(|view| view.update(layout))?;
if let Some((_, view)) = &mut state.view_launcher {
view.update(layout)?;
}
Ok(()) Ok(())
} }
@ -286,11 +277,7 @@ impl View {
self.executor.clone(), self.executor.clone(),
self.globals.clone(), self.globals.clone(),
manifest, manifest,
self.tasks.make_callback_box(Task::CloseLauncher), self.view_launcher.clone(),
Box::new({
let state = self.state.clone();
move |popup| state.borrow_mut().view_launcher = Some(popup)
}),
); );
Ok(()) Ok(())

View File

@ -169,8 +169,7 @@ pub fn mount_popup(
globals: WguiGlobals, globals: WguiGlobals,
entry: networking::skymap_catalog::SkymapCatalogEntry, entry: networking::skymap_catalog::SkymapCatalogEntry,
preview_image: Option<CustomGlyphData>, preview_image: Option<CustomGlyphData>,
on_close_request: Box<dyn Fn()>, popup: PopupHolder<View>,
set_holder: Box<dyn FnOnce(PopupHolder<View>)>,
) { ) {
frontend_tasks frontend_tasks
.clone() .clone()
@ -183,11 +182,11 @@ pub fn mount_popup(
executor: &executor, executor: &executor,
parent_id: data.id_content, parent_id: data.id_content,
entry, entry,
on_close_request, on_close_request: popup.get_close_callback(),
preview_image, preview_image,
})?; })?;
set_holder((data.handle, view)); popup.set_view(data.handle, view);
Ok(()) Ok(())
}), }),
))); )));

View File

@ -1,4 +1,4 @@
use std::{cell::RefCell, rc::Rc}; use std::rc::Rc;
use wgui::{ use wgui::{
assets::AssetPath, assets::AssetPath,
@ -38,7 +38,6 @@ enum Task {
SetSkymapCatalog(Rc<anyhow::Result<networking::skymap_catalog::SkymapCatalog>>), SetSkymapCatalog(Rc<anyhow::Result<networking::skymap_catalog::SkymapCatalog>>),
SetSkymapPreview((SkymapUuid, Option<CustomGlyphData>)), SetSkymapPreview((SkymapUuid, Option<CustomGlyphData>)),
ShowRemoteSkymapDownloader(SkymapUuid), ShowRemoteSkymapDownloader(SkymapUuid),
CloseRemoteSkymapDownloader,
} }
struct MountedCell { struct MountedCell {
@ -46,10 +45,6 @@ struct MountedCell {
view: views::skymap_list_cell::View, view: views::skymap_list_cell::View,
} }
pub struct State {
popup_remote_skymap_downloader: Option<PopupHolder<views::remote_skymap_downloader::View>>,
}
pub struct View { pub struct View {
id_parent: WidgetID, id_parent: WidgetID,
id_list: WidgetID, id_list: WidgetID,
@ -60,7 +55,7 @@ pub struct View {
executor: AsyncExecutor, executor: AsyncExecutor,
frontend_tasks: FrontendTasks, frontend_tasks: FrontendTasks,
catalog: Option<networking::skymap_catalog::SkymapCatalog>, catalog: Option<networking::skymap_catalog::SkymapCatalog>,
state: Rc<RefCell<State>>, popup_remote_skymap_downloader: PopupHolder<views::remote_skymap_downloader::View>,
} }
impl View { impl View {
@ -88,9 +83,7 @@ impl View {
executor: par.executor.clone(), executor: par.executor.clone(),
frontend_tasks: par.frontend_tasks, frontend_tasks: par.frontend_tasks,
catalog: None, catalog: None,
state: Rc::new(RefCell::new(State { popup_remote_skymap_downloader: Default::default(),
popup_remote_skymap_downloader: None,
})),
}) })
} }
@ -171,11 +164,7 @@ impl View {
self.globals.clone(), self.globals.clone(),
entry.clone(), entry.clone(),
preview_image, preview_image,
self.tasks.make_callback_box(Task::CloseRemoteSkymapDownloader), self.popup_remote_skymap_downloader.clone(),
Box::new({
let state = self.state.clone();
move |popup| state.borrow_mut().popup_remote_skymap_downloader = Some(popup)
}),
); );
Ok(()) Ok(())
@ -189,12 +178,9 @@ impl View {
} }
pub fn update(&mut self, layout: &mut Layout) -> anyhow::Result<()> { pub fn update(&mut self, layout: &mut Layout) -> anyhow::Result<()> {
{ self
let mut state = self.state.borrow_mut(); .popup_remote_skymap_downloader
if let Some(view) = &mut state.popup_remote_skymap_downloader { .with_view_res(|view| view.update(layout))?;
view.1.update(layout)?;
}
}
for task in self.tasks.drain() { for task in self.tasks.drain() {
match task { match task {
@ -224,9 +210,6 @@ impl View {
let preview_image = self.get_image_preview(skymap_uuid); let preview_image = self.get_image_preview(skymap_uuid);
self.show_remote_skymap_downloader(skymap_uuid, preview_image)?; self.show_remote_skymap_downloader(skymap_uuid, preview_image)?;
} }
Task::CloseRemoteSkymapDownloader => {
self.state.borrow_mut().popup_remote_skymap_downloader = None;
}
} }
} }
Ok(()) Ok(())
@ -237,8 +220,7 @@ pub fn mount_popup(
frontend_tasks: FrontendTasks, frontend_tasks: FrontendTasks,
executor: AsyncExecutor, executor: AsyncExecutor,
globals: WguiGlobals, globals: WguiGlobals,
on_close_request: Box<dyn Fn()>, popup: PopupHolder<View>,
set_holder: Box<dyn FnOnce(PopupHolder<View>)>,
) { ) {
frontend_tasks frontend_tasks
.clone() .clone()
@ -250,11 +232,11 @@ pub fn mount_popup(
layout: data.layout, layout: data.layout,
executor: &executor, executor: &executor,
parent_id: data.id_content, parent_id: data.id_content,
on_close_request, on_close_request: popup.get_close_callback(),
frontend_tasks, frontend_tasks,
})?; })?;
set_holder((data.handle, view)); popup.set_view(data.handle, view);
Ok(()) Ok(())
}), }),
))); )));

View File

@ -1,5 +1,3 @@
use std::{cell::RefCell, rc::Rc};
use wgui::{ use wgui::{
assets::AssetPath, assets::AssetPath,
components::button::ComponentButton, components::button::ComponentButton,
@ -20,7 +18,6 @@ use crate::{
#[derive(Clone)] #[derive(Clone)]
enum Task { enum Task {
DownloadSkymaps, DownloadSkymaps,
ClosePopupDownloadSkymaps,
Refresh, Refresh,
} }
@ -31,10 +28,6 @@ pub struct Params<'a> {
pub frontend_tasks: &'a FrontendTasks, pub frontend_tasks: &'a FrontendTasks,
} }
pub struct State {
popup_remote_skymap_list: Option<PopupHolder<views::remote_skymap_list::View>>,
}
pub struct View { pub struct View {
#[allow(dead_code)] #[allow(dead_code)]
parser_state: ParserState, parser_state: ParserState,
@ -42,7 +35,7 @@ pub struct View {
list_parent: WidgetID, list_parent: WidgetID,
frontend_tasks: FrontendTasks, frontend_tasks: FrontendTasks,
globals: WguiGlobals, globals: WguiGlobals,
state: Rc<RefCell<State>>, popup_remote_skymap_list: PopupHolder<views::remote_skymap_list::View>,
} }
impl View { impl View {
@ -69,27 +62,20 @@ impl View {
Task::Refresh, Task::Refresh,
); );
let state = Rc::new(RefCell::new(State {
popup_remote_skymap_list: None,
}));
Ok(Self { Ok(Self {
parser_state, parser_state,
tasks, tasks,
list_parent, list_parent,
frontend_tasks: params.frontend_tasks.clone(), frontend_tasks: params.frontend_tasks.clone(),
state,
globals: params.globals.clone(), globals: params.globals.clone(),
popup_remote_skymap_list: Default::default(),
}) })
} }
pub fn update(&mut self, layout: &mut Layout, executor: &AsyncExecutor) -> anyhow::Result<()> { pub fn update(&mut self, layout: &mut Layout, executor: &AsyncExecutor) -> anyhow::Result<()> {
{ self
let mut state = self.state.borrow_mut(); .popup_remote_skymap_list
if let Some(popup) = &mut state.popup_remote_skymap_list { .with_view_res(|view| view.update(layout))?;
popup.1.update(layout)?;
}
}
loop { loop {
let tasks = self.tasks.drain(); let tasks = self.tasks.drain();
@ -104,9 +90,6 @@ impl View {
Task::Refresh => { Task::Refresh => {
self.refresh(layout)?; self.refresh(layout)?;
} }
Task::ClosePopupDownloadSkymaps => {
(*self.state.borrow_mut()).popup_remote_skymap_list = None;
}
} }
} }
} }
@ -119,13 +102,7 @@ impl View {
self.frontend_tasks.clone(), self.frontend_tasks.clone(),
executor.clone(), executor.clone(),
self.globals.clone(), self.globals.clone(),
self.tasks.make_callback_box(Task::ClosePopupDownloadSkymaps), self.popup_remote_skymap_list.clone(),
Box::new({
let state = self.state.clone();
move |popup| {
state.borrow_mut().popup_remote_skymap_list = Some(popup);
}
}),
); );
Ok(()) Ok(())
} }

View File

@ -46,7 +46,6 @@ pub struct TestbedGeneric {
pub parser_state: ParserState, pub parser_state: ParserState,
tasks: Tasks<TestbedTask>, tasks: Tasks<TestbedTask>,
globals: WguiGlobals,
data: Rc<RefCell<Data>>, data: Rc<RefCell<Data>>,
} }
@ -183,7 +182,6 @@ impl TestbedGeneric {
layout, layout,
parser_state, parser_state,
tasks: Default::default(), tasks: Default::default(),
globals: globals.clone(),
data: Rc::new(RefCell::new(Data { data: Rc::new(RefCell::new(Data {
popup_window: WguiWindow::default(), popup_window: WguiWindow::default(),
context_menu: context_menu::ContextMenu::default(), context_menu: context_menu::ContextMenu::default(),

View File

@ -7,10 +7,9 @@ use crate::{
}, },
drawing::{self}, drawing::{self},
event::CallbackDataCommon, event::CallbackDataCommon,
globals::WguiGlobals,
i18n::Translation, i18n::Translation,
layout::{Layout, WidgetID, WidgetPair}, layout::{Layout, WidgetID, WidgetPair},
parser::{self, Fetchable, ParseDocumentParams, ParserState}, parser::{self, Fetchable, ParseDocumentParams},
widget::{ConstructEssentials, rectangle::WidgetRectangle, util::WLength}, widget::{ConstructEssentials, rectangle::WidgetRectangle, util::WLength},
windowing::window::{WguiWindow, WguiWindowParams, WguiWindowParamsExtra}, windowing::window::{WguiWindow, WguiWindowParams, WguiWindowParamsExtra},
}; };

View File

@ -321,13 +321,8 @@ impl Layout {
self.needs_redraw = true; self.needs_redraw = true;
} }
fn process_pending_components(&mut self, alterables: &mut EventAlterables) { fn process_pending_components(&mut self) {
for comp in std::mem::take(&mut self.components_to_refresh_once) { for comp in std::mem::take(&mut self.components_to_refresh_once) {
let mut common = CallbackDataCommon {
state: &self.state,
alterables,
};
comp.0.refresh(&mut RefreshData { layout: self }); comp.0.refresh(&mut RefreshData { layout: self });
} }
} }
@ -684,7 +679,7 @@ impl Layout {
pub fn tick(&mut self) -> anyhow::Result<()> { pub fn tick(&mut self) -> anyhow::Result<()> {
let mut alterables = EventAlterables::default(); let mut alterables = EventAlterables::default();
self.animations.tick(&self.state, &mut alterables); self.animations.tick(&self.state, &mut alterables);
self.process_pending_components(&mut alterables); self.process_pending_components();
self.process_pending_widget_ticks(&mut alterables); self.process_pending_widget_ticks(&mut alterables);
self.process_alterables(alterables)?; self.process_alterables(alterables)?;
Ok(()) Ok(())

View File

@ -9,7 +9,6 @@ use crate::{
components::button::ComponentButton, components::button::ComponentButton,
drawing, drawing,
event::{EventListenerKind, StyleSetRequest}, event::{EventListenerKind, StyleSetRequest},
globals::WguiGlobals,
i18n::Translation, i18n::Translation,
layout::{Layout, LayoutTask, LayoutTasks, WidgetPair}, layout::{Layout, LayoutTask, LayoutTasks, WidgetPair},
parser::{self, Fetchable, ParserState}, parser::{self, Fetchable, ParserState},