Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion config-frontend/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use iced::keyboard::{Key, Modifiers};
use messaging::protos::key_config::command_action::Command;

#[derive(Debug, Clone, Default, PartialEq)]
pub enum ConfigurableZones {
Button1(ButtonInput),
Expand Down Expand Up @@ -55,9 +58,16 @@ pub enum TouchscreenInput {
None,
}

#[derive(Debug, Clone, Default, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub enum KeyConfigOptions {
Command(Command),
Key((Key, Modifiers)),
}

#[derive(Debug, Clone, Default, PartialEq, Copy, Eq)]
pub enum ExtraConfigMode {
#[default]
Default,
KeyRecording,
Command,
}
71 changes: 52 additions & 19 deletions config-frontend/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ mod messages;
mod tasks;
mod views;

use crate::common::{ConfigurableZones, ExtraConfigMode};
use crate::common::{ConfigurableZones, ExtraConfigMode, KeyConfigOptions};
use crate::mappers::ProtoKeyActionWrapper;
use crate::messages::Messages;
use crate::tasks::{connect_to_backend, select_image_blocking};
use iced::keyboard::{Key, Modifiers};
use iced::task::Task;
use iced::{Element, Subscription};
use messaging::client_wrapper::{ClientCommands, ClientWrapper};
use messaging::protos::key_config::command_action::Command;
use std::cmp::PartialEq;
use std::time::Duration;

Expand All @@ -31,7 +31,8 @@ struct LaunchpadConfigApp {
socket_client: Option<ClientWrapper>,
connecting_to_backend: bool,
brightness: u8,
current_input_sequence: Vec<(Key, Modifiers)>,
current_input_sequence: Vec<KeyConfigOptions>,
current_command_input_value: String,
}

impl LaunchpadConfigApp {
Expand All @@ -43,10 +44,12 @@ impl LaunchpadConfigApp {
fn view(application_state: &'_ LaunchpadConfigApp) -> Element<'_, Messages> {
match &application_state.view {
View::Initialise => views::initialise::Initialise.view(),
View::Configure(modal_zone, _) => views::config::Config.view(
View::Configure(modal_zone, mode) => views::config::Config.view(
application_state.brightness,
modal_zone.clone(),
application_state.current_input_sequence.clone(),
modal_zone.to_owned(),
application_state.current_input_sequence.to_owned(),
mode.to_owned(),
application_state.current_command_input_value.to_owned(),
),
_ => todo!(),
}
Expand Down Expand Up @@ -125,46 +128,76 @@ fn update(application_state: &mut LaunchpadConfigApp, message: Messages) -> Task
application_state.view = View::Configure(zone, ExtraConfigMode::Default);
}

Messages::OpenInputMappingConfigurationPanel(zone) => {
application_state.view = View::Configure(zone, ExtraConfigMode::KeyRecording);
// We need a new set of inputs every time the panel is opened
return Task::done(Messages::ResetInputBuffer);
Messages::OpenInputMappingConfigurationPanel(zone, mode) => match mode {
ExtraConfigMode::Command | ExtraConfigMode::KeyRecording => {
application_state.view = View::Configure(zone, mode);
}
_ => (),
},

Messages::RemoveAction(index) => {
if index < application_state.current_input_sequence.len() {
application_state.current_input_sequence.remove(index);
}
}

Messages::CloseConfigurationPanel => {
application_state.view =
View::Configure(ConfigurableZones::None, ExtraConfigMode::Default);
// We need a new set of inputs every time the panel is opened
return Task::done(Messages::ResetInputBuffer);
}

Messages::ResetInputBuffer => {
application_state.current_input_sequence.clear();
}

Messages::ClearCommandInput => {
application_state.current_command_input_value.clear();
}

Messages::KeyboardInput(key, modifier) => {
match application_state.view {
View::Configure(ConfigurableZones::None, _) => {
// Do nothing if we aren't in a configurable state
}
View::Configure(_, ref config_mode) => {
match config_mode {
ExtraConfigMode::Default => {
// Default mode does not need to capture input
ExtraConfigMode::Default | ExtraConfigMode::Command => {
// Default or command mode does not need to capture input
}
_ => application_state
.current_input_sequence
.push((key, modifier)),
.push(KeyConfigOptions::Key((key, modifier))),
}
}
_ => {}
};
}
Messages::CommandInputChanged(text) => {
application_state.current_command_input_value = text;
}
Messages::CommandAdded(command) => {
if let Command::FreeformCommand(ref freeform) = command {
application_state.current_command_input_value = freeform.clone().command;
}
application_state
.current_input_sequence
.push(KeyConfigOptions::Command(command));
return Task::done(Messages::ClearCommandInput);
}
Messages::SetKeyConfig(input_id, sequence) => {
let key_actions = sequence
.iter()
.map(|mapping| ProtoKeyActionWrapper::from(mapping.clone()).key_action())
.collect::<Vec<_>>();

let builder = messaging::proto_builders::KeyConfigActionBuilder::from(key_actions);
let mut builder = messaging::proto_builders::KeyConfigActionBuilder::new();
sequence.iter().for_each(|action| match action {
common::KeyConfigOptions::Key(key_action) => {
builder.add_prebuilt_key_action(
ProtoKeyActionWrapper::from(key_action.to_owned()).key_action(),
);
}
common::KeyConfigOptions::Command(command_action) => {
builder.add_command_action(command_action.to_owned())
}
});

if let Some(client) = application_state.get_client() {
client
Expand Down
11 changes: 8 additions & 3 deletions config-frontend/src/messages.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::common::ConfigurableZones;
use crate::common::{ConfigurableZones, ExtraConfigMode, KeyConfigOptions};
use iced::keyboard::{Key, Modifiers};
use messaging::protos::display_zones::DisplayZone;
use messaging::protos::inputs::InputId;
use messaging::protos::key_config::command_action::Command;

#[derive(Debug, Clone)]
pub enum Messages {
SetKeyConfig(InputId, Vec<(Key, Modifiers)>),
SetKeyConfig(InputId, Vec<KeyConfigOptions>),
SetDisplayZoneImage(DisplayZone),
ClearDisplayZoneImage(DisplayZone),
ClearAllDisplayZoneImages,
Expand All @@ -16,12 +17,16 @@ pub enum Messages {
BackendInitialised,

OpenConfigurationPanel(ConfigurableZones),
OpenInputMappingConfigurationPanel(ConfigurableZones),
OpenInputMappingConfigurationPanel(ConfigurableZones, ExtraConfigMode),
CloseConfigurationPanel,

ResetInputBuffer,
ClearCommandInput,

CommandInputChanged(String),
CommandAdded(Command),
KeyboardInput(Key, Modifiers),
RemoveAction(usize),

Tick,
}
110 changes: 93 additions & 17 deletions config-frontend/src/views/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ mod knobs;
mod touchscreen;

use crate::common::{
ButtonInput, ConfigurableZones, KnobInput, TouchscreenInput, TouchscreenZoneInput,
ButtonInput, ConfigurableZones, ExtraConfigMode, KeyConfigOptions, KnobInput, TouchscreenInput,
TouchscreenZoneInput,
};
use crate::components::modal::modal;
use crate::messages::Messages;
Expand All @@ -15,10 +16,11 @@ use crate::views::config::touchscreen::{
touchscreen_extra, touchscreen_swipe_settings, touchscreen_zone_config_settings,
touchscreen_zones_row,
};
use iced::keyboard::{Key, Modifiers};
use iced::widget::column;
use iced::widget::{column, row};
use iced::{Length, widget};
use messaging::protos::inputs::InputId;
use messaging::protos::key_config::FreeformCommand;
use messaging::protos::key_config::command_action::Command;

pub struct Config;

Expand All @@ -30,23 +32,81 @@ const TOUCHSCREEN_ZONES: u8 = 4;
impl<'a> Config {
fn input_capture_modal(
input: ConfigurableZones,
current_key_sequence: Vec<(Key, Modifiers)>,
current_key_sequence: Vec<KeyConfigOptions>,
current_mode: ExtraConfigMode,
current_command_input: String,
) -> widget::Column<'a, Messages> {
let options = row![
widget::radio(
"Key",
ExtraConfigMode::KeyRecording,
Some(current_mode),
|value| { Messages::OpenInputMappingConfigurationPanel(input.clone(), value) }
),
widget::radio(
"Command",
ExtraConfigMode::Command,
Some(current_mode),
|value| { Messages::OpenInputMappingConfigurationPanel(input.clone(), value) }
),
];

let input_id: InputId = input.into();

let current_display = widget::text!("{:?}", current_key_sequence);
let actions_display: widget::Column<'a, Messages> = current_key_sequence
.iter()
.enumerate()
.fold(column![], |item, (index, action)| {
item.push(
widget::button(widget::text(format!("{:?}", action)))
.on_press(Messages::RemoveAction(index)),
)
});

let submit_button = widget::button("OK").on_press(Messages::SetKeyConfig(
input_id,
current_key_sequence
.iter()
.map(|mapping| match mapping {
KeyConfigOptions::Key(key) => KeyConfigOptions::Key(key.to_owned()),
KeyConfigOptions::Command(command) => {
KeyConfigOptions::Command(command.to_owned())
}
})
.collect(),
));

let submit_button =
widget::button("OK").on_press(Messages::SetKeyConfig(input_id, current_key_sequence));
let reset_button = widget::button("Reset").on_press(Messages::ResetInputBuffer);

column![current_display, submit_button]
let ctas = row![submit_button, reset_button];

if current_mode == ExtraConfigMode::Command {
let command_input = widget::text_input("Input command", &current_command_input)
.on_input(Messages::CommandInputChanged);
let add_command_button = widget::button("Add Command").on_press(
Messages::CommandAdded(Command::FreeformCommand(FreeformCommand {
command: current_command_input.clone(),
..FreeformCommand::default()
})),
);
return column![
options,
actions_display,
command_input,
add_command_button,
ctas
];
}
column![options, actions_display, ctas]
}

pub fn view(
&'_ self,
brightness: u8,
selected_config_zone: ConfigurableZones,
current_key_sequence: Vec<(Key, Modifiers)>,
current_key_sequence: Vec<KeyConfigOptions>,
selected_mode: ExtraConfigMode,
current_command_input: String,
) -> iced::Element<'_, Messages> {
let base = widget::container(
column![
Expand Down Expand Up @@ -79,24 +139,35 @@ impl<'a> Config {
| ConfigurableZones::Button9(ref selected_input)
| ConfigurableZones::Button10(ref selected_input) => match selected_input {
// Open the capture modal
ButtonInput::Released | ButtonInput::Pressed => {
Self::input_capture_modal(selected_config_zone, current_key_sequence)
}
ButtonInput::Released | ButtonInput::Pressed => Self::input_capture_modal(
selected_config_zone,
current_key_sequence,
selected_mode,
current_command_input,
),
_ => button_config_settings(selected_config_zone),
},
ConfigurableZones::Touchscreen1(ref selected_input)
| ConfigurableZones::Touchscreen2(ref selected_input)
| ConfigurableZones::Touchscreen3(ref selected_input)
| ConfigurableZones::Touchscreen4(ref selected_input) => match selected_input {
TouchscreenZoneInput::Pressed => {
Self::input_capture_modal(selected_config_zone, current_key_sequence)
}
TouchscreenZoneInput::Pressed => Self::input_capture_modal(
selected_config_zone,
current_key_sequence,
selected_mode,
current_command_input,
),
_ => touchscreen_zone_config_settings(selected_config_zone),
},
ConfigurableZones::TouchscreenExtra(ref selected_input) => match selected_input
{
TouchscreenInput::SwipeLeft | TouchscreenInput::SwipeRight => {
Self::input_capture_modal(selected_config_zone, current_key_sequence)
Self::input_capture_modal(
selected_config_zone,
current_key_sequence,
selected_mode,
current_command_input,
)
}
_ => touchscreen_swipe_settings(),
},
Expand All @@ -105,7 +176,12 @@ impl<'a> Config {
| ConfigurableZones::Knob3(ref selected_input)
| ConfigurableZones::Knob4(ref selected_input) => match selected_input {
KnobInput::CounterClockwise | KnobInput::Clockwise | KnobInput::Pressed => {
Self::input_capture_modal(selected_config_zone, current_key_sequence)
Self::input_capture_modal(
selected_config_zone,
current_key_sequence,
selected_mode,
current_command_input,
)
}
_ => knob_config_settings(selected_config_zone),
},
Expand Down
18 changes: 11 additions & 7 deletions config-frontend/src/views/config/buttons.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::common::{ButtonInput, ConfigurableZones};
use crate::common::{ButtonInput, ConfigurableZones, ExtraConfigMode};
use crate::messages::Messages;
use crate::views::config::BUTTON_COUNT;
use iced::widget;
Expand Down Expand Up @@ -113,12 +113,16 @@ pub fn button_config_settings<'a>(button: ConfigurableZones) -> widget::Column<'
let button =
widget::button("Set Image").on_press(Messages::SetDisplayZoneImage(button_mapping.1));

let pressed_action_button = widget::button("On pressed").on_press(
Messages::OpenInputMappingConfigurationPanel(button_mapping.2),
);
let released_action_button = widget::button("On released").on_press(
Messages::OpenInputMappingConfigurationPanel(button_mapping.3),
);
let pressed_action_button =
widget::button("On pressed").on_press(Messages::OpenInputMappingConfigurationPanel(
button_mapping.2,
ExtraConfigMode::KeyRecording,
));
let released_action_button =
widget::button("On released").on_press(Messages::OpenInputMappingConfigurationPanel(
button_mapping.3,
ExtraConfigMode::KeyRecording,
));

let clear_image_button =
widget::button("Clear Image").on_press(Messages::ClearDisplayZoneImage(button_mapping.1));
Expand Down
Loading
Loading