diff --git a/dash-frontend/assets/dashboard/splash.png b/dash-frontend/assets/dashboard/splash.png new file mode 100644 index 00000000..15a9b387 Binary files /dev/null and b/dash-frontend/assets/dashboard/splash.png differ diff --git a/dash-frontend/assets/dashboard/welcome.svg b/dash-frontend/assets/dashboard/welcome.svg new file mode 100644 index 00000000..1e79ee67 --- /dev/null +++ b/dash-frontend/assets/dashboard/welcome.svg @@ -0,0 +1 @@ + diff --git a/dash-frontend/assets/gui/tab/welcome.xml b/dash-frontend/assets/gui/tab/welcome.xml new file mode 100644 index 00000000..4753bd37 --- /dev/null +++ b/dash-frontend/assets/gui/tab/welcome.xml @@ -0,0 +1,22 @@ + + + + +
+ +
+ +
+ +
+
+
+
+
diff --git a/dash-frontend/assets/gui/tab/welcome_page_0.xml b/dash-frontend/assets/gui/tab/welcome_page_0.xml new file mode 100644 index 00000000..ae29c5d2 --- /dev/null +++ b/dash-frontend/assets/gui/tab/welcome_page_0.xml @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/dash-frontend/assets/gui/tab/welcome_page_1.xml b/dash-frontend/assets/gui/tab/welcome_page_1.xml new file mode 100644 index 00000000..c7fa5d71 --- /dev/null +++ b/dash-frontend/assets/gui/tab/welcome_page_1.xml @@ -0,0 +1,5 @@ + + + + diff --git a/dash-frontend/assets/gui/tab/welcome_page_2.xml b/dash-frontend/assets/gui/tab/welcome_page_2.xml new file mode 100644 index 00000000..e25b5249 --- /dev/null +++ b/dash-frontend/assets/gui/tab/welcome_page_2.xml @@ -0,0 +1,5 @@ + + + + diff --git a/dash-frontend/assets/gui/tab/welcome_page_3.xml b/dash-frontend/assets/gui/tab/welcome_page_3.xml new file mode 100644 index 00000000..344cbe6e --- /dev/null +++ b/dash-frontend/assets/gui/tab/welcome_page_3.xml @@ -0,0 +1,5 @@ + + + + diff --git a/dash-frontend/assets/gui/tab/welcome_page_4.xml b/dash-frontend/assets/gui/tab/welcome_page_4.xml new file mode 100644 index 00000000..b7f18379 --- /dev/null +++ b/dash-frontend/assets/gui/tab/welcome_page_4.xml @@ -0,0 +1,7 @@ + + + + diff --git a/dash-frontend/assets/lang/en.json b/dash-frontend/assets/lang/en.json index 14b8d023..e48fe534 100644 --- a/dash-frontend/assets/lang/en.json +++ b/dash-frontend/assets/lang/en.json @@ -101,6 +101,7 @@ "SCROLL_SPEED": "Scroll speed", "SELECT_VARIANT": "Select variant", "SETS_ON_WATCH": "Sets on watch", + "SHOW_WELCOME_SCREEN": "Show welcome screen", "SKYBOX": "Skybox", "SKYMAP_ALREADY_DOWNLOADED": "This skymap is already downloaded. Select desired action.", "SPACE_DRAG_MULTIPLIER": "Space drag multiplier", @@ -154,6 +155,7 @@ }, "GAMES": "Games", "GENERAL_SETTINGS": "General settings", + "GETTING_STARTED": "Getting started", "HEIGHT": "Height", "HELLO": "Hello!", "HELLO_USER": "Hello, {USER}!", diff --git a/dash-frontend/src/frontend.rs b/dash-frontend/src/frontend.rs index 192cbc06..0b1f9bb0 100644 --- a/dash-frontend/src/frontend.rs +++ b/dash-frontend/src/frontend.rs @@ -26,7 +26,10 @@ use wlx_common::{ use crate::{ assets, - tab::{Tab, TabType, apps::TabApps, games::TabGames, home::TabHome, monado::TabMonado, settings::TabSettings}, + tab::{ + Tab, TabType, apps::TabApps, games::TabGames, home::TabHome, monado::TabMonado, settings::TabSettings, + welcome::TabWelcome, + }, util::{ popup_manager::{MountPopupOnceParams, PopupManager, PopupManagerParams}, toast_manager::ToastManager, @@ -390,6 +393,7 @@ impl Frontend { self.layout.remove_children(widget_content.id); let (tab_translation, icon_path) = match tab_type { + TabType::Welcome => ("GETTING_STARTED", "dashboard/welcome.svg"), TabType::Home => ("HOME_SCREEN", "dashboard/home.svg"), TabType::Apps => ("APPLICATIONS", "dashboard/apps.svg"), TabType::Games => ("GAMES", "dashboard/games.svg"), @@ -400,6 +404,7 @@ impl Frontend { self.set_tab_title(tab_translation, icon_path)?; let tab: Box> = match tab_type { + TabType::Welcome => Box::new(TabWelcome::new(self, widget_content.id, data)?), TabType::Home => Box::new(TabHome::new(self, widget_content.id, data)?), TabType::Apps => Box::new(TabApps::new(self, widget_content.id, data)?), TabType::Games => Box::new(TabGames::new(self, widget_content.id)?), diff --git a/dash-frontend/src/tab/mod.rs b/dash-frontend/src/tab/mod.rs index 68e7fb03..915019dc 100644 --- a/dash-frontend/src/tab/mod.rs +++ b/dash-frontend/src/tab/mod.rs @@ -5,6 +5,7 @@ pub mod games; pub mod home; pub mod monado; pub mod settings; +pub mod welcome; #[derive(Clone, Copy, Debug)] pub enum TabType { @@ -13,6 +14,7 @@ pub enum TabType { Games, Monado, Settings, + Welcome, } pub trait Tab { diff --git a/dash-frontend/src/tab/settings/mod.rs b/dash-frontend/src/tab/settings/mod.rs index ab32bdf1..1c0896f5 100644 --- a/dash-frontend/src/tab/settings/mod.rs +++ b/dash-frontend/src/tab/settings/mod.rs @@ -81,6 +81,7 @@ enum Task { RestartSoftware, RemoveAutostartApp(Rc), SetTab(TabNameEnum), + ShowWelcomeScreen, } struct SettingsMountParams<'a> { @@ -136,6 +137,9 @@ impl Tab for TabSettings { Task::SetTab(tab) => { self.set_tab(frontend, data, tab)?; } + Task::ShowWelcomeScreen => { + self.frontend_tasks.push(FrontendTask::SetTab(TabType::Welcome)); + } Task::UpdateBool(setting, n) => { self.tasks.push(Task::SettingUpdated(setting)); if let Some(task) = setting.get_frontend_task() { diff --git a/dash-frontend/src/tab/settings/tab_troubleshooting.rs b/dash-frontend/src/tab/settings/tab_troubleshooting.rs index 8635efe5..70ba2111 100644 --- a/dash-frontend/src/tab/settings/tab_troubleshooting.rs +++ b/dash-frontend/src/tab/settings/tab_troubleshooting.rs @@ -50,6 +50,13 @@ impl State { "dashboard/refresh.svg", Task::RestartSoftware, )?; + options_danger_button( + par.mp, + c, + "APP_SETTINGS.SHOW_WELCOME_SCREEN", + "dashboard/welcome.svg", + Task::ShowWelcomeScreen, + )?; Ok(State {}) } } diff --git a/dash-frontend/src/tab/welcome.rs b/dash-frontend/src/tab/welcome.rs new file mode 100644 index 00000000..40798c2a --- /dev/null +++ b/dash-frontend/src/tab/welcome.rs @@ -0,0 +1,147 @@ +use std::{collections::HashMap, marker::PhantomData, rc::Rc}; + +use wgui::{ + assets::AssetPath, + components::button::ComponentButton, + globals::WguiGlobals, + layout::{Layout, WidgetID}, + parser::{Fetchable, ParseDocumentParams, ParserState}, + task::Tasks, +}; + +use crate::{ + frontend::Frontend, + tab::{Tab, TabType}, +}; + +#[derive(Clone)] +#[allow(clippy::enum_variant_names)] +enum Task { + SetPage(u8), + SetPageNext, + SetPagePrev, +} + +pub struct TabWelcome { + #[allow(dead_code)] + pub state: ParserState, + marker: PhantomData, + tasks: Tasks, + current_page: u8, + id_pips: WidgetID, + id_content: WidgetID, +} + +const PAGE_COUNT: u8 = 5; // 0-4 inclusive + +impl Tab for TabWelcome { + fn get_type(&self) -> TabType { + TabType::Welcome + } + + fn update(&mut self, frontend: &mut Frontend, _time_ms: u32, _user_data: &mut T) -> anyhow::Result<()> { + for task in self.tasks.drain() { + match task { + Task::SetPage(page_num) => { + self.set_page(&mut frontend.layout, page_num)?; + } + Task::SetPageNext => { + if self.current_page < PAGE_COUNT - 1 { + self.tasks.push(Task::SetPage(self.current_page + 1)); + } + } + Task::SetPagePrev => { + if self.current_page > 0 { + self.tasks.push(Task::SetPage(self.current_page - 1)); + } + } + } + } + + Ok(()) + } +} + +fn doc_params(globals: &WguiGlobals) -> ParseDocumentParams<'_> { + ParseDocumentParams { + globals: globals.clone(), + path: AssetPath::BuiltIn("gui/tab/welcome.xml"), + extra: Default::default(), + } +} + +impl TabWelcome { + pub fn new(frontend: &mut Frontend, parent_id: WidgetID, _data: &mut T) -> anyhow::Result { + let state = wgui::parser::parse_from_assets(&doc_params(&frontend.globals), &mut frontend.layout, parent_id)?; + + let tasks = Tasks::::new(); + + let btn_prev = state.fetch_component_as::("btn_prev")?; + let btn_next = state.fetch_component_as::("btn_next")?; + + tasks.handle_button(&btn_prev, Task::SetPagePrev); + tasks.handle_button(&btn_next, Task::SetPageNext); + + let id_pips = state.get_widget_id("pips")?; + let id_content = state.get_widget_id("content")?; + + tasks.push(Task::SetPage(0)); + + Ok(Self { + state, + marker: PhantomData, + current_page: 0, + id_pips, + id_content, + tasks, + }) + } + + fn refresh_pips(&mut self, layout: &mut Layout) -> anyhow::Result<()> { + layout.remove_children(self.id_pips); + + let globals = layout.state.globals.clone(); + + for i in 0..PAGE_COUNT { + let mut vars = HashMap::, Rc>::new(); + let is_selected = i == self.current_page; + vars.insert( + Rc::from("COLOR"), + Rc::from(if is_selected { "#FFFFFF" } else { "#FFFFFF11" }), + ); + + self + .state + .instantiate_template(&doc_params(&globals), "Pip", layout, self.id_pips, vars)? + } + + Ok(()) + } + + fn fill_page(&mut self, layout: &mut Layout) -> anyhow::Result<()> { + layout.remove_children(self.id_content); + + let globals = layout.state.globals.clone(); + + let _ = wgui::parser::parse_from_assets( + &ParseDocumentParams { + globals, + path: AssetPath::BuiltIn(&format!("gui/tab/welcome_page_{}.xml", self.current_page)), + extra: Default::default(), + }, + layout, + self.id_content, + )?; + + Ok(()) + } + + fn set_page(&mut self, layout: &mut Layout, page_num: u8) -> anyhow::Result<()> { + self.current_page = page_num; + + self.refresh_pips(layout)?; + self.fill_page(layout)?; + + Ok(()) + } +}