mirror of https://github.com/wayvr-org/wayvr.git
Welcome screen basics
This commit is contained in:
parent
1591466a8d
commit
1cc537807d
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Design Icons by Pictogrammers - https://github.com/Templarian/MaterialDesign/blob/master/LICENSE --><path fill="currentColor" d="M1.5 4v1.5c0 4.15 2.21 7.78 5.5 9.8V20h15v-2c0-2.66-5.33-4-8-4h-.25C9 14 5 10 5 5.5V4m9 0a4 4 0 0 0-4 4a4 4 0 0 0 4 4a4 4 0 0 0 4-4a4 4 0 0 0-4-4"/></svg>
|
||||||
|
After Width: | Height: | Size: 391 B |
|
|
@ -0,0 +1,22 @@
|
||||||
|
<layout>
|
||||||
|
<template name="Pip">
|
||||||
|
<rectangle id="pip" width="8" height="8" round="100%" color="${COLOR}"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<elements>
|
||||||
|
<div flex_direction="column" flex_grow="1" gap="16" align_items="center" overflow_y="hidden">
|
||||||
|
<!-- Content -->
|
||||||
|
<div id="content" flex_direction="column" flex_grow="1" align_items="center" justify_content="center" gap="16" overflow_y="scroll">
|
||||||
|
<!-- filled-in at runtime -->
|
||||||
|
</div>
|
||||||
|
<!-- Page buttons -->
|
||||||
|
<div flex_direction="row" gap="8" align_items="center">
|
||||||
|
<Button id="btn_prev" width="32" height="32" round="100%" sprite_src_builtin="dashboard/arrow_left.svg" />
|
||||||
|
<div id="pips" gap="4" align_items="center">
|
||||||
|
<!-- filled-in at runtime -->
|
||||||
|
</div>
|
||||||
|
<Button id="btn_next" width="32" height="32" round="100%" sprite_src_builtin="dashboard/arrow_right.svg" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</elements>
|
||||||
|
</layout>
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<layout>
|
||||||
|
<elements>
|
||||||
|
<image src_builtin="dashboard/splash.png" min_width="431" min_height="128" />
|
||||||
|
|
||||||
|
<rectangle color="#FFFFFF11" width="100%" height="2"/>
|
||||||
|
|
||||||
|
<label weight="bold" size="32" text="Hi there!"/>
|
||||||
|
<label weight="bold" size="20" text="Thank you for installing WayVR ❤️"/>
|
||||||
|
|
||||||
|
<label size="20" margin_top="16" text="Let us guide you through your first steps."/>
|
||||||
|
<label size="20" text="Press "Next" button below to get started."/>
|
||||||
|
</elements>
|
||||||
|
</layout>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<layout>
|
||||||
|
<elements>
|
||||||
|
<label text="Page 1"/>
|
||||||
|
</elements>
|
||||||
|
</layout>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<layout>
|
||||||
|
<elements>
|
||||||
|
<label text="Page 2" weight="bold" size="20"/>
|
||||||
|
</elements>
|
||||||
|
</layout>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<layout>
|
||||||
|
<elements>
|
||||||
|
<label text="Page 3" weight="bold" size="50"/>
|
||||||
|
</elements>
|
||||||
|
</layout>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<layout>
|
||||||
|
<elements>
|
||||||
|
<label text="Page 4" shadow="#000000" shadow_x="10" shadow_y="10" color="#FF00FF" size="30"/>
|
||||||
|
<label text="Page 4" shadow="#000000" shadow_x="10" shadow_y="10" weight="bold" color="#FFFF00" size="30"/>
|
||||||
|
<label text="Page 4" shadow="#000000" shadow_x="10" shadow_y="10" color="#00FFFF" size="30"/>
|
||||||
|
</elements>
|
||||||
|
</layout>
|
||||||
|
|
@ -101,6 +101,7 @@
|
||||||
"SCROLL_SPEED": "Scroll speed",
|
"SCROLL_SPEED": "Scroll speed",
|
||||||
"SELECT_VARIANT": "Select variant",
|
"SELECT_VARIANT": "Select variant",
|
||||||
"SETS_ON_WATCH": "Sets on watch",
|
"SETS_ON_WATCH": "Sets on watch",
|
||||||
|
"SHOW_WELCOME_SCREEN": "Show welcome screen",
|
||||||
"SKYBOX": "Skybox",
|
"SKYBOX": "Skybox",
|
||||||
"SKYMAP_ALREADY_DOWNLOADED": "This skymap is already downloaded. Select desired action.",
|
"SKYMAP_ALREADY_DOWNLOADED": "This skymap is already downloaded. Select desired action.",
|
||||||
"SPACE_DRAG_MULTIPLIER": "Space drag multiplier",
|
"SPACE_DRAG_MULTIPLIER": "Space drag multiplier",
|
||||||
|
|
@ -154,6 +155,7 @@
|
||||||
},
|
},
|
||||||
"GAMES": "Games",
|
"GAMES": "Games",
|
||||||
"GENERAL_SETTINGS": "General settings",
|
"GENERAL_SETTINGS": "General settings",
|
||||||
|
"GETTING_STARTED": "Getting started",
|
||||||
"HEIGHT": "Height",
|
"HEIGHT": "Height",
|
||||||
"HELLO": "Hello!",
|
"HELLO": "Hello!",
|
||||||
"HELLO_USER": "Hello, {USER}!",
|
"HELLO_USER": "Hello, {USER}!",
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ use wlx_common::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assets,
|
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::{
|
util::{
|
||||||
popup_manager::{MountPopupOnceParams, PopupManager, PopupManagerParams},
|
popup_manager::{MountPopupOnceParams, PopupManager, PopupManagerParams},
|
||||||
toast_manager::ToastManager,
|
toast_manager::ToastManager,
|
||||||
|
|
@ -390,6 +393,7 @@ impl<T: 'static> Frontend<T> {
|
||||||
self.layout.remove_children(widget_content.id);
|
self.layout.remove_children(widget_content.id);
|
||||||
|
|
||||||
let (tab_translation, icon_path) = match tab_type {
|
let (tab_translation, icon_path) = match tab_type {
|
||||||
|
TabType::Welcome => ("GETTING_STARTED", "dashboard/welcome.svg"),
|
||||||
TabType::Home => ("HOME_SCREEN", "dashboard/home.svg"),
|
TabType::Home => ("HOME_SCREEN", "dashboard/home.svg"),
|
||||||
TabType::Apps => ("APPLICATIONS", "dashboard/apps.svg"),
|
TabType::Apps => ("APPLICATIONS", "dashboard/apps.svg"),
|
||||||
TabType::Games => ("GAMES", "dashboard/games.svg"),
|
TabType::Games => ("GAMES", "dashboard/games.svg"),
|
||||||
|
|
@ -400,6 +404,7 @@ impl<T: 'static> Frontend<T> {
|
||||||
self.set_tab_title(tab_translation, icon_path)?;
|
self.set_tab_title(tab_translation, icon_path)?;
|
||||||
|
|
||||||
let tab: Box<dyn Tab<T>> = match tab_type {
|
let tab: Box<dyn Tab<T>> = 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::Home => Box::new(TabHome::new(self, widget_content.id, data)?),
|
||||||
TabType::Apps => Box::new(TabApps::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)?),
|
TabType::Games => Box::new(TabGames::new(self, widget_content.id)?),
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ pub mod games;
|
||||||
pub mod home;
|
pub mod home;
|
||||||
pub mod monado;
|
pub mod monado;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
|
pub mod welcome;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum TabType {
|
pub enum TabType {
|
||||||
|
|
@ -13,6 +14,7 @@ pub enum TabType {
|
||||||
Games,
|
Games,
|
||||||
Monado,
|
Monado,
|
||||||
Settings,
|
Settings,
|
||||||
|
Welcome,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Tab<T> {
|
pub trait Tab<T> {
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ enum Task {
|
||||||
RestartSoftware,
|
RestartSoftware,
|
||||||
RemoveAutostartApp(Rc<str>),
|
RemoveAutostartApp(Rc<str>),
|
||||||
SetTab(TabNameEnum),
|
SetTab(TabNameEnum),
|
||||||
|
ShowWelcomeScreen,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SettingsMountParams<'a> {
|
struct SettingsMountParams<'a> {
|
||||||
|
|
@ -136,6 +137,9 @@ impl<T> Tab<T> for TabSettings<T> {
|
||||||
Task::SetTab(tab) => {
|
Task::SetTab(tab) => {
|
||||||
self.set_tab(frontend, data, tab)?;
|
self.set_tab(frontend, data, tab)?;
|
||||||
}
|
}
|
||||||
|
Task::ShowWelcomeScreen => {
|
||||||
|
self.frontend_tasks.push(FrontendTask::SetTab(TabType::Welcome));
|
||||||
|
}
|
||||||
Task::UpdateBool(setting, n) => {
|
Task::UpdateBool(setting, n) => {
|
||||||
self.tasks.push(Task::SettingUpdated(setting));
|
self.tasks.push(Task::SettingUpdated(setting));
|
||||||
if let Some(task) = setting.get_frontend_task() {
|
if let Some(task) = setting.get_frontend_task() {
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,13 @@ impl State {
|
||||||
"dashboard/refresh.svg",
|
"dashboard/refresh.svg",
|
||||||
Task::RestartSoftware,
|
Task::RestartSoftware,
|
||||||
)?;
|
)?;
|
||||||
|
options_danger_button(
|
||||||
|
par.mp,
|
||||||
|
c,
|
||||||
|
"APP_SETTINGS.SHOW_WELCOME_SCREEN",
|
||||||
|
"dashboard/welcome.svg",
|
||||||
|
Task::ShowWelcomeScreen,
|
||||||
|
)?;
|
||||||
Ok(State {})
|
Ok(State {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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<T> {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub state: ParserState,
|
||||||
|
marker: PhantomData<T>,
|
||||||
|
tasks: Tasks<Task>,
|
||||||
|
current_page: u8,
|
||||||
|
id_pips: WidgetID,
|
||||||
|
id_content: WidgetID,
|
||||||
|
}
|
||||||
|
|
||||||
|
const PAGE_COUNT: u8 = 5; // 0-4 inclusive
|
||||||
|
|
||||||
|
impl<T> Tab<T> for TabWelcome<T> {
|
||||||
|
fn get_type(&self) -> TabType {
|
||||||
|
TabType::Welcome
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, frontend: &mut Frontend<T>, _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<T> TabWelcome<T> {
|
||||||
|
pub fn new(frontend: &mut Frontend<T>, parent_id: WidgetID, _data: &mut T) -> anyhow::Result<Self> {
|
||||||
|
let state = wgui::parser::parse_from_assets(&doc_params(&frontend.globals), &mut frontend.layout, parent_id)?;
|
||||||
|
|
||||||
|
let tasks = Tasks::<Task>::new();
|
||||||
|
|
||||||
|
let btn_prev = state.fetch_component_as::<ComponentButton>("btn_prev")?;
|
||||||
|
let btn_next = state.fetch_component_as::<ComponentButton>("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<str>, Rc<str>>::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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue