tweak watch ui, load application list gradually (prevent lag)

This commit is contained in:
Aleksander
2026-01-04 13:11:31 +01:00
parent 553dd02fc4
commit c3e04e0a89
2 changed files with 69 additions and 63 deletions

View File

@@ -1,4 +1,9 @@
use std::{cell::RefCell, collections::HashMap, marker::PhantomData, rc::Rc}; use std::{
cell::RefCell,
collections::{HashMap, VecDeque},
marker::PhantomData,
rc::Rc,
};
use wgui::{ use wgui::{
assets::AssetPath, assets::AssetPath,
@@ -33,7 +38,6 @@ pub struct TabApps<T> {
parser_state: ParserState, parser_state: ParserState,
state: Rc<RefCell<State>>, state: Rc<RefCell<State>>,
entries: Vec<DesktopEntry>,
app_list: AppList, app_list: AppList,
tasks: Tasks<Task>, tasks: Tasks<Task>,
marker: PhantomData<T>, marker: PhantomData<T>,
@@ -53,6 +57,10 @@ impl<T> Tab<T> for TabApps<T> {
} }
} }
self
.app_list
.tick(frontend, &self.state, &self.tasks, &mut self.parser_state)?;
if let Some((_, launcher)) = &mut state.view_launcher { if let Some((_, launcher)) = &mut state.view_launcher {
launcher.update(&mut frontend.interface, data)?; launcher.update(&mut frontend.interface, data)?;
} }
@@ -60,9 +68,10 @@ impl<T> Tab<T> for TabApps<T> {
} }
} }
#[derive(Default)]
struct AppList { struct AppList {
//data: Vec<ParserData>, //data: Vec<ParserData>,
entries_to_mount: VecDeque<DesktopEntry>,
list_parent: WidgetPair,
} }
// called after the user clicks any desktop entry // called after the user clicks any desktop entry
@@ -109,47 +118,31 @@ fn on_app_click(
}) })
} }
fn doc_params(globals: WguiGlobals) -> ParseDocumentParams<'static> {
ParseDocumentParams {
globals,
path: AssetPath::BuiltIn("gui/tab/apps.xml"),
extra: Default::default(),
}
}
impl<T> TabApps<T> { impl<T> TabApps<T> {
pub fn new(frontend: &mut Frontend<T>, parent_id: WidgetID) -> anyhow::Result<Self> { pub fn new(frontend: &mut Frontend<T>, parent_id: WidgetID) -> anyhow::Result<Self> {
let doc_params = &ParseDocumentParams {
globals: frontend.layout.state.globals.clone(),
path: AssetPath::BuiltIn("gui/tab/apps.xml"),
extra: Default::default(),
};
let entries = frontend.desktop_finder.find_entries();
let frontend_tasks = frontend.tasks.clone();
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: None }));
let mut parser_state = wgui::parser::parse_from_assets(doc_params, &mut frontend.layout, parent_id)?; let mut entries = frontend.desktop_finder.find_entries();
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")?;
let mut app_list = AppList::default(); let app_list = AppList {
app_list.mount_entries( entries_to_mount: entries.drain(..).collect(),
frontend, list_parent: app_list_parent,
&entries, };
&mut parser_state,
doc_params,
&app_list_parent,
|button, entry| {
// Set up the click handler for the app button
button.on_click(on_app_click(
frontend_tasks.clone(),
globals.clone(),
entry.clone(),
state.clone(),
tasks.clone(),
));
},
)?;
Ok(Self { Ok(Self {
app_list, app_list,
parser_state, parser_state,
entries,
state, state,
tasks, tasks,
marker: PhantomData, marker: PhantomData,
@@ -163,7 +156,6 @@ impl AppList {
frontend: &mut Frontend<T>, frontend: &mut Frontend<T>,
parser_state: &mut ParserState, parser_state: &mut ParserState,
doc_params: &ParseDocumentParams, doc_params: &ParseDocumentParams,
list_parent: &WidgetPair,
entry: &DesktopEntry, entry: &DesktopEntry,
) -> anyhow::Result<Rc<ComponentButton>> { ) -> anyhow::Result<Rc<ComponentButton>> {
let mut template_params = HashMap::new(); let mut template_params = HashMap::new();
@@ -193,25 +185,32 @@ impl AppList {
doc_params, doc_params,
"AppEntry", "AppEntry",
&mut frontend.layout, &mut frontend.layout,
list_parent.id, self.list_parent.id,
template_params, template_params,
)?; )?;
data.fetch_component_as::<ComponentButton>("button") data.fetch_component_as::<ComponentButton>("button")
} }
fn mount_entries<T>( fn tick<T>(
&mut self, &mut self,
frontend: &mut Frontend<T>, frontend: &mut Frontend<T>,
entries: &[DesktopEntry], state: &Rc<RefCell<State>>,
tasks: &Tasks<Task>,
parser_state: &mut ParserState, parser_state: &mut ParserState,
doc_params: &ParseDocumentParams,
list_parent: &WidgetPair,
on_button: impl Fn(Rc<ComponentButton>, &DesktopEntry),
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
for entry in entries { if let Some(entry) = self.entries_to_mount.pop_front() {
let button = self.mount_entry(frontend, parser_state, doc_params, list_parent, entry)?; let globals = frontend.layout.state.globals.clone();
on_button(button, entry); let button = self.mount_entry(frontend, parser_state, &doc_params(globals.clone()), &entry)?;
button.on_click(on_app_click(
frontend.tasks.clone(),
globals.clone(),
entry.clone(),
state.clone(),
tasks.clone(),
));
} }
Ok(()) Ok(())
} }
} }

View File

@@ -26,7 +26,7 @@
</template> </template>
<template name="Overlay"> <template name="Overlay">
<Button macro="button_style" id="overlay_${idx}" <Button macro="button_style" id="overlay_${idx}"
tooltip="WATCH.TOGGLE_FOR_CURRENT_SET" _press="::EditModeOverlayToggle ${idx}" tooltip="WATCH.TOGGLE_FOR_CURRENT_SET" _press="::EditModeOverlayToggle ${idx}"
align_items="center" align_items="center"
height="40"> height="40">
@@ -44,6 +44,10 @@
</Button> </Button>
</template> </template>
<template name="VerticalSeparator">
<rectangle width="2" height="100%" color="~color_accent" />
</template>
<!-- <!--
[!!!!!!!!] Disclaimer [!!!!!!!!] [!!!!!!!!] Disclaimer [!!!!!!!!]
Elements with id="norm_*" show in normal mode. Elements with id="norm_*" show in normal mode.
@@ -116,11 +120,11 @@
</div> </div>
<div flex_direction="column" align_items="center" justify_content="center"> <div flex_direction="column" align_items="center" justify_content="center">
<div id="toolbox" gap="8" width="100%" max_width="400" flex_direction="row" flex_wrap="wrap"> <div id="toolbox" gap="8" width="100%" max_width="400" flex_direction="row" flex_wrap="wrap">
<Button id="btn_keyboard" height="40" macro="button_style" tooltip="WATCH.TOGGLE_FOR_CURRENT_SET" _press="::OverlayToggle kbd" > <Button id="btn_keyboard" height="40" macro="button_style" tooltip="WATCH.TOGGLE_FOR_CURRENT_SET" _press="::OverlayToggle kbd">
<sprite src_builtin="watch/keyboard.svg" width="32" height="32" /> <sprite src_builtin="watch/keyboard.svg" width="32" height="32" />
<label translation="EDIT_MODE.KEYBOARD" size="18" /> <label translation="EDIT_MODE.KEYBOARD" size="18" />
</Button> </Button>
<!-- Src here may be changed, but maintain `OverlayCategor` order: Panel, Screen, Mirror, WayVR --> <!-- Src here may be changed, but maintain `OverlayCategory` order: Panel, Screen, Mirror, WayVR -->
<Overlay src="edit/panel.svg" idx="0" /> <Overlay src="edit/panel.svg" idx="0" />
<Overlay src="edit/screen.svg" idx="1" /> <Overlay src="edit/screen.svg" idx="1" />
<Overlay src="edit/mirror.svg" idx="2" /> <Overlay src="edit/mirror.svg" idx="2" />
@@ -131,29 +135,32 @@
</rectangle> </rectangle>
<!-- Bottom buttons --> <!-- Bottom buttons -->
<div flex_direction="row" gap="4"> <div flex_direction="row" gap="8">
<Button id="btn_dashboard" macro="button_style" _press="::DashToggle" tooltip="WATCH.DASHBOARD" tooltip_side="top" > <div gap="4">
<sprite color="~text_color" width="40" height="40" src="watch/wayvr_dashboard_mono.svg" /> <Button id="btn_dashboard" macro="button_style" _press="::DashToggle" tooltip="WATCH.DASHBOARD" tooltip_side="top">
</Button> <sprite color="~text_color" width="40" height="40" src="watch/wayvr_dashboard_mono.svg" />
<div id="edit_delete" display="none">
<Button macro="button_style" _long_release="::EditModeDeleteSet" tooltip="WATCH.LONG_PRESS_TO_DELETE_SET" tooltip_side="top" border_color="~color_danger_translucent" color="~color_danger_40" color2="~color_danger_10">
<sprite color="~text_color" width="40" height="40" src="edit/delete.svg" />
</Button> </Button>
<Button id="btn_edit_mode" macro="button_style" _press="::EditToggle" tooltip="WATCH.EDIT_MODE" tooltip_side="top">
<sprite color="~text_color" width="40" height="40" src="watch/edit.svg" />
</Button>
<div id="edit_delete" display="none">
<Button macro="button_style" _long_release="::EditModeDeleteSet" tooltip="WATCH.LONG_PRESS_TO_DELETE_SET" tooltip_side="top" border_color="~color_danger_translucent" color="~color_danger_40" color2="~color_danger_10">
<sprite color="~text_color" width="40" height="40" src="edit/delete.svg" />
</Button>
</div>
<div id="edit_add" display="none">
<Button macro="button_style" _press="::EditModeAddSet" tooltip="WATCH.ADD_NEW_SET" tooltip_side="top">
<sprite color="~text_color" width="40" height="40" src="edit/add.svg" />
</Button>
</div>
</div> </div>
<div id="sets"> <VerticalSeparator />
<div id="sets" gap="4">
<Set idx="0" display="1" /> <Set idx="0" display="1" />
<!-- Will populate additional <Set> tags at runtime --> <!-- Will populate additional <Set> tags at runtime -->
</div> </div>
<div id="edit_add" display="none">
<Button macro="button_style" _press="::EditModeAddSet" tooltip="WATCH.ADD_NEW_SET" tooltip_side="top">
<sprite color="~text_color" width="40" height="40" src="edit/add.svg" />
</Button>
</div>
<Button id="btn_edit_mode" macro="button_style" _press="::EditToggle" tooltip="WATCH.EDIT_MODE" tooltip_side="top">
<sprite color="~text_color" width="40" height="40" src="watch/edit.svg" />
</Button>
</div> </div>
</div> </div>
</div> </div>
</elements> </elements>
</layout> </layout>