diff --git a/src/app/keybind.rs b/src/app/keybind.rs new file mode 100644 index 0000000..2dbd950 --- /dev/null +++ b/src/app/keybind.rs @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-3.0-only + +use crate::Message; +use crate::app::{ContextPage, Subscription}; +use cosmic::iced::Event; +use cosmic::iced::keyboard; +use cosmic::iced::keyboard::Key; +use cosmic::iced::keyboard::key::Named; + +//TODO: HashMap for reconfigurable ones + +/// Keybinding are currently hardcoded as follows: +/// +/// | Character | Binding | +/// |-----------|---------| +/// | F1 | => about | +/// | Enter | => take a picture or start/stop recording | +/// | a | => toggles auto focus | +/// | c | => toggles color picker | +/// | e | => toggles exposure picker | +/// | f | => toggles flash | +/// | g | => opens gallery | +/// | n | => next mode | +/// | m | => toggle audio recording or mute/unmute | +/// | p | => toggle motor picker | +/// | q | => toggle QR detection | +/// | r | => toggle save burst RAW | +/// | s | => switches camera | +/// | t | => toggles timelapse | +/// | u | => toggles theatre UI | +/// | v | => toggles virtual camera | +/// | | => toggles play/pause | +/// | Ctrl + a | => cycles aspect ratio | +/// | Ctrl + f | => toggles format picker | +/// | Ctrl + q | => currently noop //TODO: close app | +/// | Ctrl + r | => reset settings | +/// | Ctrl + t | => toggles theatre mode | +/// | Ctrl + + | => zoom in | +/// | Ctrl + - | => zoom out | +/// | Ctrl + 0 | => reset zoom | +/// | Ctrl + , | => opens/closes settings | +/// | Ctrl + Enter |=> start recording after delay | +/// +/// **Returns** a subscription to key events mapped similarly as GNOME Camera's for now +pub fn key_subscription() -> Subscription { + fn event_to_functionality( + event: cosmic::iced::Event, + _status: cosmic::iced::event::Status, + _window: cosmic::iced::window::Id, + ) -> Option { + let Event::Keyboard(keyboard::Event::KeyPressed { key, modifiers, .. }) = event else { + return None; + }; + + match &key { + Key::Named(Named::F1) + if !modifiers.control() && !modifiers.logo() && !modifiers.alt() => + { + Some(Message::ToggleContextPage(ContextPage::About)) + } + + // TODO: couldn't capture mode, need to think about it + Key::Named(Named::Enter) + if !modifiers.control() && !modifiers.logo() && !modifiers.alt() => + { + Some(Message::Capture) + } + Key::Named(Named::Enter) + if modifiers.control() && !modifiers.logo() && !modifiers.alt() => + { + Some(Message::StartRecordingAfterDelay) + } + + Key::Character(c) if modifiers.control() && !modifiers.logo() && !modifiers.alt() => { + match c.as_str() { + "a" => Some(Message::CyclePhotoAspectRatio), + "f" => Some(Message::ToggleFormatPicker), + "q" => Some(Message::Noop), + "r" => Some(Message::ResetAllSettings), + "t" => Some(Message::ToggleTheatreMode), + "+" => Some(Message::ZoomIn), + "-" => Some(Message::ZoomOut), + " " => Some(Message::AbortPhotoTimer), + "0" => Some(Message::ResetZoom), + "," => Some(Message::ToggleContextPage(ContextPage::Settings)), + _ => None, + } + } + + Key::Character(c) if !modifiers.control() && !modifiers.logo() && !modifiers.alt() => { + match c.as_str() { + "a" => Some(Message::ToggleFocusAuto), + "c" => Some(Message::ToggleColorPicker), + "e" => Some(Message::ToggleExposurePicker), + "f" => Some(Message::ToggleFlash), + "g" => Some(Message::OpenGallery), + "n" => Some(Message::NextMode), + "m" => Some(Message::ToggleRecordAudio), + "p" => Some(Message::ToggleMotorPicker), + "q" => Some(Message::ToggleQrDetection), + "r" => Some(Message::ToggleSaveBurstRaw), + "s" => Some(Message::SwitchCamera), + "t" => Some(Message::ToggleTimelapse), + "u" => Some(Message::TheatreToggleUI), + "v" => Some(Message::ToggleVirtualCamera), + " " => Some(Message::ToggleVideoPlayPause), + _ => None, + } + } + _ => None, + } + } + cosmic::iced::event::listen_raw(event_to_functionality) +} diff --git a/src/app/mod.rs b/src/app/mod.rs index 87e8097..03b2e8b 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -39,6 +39,7 @@ mod gallery_primitive; mod gallery_widget; mod handlers; pub mod insights; +mod keybind; mod motor_picker; pub mod qr_overlay; pub mod settings; @@ -51,6 +52,7 @@ mod video_widget; mod view; // Re-export public API +use crate::app::keybind::key_subscription; use crate::config::Config; use crate::fl; use cosmic::app::context_drawer; @@ -1498,6 +1500,8 @@ impl cosmic::Application for AppModel { Subscription::none() }; + let keybind_sub = key_subscription(); + Subscription::batch([ config_sub, camera_sub, @@ -1510,6 +1514,7 @@ impl cosmic::Application for AppModel { brightness_eval_sub, insights_update_sub, portal_theme_sub, + keybind_sub, ]) }