use std::collections::VecDeque;
use windows::Win32::{
Foundation::HWND,
Graphics::Gdi::{HBRUSH, HFONT},
UI::WindowsAndMessaging::HMENU,
};
use crate::{config, input::hotkeys::HotkeyAction};
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum RuntimeCommand {
Hotkey(HotkeyAction),
AutoconvertLastWord,
}
#[derive(Debug, Clone)]
pub struct UiError {
pub title: String,
pub user_text: String,
pub _debug_text: String,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum HotkeySlot {
LastWord,
LastSequence,
Pause,
Selection,
SwitchLayout,
}
#[derive(Debug, Default, Clone)]
pub struct HotkeyValues {
pub last_word: Option<config::Hotkey>,
pub last_sequence: Option<config::Hotkey>,
pub pause: Option<config::Hotkey>,
pub selection: Option<config::Hotkey>,
pub switch_layout: Option<config::Hotkey>,
}
impl HotkeyValues {
pub fn from_config(cfg: &config::Config) -> Self {
Self {
last_word: cfg.hotkey_convert_last_word,
last_sequence: cfg.hotkey_convert_last_sequence,
pause: cfg.hotkey_pause,
selection: cfg.hotkey_convert_selection,
switch_layout: cfg.hotkey_switch_layout,
}
}
#[allow(dead_code)]
pub fn get(&self, slot: HotkeySlot) -> Option<config::Hotkey> {
match slot {
HotkeySlot::LastWord => self.last_word,
HotkeySlot::LastSequence => self.last_sequence,
HotkeySlot::Pause => self.pause,
HotkeySlot::Selection => self.selection,
HotkeySlot::SwitchLayout => self.switch_layout,
}
}
pub fn set(&mut self, slot: HotkeySlot, hk: Option<config::Hotkey>) {
match slot {
HotkeySlot::LastWord => self.last_word = hk,
HotkeySlot::LastSequence => self.last_sequence = hk,
HotkeySlot::Pause => self.pause = hk,
HotkeySlot::Selection => self.selection = hk,
HotkeySlot::SwitchLayout => self.switch_layout = hk,
}
}
}
#[derive(Debug, Default, Clone)]
pub struct HotkeySequenceValues {
pub last_word: Option<config::HotkeySequence>,
pub last_sequence: Option<config::HotkeySequence>,
pub pause: Option<config::HotkeySequence>,
pub selection: Option<config::HotkeySequence>,
pub switch_layout: Option<config::HotkeySequence>,
}
impl HotkeySequenceValues {
pub fn from_config(cfg: &config::Config) -> Self {
Self {
last_word: cfg.hotkey_convert_last_word_sequence,
last_sequence: cfg.hotkey_convert_last_sequence_sequence,
pause: cfg.hotkey_pause_sequence,
selection: cfg.hotkey_convert_selection_sequence,
switch_layout: cfg.hotkey_switch_layout_sequence,
}
}
pub fn get(&self, slot: HotkeySlot) -> Option<config::HotkeySequence> {
match slot {
HotkeySlot::LastWord => self.last_word,
HotkeySlot::LastSequence => self.last_sequence,
HotkeySlot::Pause => self.pause,
HotkeySlot::Selection => self.selection,
HotkeySlot::SwitchLayout => self.switch_layout,
}
}
pub fn set(&mut self, slot: HotkeySlot, seq: Option<config::HotkeySequence>) {
match slot {
HotkeySlot::LastWord => self.last_word = seq,
HotkeySlot::LastSequence => self.last_sequence = seq,
HotkeySlot::Pause => self.pause = seq,
HotkeySlot::Selection => self.selection = seq,
HotkeySlot::SwitchLayout => self.switch_layout = seq,
}
}
}
#[derive(Debug, Default)]
pub struct HotkeyCaptureUi {
pub active: bool,
pub slot: Option<HotkeySlot>,
pub pending_mods_vks: u32,
pub pending_mods: u32,
pub pending_mods_valid: bool,
pub saw_non_mod: bool,
pub last_input_tick_ms: u64,
}
impl HotkeyCaptureUi {
pub fn start(&mut self, slot: HotkeySlot) {
self.active = true;
self.slot = Some(slot);
self.pending_mods_vks = 0;
self.pending_mods = 0;
self.pending_mods_valid = false;
self.saw_non_mod = false;
self.last_input_tick_ms = 0;
}
pub fn stop(&mut self) {
self.active = false;
self.slot = None;
self.pending_mods_vks = 0;
self.pending_mods = 0;
self.pending_mods_valid = false;
self.saw_non_mod = false;
self.last_input_tick_ms = 0;
}
}
#[derive(Debug, Default)]
pub struct RuntimeChordCapture {
pub pending_mods_vks: u32,
pub pending_mods: u32,
pub pending_mods_valid: bool,
pub saw_non_mod: bool,
}
#[derive(Debug, Default, Clone, Copy)]
pub struct SequenceProgress {
pub waiting_second: bool,
pub first_tick_ms: u64,
}
#[derive(Debug, Default)]
pub struct HotkeySequenceProgress {
pub last_word: SequenceProgress,
pub last_sequence: SequenceProgress,
pub pause: SequenceProgress,
pub selection: SequenceProgress,
pub switch_layout: SequenceProgress,
}
#[derive(Debug, Default)]
pub struct AppState {
pub font: HFONT,
pub checkboxes: Checkboxes,
pub edits: Edits,
pub hotkeys: HotkeyEdits,
pub buttons: Buttons,
pub autoconvert_enabled: bool,
pub errors: VecDeque<UiError>,
pub hotkey_values: HotkeyValues,
pub hotkey_sequence_values: HotkeySequenceValues,
pub hotkey_capture: HotkeyCaptureUi,
pub active_hotkey_sequences: HotkeySequenceValues,
pub runtime_chord_capture: RuntimeChordCapture,
pub hotkey_sequence_progress: HotkeySequenceProgress,
pub pending_runtime_commands: VecDeque<RuntimeCommand>,
pub runtime_command_running: bool,
pub active_switch_layout_sequence: Option<config::HotkeySequence>,
pub switch_layout_waiting_second: bool,
pub switch_layout_first_tick_ms: u64,
pub current_theme_dark: bool,
pub dark_brush_window_bg: HBRUSH,
pub dark_brush_control_bg: HBRUSH,
pub dark_brush_edit_bg: HBRUSH,
}
#[derive(Debug, Default)]
pub struct Checkboxes {
pub autostart: HWND,
pub start_minimized: HWND,
pub theme_dark: HWND,
}
#[derive(Debug, Default)]
pub struct Edits {
pub delay_ms: HWND,
}
#[derive(Debug, Default)]
pub struct HotkeyEdits {
pub last_word: HWND,
pub last_sequence: HWND,
pub pause: HWND,
pub selection: HWND,
pub switch_layout: HWND,
}
#[derive(Debug, Default)]
pub struct Buttons {
pub apply: HWND,
pub cancel: HWND,
pub exit: HWND,
}
#[repr(i32)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ControlId {
Autostart = 1001,
Tray = 1002,
DelayMs = 1003,
StartMinimized = 1004,
DarkTheme = 1005,
HotkeyLastWord = 1201,
HotkeyLastSequence = 1202,
HotkeyPause = 1203,
HotkeySelection = 1204,
HotkeySwitchLayout = 1205,
Apply = 1101,
Cancel = 1102,
Exit = 1103,
}
impl ControlId {
#[inline]
pub const fn from_i32(v: i32) -> Option<Self> {
match v {
1001 => Some(Self::Autostart),
1002 => Some(Self::Tray),
1003 => Some(Self::DelayMs),
1004 => Some(Self::StartMinimized),
1005 => Some(Self::DarkTheme),
1201 => Some(Self::HotkeyLastWord),
1202 => Some(Self::HotkeyLastSequence),
1203 => Some(Self::HotkeyPause),
1204 => Some(Self::HotkeySelection),
1205 => Some(Self::HotkeySwitchLayout),
1101 => Some(Self::Apply),
1102 => Some(Self::Cancel),
1103 => Some(Self::Exit),
_ => None,
}
}
#[inline]
pub fn hmenu(self) -> windows::Win32::UI::WindowsAndMessaging::HMENU {
use std::ffi::c_void;
let id = self as u16;
HMENU(usize::from(id) as *mut c_void)
}
}