diff --git a/dash-frontend/assets/gui/dashboard.xml b/dash-frontend/assets/gui/dashboard.xml
index ed76a08..8852664 100644
--- a/dash-frontend/assets/gui/dashboard.xml
+++ b/dash-frontend/assets/gui/dashboard.xml
@@ -3,6 +3,7 @@
+
@@ -25,13 +26,6 @@
-
-
@@ -60,15 +54,29 @@
-
+
-
+
+
+
-
@@ -25,7 +24,6 @@
-
@@ -27,7 +25,6 @@
-
diff --git a/dash-frontend/assets/gui/tab/settings.xml b/dash-frontend/assets/gui/tab/settings.xml
index 7c442b7..5350a0e 100644
--- a/dash-frontend/assets/gui/tab/settings.xml
+++ b/dash-frontend/assets/gui/tab/settings.xml
@@ -1,5 +1,4 @@
-
@@ -46,7 +45,6 @@
-
diff --git a/dash-frontend/assets/gui/tab/t_tab_title.xml b/dash-frontend/assets/gui/tab/t_tab_title.xml
deleted file mode 100644
index a7f63e1..0000000
--- a/dash-frontend/assets/gui/tab/t_tab_title.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/dash-frontend/assets/gui/theme.xml b/dash-frontend/assets/gui/theme.xml
index 28f4e57..cbfcdab 100644
--- a/dash-frontend/assets/gui/theme.xml
+++ b/dash-frontend/assets/gui/theme.xml
@@ -2,6 +2,7 @@
+
\ No newline at end of file
diff --git a/dash-frontend/src/frontend.rs b/dash-frontend/src/frontend.rs
index ffa9b94..639e311 100644
--- a/dash-frontend/src/frontend.rs
+++ b/dash-frontend/src/frontend.rs
@@ -1,5 +1,6 @@
use std::{path::PathBuf, rc::Rc};
+use anyhow::Context;
use chrono::Timelike;
use glam::Vec2;
use wgui::{
@@ -10,8 +11,9 @@ use wgui::{
i18n::Translation,
layout::{Layout, LayoutParams, LayoutUpdateParams, LayoutUpdateResult, WidgetID},
parser::{Fetchable, ParseDocumentParams, ParserState},
+ renderer_vk::text::custom_glyph::CustomGlyphData,
task::Tasks,
- widget::{label::WidgetLabel, rectangle::WidgetRectangle},
+ widget::{label::WidgetLabel, rectangle::WidgetRectangle, sprite::WidgetSprite},
windowing::window::{WguiWindow, WguiWindowParams, WguiWindowParamsExtra, WguiWindowPlacement},
};
use wlx_common::{
@@ -22,7 +24,7 @@ use wlx_common::{
use crate::{
assets,
- tab::{apps::TabApps, games::TabGames, home::TabHome, monado::TabMonado, settings::TabSettings, Tab, TabType},
+ tab::{Tab, TabType, apps::TabApps, games::TabGames, home::TabHome, monado::TabMonado, settings::TabSettings},
util::{
popup_manager::{MountPopupParams, PopupManager, PopupManagerParams},
toast_manager::ToastManager,
@@ -32,8 +34,10 @@ use crate::{
};
pub struct FrontendWidgets {
- pub id_label_time: WidgetID,
- pub id_rect_content: WidgetID,
+ id_label_time: WidgetID,
+ id_rect_content: WidgetID,
+ id_sprite_titlebar_icon: WidgetID,
+ id_label_titlebar_title: WidgetID,
}
pub type FrontendTasks = Tasks;
@@ -148,6 +152,8 @@ impl Frontend {
let id_label_time = state.get_widget_id("label_time")?;
let id_rect_content = state.get_widget_id("rect_content")?;
+ let id_sprite_titlebar_icon = state.get_widget_id("sprite_titlebar_icon")?;
+ let id_label_titlebar_title = state.get_widget_id("label_titlebar_title")?;
let timestep = Timestep::new(60.0);
@@ -161,6 +167,8 @@ impl Frontend {
widgets: FrontendWidgets {
id_label_time,
id_rect_content,
+ id_sprite_titlebar_icon,
+ id_label_titlebar_title,
},
timestep,
interface: params.interface,
@@ -283,9 +291,10 @@ impl Frontend {
let mut common = c.common();
{
- let Some(mut label) = common.state.widgets.get_as::(self.widgets.id_label_time) else {
- anyhow::bail!("");
- };
+ let mut label = common
+ .state
+ .widgets
+ .cast_as::(self.widgets.id_label_time)?;
let now = chrono::Local::now();
let hours = now.hour();
@@ -370,11 +379,48 @@ impl Frontend {
Ok(())
}
+ fn set_tab_title(&mut self, translation: &str, icon: &str) -> anyhow::Result<()> {
+ let mut c = self.layout.start_common();
+ let mut common = c.common();
+
+ {
+ let mut label = common
+ .state
+ .widgets
+ .cast_as::(self.widgets.id_label_titlebar_title)?;
+ label.set_text(&mut common, Translation::from_translation_key(translation));
+ }
+
+ {
+ let mut sprite = common
+ .state
+ .widgets
+ .cast_as::(self.widgets.id_sprite_titlebar_icon)?;
+ sprite.set_content(
+ &mut common,
+ Some(CustomGlyphData::from_assets(&self.globals, AssetPath::BuiltIn(icon))?),
+ );
+ }
+
+ c.finish()?;
+ Ok(())
+ }
+
fn set_tab(&mut self, data: &mut T, tab_type: TabType) -> anyhow::Result<()> {
log::info!("Setting tab to {tab_type:?}");
let widget_content = self.state.fetch_widget(&self.layout.state, "content")?;
self.layout.remove_children(widget_content.id);
+ let (tab_translation, icon_path) = match tab_type {
+ TabType::Home => ("HOME_SCREEN", "dashboard/home.svg"),
+ TabType::Apps => ("APPLICATIONS", "dashboard/apps.svg"),
+ TabType::Games => ("GAMES", "dashboard/games.svg"),
+ TabType::Monado => ("MONADO_RUNTIME", "dashboard/monado.svg"),
+ TabType::Settings => ("SETTINGS", "dashboard/settings.svg"),
+ };
+
+ self.set_tab_title(tab_translation, icon_path)?;
+
let tab: Box> = match tab_type {
TabType::Home => Box::new(TabHome::new(self, widget_content.id, data)?),
TabType::Apps => Box::new(TabApps::new(self, widget_content.id, data)?),
diff --git a/uidev/src/testbed/testbed_generic.rs b/uidev/src/testbed/testbed_generic.rs
index c577117..1e4b25e 100644
--- a/uidev/src/testbed/testbed_generic.rs
+++ b/uidev/src/testbed/testbed_generic.rs
@@ -55,8 +55,7 @@ fn button_click_callback(
) -> ButtonClickCallback {
Rc::new(move |common, _e| {
label
- .get_as::()
- .unwrap()
+ .cast::()?
.set_text(common, Translation::from_raw_text(text));
button.try_cast::()?.set_text(
@@ -169,7 +168,7 @@ impl TestbedGeneric {
let cb_first = parser_state.fetch_component_as::("cb_first")?;
let label = label_cur_option.widget.clone();
cb_first.on_toggle(Box::new(move |common, e| {
- let mut widget = label.get_as::().unwrap();
+ let mut widget = label.cast::()?;
let text = format!("checkbox toggle: {}", e.checked);
widget.set_text(common, Translation::from_raw_text(&text));
Ok(())
diff --git a/wayvr/src/gui/panel/label.rs b/wayvr/src/gui/panel/label.rs
index b13d804..e8a32b5 100644
--- a/wayvr/src/gui/panel/label.rs
+++ b/wayvr/src/gui/panel/label.rs
@@ -103,8 +103,7 @@ pub(super) fn setup_custom_label(
layout
.state
.widgets
- .get_as::(attribs.widget_id)
- .unwrap()
+ .cast_as::(attribs.widget_id)?
.set_text_simple(&mut globals, Translation::from_raw_text(pretty_tz));
// does not need to be dynamic
diff --git a/wgui/src/layout.rs b/wgui/src/layout.rs
index 823e448..45d2e37 100644
--- a/wgui/src/layout.rs
+++ b/wgui/src/layout.rs
@@ -75,6 +75,10 @@ impl WidgetMap {
self.0.get(handle)?.get_as::()
}
+ pub fn cast_as(&self, handle: WidgetID) -> anyhow::Result> {
+ self.get_as(handle).context("Widget cast failed")
+ }
+
pub fn get(&self, handle: WidgetID) -> Option<&Widget> {
self.0.get(handle)
}
diff --git a/wgui/src/widget/mod.rs b/wgui/src/widget/mod.rs
index d074a32..5f0e08a 100644
--- a/wgui/src/widget/mod.rs
+++ b/wgui/src/widget/mod.rs
@@ -1,3 +1,4 @@
+use anyhow::Context;
use glam::Vec2;
use taffy::{NodeId, TaffyTree};
@@ -248,10 +249,18 @@ impl dyn WidgetObj {
any.downcast_ref::()
}
+ pub fn cast(&self) -> anyhow::Result<&T> {
+ self.get_as().context("cast failed")
+ }
+
pub fn get_as_mut(&mut self) -> Option<&mut T> {
let any = self.as_any_mut();
any.downcast_mut::()
}
+
+ pub fn cast_mut(&mut self) -> anyhow::Result<&mut T> {
+ self.get_as_mut().context("cast failed")
+ }
}
struct InvokeData<'a, 'b, U1: 'static, U2: 'static> {