mirror of https://github.com/wayvr-org/wayvr.git
dash-frontend: skymap downloader dialog
This commit is contained in:
parent
e5e798b599
commit
47bb5ab7a2
|
|
@ -0,0 +1,35 @@
|
|||
<layout>
|
||||
|
||||
<!--
|
||||
parameters:
|
||||
"text"
|
||||
|
||||
ids:
|
||||
"button"
|
||||
-->
|
||||
<template name="ResolutionButton">
|
||||
<Button id="button" sprite_src_builtin="dashboard/download.svg" text="${text}"/>
|
||||
</template>
|
||||
|
||||
<include src="../t_separator.xml"/>
|
||||
|
||||
<elements>
|
||||
<div gap="8" flex_direction="column" min_width="100%" overflow_y="scroll">
|
||||
<label id="label_author" weight="bold"/>
|
||||
<label id="label_description" wrap="1"/>
|
||||
<Separator/>
|
||||
<div gap="24" justify_content="center">
|
||||
<label id="label_creation_date"/>
|
||||
<label id="label_modification_date"/>
|
||||
<label id="label_version"/>
|
||||
</div>
|
||||
<div gap="8" flex_direction="column" align_items="center">
|
||||
<image id="image" width="500" height="250" round="8" border="2" border_color="~color_accent"/>
|
||||
|
||||
<div id="resolution_buttons" gap="8" flex_direction="row">
|
||||
<!-- filled-in at runtime -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</elements>
|
||||
</layout>
|
||||
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
<!--
|
||||
ids:
|
||||
"button"
|
||||
"image_preview"
|
||||
"label_title"
|
||||
"label_desc"
|
||||
-->
|
||||
<template name="Cell">
|
||||
<Button
|
||||
id="button"
|
||||
padding="8"
|
||||
round="8"
|
||||
flex_direction="column"
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@
|
|||
"VOLUME": "Volume"
|
||||
},
|
||||
"CLOSE_WINDOW": "Close window",
|
||||
"CREATION_DATE": "Creation date",
|
||||
"DEBUG_INFO": "Debug info",
|
||||
"DISPLAY_BRIGHTNESS": "Display brightness",
|
||||
"FAILED_TO_LAUNCH_APPLICATION": "Failed to launch a application:",
|
||||
|
|
@ -154,6 +155,7 @@
|
|||
"HELLO_USER": "Hello, {USER}!",
|
||||
"HIDE": "Hide",
|
||||
"HOME_SCREEN": "Home",
|
||||
"MODIFICATION_DATE": "Modification date",
|
||||
"MONADO_RUNTIME": "Monado runtime",
|
||||
"LOADING": "Loading...",
|
||||
"POPUP_ADD_DISPLAY": {
|
||||
|
|
@ -169,5 +171,6 @@
|
|||
"SETTINGS": "Settings",
|
||||
"SHOW": "Show",
|
||||
"TERMINATE_PROCESS": "Terminate process",
|
||||
"VERSION": "Version",
|
||||
"WIDTH": "Width"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,19 +6,28 @@ use crate::util::networking::{self, WAYVR_SKYMAPS_ROOT, http_client};
|
|||
|
||||
pub type SkymapUuid = uuid::Uuid;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum SkymapResolution {
|
||||
Res2k,
|
||||
Res4k,
|
||||
Res8k,
|
||||
Res16k,
|
||||
}
|
||||
|
||||
impl SkymapResolution {
|
||||
pub const fn get_display_str(&self) -> &'static str {
|
||||
match self {
|
||||
SkymapResolution::Res2k => "2K (6 MiB VRAM)",
|
||||
SkymapResolution::Res4k => "4K (24 MiB VRAM)",
|
||||
SkymapResolution::Res8k => "8K (96 MiB VRAM)",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct SkymapCatalogEntryFiles {
|
||||
pub size_16k: Option<String>, // "my_skymap_16k.png"
|
||||
pub size_8k: Option<String>, // "my_skymap_8k.png"
|
||||
pub size_4k: Option<String>, // "my_skymap_4k.png"
|
||||
pub size_2k: String, // we should have *at least* this
|
||||
pub size_8k: Option<String>, // "my_skymap_8k.png"
|
||||
pub size_4k: Option<String>, // "my_skymap_4k.png"
|
||||
pub size_2k: String, // we should have *at least* this
|
||||
pub preview: String,
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +41,6 @@ impl SkymapCatalogEntryFiles {
|
|||
SkymapResolution::Res2k => Some(&self.size_2k),
|
||||
SkymapResolution::Res4k => self.size_4k.as_ref(),
|
||||
SkymapResolution::Res8k => self.size_8k.as_ref(),
|
||||
SkymapResolution::Res16k => self.size_16k.as_ref(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ pub mod audio_settings;
|
|||
pub mod game_cover;
|
||||
pub mod game_launcher;
|
||||
pub mod game_list;
|
||||
pub mod remote_skymap_downloader;
|
||||
pub mod remote_skymap_list;
|
||||
pub mod running_games_list;
|
||||
pub mod skymap_list;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,199 @@
|
|||
use std::{collections::HashMap, rc::Rc};
|
||||
|
||||
use crate::{
|
||||
frontend::{FrontendTask, FrontendTasks},
|
||||
util::{
|
||||
networking::{self, skymap_catalog::SkymapResolution},
|
||||
popup_manager::{MountPopupOnceParams, PopupHolder},
|
||||
},
|
||||
};
|
||||
use wgui::{
|
||||
assets::AssetPath,
|
||||
components::button::ComponentButton,
|
||||
event::EventAlterables,
|
||||
globals::WguiGlobals,
|
||||
i18n::Translation,
|
||||
layout::{Layout, WidgetID},
|
||||
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||
renderer_vk::text::custom_glyph::CustomGlyphData,
|
||||
task::Tasks,
|
||||
widget::{image::WidgetImage, 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 entry: networking::skymap_catalog::SkymapCatalogEntry,
|
||||
pub on_close_request: Box<dyn Fn()>,
|
||||
pub preview_image: Option<CustomGlyphData>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
enum Task {
|
||||
ResolutionClicked(networking::skymap_catalog::SkymapResolution),
|
||||
}
|
||||
|
||||
pub struct View {
|
||||
id_parent: WidgetID,
|
||||
entry: networking::skymap_catalog::SkymapCatalogEntry,
|
||||
globals: WguiGlobals,
|
||||
tasks: Tasks<Task>,
|
||||
executor: AsyncExecutor,
|
||||
|
||||
#[allow(dead_code)]
|
||||
parser_state: ParserState,
|
||||
}
|
||||
|
||||
fn mount_resolution_button(
|
||||
parser_state: &mut ParserState,
|
||||
doc_params: &ParseDocumentParams,
|
||||
layout: &mut Layout,
|
||||
parent_id: WidgetID,
|
||||
res: SkymapResolution,
|
||||
tasks: &Tasks<Task>,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut t = HashMap::<Rc<str>, Rc<str>>::new();
|
||||
t.insert(Rc::from("text"), Rc::from(res.get_display_str()));
|
||||
let data = parser_state.realize_template(doc_params, "ResolutionButton", layout, parent_id, t)?;
|
||||
let button = data.fetch_component_as::<ComponentButton>("button")?;
|
||||
tasks.handle_button(&button, Task::ResolutionClicked(res));
|
||||
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/remote_skymap_downloader.xml"),
|
||||
extra: Default::default(),
|
||||
};
|
||||
|
||||
let mut parser_state = wgui::parser::parse_from_assets(&doc_params, par.layout, par.parent_id)?;
|
||||
let id_resolution_buttons = parser_state.get_widget_id("resolution_buttons")?;
|
||||
|
||||
let str_version = par.globals.i18n().translate("VERSION");
|
||||
let str_creation_date = par.globals.i18n().translate("CREATION_DATE");
|
||||
let str_modification_date = par.globals.i18n().translate("MODIFICATION_DATE");
|
||||
|
||||
{
|
||||
let mut alterables = EventAlterables::default();
|
||||
let image = parser_state.fetch_widget(&par.layout.state, "image")?.widget;
|
||||
let mut image = image.cast::<WidgetImage>()?;
|
||||
image.set_content(&mut alterables, par.preview_image);
|
||||
par.layout.process_alterables(alterables)?;
|
||||
}
|
||||
|
||||
// Set author label
|
||||
parser_state
|
||||
.fetch_widget_as::<WidgetLabel>(&par.layout.state, "label_author")?
|
||||
.set_text_simple(
|
||||
&mut par.globals.get(),
|
||||
Translation::from_raw_text_string(format!("by {}", par.entry.author)),
|
||||
);
|
||||
|
||||
// Set description label
|
||||
parser_state
|
||||
.fetch_widget_as::<WidgetLabel>(&par.layout.state, "label_description")?
|
||||
.set_text_simple(
|
||||
&mut par.globals.get(),
|
||||
Translation::from_raw_text(&par.entry.description),
|
||||
);
|
||||
|
||||
// Set version label
|
||||
parser_state
|
||||
.fetch_widget_as::<WidgetLabel>(&par.layout.state, "label_version")?
|
||||
.set_text_simple(
|
||||
&mut par.globals.get(),
|
||||
Translation::from_raw_text_string(format!("{}: {}", str_version, par.entry.version)),
|
||||
);
|
||||
|
||||
// Set creation date label
|
||||
parser_state
|
||||
.fetch_widget_as::<WidgetLabel>(&par.layout.state, "label_creation_date")?
|
||||
.set_text_simple(
|
||||
&mut par.globals.get(),
|
||||
Translation::from_raw_text_string(format!("{}: {}", str_creation_date, par.entry.created_at,)),
|
||||
);
|
||||
|
||||
// Set modification date label
|
||||
parser_state
|
||||
.fetch_widget_as::<WidgetLabel>(&par.layout.state, "label_modification_date")?
|
||||
.set_text_simple(
|
||||
&mut par.globals.get(),
|
||||
Translation::from_raw_text_string(format!("{}: {}", str_modification_date, par.entry.created_at,)),
|
||||
);
|
||||
|
||||
let files = &par.entry.files;
|
||||
let mut mount_res = |res: SkymapResolution| -> anyhow::Result<()> {
|
||||
mount_resolution_button(
|
||||
&mut parser_state,
|
||||
&doc_params,
|
||||
par.layout,
|
||||
id_resolution_buttons,
|
||||
res,
|
||||
&tasks,
|
||||
)
|
||||
};
|
||||
|
||||
mount_res(SkymapResolution::Res2k)?;
|
||||
if files.size_4k.is_some() {
|
||||
mount_res(SkymapResolution::Res4k)?;
|
||||
}
|
||||
if files.size_8k.is_some() {
|
||||
mount_res(SkymapResolution::Res8k)?;
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
id_parent: par.parent_id,
|
||||
tasks,
|
||||
globals: par.globals.clone(),
|
||||
executor: par.executor.clone(),
|
||||
entry: par.entry,
|
||||
parser_state,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn update(&mut self, layout: &mut Layout) -> anyhow::Result<()> {
|
||||
for task in self.tasks.drain() {
|
||||
match task {
|
||||
Task::ResolutionClicked(skymap_resolution) => todo!(),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mount_popup(
|
||||
frontend_tasks: FrontendTasks,
|
||||
executor: AsyncExecutor,
|
||||
globals: WguiGlobals,
|
||||
entry: networking::skymap_catalog::SkymapCatalogEntry,
|
||||
preview_image: Option<CustomGlyphData>,
|
||||
on_close_request: Box<dyn Fn()>,
|
||||
set_holder: Box<dyn FnOnce(PopupHolder<View>)>,
|
||||
) {
|
||||
frontend_tasks
|
||||
.clone()
|
||||
.push(FrontendTask::MountPopupOnce(MountPopupOnceParams::new(
|
||||
Translation::from_raw_text(&entry.name),
|
||||
Box::new(move |data| {
|
||||
let view = View::new(Params {
|
||||
globals: &globals,
|
||||
layout: data.layout,
|
||||
executor: &executor,
|
||||
parent_id: data.id_content,
|
||||
entry,
|
||||
on_close_request,
|
||||
preview_image,
|
||||
})?;
|
||||
|
||||
set_holder((data.handle, view));
|
||||
Ok(())
|
||||
}),
|
||||
)));
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use wgui::{
|
||||
assets::AssetPath,
|
||||
globals::WguiGlobals,
|
||||
|
|
@ -28,11 +30,15 @@ pub struct Params<'a> {
|
|||
pub executor: &'a AsyncExecutor,
|
||||
pub parent_id: WidgetID,
|
||||
pub on_close_request: Box<dyn Fn()>,
|
||||
pub frontend_tasks: FrontendTasks,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
enum Task {
|
||||
SetSkymapCatalog(anyhow::Result<networking::skymap_catalog::SkymapCatalog>),
|
||||
SetSkymapCatalog(Rc<anyhow::Result<networking::skymap_catalog::SkymapCatalog>>),
|
||||
SetSkymapPreview((SkymapUuid, Option<CustomGlyphData>)),
|
||||
ShowRemoteSkymapDownloader(SkymapUuid),
|
||||
CloseRemoteSkymapDownloader,
|
||||
}
|
||||
|
||||
struct MountedCell {
|
||||
|
|
@ -40,6 +46,10 @@ struct MountedCell {
|
|||
view: views::skymap_list_cell::View,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
popup_remote_skymap_downloader: Option<PopupHolder<views::remote_skymap_downloader::View>>,
|
||||
}
|
||||
|
||||
pub struct View {
|
||||
id_parent: WidgetID,
|
||||
id_list: WidgetID,
|
||||
|
|
@ -48,12 +58,15 @@ pub struct View {
|
|||
tasks: Tasks<Task>,
|
||||
mounted_cells: Vec<MountedCell>,
|
||||
executor: AsyncExecutor,
|
||||
frontend_tasks: FrontendTasks,
|
||||
catalog: Option<networking::skymap_catalog::SkymapCatalog>,
|
||||
state: Rc<RefCell<State>>,
|
||||
}
|
||||
|
||||
impl View {
|
||||
async fn skymap_catalog_request_wrapper(tasks: Tasks<Task>, executor: AsyncExecutor) {
|
||||
let res = networking::skymap_catalog::request_catalog(&executor).await;
|
||||
tasks.push(Task::SetSkymapCatalog(res))
|
||||
tasks.push(Task::SetSkymapCatalog(Rc::new(res)))
|
||||
}
|
||||
|
||||
pub fn new(par: Params) -> anyhow::Result<Self> {
|
||||
|
|
@ -73,6 +86,11 @@ impl View {
|
|||
globals: par.globals.clone(),
|
||||
mounted_cells: Vec::new(),
|
||||
executor: par.executor.clone(),
|
||||
frontend_tasks: par.frontend_tasks,
|
||||
catalog: None,
|
||||
state: Rc::new(RefCell::new(State {
|
||||
popup_remote_skymap_downloader: None,
|
||||
})),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +109,7 @@ impl View {
|
|||
fn mount_catalog(
|
||||
&mut self,
|
||||
layout: &mut Layout,
|
||||
catalog: networking::skymap_catalog::SkymapCatalog,
|
||||
catalog: &networking::skymap_catalog::SkymapCatalog,
|
||||
) -> anyhow::Result<()> {
|
||||
let doc_params = &ParseDocumentParams {
|
||||
globals: self.globals.clone(),
|
||||
|
|
@ -103,7 +121,7 @@ impl View {
|
|||
|
||||
let id_list = parser_state.fetch_widget(&layout.state, "list")?.id;
|
||||
|
||||
for entry in catalog.entries {
|
||||
for entry in &catalog.entries {
|
||||
let task = View::request_skymap_preview(
|
||||
self.globals.clone(),
|
||||
self.executor.clone(),
|
||||
|
|
@ -111,27 +129,78 @@ impl View {
|
|||
self.tasks.clone(),
|
||||
);
|
||||
|
||||
let skymap_uuid = entry.uuid.clone();
|
||||
|
||||
self.mounted_cells.push(MountedCell {
|
||||
skymap_uuid: entry.uuid.clone(),
|
||||
view: views::skymap_list_cell::View::new(views::skymap_list_cell::Params {
|
||||
id_parent: id_list,
|
||||
layout,
|
||||
entry,
|
||||
entry: entry.clone(),
|
||||
on_click: self
|
||||
.tasks
|
||||
.get_button_click_callback(Task::ShowRemoteSkymapDownloader(skymap_uuid)),
|
||||
})?,
|
||||
});
|
||||
|
||||
self.executor.spawn(task).detach();
|
||||
}
|
||||
|
||||
self.catalog = Some(catalog.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn show_remote_skymap_downloader(
|
||||
&mut self,
|
||||
uuid: SkymapUuid,
|
||||
preview_image: Option<CustomGlyphData>,
|
||||
) -> anyhow::Result<()> {
|
||||
let Some(catalog) = &self.catalog else {
|
||||
debug_assert!(false); // impossible
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let Some(entry) = catalog.entries.iter().find(|entry| entry.uuid == uuid) else {
|
||||
debug_assert!(false); // impossible
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
views::remote_skymap_downloader::mount_popup(
|
||||
self.frontend_tasks.clone(),
|
||||
self.executor.clone(),
|
||||
self.globals.clone(),
|
||||
entry.clone(),
|
||||
preview_image,
|
||||
self.tasks.make_callback_box(Task::CloseRemoteSkymapDownloader),
|
||||
Box::new({
|
||||
let state = self.state.clone();
|
||||
move |popup| state.borrow_mut().popup_remote_skymap_downloader = Some(popup)
|
||||
}),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_image_preview(&self, skymap_uuid: SkymapUuid) -> Option<CustomGlyphData> {
|
||||
if let Some(cell) = &self.mounted_cells.iter().find(|mc| mc.skymap_uuid == skymap_uuid) {
|
||||
return cell.view.get_image();
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn update(&mut self, layout: &mut Layout) -> anyhow::Result<()> {
|
||||
{
|
||||
let mut state = self.state.borrow_mut();
|
||||
if let Some(view) = &mut state.popup_remote_skymap_downloader {
|
||||
view.1.update(layout)?;
|
||||
}
|
||||
}
|
||||
|
||||
for task in self.tasks.drain() {
|
||||
match task {
|
||||
Task::SetSkymapCatalog(skymap_catalog) => {
|
||||
layout.remove_widget(self.id_loading);
|
||||
match skymap_catalog {
|
||||
match &*skymap_catalog {
|
||||
Ok(skymap_catalog) => {
|
||||
self.mount_catalog(layout, skymap_catalog)?;
|
||||
}
|
||||
|
|
@ -151,6 +220,13 @@ impl View {
|
|||
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)?;
|
||||
}
|
||||
Task::CloseRemoteSkymapDownloader => {
|
||||
self.state.borrow_mut().popup_remote_skymap_downloader = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
@ -175,6 +251,7 @@ pub fn mount_popup(
|
|||
executor: &executor,
|
||||
parent_id: data.id_content,
|
||||
on_close_request,
|
||||
frontend_tasks,
|
||||
})?;
|
||||
|
||||
set_holder((data.handle, view));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use wgui::{
|
||||
assets::AssetPath,
|
||||
components::button::{ButtonClickCallback, ComponentButton},
|
||||
event::EventAlterables,
|
||||
i18n::Translation,
|
||||
layout::{Layout, WidgetID},
|
||||
|
|
@ -14,6 +15,7 @@ pub struct Params<'a> {
|
|||
pub id_parent: WidgetID,
|
||||
pub layout: &'a mut Layout,
|
||||
pub entry: networking::skymap_catalog::SkymapCatalogEntry,
|
||||
pub on_click: ButtonClickCallback,
|
||||
}
|
||||
|
||||
pub struct View {
|
||||
|
|
@ -21,6 +23,7 @@ pub struct View {
|
|||
parser_state: ParserState,
|
||||
id_loading: WidgetID,
|
||||
id_image_preview: WidgetID,
|
||||
image: Option<CustomGlyphData>,
|
||||
}
|
||||
|
||||
impl View {
|
||||
|
|
@ -38,6 +41,10 @@ impl View {
|
|||
|
||||
let id_image_preview = data.get_widget_id("image_preview")?;
|
||||
|
||||
data
|
||||
.fetch_component_as::<ComponentButton>("button")?
|
||||
.on_click(par.on_click);
|
||||
|
||||
{
|
||||
let mut label_title = data.fetch_widget_as::<WidgetLabel>(&par.layout.state, "label_title")?;
|
||||
let mut label_author = data.fetch_widget_as::<WidgetLabel>(&par.layout.state, "label_author")?;
|
||||
|
|
@ -59,6 +66,7 @@ impl View {
|
|||
parser_state,
|
||||
id_loading,
|
||||
id_image_preview,
|
||||
image: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -67,10 +75,14 @@ impl View {
|
|||
let mut alt = EventAlterables::default();
|
||||
{
|
||||
let mut image_preview = layout.state.widgets.cast_as::<WidgetImage>(self.id_image_preview)?;
|
||||
image_preview.set_content(&mut alt, content);
|
||||
image_preview.set_content(&mut alt, content.clone());
|
||||
}
|
||||
layout.process_alterables(alt)?;
|
||||
|
||||
self.image = content;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_image(&self) -> Option<CustomGlyphData> {
|
||||
return self.image.clone();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::components::button::ComponentButton;
|
||||
use crate::components::button::{ButtonClickCallback, ComponentButton};
|
||||
use std::{cell::RefCell, collections::VecDeque, rc::Rc};
|
||||
|
||||
pub struct Tasks<TaskType>(Rc<RefCell<VecDeque<TaskType>>>);
|
||||
|
|
@ -30,15 +30,18 @@ impl<TaskType: 'static> Default for Tasks<TaskType> {
|
|||
}
|
||||
}
|
||||
|
||||
// copyable tasks only!
|
||||
impl<TaskType: Clone + 'static> Tasks<TaskType> {
|
||||
pub fn get_button_click_callback(&self, task: TaskType) -> ButtonClickCallback {
|
||||
let this = self.clone();
|
||||
Rc::new(move |_, _| {
|
||||
this.push(task.clone());
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn handle_button(&self, button: &Rc<ComponentButton>, task: TaskType) {
|
||||
button.on_click({
|
||||
let this = self.clone();
|
||||
Rc::new(move |_, _| {
|
||||
this.push(task.clone());
|
||||
Ok(())
|
||||
})
|
||||
});
|
||||
button.on_click(self.get_button_click_callback(task));
|
||||
}
|
||||
|
||||
pub fn make_callback_rc(&self, task: TaskType) -> Rc<dyn Fn()> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue