refactor(dtmm): Use commands instead of notifications
This commit is contained in:
parent
b8804409a3
commit
4b7f12e487
3 changed files with 90 additions and 110 deletions
|
@ -18,7 +18,7 @@ use tracing_subscriber::prelude::*;
|
|||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
use crate::engine::deploy_mods;
|
||||
use crate::state::{AsyncAction, Delegate, State, COMMAND_FINISH_DEPLOY};
|
||||
use crate::state::{AsyncAction, Delegate, State, ACTION_FINISH_DEPLOY};
|
||||
|
||||
mod controller;
|
||||
mod engine;
|
||||
|
@ -45,7 +45,7 @@ fn work_thread(
|
|||
event_sink
|
||||
.write()
|
||||
.await
|
||||
.submit_command(COMMAND_FINISH_DEPLOY, (), Target::Auto)
|
||||
.submit_command(ACTION_FINISH_DEPLOY, (), Target::Auto)
|
||||
.expect("failed to send command");
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -5,9 +5,10 @@ use druid::widget::{
|
|||
};
|
||||
use druid::{lens, Insets, LensExt, Widget, WidgetExt, WindowDesc};
|
||||
|
||||
use crate::state::{ModInfo, PathBufFormatter, State, View, ACTION_ADD_MOD};
|
||||
use crate::state::{
|
||||
ModInfo, PathBufFormatter, State, StateController, View, ACTION_DELETE_SELECTED_MOD,
|
||||
ACTION_SELECTED_MOD_DOWN, ACTION_SELECTED_MOD_UP, ACTION_SELECT_MOD, COMMAND_START_DEPLOY,
|
||||
ACTION_DELETE_SELECTED_MOD, ACTION_SELECTED_MOD_DOWN, ACTION_SELECTED_MOD_UP,
|
||||
ACTION_SELECT_MOD, ACTION_START_DEPLOY,
|
||||
};
|
||||
use crate::theme;
|
||||
use crate::widget::ExtraWidgetExt;
|
||||
|
@ -51,7 +52,7 @@ fn build_top_bar() -> impl Widget<State> {
|
|||
.with_child(
|
||||
Button::new("Deploy Mods")
|
||||
.on_click(|ctx, _state: &mut State, _env| {
|
||||
ctx.submit_command(COMMAND_START_DEPLOY);
|
||||
ctx.submit_command(ACTION_START_DEPLOY);
|
||||
})
|
||||
.disabled_if(|data, _| !data.can_deploy_mods()),
|
||||
)
|
||||
|
@ -83,7 +84,7 @@ fn build_mod_list() -> impl Widget<State> {
|
|||
.lens(lens!((usize, ModInfo), 1).then(ModInfo::enabled)),
|
||||
)
|
||||
.with_child(Label::raw().lens(lens!((usize, ModInfo), 1).then(ModInfo::name)))
|
||||
.on_click(|ctx, (i, _info), _env| ctx.submit_notification(ACTION_SELECT_MOD.with(*i)))
|
||||
.on_click(|ctx, (i, _info), _env| ctx.submit_command(ACTION_SELECT_MOD.with(*i)))
|
||||
});
|
||||
|
||||
let scroll = Scroll::new(list)
|
||||
|
@ -123,11 +124,11 @@ fn build_mod_details() -> impl Widget<State> {
|
|||
.lens(State::selected_mod);
|
||||
|
||||
let button_move_up = Button::new("Move Up")
|
||||
.on_click(|ctx, _state, _env| ctx.submit_notification(ACTION_SELECTED_MOD_UP))
|
||||
.on_click(|ctx, _state, _env| ctx.submit_command(ACTION_SELECTED_MOD_UP))
|
||||
.disabled_if(|state: &State, _env: &druid::Env| !state.can_move_mod_up());
|
||||
|
||||
let button_move_down = Button::new("Move Down")
|
||||
.on_click(|ctx, _state, _env| ctx.submit_notification(ACTION_SELECTED_MOD_DOWN))
|
||||
.on_click(|ctx, _state, _env| ctx.submit_command(ACTION_SELECTED_MOD_DOWN))
|
||||
.disabled_if(|state: &State, _env: &druid::Env| !state.can_move_mod_down());
|
||||
|
||||
let button_toggle_mod = Maybe::new(
|
||||
|
@ -150,14 +151,11 @@ fn build_mod_details() -> impl Widget<State> {
|
|||
.disabled_if(|info: &Option<ModInfo>, _env: &druid::Env| info.is_none())
|
||||
.lens(State::selected_mod);
|
||||
|
||||
let button_add_mod = Button::new("Add Mod").on_click(|_ctx, state: &mut State, _env| {
|
||||
// TODO: Implement properly
|
||||
let info = ModInfo::new();
|
||||
state.add_mod(info);
|
||||
});
|
||||
let button_add_mod = Button::new("Add Mod")
|
||||
.on_click(|ctx, _state: &mut State, _env| ctx.submit_command(ACTION_ADD_MOD));
|
||||
|
||||
let button_delete_mod = Button::new("Delete Mod")
|
||||
.on_click(|ctx, _state, _env| ctx.submit_notification(ACTION_DELETE_SELECTED_MOD))
|
||||
.on_click(|ctx, _state, _env| ctx.submit_command(ACTION_DELETE_SELECTED_MOD))
|
||||
.disabled_if(|info: &Option<ModInfo>, _env: &druid::Env| info.is_none())
|
||||
.lens(State::selected_mod);
|
||||
|
||||
|
@ -250,5 +248,4 @@ fn build_window() -> impl Widget<State> {
|
|||
.must_fill_main_axis(true)
|
||||
.with_child(build_top_bar())
|
||||
.with_flex_child(build_main(), 1.0)
|
||||
.controller(StateController::new())
|
||||
}
|
||||
|
|
|
@ -3,20 +3,18 @@ use std::sync::Arc;
|
|||
|
||||
use druid::im::Vector;
|
||||
use druid::text::Formatter;
|
||||
use druid::widget::Controller;
|
||||
use druid::{
|
||||
AppDelegate, Command, Data, DelegateCtx, Env, Event, EventCtx, Handled, Lens, Selector, Target,
|
||||
Widget,
|
||||
};
|
||||
use druid::{AppDelegate, Command, Data, DelegateCtx, Env, Handled, Lens, Selector, Target};
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
|
||||
pub const ACTION_SELECT_MOD: Selector<usize> = Selector::new("dtmm.action..select-mod");
|
||||
pub const ACTION_SELECT_MOD: Selector<usize> = Selector::new("dtmm.action.select-mod");
|
||||
pub const ACTION_SELECTED_MOD_UP: Selector = Selector::new("dtmm.action.selected-mod-up");
|
||||
pub const ACTION_SELECTED_MOD_DOWN: Selector = Selector::new("dtmm.action.selected-mod-down");
|
||||
pub const ACTION_DELETE_SELECTED_MOD: Selector = Selector::new("dtmm.action.delete-selected-mod");
|
||||
|
||||
pub const COMMAND_FINISH_DEPLOY: Selector = Selector::new("dtmm.command.finish-deploy");
|
||||
pub const COMMAND_START_DEPLOY: Selector = Selector::new("dtmm.command.start-deploy");
|
||||
pub const ACTION_START_DEPLOY: Selector = Selector::new("dtmm.action.start-deploy");
|
||||
pub const ACTION_FINISH_DEPLOY: Selector = Selector::new("dtmm.action.finish-deploy");
|
||||
|
||||
pub const ACTION_ADD_MOD: Selector = Selector::new("dtmm.action.add-mod");
|
||||
|
||||
#[derive(Copy, Clone, Data, Debug, PartialEq)]
|
||||
pub(crate) enum View {
|
||||
|
@ -236,75 +234,6 @@ impl<T: Data> Lens<Vector<T>, Vector<(usize, T)>> for IndexedVectorLens {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct StateController {}
|
||||
|
||||
impl StateController {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Turn notifications into commands on the AppDelegate
|
||||
impl<W: Widget<State>> Controller<State, W> for StateController {
|
||||
#[tracing::instrument(name = "StateController::event", skip_all)]
|
||||
fn event(
|
||||
&mut self,
|
||||
child: &mut W,
|
||||
ctx: &mut EventCtx,
|
||||
event: &Event,
|
||||
state: &mut State,
|
||||
env: &Env,
|
||||
) {
|
||||
match event {
|
||||
Event::Notification(notif) if notif.is(ACTION_SELECT_MOD) => {
|
||||
ctx.set_handled();
|
||||
let index = notif
|
||||
.get(ACTION_SELECT_MOD)
|
||||
.expect("notification type didn't match after check");
|
||||
|
||||
state.select_mod(*index);
|
||||
}
|
||||
Event::Notification(notif) if notif.is(ACTION_SELECTED_MOD_UP) => {
|
||||
ctx.set_handled();
|
||||
let Some(i) = state.selected_mod_index else {
|
||||
return;
|
||||
};
|
||||
|
||||
let len = state.mods.len();
|
||||
if len == 0 || i == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
state.mods.swap(i, i - 1);
|
||||
state.selected_mod_index = Some(i - 1);
|
||||
}
|
||||
Event::Notification(notif) if notif.is(ACTION_SELECTED_MOD_DOWN) => {
|
||||
ctx.set_handled();
|
||||
let Some(i) = state.selected_mod_index else {
|
||||
return;
|
||||
};
|
||||
|
||||
let len = state.mods.len();
|
||||
if len == 0 || i == usize::MAX || i >= len - 1 {
|
||||
return;
|
||||
}
|
||||
|
||||
state.mods.swap(i, i + 1);
|
||||
state.selected_mod_index = Some(i + 1);
|
||||
}
|
||||
Event::Notification(notif) if notif.is(ACTION_DELETE_SELECTED_MOD) => {
|
||||
ctx.set_handled();
|
||||
let Some(index) = state.selected_mod_index else {
|
||||
return;
|
||||
};
|
||||
|
||||
state.mods.remove(index);
|
||||
}
|
||||
_ => child.event(ctx, event, state, env),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) enum AsyncAction {
|
||||
DeployMods(State),
|
||||
}
|
||||
|
@ -326,29 +255,83 @@ impl AppDelegate<State> for Delegate {
|
|||
_ctx: &mut DelegateCtx,
|
||||
_target: Target,
|
||||
cmd: &Command,
|
||||
data: &mut State,
|
||||
state: &mut State,
|
||||
_env: &Env,
|
||||
) -> Handled {
|
||||
if cmd.is(COMMAND_START_DEPLOY) {
|
||||
match cmd {
|
||||
cmd if cmd.is(ACTION_START_DEPLOY) => {
|
||||
if self
|
||||
.sender
|
||||
.send(AsyncAction::DeployMods(data.clone()))
|
||||
.send(AsyncAction::DeployMods(state.clone()))
|
||||
.is_ok()
|
||||
{
|
||||
data.is_deployment_in_progress = true;
|
||||
state.is_deployment_in_progress = true;
|
||||
} else {
|
||||
tracing::error!("Failed to queue action to deploy mods");
|
||||
}
|
||||
|
||||
Handled::Yes
|
||||
} else if cmd.is(COMMAND_FINISH_DEPLOY) {
|
||||
data.is_deployment_in_progress = false;
|
||||
}
|
||||
cmd if cmd.is(ACTION_START_DEPLOY) => {
|
||||
state.is_deployment_in_progress = false;
|
||||
Handled::Yes
|
||||
} else {
|
||||
}
|
||||
cmd if cmd.is(ACTION_SELECT_MOD) => {
|
||||
let index = cmd
|
||||
.get(ACTION_SELECT_MOD)
|
||||
.expect("command type matched but didn't contain the expected value");
|
||||
|
||||
state.select_mod(*index);
|
||||
Handled::Yes
|
||||
}
|
||||
cmd if cmd.is(ACTION_SELECTED_MOD_UP) => {
|
||||
let Some(i) = state.selected_mod_index else {
|
||||
return Handled::No;
|
||||
};
|
||||
|
||||
let len = state.mods.len();
|
||||
if len == 0 || i == 0 {
|
||||
return Handled::No;
|
||||
}
|
||||
|
||||
state.mods.swap(i, i - 1);
|
||||
state.selected_mod_index = Some(i - 1);
|
||||
Handled::Yes
|
||||
}
|
||||
cmd if cmd.is(ACTION_SELECTED_MOD_DOWN) => {
|
||||
let Some(i) = state.selected_mod_index else {
|
||||
return Handled::No;
|
||||
};
|
||||
|
||||
let len = state.mods.len();
|
||||
if len == 0 || i == usize::MAX || i >= len - 1 {
|
||||
return Handled::No;
|
||||
}
|
||||
|
||||
state.mods.swap(i, i + 1);
|
||||
state.selected_mod_index = Some(i + 1);
|
||||
Handled::Yes
|
||||
}
|
||||
cmd if cmd.is(ACTION_DELETE_SELECTED_MOD) => {
|
||||
let Some(index) = state.selected_mod_index else {
|
||||
return Handled::No;
|
||||
};
|
||||
|
||||
state.mods.remove(index);
|
||||
Handled::Yes
|
||||
}
|
||||
cmd if cmd.is(ACTION_ADD_MOD) => {
|
||||
// TODO: Implement properly
|
||||
let info = ModInfo::new();
|
||||
state.add_mod(info);
|
||||
Handled::Yes
|
||||
}
|
||||
cmd => {
|
||||
tracing::debug!("Unknown command: {:?}", cmd);
|
||||
Handled::No
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct PathBufFormatter;
|
||||
|
|
Loading…
Add table
Reference in a new issue