diff --git a/src/main.rs b/src/main.rs index e216388..9e218ac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,11 +12,12 @@ mod ui; fn main() { let toolbx_list = VecDeque::from(ToolbxContainer::get_toolboxes()); - let factory_vec = FactoryVecDeque::from_vec_deque(toolbx_list); - - let model = AppModel { + let factory_vec = FactoryVecDeque::new(); + + let mut model = AppModel { toolboxes: factory_vec, }; + model.update_toolbxes(toolbx_list.into_iter()); let app = RelmApp::new(model); app.run(); } diff --git a/src/ui/app/model.rs b/src/ui/app/model.rs index 286b3d1..ccade82 100644 --- a/src/ui/app/model.rs +++ b/src/ui/app/model.rs @@ -7,12 +7,48 @@ use crate::{toolbx::ToolbxContainer, ui::components::AppComponents}; use super::{messages::AppMsg, widgets::AppWidgets}; -pub struct AppModel { - pub toolboxes: FactoryVecDeque, +pub struct ToolbxEntry { + pub toolbx_container: ToolbxContainer, + pub changing_status: bool, + // TODO: settings } -impl Model for AppModel { +impl ToolbxEntry { + pub fn update_container(&mut self, container : ToolbxContainer) { + std::mem::replace::(&mut self.toolbx_container, container); + } +} + +pub struct AppModel { + pub toolboxes: FactoryVecDeque, +} + +impl Model for AppModel { type Msg = AppMsg; type Widgets = AppWidgets; type Components = AppComponents; } + +impl AppModel { + pub fn update_toolbxes(&mut self, toolbox_iter: I) + where + I: Iterator, { + // Update each toolbx entry if there were changes to it + // TODO: deal with the removal of toolboxes + for tbx_update in toolbox_iter { + println!("name: {}", tbx_update.name); + let mut exists = false; + for (index, tbx_entry) in self.toolboxes.iter().enumerate() { + if tbx_update.name == tbx_entry.toolbx_container.name { + self.toolboxes.get_mut(index).map(|x| x.update_container(tbx_update.clone())); + exists = true; + break; + } + } + if !exists { + println!("{}", tbx_update.name); + self.toolboxes.push_back(ToolbxEntry { toolbx_container: tbx_update, changing_status: false}) + } + } + } +} \ No newline at end of file diff --git a/src/ui/app/toolbox_list.rs b/src/ui/app/toolbox_list.rs index 842764e..ccf4698 100644 --- a/src/ui/app/toolbox_list.rs +++ b/src/ui/app/toolbox_list.rs @@ -16,15 +16,16 @@ use crate::{ }, }; -use super::messages::AppMsg; +use super::{messages::AppMsg, model::ToolbxEntry}; #[derive(Debug)] pub struct FactoryWidgets { pub action_row: adw::ActionRow, status_button: gtk::Button, + status_spinner: gtk::Spinner, } -impl FactoryPrototype for ToolbxContainer { +impl FactoryPrototype for ToolbxEntry { type Factory = FactoryVecDeque; type Widgets = FactoryWidgets; type Root = adw::ActionRow; @@ -95,7 +96,7 @@ impl FactoryPrototype for ToolbxContainer { let mut status_button_tooltip = START_TOOLTIP; let mut status_button_icon = START_ICON; - match self.status { + match self.toolbx_container.status { ToolbxStatus::Running => { status_button_tooltip = SHUTDOWN_TOOLTIP; status_button_icon = SHUTDOWN_ICON; @@ -106,10 +107,21 @@ impl FactoryPrototype for ToolbxContainer { } } - let subtitle = format!("created {}\n{}", self.created, self.image); + let subtitle = format!("created {}\n{}", self.toolbx_container.created, self.toolbx_container.image); let index = key.clone(); + view! { + status_spinner = >k::Spinner { + set_margin_top: 10, + set_margin_bottom: 10, + set_tooltip_text: Some(status_button_tooltip), + set_css_classes: &["circular"], + + } + }; + //status_spinner.start(); + view! { status_button = >k::Button::from_icon_name(status_button_icon) { set_margin_top: 10, @@ -123,10 +135,10 @@ impl FactoryPrototype for ToolbxContainer { }, } }; - + view! { action_row = &adw::ActionRow { - set_title: &self.name, + set_title: &self.toolbx_container.name, set_subtitle: subtitle.as_str(), add_prefix = >k::Box { append = >k::AspectFrame{ @@ -138,7 +150,7 @@ impl FactoryPrototype for ToolbxContainer { } }; - FactoryWidgets { action_row, status_button } + FactoryWidgets { action_row, status_button, status_spinner} } fn view( @@ -150,17 +162,26 @@ impl FactoryPrototype for ToolbxContainer { // fixme: IDEALY this is would be done with message handling and only if the request actually is done - match self.status { - ToolbxStatus::Running => { - widgets.status_button.set_icon_name(SHUTDOWN_ICON); - widgets.status_button.set_tooltip_text(Some(SHUTDOWN_TOOLTIP)); - } - _ => { - widgets.status_button.set_icon_name(START_ICON); - widgets.status_button.set_tooltip_text(Some(START_TOOLTIP)); + + if self.changing_status { + widgets.status_button.set_sensitive(false); + widgets.status_button.set_child(Some(&widgets.status_spinner)); + widgets.status_spinner.start(); + + } else { + match self.toolbx_container.status { + ToolbxStatus::Running => { + widgets.status_button.set_icon_name(SHUTDOWN_ICON); + widgets.status_button.set_tooltip_text(Some(SHUTDOWN_TOOLTIP)); + } + _ => { + widgets.status_button.set_icon_name(START_ICON); + widgets.status_button.set_tooltip_text(Some(START_TOOLTIP)); + } } + widgets.status_button.set_sensitive(true); + widgets.status_spinner.stop(); } - widgets.status_button.set_sensitive(true); } diff --git a/src/ui/app/update.rs b/src/ui/app/update.rs index 1ee8a92..dd423f5 100644 --- a/src/ui/app/update.rs +++ b/src/ui/app/update.rs @@ -27,12 +27,18 @@ impl AppUpdate for AppModel { } AppMsg::ToolbxContainerToggleStartStop(index) => { if let Some(toolbx_container) = self.toolboxes.get_mut(index.current_index()) { - match toolbx_container.status { + + match toolbx_container.toolbx_container.status { ToolbxStatus::Exited | ToolbxStatus::Configured => { - toolbx_container.start(); + toolbx_container.changing_status = true; + // Send message to background worker to start + //toolbx_container.toolbx_container.start(); + } ToolbxStatus::Running => { - toolbx_container.stop(); + toolbx_container.changing_status = true; + // send message to beackground worker to stop + //toolbx_container.toolbx_container.stop(); } } // TODO: tell button to reactivate somehow