custom interactivity hotkey

This commit is contained in:
2026-03-21 22:28:14 +08:00
parent 8f4aab3d87
commit a72430e65f
6 changed files with 796 additions and 10 deletions

View File

@@ -1,7 +1,7 @@
mod store;
mod window;
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize};
use specta::Type;
use thiserror::Error;
@@ -12,6 +12,213 @@ pub use window::open_config_window;
pub struct AppConfig {
pub api_base_url: Option<String>,
pub debug_mode: bool,
#[serde(default)]
pub scene_interactivity_hotkey: SceneInteractivityHotkey,
}
#[derive(Serialize, Clone, Debug, PartialEq, Eq, Type)]
pub struct SceneInteractivityHotkey {
#[serde(default)]
pub modifiers: Vec<SceneInteractivityModifier>,
#[serde(default)]
pub key: Option<SceneInteractivityKey>,
}
impl SceneInteractivityHotkey {
pub fn normalized(mut self) -> Self {
self.modifiers.sort_unstable();
self.modifiers.dedup();
if self.modifiers.is_empty() {
return Self::default();
}
self
}
fn from_legacy(value: LegacySceneInteractivityHotkey) -> Self {
let modifiers = match value {
LegacySceneInteractivityHotkey::CmdAlt => {
vec![
SceneInteractivityModifier::Cmd,
SceneInteractivityModifier::Alt,
]
}
LegacySceneInteractivityHotkey::CmdCtrl => {
vec![
SceneInteractivityModifier::Cmd,
SceneInteractivityModifier::Ctrl,
]
}
LegacySceneInteractivityHotkey::AltCtrl => {
vec![
SceneInteractivityModifier::Alt,
SceneInteractivityModifier::Ctrl,
]
}
LegacySceneInteractivityHotkey::Cmd => vec![SceneInteractivityModifier::Cmd],
LegacySceneInteractivityHotkey::Alt => vec![SceneInteractivityModifier::Alt],
LegacySceneInteractivityHotkey::Ctrl => vec![SceneInteractivityModifier::Ctrl],
};
Self {
modifiers,
key: None,
}
}
}
impl<'de> Deserialize<'de> for SceneInteractivityHotkey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct SceneInteractivityHotkeyV2 {
#[serde(default)]
modifiers: Vec<SceneInteractivityModifier>,
#[serde(default)]
key: Option<SceneInteractivityKey>,
}
#[derive(Deserialize)]
#[serde(untagged)]
enum SceneInteractivityHotkeySerde {
V2(SceneInteractivityHotkeyV2),
Legacy(LegacySceneInteractivityHotkey),
}
let value = SceneInteractivityHotkeySerde::deserialize(deserializer)?;
let normalized = match value {
SceneInteractivityHotkeySerde::V2(v2) => Self {
modifiers: v2.modifiers,
key: v2.key,
}
.normalized(),
SceneInteractivityHotkeySerde::Legacy(legacy) => Self::from_legacy(legacy).normalized(),
};
Ok(normalized)
}
}
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Type)]
#[serde(rename_all = "snake_case")]
pub enum SceneInteractivityModifier {
Cmd,
Alt,
Ctrl,
Shift,
}
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Type)]
#[serde(rename_all = "snake_case")]
pub enum SceneInteractivityKey {
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
Num0,
Num1,
Num2,
Num3,
Num4,
Num5,
Num6,
Num7,
Num8,
Num9,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
Enter,
Space,
Escape,
Tab,
Backspace,
Delete,
Insert,
Home,
End,
PageUp,
PageDown,
ArrowUp,
ArrowDown,
ArrowLeft,
ArrowRight,
Minus,
Equal,
LeftBracket,
RightBracket,
BackSlash,
Semicolon,
Apostrophe,
Comma,
Dot,
Slash,
Grave,
}
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
enum LegacySceneInteractivityHotkey {
CmdAlt,
CmdCtrl,
AltCtrl,
Cmd,
Alt,
Ctrl,
}
impl Default for SceneInteractivityHotkey {
fn default() -> Self {
#[cfg(target_os = "macos")]
{
Self {
modifiers: vec![SceneInteractivityModifier::Cmd],
key: None,
}
}
#[cfg(not(target_os = "macos"))]
{
Self {
modifiers: vec![SceneInteractivityModifier::Alt],
key: None,
}
}
}
}
#[derive(Debug, Error)]