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::{
assets::AssetPath,
@@ -33,7 +38,6 @@ pub struct TabApps<T> {
parser_state: ParserState,
state: Rc<RefCell<State>>,
entries: Vec<DesktopEntry>,
app_list: AppList,
tasks: Tasks<Task>,
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 {
launcher.update(&mut frontend.interface, data)?;
}
@@ -60,9 +68,10 @@ impl<T> Tab<T> for TabApps<T> {
}
}
#[derive(Default)]
struct AppList {
//data: Vec<ParserData>,
entries_to_mount: VecDeque<DesktopEntry>,
list_parent: WidgetPair,
}
// 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> {
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 tasks = Tasks::new();
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 mut app_list = AppList::default();
app_list.mount_entries(
frontend,
&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(),
));
},
)?;
let app_list = AppList {
entries_to_mount: entries.drain(..).collect(),
list_parent: app_list_parent,
};
Ok(Self {
app_list,
parser_state,
entries,
state,
tasks,
marker: PhantomData,
@@ -163,7 +156,6 @@ impl AppList {
frontend: &mut Frontend<T>,
parser_state: &mut ParserState,
doc_params: &ParseDocumentParams,
list_parent: &WidgetPair,
entry: &DesktopEntry,
) -> anyhow::Result<Rc<ComponentButton>> {
let mut template_params = HashMap::new();
@@ -193,25 +185,32 @@ impl AppList {
doc_params,
"AppEntry",
&mut frontend.layout,
list_parent.id,
self.list_parent.id,
template_params,
)?;
data.fetch_component_as::<ComponentButton>("button")
}
fn mount_entries<T>(
fn tick<T>(
&mut self,
frontend: &mut Frontend<T>,
entries: &[DesktopEntry],
state: &Rc<RefCell<State>>,
tasks: &Tasks<Task>,
parser_state: &mut ParserState,
doc_params: &ParseDocumentParams,
list_parent: &WidgetPair,
on_button: impl Fn(Rc<ComponentButton>, &DesktopEntry),
) -> anyhow::Result<()> {
for entry in entries {
let button = self.mount_entry(frontend, parser_state, doc_params, list_parent, entry)?;
on_button(button, entry);
if let Some(entry) = self.entries_to_mount.pop_front() {
let globals = frontend.layout.state.globals.clone();
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(())
}
}

View File

@@ -26,7 +26,7 @@
</template>
<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}"
align_items="center"
height="40">
@@ -44,6 +44,10 @@
</Button>
</template>
<template name="VerticalSeparator">
<rectangle width="2" height="100%" color="~color_accent" />
</template>
<!--
[!!!!!!!!] Disclaimer [!!!!!!!!]
Elements with id="norm_*" show in normal mode.
@@ -116,11 +120,11 @@
</div>
<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">
<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" />
<label translation="EDIT_MODE.KEYBOARD" size="18" />
</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/screen.svg" idx="1" />
<Overlay src="edit/mirror.svg" idx="2" />
@@ -131,29 +135,32 @@
</rectangle>
<!-- Bottom buttons -->
<div flex_direction="row" gap="4">
<Button id="btn_dashboard" macro="button_style" _press="::DashToggle" tooltip="WATCH.DASHBOARD" tooltip_side="top" >
<sprite color="~text_color" width="40" height="40" src="watch/wayvr_dashboard_mono.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" />
<div flex_direction="row" gap="8">
<div gap="4">
<Button id="btn_dashboard" macro="button_style" _press="::DashToggle" tooltip="WATCH.DASHBOARD" tooltip_side="top">
<sprite color="~text_color" width="40" height="40" src="watch/wayvr_dashboard_mono.svg" />
</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 id="sets">
<VerticalSeparator />
<div id="sets" gap="4">
<Set idx="0" display="1" />
<!-- Will populate additional <Set> tags at runtime -->
</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>
</elements>
</layout>
</layout>