mirror of
https://github.com/13hannes11/toolbx-tuner.git
synced 2024-09-03 23:21:00 +02:00
Added internal messaging and workers to handle per toolbx settings, actual settings handling still missing
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use relm4::gtk::{Application, ApplicationWindow};
|
||||
use relm4::{factory::FactoryVecDeque, RelmApp};
|
||||
use toolbx::ToolbxContainer;
|
||||
use ui::app::model::AppModel;
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::toolbx::ToolbxContainer;
|
||||
use super::model::ToolbxEntry;
|
||||
|
||||
pub enum AppMsg {
|
||||
ShowToolboxSettingsRequest,
|
||||
ShowToolboxSettingsRequest(DynamicIndex),
|
||||
ShowToolboxAppsRequest,
|
||||
ToolbxListUpdate(Vec<ToolbxContainer>),
|
||||
ToolbxContainerToggleStartStop(DynamicIndex),
|
||||
|
||||
@@ -33,7 +33,8 @@ impl FactoryPrototype for ToolbxEntry {
|
||||
type Msg = AppMsg;
|
||||
|
||||
fn init_view(&self, key: &DynamicIndex, sender: Sender<Self::Msg>) -> Self::Widgets {
|
||||
let index = key.clone();
|
||||
let index_terminal = key.clone();
|
||||
let index_settings = key.clone();
|
||||
|
||||
view! {
|
||||
suffix_box = >k::Box{
|
||||
@@ -60,7 +61,7 @@ impl FactoryPrototype for ToolbxEntry {
|
||||
set_tooltip_text: Some(TERMINAL_TOOLTIP),
|
||||
set_css_classes: &["flat"],
|
||||
connect_clicked(sender) => move |btn| {
|
||||
send!(sender, AppMsg::OpenToolbxTerminal(index.clone()));
|
||||
send!(sender, AppMsg::OpenToolbxTerminal(index_terminal.clone()));
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -73,7 +74,7 @@ impl FactoryPrototype for ToolbxEntry {
|
||||
set_tooltip_text: Some(SETTINGS_TOOLTIP),
|
||||
set_css_classes: &["circular"],
|
||||
connect_clicked(sender) => move |btn| {
|
||||
send!(sender, AppMsg::ShowToolboxSettingsRequest);
|
||||
send!(sender, AppMsg::ShowToolboxSettingsRequest(index_settings.clone()));
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -15,12 +15,16 @@ use super::{messages::AppMsg, model::AppModel, workers::AsyncHandlerMsg};
|
||||
impl AppUpdate for AppModel {
|
||||
fn update(&mut self, msg: AppMsg, components: &AppComponents, _sender: Sender<AppMsg>) -> bool {
|
||||
match msg {
|
||||
AppMsg::ShowToolboxSettingsRequest => {
|
||||
AppMsg::ShowToolboxSettingsRequest(index) => {
|
||||
if let Some(toolbx_entry) = self.toolboxes.get(index.current_index()) {
|
||||
components
|
||||
.toolbox_settings_dialog
|
||||
.send(ToolboxSettingsDialogMsg::Show)
|
||||
.send(ToolboxSettingsDialogMsg::Show(
|
||||
toolbx_entry.toolbx_container.clone(),
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
AppMsg::ShowToolboxAppsRequest => {
|
||||
components
|
||||
.toolbox_apps_dialog
|
||||
|
||||
11
src/ui/components/toolbox_settings/components.rs
Normal file
11
src/ui/components/toolbox_settings/components.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
use relm4::RelmComponent;
|
||||
use relm4::RelmMsgHandler;
|
||||
use relm4::Sender;
|
||||
|
||||
use super::model::ToolboxSettingsDialogModel;
|
||||
use crate::ui::components::toolbox_settings::workers::AsyncSettingsHandler;
|
||||
|
||||
#[derive(relm4::Components)]
|
||||
pub struct SettingsComponents {
|
||||
pub async_handler: RelmMsgHandler<AsyncSettingsHandler, ToolboxSettingsDialogModel>,
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
use crate::toolbx::ToolbxContainer;
|
||||
|
||||
use super::model::ToolboxPreferences;
|
||||
|
||||
pub enum ToolboxSettingsDialogMsg {
|
||||
Show,
|
||||
Show(ToolbxContainer),
|
||||
ReplyToolbxSettings(ToolboxPreferences),
|
||||
Close,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
pub mod components;
|
||||
pub mod messages;
|
||||
pub mod model;
|
||||
pub mod update;
|
||||
pub mod widgets;
|
||||
pub mod workers;
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
use relm4::Model;
|
||||
|
||||
use super::{messages::ToolboxSettingsDialogMsg, widgets::ToolboxSettingsDialogWidgets};
|
||||
use super::{
|
||||
components::SettingsComponents, messages::ToolboxSettingsDialogMsg,
|
||||
widgets::ToolboxSettingsDialogWidgets,
|
||||
};
|
||||
use crate::toolbx::ToolbxContainer;
|
||||
|
||||
pub struct ToolboxSettingsDialogModel {
|
||||
pub hidden: bool,
|
||||
pub window_title: Option<String>,
|
||||
pub current_toolbox_container: Option<ToolbxContainer>,
|
||||
pub current_toolbx_settings: Option<ToolboxPreferences>,
|
||||
}
|
||||
|
||||
impl Model for ToolboxSettingsDialogModel {
|
||||
type Msg = ToolboxSettingsDialogMsg;
|
||||
type Widgets = ToolboxSettingsDialogWidgets;
|
||||
type Components = ();
|
||||
type Components = SettingsComponents;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ToolboxPreferences {}
|
||||
|
||||
@@ -2,23 +2,66 @@ use relm4::{ComponentUpdate, Sender};
|
||||
|
||||
use crate::ui::app::{messages::AppMsg, model::AppModel};
|
||||
|
||||
use super::{messages::ToolboxSettingsDialogMsg, model::ToolboxSettingsDialogModel};
|
||||
use super::{
|
||||
components::SettingsComponents, messages::ToolboxSettingsDialogMsg,
|
||||
model::ToolboxSettingsDialogModel, workers::AsyncSettingsHandlerMsg,
|
||||
};
|
||||
|
||||
impl ComponentUpdate<AppModel> for ToolboxSettingsDialogModel {
|
||||
fn init_model(_parent_model: &AppModel) -> Self {
|
||||
ToolboxSettingsDialogModel { hidden: true }
|
||||
ToolboxSettingsDialogModel {
|
||||
hidden: true,
|
||||
window_title: None,
|
||||
current_toolbox_container: None,
|
||||
current_toolbx_settings: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn update(
|
||||
&mut self,
|
||||
msg: ToolboxSettingsDialogMsg,
|
||||
_components: &(),
|
||||
components: &SettingsComponents,
|
||||
_sender: Sender<ToolboxSettingsDialogMsg>,
|
||||
parent_sender: Sender<AppMsg>,
|
||||
) {
|
||||
match msg {
|
||||
ToolboxSettingsDialogMsg::Show => self.hidden = false,
|
||||
ToolboxSettingsDialogMsg::Close => self.hidden = true,
|
||||
ToolboxSettingsDialogMsg::ReplyToolbxSettings(settings) => {
|
||||
self.current_toolbx_settings = Some(settings);
|
||||
println!("Received Toolbox Settings");
|
||||
}
|
||||
ToolboxSettingsDialogMsg::Show(toolbx_container) => {
|
||||
self.hidden = false;
|
||||
self.window_title = Some(format!(
|
||||
"Toolbx Preferences: {}",
|
||||
toolbx_container.name.clone()
|
||||
));
|
||||
// TODO: create settings handling for each toolbox
|
||||
// probably settings for a toolbox should be stored in a HashMap and loaded based on that
|
||||
components
|
||||
.async_handler
|
||||
.sender()
|
||||
.blocking_send(AsyncSettingsHandlerMsg::RequestToolbxSettings(
|
||||
toolbx_container.clone(),
|
||||
))
|
||||
.expect("Receiver dropped");
|
||||
self.current_toolbox_container = Some(toolbx_container);
|
||||
}
|
||||
ToolboxSettingsDialogMsg::Close => {
|
||||
self.current_toolbx_settings.as_ref().map(|settings| {
|
||||
components
|
||||
.async_handler
|
||||
.sender()
|
||||
.blocking_send(AsyncSettingsHandlerMsg::SaveToolboxSettings(
|
||||
settings.clone(),
|
||||
))
|
||||
.expect("Receiver dropped");
|
||||
});
|
||||
|
||||
self.hidden = true;
|
||||
self.window_title = None;
|
||||
self.current_toolbox_container = None;
|
||||
self.current_toolbx_settings = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ use super::model::ToolboxSettingsDialogModel;
|
||||
impl Widgets<ToolboxSettingsDialogModel, AppModel> for ToolboxSettingsDialogWidgets {
|
||||
view! {
|
||||
adw::PreferencesWindow {
|
||||
set_title: Some("Preferences: <Toolbox_name>"),
|
||||
set_title: watch!{ model.window_title.as_ref().map( |x| x.as_str() ) },
|
||||
set_transient_for: parent!{Some(&parent_widgets.main_window)},
|
||||
set_modal: true,
|
||||
set_visible: watch!(!model.hidden),
|
||||
|
||||
76
src/ui/components/toolbox_settings/workers.rs
Normal file
76
src/ui/components/toolbox_settings/workers.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::toolbx::ToolbxContainer;
|
||||
|
||||
use relm4::factory::DynamicIndex;
|
||||
use relm4::{send, MessageHandler, Sender};
|
||||
use tokio::runtime::{Builder, Runtime};
|
||||
use tokio::sync::mpsc::{channel, Sender as TokioSender};
|
||||
|
||||
use crate::ui::app::{messages::AppMsg, model::AppModel};
|
||||
|
||||
use super::model::ToolboxPreferences;
|
||||
use crate::ui::components::toolbox_settings::messages::ToolboxSettingsDialogMsg;
|
||||
use crate::ui::components::ToolboxSettingsDialogModel;
|
||||
|
||||
// Code adapted from https://relm4.org/book/stable/message_handler.html
|
||||
pub struct AsyncSettingsHandler {
|
||||
_rt: Runtime,
|
||||
sender: TokioSender<AsyncSettingsHandlerMsg>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AsyncSettingsHandlerMsg {
|
||||
RequestToolbxSettings(ToolbxContainer),
|
||||
SaveToolboxSettings(ToolboxPreferences),
|
||||
}
|
||||
|
||||
impl MessageHandler<ToolboxSettingsDialogModel> for AsyncSettingsHandler {
|
||||
type Msg = AsyncSettingsHandlerMsg;
|
||||
type Sender = TokioSender<AsyncSettingsHandlerMsg>;
|
||||
|
||||
fn init(
|
||||
_parent_model: &ToolboxSettingsDialogModel,
|
||||
parent_sender: Sender<ToolboxSettingsDialogMsg>,
|
||||
) -> Self {
|
||||
let (sender, mut rx) = channel::<AsyncSettingsHandlerMsg>(10);
|
||||
|
||||
let rt = Builder::new_multi_thread()
|
||||
.worker_threads(1)
|
||||
.enable_time()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
rt.spawn(async move {
|
||||
while let Some(msg) = rx.recv().await {
|
||||
let parent_sender = parent_sender.clone();
|
||||
tokio::spawn(async move {
|
||||
match msg {
|
||||
AsyncSettingsHandlerMsg::SaveToolboxSettings(tbx_settings) => {
|
||||
// TODO: actually save settings
|
||||
println!("Received Toolbx Settings save request");
|
||||
}
|
||||
AsyncSettingsHandlerMsg::RequestToolbxSettings(tbx) => {
|
||||
println!("Received ToolbxSettings Request");
|
||||
parent_sender
|
||||
.send(ToolboxSettingsDialogMsg::ReplyToolbxSettings(
|
||||
ToolboxPreferences {},
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
AsyncSettingsHandler { _rt: rt, sender }
|
||||
}
|
||||
|
||||
fn send(&self, msg: Self::Msg) {
|
||||
self.sender.blocking_send(msg).unwrap();
|
||||
}
|
||||
|
||||
fn sender(&self) -> Self::Sender {
|
||||
self.sender.clone()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user