feat: KO creation with checkboxes (matching egui)
- Replace ModComboBox with Ctrl/Shift/Alt checkboxes for KO mods - Build HID bitmask from checkboxes (Ctrl=0x01, Shift=0x02, Alt=0x04) - Add DarkCheckbox component (Dracula theme) - Descriptive label: "When you press [From] key, output [To] key instead" - Read all KO fields from properties (no args in callback) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
33adcc5aa4
commit
e8f4ee41a6
4 changed files with 75 additions and 19 deletions
21
src/main.rs
21
src/main.rs
|
|
@ -1083,13 +1083,18 @@ fn main() {
|
|||
let tx = bg_tx.clone();
|
||||
let window_weak = window.as_weak();
|
||||
|
||||
window.global::<AdvancedBridge>().on_create_ko(move |trig_code, trig_mod_idx, result_code, res_mod_idx| {
|
||||
window.global::<AdvancedBridge>().on_create_ko(move || {
|
||||
let Some(w) = window_weak.upgrade() else { return };
|
||||
let trig = trig_code as u8;
|
||||
let trig_mod = mod_idx_to_byte(trig_mod_idx);
|
||||
let result = result_code as u8;
|
||||
let res_mod = mod_idx_to_byte(res_mod_idx);
|
||||
let next_idx = w.global::<AdvancedBridge>().get_key_overrides().row_count() as u8;
|
||||
let adv = w.global::<AdvancedBridge>();
|
||||
let trig = adv.get_new_ko_trigger_code() as u8;
|
||||
let trig_mod = (adv.get_new_ko_trig_ctrl() as u8)
|
||||
| ((adv.get_new_ko_trig_shift() as u8) << 1)
|
||||
| ((adv.get_new_ko_trig_alt() as u8) << 2);
|
||||
let result = adv.get_new_ko_result_code() as u8;
|
||||
let res_mod = (adv.get_new_ko_res_ctrl() as u8)
|
||||
| ((adv.get_new_ko_res_shift() as u8) << 1)
|
||||
| ((adv.get_new_ko_res_alt() as u8) << 2);
|
||||
let next_idx = adv.get_key_overrides().row_count() as u8;
|
||||
let cmd = logic::protocol::cmd_koset(next_idx, trig, trig_mod, result, res_mod);
|
||||
let serial = serial.clone();
|
||||
let tx = tx.clone();
|
||||
|
|
@ -1100,9 +1105,7 @@ fn main() {
|
|||
let lines = ser.query_command("KO?").unwrap_or_default();
|
||||
let _ = tx.send(BgMsg::TextLines("ko".into(), lines));
|
||||
});
|
||||
if let Some(w) = window_weak.upgrade() {
|
||||
w.global::<AppState>().set_status_text("Creating key override...".into());
|
||||
}
|
||||
w.global::<AppState>().set_status_text("Creating key override...".into());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
45
ui/components/dark_checkbox.slint
Normal file
45
ui/components/dark_checkbox.slint
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { Theme } from "../theme.slint";
|
||||
|
||||
export component DarkCheckbox inherits Rectangle {
|
||||
in property <string> text;
|
||||
in-out property <bool> checked: false;
|
||||
|
||||
height: 24px;
|
||||
min-width: box.width + label.preferred-width + 10px;
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: 4px;
|
||||
alignment: start;
|
||||
|
||||
box := Rectangle {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
y: (parent.height - self.height) / 2;
|
||||
border-radius: 3px;
|
||||
border-width: 1px;
|
||||
border-color: root.checked ? Theme.accent-purple : Theme.button-border;
|
||||
background: root.checked ? Theme.accent-purple : Theme.button-bg;
|
||||
|
||||
Text {
|
||||
text: root.checked ? "v" : "";
|
||||
color: #282a36;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
label := Text {
|
||||
text: root.text;
|
||||
color: Theme.fg-primary;
|
||||
font-size: 11px;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => { root.checked = !root.checked; }
|
||||
mouse-cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
|
@ -171,10 +171,14 @@ export global AdvancedBridge {
|
|||
// KO creation: keycodes for trigger and result
|
||||
in-out property <int> new-ko-trigger-code: 0;
|
||||
in-out property <string> new-ko-trigger-name: "Pick...";
|
||||
in-out property <int> new-ko-trig-mod-idx: 0; // 0=None,1=Ctrl,2=Shift,...
|
||||
in-out property <bool> new-ko-trig-ctrl: false;
|
||||
in-out property <bool> new-ko-trig-shift: false;
|
||||
in-out property <bool> new-ko-trig-alt: false;
|
||||
in-out property <int> new-ko-result-code: 0;
|
||||
in-out property <string> new-ko-result-name: "Pick...";
|
||||
in-out property <int> new-ko-res-mod-idx: 0;
|
||||
in-out property <bool> new-ko-res-ctrl: false;
|
||||
in-out property <bool> new-ko-res-shift: false;
|
||||
in-out property <bool> new-ko-res-alt: false;
|
||||
// Leader creation
|
||||
in-out property <int> new-leader-seq0-code: 0;
|
||||
in-out property <string> new-leader-seq0-name: "";
|
||||
|
|
@ -200,7 +204,7 @@ export global AdvancedBridge {
|
|||
callback set-trilayer(int, int, int);
|
||||
callback bt-switch(int);
|
||||
callback create-combo(); // reads r1,c1,r2,c2,result from properties
|
||||
callback create-ko(int, int, int, int); // trigger_code, trig_mod_idx, result_code, res_mod_idx
|
||||
callback create-ko(); // reads all fields from properties
|
||||
callback create-leader(int, int); // result_code, result_mod_idx (sequence comes from seq0-3 properties)
|
||||
// TAMA
|
||||
in property <string> tama-status: "";
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { ScrollView } from "std-widgets.slint";
|
|||
import { Theme } from "../theme.slint";
|
||||
import { DarkButton } from "../components/dark_button.slint";
|
||||
import { DarkComboBox } from "../components/dark_combo_box.slint";
|
||||
import { DarkCheckbox } from "../components/dark_checkbox.slint";
|
||||
import { AdvancedBridge, AppState, ConnectionState, KeymapBridge } from "../globals.slint";
|
||||
|
||||
component SectionHeader inherits Text {
|
||||
|
|
@ -141,25 +142,28 @@ export component TabAdvanced inherits Rectangle {
|
|||
padding: 10px;
|
||||
spacing: 8px;
|
||||
Text { text: "Add Key Override"; color: Theme.fg-secondary; font-size: 12px; font-weight: 600; }
|
||||
Text { text: "When you press [From] key, output [To] key instead"; color: Theme.fg-secondary; font-size: 10px; }
|
||||
HorizontalLayout {
|
||||
spacing: 8px;
|
||||
alignment: start;
|
||||
Text { text: "Trigger:"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; }
|
||||
Text { text: "From:"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; }
|
||||
PickButton { label: AdvancedBridge.new-ko-trigger-name; target: "ko-trigger"; }
|
||||
Text { text: "Mod:"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; }
|
||||
ModComboBox { current-index <=> AdvancedBridge.new-ko-trig-mod-idx; }
|
||||
DarkCheckbox { text: "Ctrl"; checked <=> AdvancedBridge.new-ko-trig-ctrl; }
|
||||
DarkCheckbox { text: "Shift"; checked <=> AdvancedBridge.new-ko-trig-shift; }
|
||||
DarkCheckbox { text: "Alt"; checked <=> AdvancedBridge.new-ko-trig-alt; }
|
||||
}
|
||||
HorizontalLayout {
|
||||
spacing: 8px;
|
||||
alignment: start;
|
||||
Text { text: "Result:"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; }
|
||||
Text { text: "To:"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; }
|
||||
PickButton { label: AdvancedBridge.new-ko-result-name; target: "ko-result"; }
|
||||
Text { text: "Mod:"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; }
|
||||
ModComboBox { current-index <=> AdvancedBridge.new-ko-res-mod-idx; }
|
||||
DarkCheckbox { text: "Ctrl"; checked <=> AdvancedBridge.new-ko-res-ctrl; }
|
||||
DarkCheckbox { text: "Shift"; checked <=> AdvancedBridge.new-ko-res-shift; }
|
||||
DarkCheckbox { text: "Alt"; checked <=> AdvancedBridge.new-ko-res-alt; }
|
||||
}
|
||||
DarkButton {
|
||||
text: "Add Key Override";
|
||||
clicked => { AdvancedBridge.create-ko(AdvancedBridge.new-ko-trigger-code, AdvancedBridge.new-ko-trig-mod-idx, AdvancedBridge.new-ko-result-code, AdvancedBridge.new-ko-res-mod-idx); }
|
||||
clicked => { AdvancedBridge.create-ko(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue