mirror of https://github.com/wayvr-org/wayvr.git
dash-frontend: ViewTrait, refactoring, `download_file::View` (wip)
This commit is contained in:
parent
24e3099b7b
commit
2035d9ba76
|
|
@ -0,0 +1,11 @@
|
||||||
|
<layout>
|
||||||
|
<elements>
|
||||||
|
<div align_items="center" justify_content="center">
|
||||||
|
<div flex_direction="column" gap="8">
|
||||||
|
<label translation="DOWNLOADING_FILE" size="14"/>
|
||||||
|
<label id="label_target_path" />
|
||||||
|
<label id="label_progress"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</elements>
|
||||||
|
</layout>
|
||||||
|
|
@ -142,6 +142,8 @@
|
||||||
"CREATION_DATE": "Creation date",
|
"CREATION_DATE": "Creation date",
|
||||||
"DEBUG_INFO": "Debug info",
|
"DEBUG_INFO": "Debug info",
|
||||||
"DISPLAY_BRIGHTNESS": "Display brightness",
|
"DISPLAY_BRIGHTNESS": "Display brightness",
|
||||||
|
"DOWNLOADER": "Downloader",
|
||||||
|
"DOWNLOADING_FILE": "Downloading file...",
|
||||||
"FAILED_TO_LAUNCH_APPLICATION": "Failed to launch a application:",
|
"FAILED_TO_LAUNCH_APPLICATION": "Failed to launch a application:",
|
||||||
"GAME_LAUNCHED": "Game launched",
|
"GAME_LAUNCHED": "Game launched",
|
||||||
"GAME_LIST": {
|
"GAME_LIST": {
|
||||||
|
|
@ -170,6 +172,7 @@
|
||||||
"REMOVE": "Remove",
|
"REMOVE": "Remove",
|
||||||
"SETTINGS": "Settings",
|
"SETTINGS": "Settings",
|
||||||
"SHOW": "Show",
|
"SHOW": "Show",
|
||||||
|
"TARGET_PATH": "Target path",
|
||||||
"TERMINATE_PROCESS": "Terminate process",
|
"TERMINATE_PROCESS": "Terminate process",
|
||||||
"VERSION": "Version",
|
"VERSION": "Version",
|
||||||
"WIDTH": "Width"
|
"WIDTH": "Width"
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
frontend::Frontend,
|
frontend::Frontend,
|
||||||
tab::{Tab, TabType},
|
tab::{Tab, TabType},
|
||||||
util::steam_utils::SteamUtils,
|
util::steam_utils::SteamUtils,
|
||||||
views::{game_list, running_games_list},
|
views::{ViewTrait, ViewUpdateParams, game_list, running_games_list},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct TabGames<T> {
|
pub struct TabGames<T> {
|
||||||
|
|
@ -19,7 +19,6 @@ pub struct TabGames<T> {
|
||||||
|
|
||||||
view_game_list: game_list::View,
|
view_game_list: game_list::View,
|
||||||
view_running_games_list: running_games_list::View,
|
view_running_games_list: running_games_list::View,
|
||||||
steam_utils: SteamUtils,
|
|
||||||
marker: PhantomData<T>,
|
marker: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,9 +28,11 @@ impl<T> Tab<T> for TabGames<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, frontend: &mut Frontend<T>, time_ms: u32, _data: &mut T) -> anyhow::Result<()> {
|
fn update(&mut self, frontend: &mut Frontend<T>, time_ms: u32, _data: &mut T) -> anyhow::Result<()> {
|
||||||
self
|
self.view_game_list.update(&mut ViewUpdateParams {
|
||||||
.view_game_list
|
layout: &mut frontend.layout,
|
||||||
.update(&mut frontend.layout, &mut self.steam_utils, &frontend.executor)?;
|
executor: &mut frontend.executor,
|
||||||
|
})?;
|
||||||
|
|
||||||
self.view_running_games_list.update(&mut frontend.layout, time_ms)?;
|
self.view_running_games_list.update(&mut frontend.layout, time_ms)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -54,16 +55,17 @@ impl<T> TabGames<T> {
|
||||||
let game_list_parent = state.get_widget_id("game_list_parent")?;
|
let game_list_parent = state.get_widget_id("game_list_parent")?;
|
||||||
let id_running_games_list_parent = state.get_widget_id("running_games_list_parent")?;
|
let id_running_games_list_parent = state.get_widget_id("running_games_list_parent")?;
|
||||||
|
|
||||||
|
let mut steam_utils = SteamUtils::new()?;
|
||||||
|
|
||||||
let view_game_list = game_list::View::new(game_list::Params {
|
let view_game_list = game_list::View::new(game_list::Params {
|
||||||
executor: frontend.executor.clone(),
|
executor: frontend.executor.clone(),
|
||||||
frontend_tasks: frontend.tasks.clone(),
|
frontend_tasks: frontend.tasks.clone(),
|
||||||
globals: globals.clone(),
|
globals: globals.clone(),
|
||||||
layout: &mut frontend.layout,
|
layout: &mut frontend.layout,
|
||||||
parent_id: game_list_parent,
|
parent_id: game_list_parent,
|
||||||
|
steam_utils: &steam_utils,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut steam_utils = SteamUtils::new()?;
|
|
||||||
|
|
||||||
let view_running_games_list = running_games_list::View::new(running_games_list::Params {
|
let view_running_games_list = running_games_list::View::new(running_games_list::Params {
|
||||||
globals: globals.clone(),
|
globals: globals.clone(),
|
||||||
layout: &mut frontend.layout,
|
layout: &mut frontend.layout,
|
||||||
|
|
@ -77,7 +79,6 @@ impl<T> TabGames<T> {
|
||||||
view_game_list,
|
view_game_list,
|
||||||
view_running_games_list,
|
view_running_games_list,
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
steam_utils,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,12 @@ use wgui::{
|
||||||
},
|
},
|
||||||
windowing::context_menu::{self, Blueprint, ContextMenu, TickResult},
|
windowing::context_menu::{self, Blueprint, ContextMenu, TickResult},
|
||||||
};
|
};
|
||||||
use wlx_common::{
|
use wlx_common::{config::GeneralConfig, config_io::ConfigRoot, dash_interface::RecenterMode};
|
||||||
async_executor::AsyncExecutor, config::GeneralConfig, config_io::ConfigRoot, dash_interface::RecenterMode,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
frontend::{Frontend, FrontendTask, FrontendTasks},
|
frontend::{Frontend, FrontendTask, FrontendTasks},
|
||||||
tab::{Tab, TabType, settings::macros::MacroParams},
|
tab::{Tab, TabType, settings::macros::MacroParams},
|
||||||
|
views::ViewUpdateParams,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
@ -86,13 +85,8 @@ struct SettingsMountParams<'a> {
|
||||||
parent_id: WidgetID,
|
parent_id: WidgetID,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SettingsUpdateParams<'a> {
|
|
||||||
layout: &'a mut Layout,
|
|
||||||
executor: &'a AsyncExecutor,
|
|
||||||
}
|
|
||||||
|
|
||||||
trait SettingsTab {
|
trait SettingsTab {
|
||||||
fn update(&mut self, _par: SettingsUpdateParams) -> anyhow::Result<()> {
|
fn update(&mut self, _par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +111,7 @@ impl<T> Tab<T> for TabSettings<T> {
|
||||||
|
|
||||||
fn update(&mut self, frontend: &mut Frontend<T>, _time_ms: u32, data: &mut T) -> anyhow::Result<()> {
|
fn update(&mut self, frontend: &mut Frontend<T>, _time_ms: u32, data: &mut T) -> anyhow::Result<()> {
|
||||||
if let Some(tab) = &mut self.current_tab {
|
if let Some(tab) = &mut self.current_tab {
|
||||||
tab.update(SettingsUpdateParams {
|
tab.update(&mut ViewUpdateParams {
|
||||||
layout: &mut frontend.layout,
|
layout: &mut frontend.layout,
|
||||||
executor: &frontend.executor,
|
executor: &frontend.executor,
|
||||||
})?;
|
})?;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use crate::{
|
||||||
SettingType, SettingsMountParams, SettingsTab,
|
SettingType, SettingsMountParams, SettingsTab,
|
||||||
macros::{options_category, options_checkbox},
|
macros::{options_category, options_checkbox},
|
||||||
},
|
},
|
||||||
views::skymap_list,
|
views::{ViewTrait, ViewUpdateParams, skymap_list},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
|
|
@ -11,8 +11,8 @@ pub struct State {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SettingsTab for State {
|
impl SettingsTab for State {
|
||||||
fn update(&mut self, par: super::SettingsUpdateParams) -> anyhow::Result<()> {
|
fn update(&mut self, par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||||
self.skymap_list.update(par.layout, par.executor)?;
|
self.skymap_list.update(par)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,10 @@ use wgui::{
|
||||||
};
|
};
|
||||||
use wlx_common::config::GeneralConfig;
|
use wlx_common::config::GeneralConfig;
|
||||||
|
|
||||||
use crate::frontend::{FrontendTask, FrontendTasks};
|
use crate::{
|
||||||
|
frontend::{FrontendTask, FrontendTasks},
|
||||||
|
views::{ViewTrait, ViewUpdateParams},
|
||||||
|
};
|
||||||
|
|
||||||
pub struct PopupManagerParams {
|
pub struct PopupManagerParams {
|
||||||
pub parent_id: WidgetID,
|
pub parent_id: WidgetID,
|
||||||
|
|
@ -45,13 +48,19 @@ pub struct PopupHandle {
|
||||||
state: Rc<RefCell<MountedPopupState>>,
|
state: Rc<RefCell<MountedPopupState>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PopupHolderState<ViewType> {
|
struct PopupHolderState<ViewType>
|
||||||
|
where
|
||||||
|
ViewType: ViewTrait,
|
||||||
|
{
|
||||||
popup_handle: PopupHandle,
|
popup_handle: PopupHandle,
|
||||||
view: Option<ViewType>,
|
view: Option<ViewType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can't use #[derive(Default)] due to the fact that ViewType can't be Default.
|
// we can't use #[derive(Default)] due to the fact that ViewType can't be Default.
|
||||||
impl<ViewType> Default for PopupHolderState<ViewType> {
|
impl<ViewType> Default for PopupHolderState<ViewType>
|
||||||
|
where
|
||||||
|
ViewType: ViewTrait,
|
||||||
|
{
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
popup_handle: Default::default(),
|
popup_handle: Default::default(),
|
||||||
|
|
@ -60,11 +69,17 @@ impl<ViewType> Default for PopupHolderState<ViewType> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PopupHolder<ViewType> {
|
pub struct PopupHolder<ViewType>
|
||||||
|
where
|
||||||
|
ViewType: ViewTrait,
|
||||||
|
{
|
||||||
state: Rc<RefCell<PopupHolderState<ViewType>>>,
|
state: Rc<RefCell<PopupHolderState<ViewType>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ViewType> Default for PopupHolder<ViewType> {
|
impl<ViewType> Default for PopupHolder<ViewType>
|
||||||
|
where
|
||||||
|
ViewType: ViewTrait,
|
||||||
|
{
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: Rc::new(RefCell::new(PopupHolderState::default())),
|
state: Rc::new(RefCell::new(PopupHolderState::default())),
|
||||||
|
|
@ -72,7 +87,10 @@ impl<ViewType> Default for PopupHolder<ViewType> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ViewType> PopupHolderState<ViewType> {
|
impl<ViewType> PopupHolderState<ViewType>
|
||||||
|
where
|
||||||
|
ViewType: ViewTrait,
|
||||||
|
{
|
||||||
fn close(&mut self) {
|
fn close(&mut self) {
|
||||||
self.view = None;
|
self.view = None;
|
||||||
self.popup_handle.close();
|
self.popup_handle.close();
|
||||||
|
|
@ -80,7 +98,10 @@ impl<ViewType> PopupHolderState<ViewType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can't derive(Clone) due to the fact that ViewType is non-cloneable
|
// we can't derive(Clone) due to the fact that ViewType is non-cloneable
|
||||||
impl<ViewType> Clone for PopupHolder<ViewType> {
|
impl<ViewType> Clone for PopupHolder<ViewType>
|
||||||
|
where
|
||||||
|
ViewType: ViewTrait,
|
||||||
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: self.state.clone(),
|
state: self.state.clone(),
|
||||||
|
|
@ -88,9 +109,17 @@ impl<ViewType> Clone for PopupHolder<ViewType> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ViewType> PopupHolder<ViewType> {
|
impl<ViewType> PopupHolder<ViewType>
|
||||||
pub fn close(&self) {
|
where
|
||||||
self.state.borrow_mut().close();
|
ViewType: ViewTrait,
|
||||||
|
{
|
||||||
|
pub fn update(&self, par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||||
|
let mut state = self.state.borrow_mut();
|
||||||
|
let Some(view) = &mut state.view else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
view.update(par)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_view(&self, handle: PopupHandle, view: ViewType) {
|
pub fn set_view(&self, handle: PopupHandle, view: ViewType) {
|
||||||
|
|
@ -131,15 +160,20 @@ impl<ViewType> PopupHolder<ViewType> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_close_callback(&self) -> Box<dyn Fn()>
|
pub fn get_close_callback(&self, layout: &Layout) -> Box<dyn FnOnce()>
|
||||||
where
|
where
|
||||||
ViewType: 'static,
|
ViewType: 'static,
|
||||||
{
|
{
|
||||||
|
let layout_tasks = layout.tasks.clone();
|
||||||
let weak_state = Rc::downgrade(&self.state);
|
let weak_state = Rc::downgrade(&self.state);
|
||||||
Box::new(move || {
|
Box::new(move || {
|
||||||
if let Some(state) = weak_state.upgrade() {
|
// we can't borrow State here yet, dispatch it.
|
||||||
state.borrow_mut().close();
|
layout_tasks.push(LayoutTask::Dispatch(Box::new(move |_common| {
|
||||||
}
|
if let Some(state) = weak_state.upgrade() {
|
||||||
|
state.borrow_mut().close();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use keyvalues_parser::{Obj, Vdf};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct SteamUtils {
|
pub struct SteamUtils {
|
||||||
steam_root: PathBuf,
|
steam_root: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ use wlx_common::{config::GeneralConfig, dash_interface::BoxDashInterface, deskto
|
||||||
use crate::{
|
use crate::{
|
||||||
frontend::{FrontendTask, FrontendTasks, SoundType},
|
frontend::{FrontendTask, FrontendTasks, SoundType},
|
||||||
util::popup_manager::{MountPopupOnceParams, PopupHolder},
|
util::popup_manager::{MountPopupOnceParams, PopupHolder},
|
||||||
|
views::{ViewTrait, ViewUpdateParams},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, EnumString, VariantNames, AsRefStr)]
|
#[derive(Clone, Copy, Eq, PartialEq, EnumString, VariantNames, AsRefStr)]
|
||||||
|
|
@ -69,7 +70,7 @@ struct LaunchParams<'a, T> {
|
||||||
interface: &'a mut BoxDashInterface<T>,
|
interface: &'a mut BoxDashInterface<T>,
|
||||||
auto_start: bool,
|
auto_start: bool,
|
||||||
data: &'a mut T,
|
data: &'a mut T,
|
||||||
on_launched: &'a dyn Fn(),
|
on_launched: Option<Box<dyn FnOnce()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct View {
|
pub struct View {
|
||||||
|
|
@ -94,7 +95,7 @@ pub struct View {
|
||||||
|
|
||||||
auto_start: bool,
|
auto_start: bool,
|
||||||
|
|
||||||
on_launched: Box<dyn Fn()>,
|
on_launched: Option<Box<dyn FnOnce()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Params<'a> {
|
pub struct Params<'a> {
|
||||||
|
|
@ -104,7 +105,13 @@ pub struct Params<'a> {
|
||||||
pub parent_id: WidgetID,
|
pub parent_id: WidgetID,
|
||||||
pub config: &'a GeneralConfig,
|
pub config: &'a GeneralConfig,
|
||||||
pub frontend_tasks: &'a FrontendTasks,
|
pub frontend_tasks: &'a FrontendTasks,
|
||||||
pub on_launched: Box<dyn Fn()>,
|
pub on_launched: Box<dyn FnOnce()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ViewTrait for View {
|
||||||
|
fn update(&mut self, _par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl View {
|
impl View {
|
||||||
|
|
@ -283,7 +290,7 @@ impl View {
|
||||||
entry: params.entry,
|
entry: params.entry,
|
||||||
frontend_tasks: params.frontend_tasks.clone(),
|
frontend_tasks: params.frontend_tasks.clone(),
|
||||||
globals: params.globals.clone(),
|
globals: params.globals.clone(),
|
||||||
on_launched: params.on_launched,
|
on_launched: Some(params.on_launched),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -319,7 +326,7 @@ impl View {
|
||||||
auto_start: self.auto_start,
|
auto_start: self.auto_start,
|
||||||
interface,
|
interface,
|
||||||
data,
|
data,
|
||||||
on_launched: &self.on_launched,
|
on_launched: self.on_launched.take(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -337,7 +344,7 @@ impl View {
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn launch<T>(params: LaunchParams<T>) -> anyhow::Result<()> {
|
fn launch<T>(mut params: LaunchParams<T>) -> anyhow::Result<()> {
|
||||||
let mut env = Vec::<String>::new();
|
let mut env = Vec::<String>::new();
|
||||||
|
|
||||||
if params.compositor_mode == CompositorMode::Native {
|
if params.compositor_mode == CompositorMode::Native {
|
||||||
|
|
@ -393,7 +400,9 @@ impl View {
|
||||||
|
|
||||||
params.frontend_tasks.push(FrontendTask::PlaySound(SoundType::Launch));
|
params.frontend_tasks.push(FrontendTask::PlaySound(SoundType::Launch));
|
||||||
|
|
||||||
(*params.on_launched)();
|
if let Some(on_launched) = params.on_launched.take() {
|
||||||
|
on_launched();
|
||||||
|
}
|
||||||
|
|
||||||
// we're done!
|
// we're done!
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -430,6 +439,7 @@ pub fn mount_popup(frontend_tasks: FrontendTasks, globals: WguiGlobals, entry: D
|
||||||
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
|
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
|
||||||
Translation::from_raw_text(&entry.app_name),
|
Translation::from_raw_text(&entry.app_name),
|
||||||
Box::new(move |data| {
|
Box::new(move |data| {
|
||||||
|
let on_launched = popup.get_close_callback(data.layout);
|
||||||
let view = View::new(Params {
|
let view = View::new(Params {
|
||||||
entry: entry.clone(),
|
entry: entry.clone(),
|
||||||
globals: &globals,
|
globals: &globals,
|
||||||
|
|
@ -437,11 +447,11 @@ pub fn mount_popup(frontend_tasks: FrontendTasks, globals: WguiGlobals, entry: D
|
||||||
parent_id: data.id_content,
|
parent_id: data.id_content,
|
||||||
frontend_tasks: &frontend_tasks,
|
frontend_tasks: &frontend_tasks,
|
||||||
config: data.config,
|
config: data.config,
|
||||||
on_launched: popup.get_close_callback(),
|
on_launched,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
popup.set_view(data.handle, view);
|
popup.set_view(data.handle, view);
|
||||||
Ok(popup.get_close_callback())
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
use crate::{
|
||||||
|
frontend::{FrontendTask, FrontendTasks},
|
||||||
|
util::popup_manager::{MountPopupOnceParams, PopupHolder},
|
||||||
|
views::{ViewTrait, ViewUpdateParams},
|
||||||
|
};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use wgui::{
|
||||||
|
assets::AssetPath,
|
||||||
|
globals::WguiGlobals,
|
||||||
|
i18n::Translation,
|
||||||
|
layout::{Layout, WidgetID},
|
||||||
|
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||||
|
task::Tasks,
|
||||||
|
widget::label::WidgetLabel,
|
||||||
|
};
|
||||||
|
use wlx_common::async_executor::AsyncExecutor;
|
||||||
|
|
||||||
|
pub struct Params<'a> {
|
||||||
|
pub globals: &'a WguiGlobals,
|
||||||
|
pub layout: &'a mut Layout,
|
||||||
|
pub executor: &'a AsyncExecutor,
|
||||||
|
pub parent_id: WidgetID,
|
||||||
|
pub target_path: PathBuf,
|
||||||
|
pub url: String,
|
||||||
|
pub on_close_request: Box<dyn FnOnce()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum Task {}
|
||||||
|
|
||||||
|
pub struct View {
|
||||||
|
id_parent: WidgetID,
|
||||||
|
globals: WguiGlobals,
|
||||||
|
tasks: Tasks<Task>,
|
||||||
|
executor: AsyncExecutor,
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
parser_state: ParserState,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ViewTrait for View {
|
||||||
|
fn update(&mut self, _par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||||
|
for task in self.tasks.drain() {
|
||||||
|
match task {}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl View {
|
||||||
|
pub fn new(par: Params) -> anyhow::Result<Self> {
|
||||||
|
let tasks = Tasks::<Task>::new();
|
||||||
|
|
||||||
|
let doc_params = ParseDocumentParams {
|
||||||
|
globals: par.globals.clone(),
|
||||||
|
path: AssetPath::BuiltIn("gui/view/download_file.xml"),
|
||||||
|
extra: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut parser_state = wgui::parser::parse_from_assets(&doc_params, par.layout, par.parent_id)?;
|
||||||
|
|
||||||
|
let str_target_path = par.globals.i18n().translate("TARGET_PATH");
|
||||||
|
|
||||||
|
{
|
||||||
|
let label_target_path = parser_state
|
||||||
|
.fetch_widget(&par.layout.state, "label_target_path")?
|
||||||
|
.widget;
|
||||||
|
label_target_path.cast::<WidgetLabel>()?.set_text(
|
||||||
|
&mut par.layout.common(),
|
||||||
|
Translation::from_raw_text_string(format!("{}: {}", str_target_path, par.target_path.display())),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
id_parent: par.parent_id,
|
||||||
|
tasks,
|
||||||
|
globals: par.globals.clone(),
|
||||||
|
executor: par.executor.clone(),
|
||||||
|
parser_state,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mount_popup(
|
||||||
|
frontend_tasks: FrontendTasks,
|
||||||
|
executor: AsyncExecutor,
|
||||||
|
globals: WguiGlobals,
|
||||||
|
popup: PopupHolder<View>,
|
||||||
|
target_path: PathBuf,
|
||||||
|
url: String,
|
||||||
|
) {
|
||||||
|
frontend_tasks
|
||||||
|
.clone()
|
||||||
|
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
|
||||||
|
Translation::from_translation_key("DOWNLOADER"),
|
||||||
|
Box::new(move |data| {
|
||||||
|
let on_close_request = popup.get_close_callback(data.layout);
|
||||||
|
let view = View::new(Params {
|
||||||
|
globals: &globals,
|
||||||
|
layout: data.layout,
|
||||||
|
executor: &executor,
|
||||||
|
parent_id: data.id_content,
|
||||||
|
on_close_request,
|
||||||
|
target_path,
|
||||||
|
url,
|
||||||
|
})?;
|
||||||
|
|
||||||
|
popup.set_view(data.handle, view);
|
||||||
|
Ok(popup.get_close_callback(data.layout))
|
||||||
|
}),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
popup_manager::{MountPopupOnceParams, PopupHolder},
|
popup_manager::{MountPopupOnceParams, PopupHolder},
|
||||||
steam_utils::{self, AppID, AppManifest},
|
steam_utils::{self, AppID, AppManifest},
|
||||||
},
|
},
|
||||||
views::game_cover,
|
views::{ViewTrait, ViewUpdateParams, game_cover},
|
||||||
};
|
};
|
||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
|
|
@ -35,13 +35,14 @@ pub struct Params<'a> {
|
||||||
pub layout: &'a mut Layout,
|
pub layout: &'a mut Layout,
|
||||||
pub parent_id: WidgetID,
|
pub parent_id: WidgetID,
|
||||||
pub frontend_tasks: &'a FrontendTasks,
|
pub frontend_tasks: &'a FrontendTasks,
|
||||||
pub on_launched: Box<dyn Fn()>,
|
pub on_launched: Box<dyn FnOnce()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct View {
|
pub struct View {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
state: ParserState,
|
state: ParserState,
|
||||||
tasks: Tasks<Task>,
|
tasks: Tasks<Task>,
|
||||||
on_launched: Box<dyn Fn()>,
|
on_launched: Option<Box<dyn FnOnce()>>,
|
||||||
frontend_tasks: FrontendTasks,
|
frontend_tasks: FrontendTasks,
|
||||||
|
|
||||||
game_cover_view_common: game_cover::ViewCommon,
|
game_cover_view_common: game_cover::ViewCommon,
|
||||||
|
|
@ -49,6 +50,30 @@ pub struct View {
|
||||||
app_id: AppID,
|
app_id: AppID,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ViewTrait for View {
|
||||||
|
fn update(&mut self, par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||||
|
loop {
|
||||||
|
let tasks = self.tasks.drain();
|
||||||
|
if tasks.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for task in tasks {
|
||||||
|
match task {
|
||||||
|
Task::FillAppDetails(details) => self.action_fill_app_details(&mut par.layout, details)?,
|
||||||
|
Task::Launch => self.action_launch(),
|
||||||
|
Task::SetCoverArt(cover_art) => {
|
||||||
|
let _ = self
|
||||||
|
.view_cover
|
||||||
|
.set_cover_art(&mut self.game_cover_view_common, &mut par.layout, &cover_art);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl View {
|
impl View {
|
||||||
async fn fetch_details(executor: AsyncExecutor, tasks: Tasks<Task>, app_id: AppID) {
|
async fn fetch_details(executor: AsyncExecutor, tasks: Tasks<Task>, app_id: AppID) {
|
||||||
let Some(details) = cached_fetcher::get_app_details_json(executor, app_id).await else {
|
let Some(details) = cached_fetcher::get_app_details_json(executor, app_id).await else {
|
||||||
|
|
@ -105,7 +130,7 @@ impl View {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
state,
|
state,
|
||||||
tasks,
|
tasks,
|
||||||
on_launched: params.on_launched,
|
on_launched: Some(params.on_launched),
|
||||||
frontend_tasks: params.frontend_tasks.clone(),
|
frontend_tasks: params.frontend_tasks.clone(),
|
||||||
game_cover_view_common: game_cover::ViewCommon::new(params.globals.clone()),
|
game_cover_view_common: game_cover::ViewCommon::new(params.globals.clone()),
|
||||||
view_cover,
|
view_cover,
|
||||||
|
|
@ -113,28 +138,6 @@ impl View {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, layout: &mut Layout) -> anyhow::Result<()> {
|
|
||||||
loop {
|
|
||||||
let tasks = self.tasks.drain();
|
|
||||||
if tasks.is_empty() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for task in tasks {
|
|
||||||
match task {
|
|
||||||
Task::FillAppDetails(details) => self.action_fill_app_details(layout, details)?,
|
|
||||||
Task::Launch => self.action_launch(),
|
|
||||||
Task::SetCoverArt(cover_art) => {
|
|
||||||
let _ = self
|
|
||||||
.view_cover
|
|
||||||
.set_cover_art(&mut self.game_cover_view_common, layout, &cover_art);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn action_fill_app_details(
|
fn action_fill_app_details(
|
||||||
&mut self,
|
&mut self,
|
||||||
layout: &mut Layout,
|
layout: &mut Layout,
|
||||||
|
|
@ -189,7 +192,9 @@ impl View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(*self.on_launched)();
|
if let Some(on_launched) = self.on_launched.take() {
|
||||||
|
on_launched();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,6 +210,7 @@ pub fn mount_popup(
|
||||||
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
|
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
|
||||||
Translation::from_raw_text(&manifest.name),
|
Translation::from_raw_text(&manifest.name),
|
||||||
Box::new(move |data| {
|
Box::new(move |data| {
|
||||||
|
let on_launched = popup.get_close_callback(data.layout);
|
||||||
let view = View::new(Params {
|
let view = View::new(Params {
|
||||||
manifest: manifest.clone(),
|
manifest: manifest.clone(),
|
||||||
executor: executor.clone(),
|
executor: executor.clone(),
|
||||||
|
|
@ -212,11 +218,11 @@ pub fn mount_popup(
|
||||||
layout: data.layout,
|
layout: data.layout,
|
||||||
parent_id: data.id_content,
|
parent_id: data.id_content,
|
||||||
frontend_tasks: &frontend_tasks,
|
frontend_tasks: &frontend_tasks,
|
||||||
on_launched: popup.get_close_callback(),
|
on_launched,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
popup.set_view(data.handle, view);
|
popup.set_view(data.handle, view);
|
||||||
Ok(popup.get_close_callback())
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ use crate::{
|
||||||
popup_manager::PopupHolder,
|
popup_manager::PopupHolder,
|
||||||
steam_utils::{self, AppID, SteamUtils},
|
steam_utils::{self, AppID, SteamUtils},
|
||||||
},
|
},
|
||||||
views::{self, game_cover},
|
views::{self, ViewTrait, ViewUpdateParams, game_cover},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
@ -41,6 +41,7 @@ pub struct Params<'a> {
|
||||||
pub frontend_tasks: FrontendTasks,
|
pub frontend_tasks: FrontendTasks,
|
||||||
pub layout: &'a mut Layout,
|
pub layout: &'a mut Layout,
|
||||||
pub parent_id: WidgetID,
|
pub parent_id: WidgetID,
|
||||||
|
pub steam_utils: &'a SteamUtils,
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_GAMES_PER_PAGE: u32 = 30;
|
const MAX_GAMES_PER_PAGE: u32 = 30;
|
||||||
|
|
@ -64,6 +65,31 @@ pub struct View {
|
||||||
page_count: u32,
|
page_count: u32,
|
||||||
id_label_page: WidgetID,
|
id_label_page: WidgetID,
|
||||||
view_launcher: PopupHolder<views::game_launcher::View>,
|
view_launcher: PopupHolder<views::game_launcher::View>,
|
||||||
|
steam_utils: SteamUtils,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ViewTrait for View {
|
||||||
|
fn update(&mut self, par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||||
|
loop {
|
||||||
|
let tasks = self.tasks.drain();
|
||||||
|
if tasks.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for task in tasks {
|
||||||
|
match task {
|
||||||
|
Task::LoadManifests => self.load_manifests(),
|
||||||
|
Task::FillPage(page_idx) => self.fill_page(&mut par.layout, &mut par.executor, page_idx)?,
|
||||||
|
Task::AppManifestClicked(manifest) => self.action_app_manifest_clicked(manifest)?,
|
||||||
|
Task::SetCoverArt(app_id, cover_art) => self.set_cover_art(&mut par.layout, app_id, cover_art),
|
||||||
|
Task::PrevPage => self.page_prev(),
|
||||||
|
Task::NextPage => self.page_next(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.view_launcher.update(par)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl View {
|
impl View {
|
||||||
|
|
@ -106,36 +132,9 @@ impl View {
|
||||||
page_count: 0,
|
page_count: 0,
|
||||||
id_label_page,
|
id_label_page,
|
||||||
view_launcher: Default::default(),
|
view_launcher: Default::default(),
|
||||||
|
steam_utils: params.steam_utils.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(
|
|
||||||
&mut self,
|
|
||||||
layout: &mut Layout,
|
|
||||||
steam_utils: &mut SteamUtils,
|
|
||||||
executor: &AsyncExecutor,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
loop {
|
|
||||||
let tasks = self.tasks.drain();
|
|
||||||
if tasks.is_empty() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for task in tasks {
|
|
||||||
match task {
|
|
||||||
Task::LoadManifests => self.load_manifests(steam_utils),
|
|
||||||
Task::FillPage(page_idx) => self.fill_page(layout, executor, page_idx)?,
|
|
||||||
Task::AppManifestClicked(manifest) => self.action_app_manifest_clicked(manifest)?,
|
|
||||||
Task::SetCoverArt(app_id, cover_art) => self.set_cover_art(layout, app_id, cover_art),
|
|
||||||
Task::PrevPage => self.page_prev(),
|
|
||||||
Task::NextPage => self.page_next(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.view_launcher.with_view_res(|view| view.update(layout))?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_game_list(
|
fn fill_game_list(
|
||||||
|
|
@ -178,8 +177,11 @@ fn fill_game_list(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl View {
|
impl View {
|
||||||
fn load_manifests(&mut self, steam_utils: &mut SteamUtils) {
|
fn load_manifests(&mut self) {
|
||||||
match steam_utils.list_installed_games(steam_utils::GameSortMethod::PlayDateDesc) {
|
match self
|
||||||
|
.steam_utils
|
||||||
|
.list_installed_games(steam_utils::GameSortMethod::PlayDateDesc)
|
||||||
|
{
|
||||||
Ok(manifests) => {
|
Ok(manifests) => {
|
||||||
self.page_count = (manifests.len() as u32 + MAX_GAMES_PER_PAGE) / MAX_GAMES_PER_PAGE;
|
self.page_count = (manifests.len() as u32 + MAX_GAMES_PER_PAGE) / MAX_GAMES_PER_PAGE;
|
||||||
self.all_manifests = manifests;
|
self.all_manifests = manifests;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
|
use wlx_common::async_executor::AsyncExecutor;
|
||||||
|
|
||||||
pub mod app_launcher;
|
pub mod app_launcher;
|
||||||
pub mod audio_settings;
|
pub mod audio_settings;
|
||||||
|
pub mod download_file;
|
||||||
pub mod game_cover;
|
pub mod game_cover;
|
||||||
pub mod game_launcher;
|
pub mod game_launcher;
|
||||||
pub mod game_list;
|
pub mod game_list;
|
||||||
|
|
@ -8,3 +11,12 @@ pub mod remote_skymap_list;
|
||||||
pub mod running_games_list;
|
pub mod running_games_list;
|
||||||
pub mod skymap_list;
|
pub mod skymap_list;
|
||||||
pub mod skymap_list_cell;
|
pub mod skymap_list_cell;
|
||||||
|
|
||||||
|
pub struct ViewUpdateParams<'a> {
|
||||||
|
pub layout: &'a mut wgui::layout::Layout,
|
||||||
|
pub executor: &'a AsyncExecutor,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ViewTrait {
|
||||||
|
fn update(&mut self, par: &mut ViewUpdateParams) -> anyhow::Result<()>;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{collections::HashMap, rc::Rc};
|
use std::{collections::HashMap, path::PathBuf, rc::Rc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
frontend::{FrontendTask, FrontendTasks},
|
frontend::{FrontendTask, FrontendTasks},
|
||||||
|
|
@ -6,6 +6,7 @@ use crate::{
|
||||||
networking::{self, skymap_catalog::SkymapResolution},
|
networking::{self, skymap_catalog::SkymapResolution},
|
||||||
popup_manager::{MountPopupOnceParams, PopupHolder},
|
popup_manager::{MountPopupOnceParams, PopupHolder},
|
||||||
},
|
},
|
||||||
|
views::{self, ViewTrait, ViewUpdateParams},
|
||||||
};
|
};
|
||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
|
|
@ -24,9 +25,10 @@ pub struct Params<'a> {
|
||||||
pub globals: &'a WguiGlobals,
|
pub globals: &'a WguiGlobals,
|
||||||
pub layout: &'a mut Layout,
|
pub layout: &'a mut Layout,
|
||||||
pub executor: &'a AsyncExecutor,
|
pub executor: &'a AsyncExecutor,
|
||||||
|
pub frontend_tasks: FrontendTasks,
|
||||||
pub parent_id: WidgetID,
|
pub parent_id: WidgetID,
|
||||||
pub entry: networking::skymap_catalog::SkymapCatalogEntry,
|
pub entry: networking::skymap_catalog::SkymapCatalogEntry,
|
||||||
pub on_close_request: Box<dyn Fn()>,
|
pub on_close_request: Box<dyn FnOnce()>,
|
||||||
pub preview_image: Option<CustomGlyphData>,
|
pub preview_image: Option<CustomGlyphData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,12 +40,15 @@ enum Task {
|
||||||
pub struct View {
|
pub struct View {
|
||||||
id_parent: WidgetID,
|
id_parent: WidgetID,
|
||||||
entry: networking::skymap_catalog::SkymapCatalogEntry,
|
entry: networking::skymap_catalog::SkymapCatalogEntry,
|
||||||
|
frontend_tasks: FrontendTasks,
|
||||||
globals: WguiGlobals,
|
globals: WguiGlobals,
|
||||||
tasks: Tasks<Task>,
|
tasks: Tasks<Task>,
|
||||||
executor: AsyncExecutor,
|
executor: AsyncExecutor,
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
parser_state: ParserState,
|
parser_state: ParserState,
|
||||||
|
|
||||||
|
popup_download: PopupHolder<views::download_file::View>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mount_resolution_button(
|
fn mount_resolution_button(
|
||||||
|
|
@ -62,6 +67,19 @@ fn mount_resolution_button(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ViewTrait for View {
|
||||||
|
fn update(&mut self, par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||||
|
for task in self.tasks.drain() {
|
||||||
|
match task {
|
||||||
|
Task::ResolutionClicked(skymap_resolution) => {
|
||||||
|
self.run_download(&mut par.layout, skymap_resolution)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl View {
|
impl View {
|
||||||
pub fn new(par: Params) -> anyhow::Result<Self> {
|
pub fn new(par: Params) -> anyhow::Result<Self> {
|
||||||
let tasks = Tasks::<Task>::new();
|
let tasks = Tasks::<Task>::new();
|
||||||
|
|
@ -150,15 +168,25 @@ impl View {
|
||||||
executor: par.executor.clone(),
|
executor: par.executor.clone(),
|
||||||
entry: par.entry,
|
entry: par.entry,
|
||||||
parser_state,
|
parser_state,
|
||||||
|
frontend_tasks: par.frontend_tasks,
|
||||||
|
popup_download: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, layout: &mut Layout) -> anyhow::Result<()> {
|
fn run_download(&mut self, layout: &mut Layout, resolution: SkymapResolution) -> anyhow::Result<()> {
|
||||||
for task in self.tasks.drain() {
|
let target_path = PathBuf::from(format!(""));
|
||||||
match task {
|
let Some(url) = self.entry.files.get_url_from_res(resolution) else {
|
||||||
Task::ResolutionClicked(skymap_resolution) => todo!(),
|
return Ok(());
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
views::download_file::mount_popup(
|
||||||
|
self.frontend_tasks.clone(),
|
||||||
|
self.executor.clone(),
|
||||||
|
self.globals.clone(),
|
||||||
|
self.popup_download.clone(),
|
||||||
|
target_path,
|
||||||
|
url,
|
||||||
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -176,18 +204,20 @@ pub fn mount_popup(
|
||||||
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
|
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
|
||||||
Translation::from_raw_text(&entry.name),
|
Translation::from_raw_text(&entry.name),
|
||||||
Box::new(move |data| {
|
Box::new(move |data| {
|
||||||
|
let on_close_request = popup.get_close_callback(data.layout);
|
||||||
let view = View::new(Params {
|
let view = View::new(Params {
|
||||||
globals: &globals,
|
globals: &globals,
|
||||||
layout: data.layout,
|
layout: data.layout,
|
||||||
executor: &executor,
|
executor: &executor,
|
||||||
parent_id: data.id_content,
|
parent_id: data.id_content,
|
||||||
entry,
|
entry,
|
||||||
on_close_request: popup.get_close_callback(),
|
on_close_request,
|
||||||
preview_image,
|
preview_image,
|
||||||
|
frontend_tasks: frontend_tasks.clone(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
popup.set_view(data.handle, view);
|
popup.set_view(data.handle, view);
|
||||||
Ok(popup.get_close_callback())
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ use crate::{
|
||||||
popup_manager::{MountPopupOnceParams, PopupHolder},
|
popup_manager::{MountPopupOnceParams, PopupHolder},
|
||||||
wgui_simple,
|
wgui_simple,
|
||||||
},
|
},
|
||||||
views,
|
views::{self, ViewTrait, ViewUpdateParams},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Params<'a> {
|
pub struct Params<'a> {
|
||||||
|
|
@ -29,7 +29,7 @@ pub struct Params<'a> {
|
||||||
pub layout: &'a mut Layout,
|
pub layout: &'a mut Layout,
|
||||||
pub executor: &'a AsyncExecutor,
|
pub executor: &'a AsyncExecutor,
|
||||||
pub parent_id: WidgetID,
|
pub parent_id: WidgetID,
|
||||||
pub on_close_request: Box<dyn Fn()>,
|
pub on_close_request: Box<dyn FnOnce()>,
|
||||||
pub frontend_tasks: FrontendTasks,
|
pub frontend_tasks: FrontendTasks,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,6 +58,44 @@ pub struct View {
|
||||||
popup_remote_skymap_downloader: PopupHolder<views::remote_skymap_downloader::View>,
|
popup_remote_skymap_downloader: PopupHolder<views::remote_skymap_downloader::View>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ViewTrait for View {
|
||||||
|
fn update(&mut self, par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||||
|
self.popup_remote_skymap_downloader.update(par)?;
|
||||||
|
|
||||||
|
for task in self.tasks.drain() {
|
||||||
|
match task {
|
||||||
|
Task::SetSkymapCatalog(skymap_catalog) => {
|
||||||
|
par.layout.remove_widget(self.id_loading);
|
||||||
|
match &*skymap_catalog {
|
||||||
|
Ok(skymap_catalog) => {
|
||||||
|
self.mount_catalog(par.layout, skymap_catalog)?;
|
||||||
|
}
|
||||||
|
Err(e) => wgui_simple::create_label_error(
|
||||||
|
par.layout,
|
||||||
|
self.id_parent,
|
||||||
|
format!("Failed to fetch skymap catalog: {:?}", e),
|
||||||
|
)?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Task::SetSkymapPreview((skymap_uuid, glyph_data)) => {
|
||||||
|
if let Some(cell) = &mut self
|
||||||
|
.mounted_cells
|
||||||
|
.iter_mut()
|
||||||
|
.find(|cell| cell.skymap_uuid == skymap_uuid)
|
||||||
|
{
|
||||||
|
cell.view.set_image(par.layout, glyph_data)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Task::ShowRemoteSkymapDownloader(skymap_uuid) => {
|
||||||
|
let preview_image = self.get_image_preview(skymap_uuid);
|
||||||
|
self.show_remote_skymap_downloader(skymap_uuid, preview_image)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl View {
|
impl View {
|
||||||
async fn skymap_catalog_request_wrapper(tasks: Tasks<Task>, executor: AsyncExecutor) {
|
async fn skymap_catalog_request_wrapper(tasks: Tasks<Task>, executor: AsyncExecutor) {
|
||||||
let res = networking::skymap_catalog::request_catalog(&executor).await;
|
let res = networking::skymap_catalog::request_catalog(&executor).await;
|
||||||
|
|
@ -176,44 +214,6 @@ impl View {
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, layout: &mut Layout) -> anyhow::Result<()> {
|
|
||||||
self
|
|
||||||
.popup_remote_skymap_downloader
|
|
||||||
.with_view_res(|view| view.update(layout))?;
|
|
||||||
|
|
||||||
for task in self.tasks.drain() {
|
|
||||||
match task {
|
|
||||||
Task::SetSkymapCatalog(skymap_catalog) => {
|
|
||||||
layout.remove_widget(self.id_loading);
|
|
||||||
match &*skymap_catalog {
|
|
||||||
Ok(skymap_catalog) => {
|
|
||||||
self.mount_catalog(layout, skymap_catalog)?;
|
|
||||||
}
|
|
||||||
Err(e) => wgui_simple::create_label_error(
|
|
||||||
layout,
|
|
||||||
self.id_parent,
|
|
||||||
format!("Failed to fetch skymap catalog: {:?}", e),
|
|
||||||
)?,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Task::SetSkymapPreview((skymap_uuid, glyph_data)) => {
|
|
||||||
if let Some(cell) = &mut self
|
|
||||||
.mounted_cells
|
|
||||||
.iter_mut()
|
|
||||||
.find(|cell| cell.skymap_uuid == skymap_uuid)
|
|
||||||
{
|
|
||||||
cell.view.set_image(layout, glyph_data)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Task::ShowRemoteSkymapDownloader(skymap_uuid) => {
|
|
||||||
let preview_image = self.get_image_preview(skymap_uuid);
|
|
||||||
self.show_remote_skymap_downloader(skymap_uuid, preview_image)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mount_popup(
|
pub fn mount_popup(
|
||||||
|
|
@ -227,17 +227,18 @@ pub fn mount_popup(
|
||||||
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
|
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
|
||||||
Translation::from_translation_key("APP_SETTINGS.DOWNLOAD_SKYMAPS"),
|
Translation::from_translation_key("APP_SETTINGS.DOWNLOAD_SKYMAPS"),
|
||||||
Box::new(move |data| {
|
Box::new(move |data| {
|
||||||
|
let on_close_request = popup.get_close_callback(data.layout);
|
||||||
let view = View::new(Params {
|
let view = View::new(Params {
|
||||||
globals: &globals,
|
globals: &globals,
|
||||||
layout: data.layout,
|
layout: data.layout,
|
||||||
executor: &executor,
|
executor: &executor,
|
||||||
parent_id: data.id_content,
|
parent_id: data.id_content,
|
||||||
on_close_request: popup.get_close_callback(),
|
on_close_request,
|
||||||
frontend_tasks,
|
frontend_tasks,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
popup.set_view(data.handle, view);
|
popup.set_view(data.handle, view);
|
||||||
Ok(popup.get_close_callback())
|
Ok(popup.get_close_callback(data.layout))
|
||||||
}),
|
}),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use wlx_common::{async_executor::AsyncExecutor, config_io};
|
||||||
use crate::{
|
use crate::{
|
||||||
frontend::FrontendTasks,
|
frontend::FrontendTasks,
|
||||||
util::{popup_manager::PopupHolder, wgui_simple},
|
util::{popup_manager::PopupHolder, wgui_simple},
|
||||||
views,
|
views::{self, ViewTrait, ViewUpdateParams},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
@ -38,6 +38,31 @@ pub struct View {
|
||||||
popup_remote_skymap_list: PopupHolder<views::remote_skymap_list::View>,
|
popup_remote_skymap_list: PopupHolder<views::remote_skymap_list::View>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ViewTrait for View {
|
||||||
|
fn update(&mut self, par: &mut ViewUpdateParams) -> anyhow::Result<()> {
|
||||||
|
self.popup_remote_skymap_list.update(par)?;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let tasks = self.tasks.drain();
|
||||||
|
if tasks.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for task in tasks {
|
||||||
|
match task {
|
||||||
|
Task::DownloadSkymaps => {
|
||||||
|
self.download_skymaps(&par.executor)?;
|
||||||
|
}
|
||||||
|
Task::Refresh => {
|
||||||
|
self.refresh(&mut par.layout)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl View {
|
impl View {
|
||||||
pub fn new(params: Params) -> anyhow::Result<Self> {
|
pub fn new(params: Params) -> anyhow::Result<Self> {
|
||||||
let doc_params = &ParseDocumentParams {
|
let doc_params = &ParseDocumentParams {
|
||||||
|
|
@ -72,31 +97,6 @@ impl View {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, layout: &mut Layout, executor: &AsyncExecutor) -> anyhow::Result<()> {
|
|
||||||
self
|
|
||||||
.popup_remote_skymap_list
|
|
||||||
.with_view_res(|view| view.update(layout))?;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let tasks = self.tasks.drain();
|
|
||||||
if tasks.is_empty() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for task in tasks {
|
|
||||||
match task {
|
|
||||||
Task::DownloadSkymaps => {
|
|
||||||
self.download_skymaps(executor)?;
|
|
||||||
}
|
|
||||||
Task::Refresh => {
|
|
||||||
self.refresh(layout)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn download_skymaps(&mut self, executor: &AsyncExecutor) -> anyhow::Result<()> {
|
fn download_skymaps(&mut self, executor: &AsyncExecutor) -> anyhow::Result<()> {
|
||||||
views::remote_skymap_list::mount_popup(
|
views::remote_skymap_list::mount_popup(
|
||||||
self.frontend_tasks.clone(),
|
self.frontend_tasks.clone(),
|
||||||
|
|
|
||||||
|
|
@ -461,7 +461,7 @@ fn handle_mouse_motion(
|
||||||
{
|
{
|
||||||
if !swipe_manager.is_current_swipe_empty() {
|
if !swipe_manager.is_current_swipe_empty() {
|
||||||
match &key.button_state {
|
match &key.button_state {
|
||||||
KeyButtonData::Key { vk, pressed } => {
|
KeyButtonData::Key { vk: _, pressed: _ } => {
|
||||||
if let Some(pos) = within_key_pos {
|
if let Some(pos) = within_key_pos {
|
||||||
// check because mouse motion can trigger despite hover being false
|
// check because mouse motion can trigger despite hover being false
|
||||||
if pos.x >= 0.0 && pos.x <= 1.0 && pos.y >= 0.0 && pos.y <= 1.0 {
|
if pos.x >= 0.0 && pos.x <= 1.0 && pos.y >= 0.0 && pos.y <= 1.0 {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue