style: Replace all std Button with custom DarkButton (Dracula theme)

Custom DarkButton component with Dracula theme colors:
- bg-secondary base, button-hover on hover
- primary variant with accent-purple
- Disabled state with reduced opacity
- Consistent 28px height, 4px border-radius

Also fixes PickDarkButton/KeyDarkButton naming errors from agent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mae PUGIN 2026-04-06 20:52:44 +02:00
parent 32ee3a6d26
commit 28fbf10b79
8 changed files with 77 additions and 38 deletions

View file

@ -1,5 +1,6 @@
import { ComboBox, Button } from "std-widgets.slint"; import { ComboBox } from "std-widgets.slint";
import { Theme } from "../theme.slint"; import { Theme } from "../theme.slint";
import { DarkButton } from "dark_button.slint";
import { AppState, ConnectionBridge, ConnectionState } from "../globals.slint"; import { AppState, ConnectionBridge, ConnectionState } from "../globals.slint";
export component ConnectionBar inherits Rectangle { export component ConnectionBar inherits Rectangle {
@ -29,7 +30,7 @@ export component ConnectionBar inherits Rectangle {
} }
// Connect/Disconnect button // Connect/Disconnect button
Button { DarkButton {
text: AppState.connection == ConnectionState.connected ? "Disconnect" : "Connect"; text: AppState.connection == ConnectionState.connected ? "Disconnect" : "Connect";
enabled: AppState.connection == ConnectionState.connected || AppState.connection == ConnectionState.disconnected; enabled: AppState.connection == ConnectionState.connected || AppState.connection == ConnectionState.disconnected;
clicked => { clicked => {

View file

@ -0,0 +1,32 @@
import { Theme } from "../theme.slint";
export component DarkButton inherits Rectangle {
in property <string> text;
in property <bool> enabled: true;
in property <bool> primary: false;
callback clicked();
min-width: btn-text.preferred-width + 20px;
height: 28px;
border-radius: 4px;
background: !root.enabled ? Theme.bg-primary
: root.primary && ta.has-hover ? Theme.accent-purple.darker(0.2)
: root.primary ? Theme.accent-purple
: ta.has-hover ? Theme.button-hover
: Theme.button-bg;
opacity: root.enabled ? 1.0 : 0.5;
btn-text := Text {
text: root.text;
color: root.enabled ? Theme.fg-primary : Theme.fg-secondary;
font-size: 12px;
horizontal-alignment: center;
vertical-alignment: center;
}
ta := TouchArea {
enabled: root.enabled;
clicked => { root.clicked(); }
mouse-cursor: root.enabled ? pointer : default;
}
}

View file

@ -1,5 +1,6 @@
import { LineEdit, Button, ComboBox, ScrollView } from "std-widgets.slint"; import { LineEdit, ComboBox, ScrollView } from "std-widgets.slint";
import { Theme } from "../theme.slint"; import { Theme } from "../theme.slint";
import { DarkButton } from "dark_button.slint";
import { KeySelectorBridge, KeymapBridge, KeyEntry, KeycapData } from "../globals.slint"; import { KeySelectorBridge, KeymapBridge, KeyEntry, KeycapData } from "../globals.slint";
import { KeyButton } from "key_button.slint"; import { KeyButton } from "key_button.slint";
@ -185,7 +186,7 @@ export component KeySelector inherits Rectangle {
font-size: 11px; font-size: 11px;
vertical-alignment: center; vertical-alignment: center;
} }
Button { DarkButton {
text: "Set"; text: "Set";
clicked => { clicked => {
KeySelectorBridge.apply-mt(mt-mod.current-index, mt-key.current-index); KeySelectorBridge.apply-mt(mt-mod.current-index, mt-key.current-index);
@ -217,7 +218,7 @@ export component KeySelector inherits Rectangle {
font-size: 11px; font-size: 11px;
vertical-alignment: center; vertical-alignment: center;
} }
Button { DarkButton {
text: "Set"; text: "Set";
clicked => { clicked => {
KeySelectorBridge.apply-lt(lt-layer.current-index, lt-key.current-index); KeySelectorBridge.apply-lt(lt-layer.current-index, lt-key.current-index);
@ -248,7 +249,7 @@ export component KeySelector inherits Rectangle {
font-size: 11px; font-size: 11px;
vertical-alignment: center; vertical-alignment: center;
} }
Button { DarkButton {
text: "Set"; text: "Set";
clicked => { clicked => {
KeySelectorBridge.apply-hex(KeySelectorBridge.hex-input); KeySelectorBridge.apply-hex(KeySelectorBridge.hex-input);

View file

@ -1,5 +1,6 @@
import { Button, ComboBox, ScrollView } from "std-widgets.slint"; import { ComboBox, ScrollView } from "std-widgets.slint";
import { Theme } from "../theme.slint"; import { Theme } from "../theme.slint";
import { DarkButton } from "../components/dark_button.slint";
import { AdvancedBridge, AppState, ConnectionState, KeymapBridge } from "../globals.slint"; import { AdvancedBridge, AppState, ConnectionState, KeymapBridge } from "../globals.slint";
component SectionHeader inherits Text { component SectionHeader inherits Text {
@ -25,7 +26,7 @@ component ItemRow inherits Rectangle {
Text { text: root.left; color: Theme.fg-primary; font-size: 11px; vertical-alignment: center; horizontal-stretch: 1; } Text { text: root.left; color: Theme.fg-primary; font-size: 11px; vertical-alignment: center; horizontal-stretch: 1; }
Text { text: "->"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; } Text { text: "->"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; }
Text { text: root.right; color: Theme.accent-green; font-size: 11px; vertical-alignment: center; } Text { text: root.right; color: Theme.accent-green; font-size: 11px; vertical-alignment: center; }
Button { text: "Del"; clicked => { root.delete(); } } DarkButton { text: "Del"; clicked => { root.delete(); } }
} }
} }
@ -61,7 +62,7 @@ export component TabAdvanced inherits Rectangle {
spacing: 8px; spacing: 8px;
Text { text: "Advanced Features"; color: Theme.fg-primary; font-size: 20px; font-weight: 700; vertical-alignment: center; } Text { text: "Advanced Features"; color: Theme.fg-primary; font-size: 20px; font-weight: 700; vertical-alignment: center; }
Rectangle { horizontal-stretch: 1; } Rectangle { horizontal-stretch: 1; }
Button { DarkButton {
text: "Refresh All"; text: "Refresh All";
enabled: AppState.connection == ConnectionState.connected; enabled: AppState.connection == ConnectionState.connected;
clicked => { AdvancedBridge.refresh-advanced(); } clicked => { AdvancedBridge.refresh-advanced(); }
@ -139,7 +140,7 @@ export component TabAdvanced inherits Rectangle {
Text { text: "Mod:"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; } Text { text: "Mod:"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; }
ModComboBox { current-index <=> AdvancedBridge.new-ko-res-mod-idx; } ModComboBox { current-index <=> AdvancedBridge.new-ko-res-mod-idx; }
} }
Button { DarkButton {
text: "Add Key Override"; 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(AdvancedBridge.new-ko-trigger-code, AdvancedBridge.new-ko-trig-mod-idx, AdvancedBridge.new-ko-result-code, AdvancedBridge.new-ko-res-mod-idx); }
} }
@ -159,7 +160,7 @@ export component TabAdvanced inherits Rectangle {
HorizontalLayout { HorizontalLayout {
spacing: 8px; spacing: 8px;
Text { text: AdvancedBridge.autoshift-status != "" ? AdvancedBridge.autoshift-status : "Unknown"; color: Theme.fg-primary; font-size: 11px; vertical-alignment: center; } Text { text: AdvancedBridge.autoshift-status != "" ? AdvancedBridge.autoshift-status : "Unknown"; color: Theme.fg-primary; font-size: 11px; vertical-alignment: center; }
Button { text: "Toggle"; clicked => { AdvancedBridge.toggle-autoshift(); } } DarkButton { text: "Toggle"; clicked => { AdvancedBridge.toggle-autoshift(); } }
} }
} }
} }
@ -207,7 +208,7 @@ export component TabAdvanced inherits Rectangle {
alignment: start; alignment: start;
Text { text: "Result:"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; } Text { text: "Result:"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; }
PickButton { label: AdvancedBridge.new-combo-result-name; target: "combo-result"; } PickButton { label: AdvancedBridge.new-combo-result-name; target: "combo-result"; }
Button { DarkButton {
text: "Add Combo"; text: "Add Combo";
clicked => { AdvancedBridge.create-combo(); } clicked => { AdvancedBridge.create-combo(); }
} }
@ -278,7 +279,7 @@ export component TabAdvanced inherits Rectangle {
Text { text: "Mod:"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; } Text { text: "Mod:"; color: Theme.fg-secondary; font-size: 11px; vertical-alignment: center; }
ModComboBox { current-index <=> AdvancedBridge.new-leader-mod-idx; } ModComboBox { current-index <=> AdvancedBridge.new-leader-mod-idx; }
} }
Button { DarkButton {
text: "Add Leader Key"; text: "Add Leader Key";
clicked => { AdvancedBridge.create-leader(AdvancedBridge.new-leader-result-code, AdvancedBridge.new-leader-mod-idx); } clicked => { AdvancedBridge.create-leader(AdvancedBridge.new-leader-result-code, AdvancedBridge.new-leader-mod-idx); }
} }
@ -304,7 +305,7 @@ export component TabAdvanced inherits Rectangle {
ComboBox { width: 50px; model: ["0","1","2","3","4","5","6","7","8","9"]; current-index <=> AdvancedBridge.tri-l2-idx; } ComboBox { width: 50px; model: ["0","1","2","3","4","5","6","7","8","9"]; current-index <=> AdvancedBridge.tri-l2-idx; }
Text { text: "-> L3:"; color: Theme.fg-secondary; font-size: 12px; vertical-alignment: center; } Text { text: "-> L3:"; color: Theme.fg-secondary; font-size: 12px; vertical-alignment: center; }
ComboBox { width: 50px; model: ["0","1","2","3","4","5","6","7","8","9"]; current-index <=> AdvancedBridge.tri-l3-idx; } ComboBox { width: 50px; model: ["0","1","2","3","4","5","6","7","8","9"]; current-index <=> AdvancedBridge.tri-l3-idx; }
Button { text: "Set"; clicked => { AdvancedBridge.set-trilayer(AdvancedBridge.tri-l1-idx, AdvancedBridge.tri-l2-idx, AdvancedBridge.tri-l3-idx); } } DarkButton { text: "Set"; clicked => { AdvancedBridge.set-trilayer(AdvancedBridge.tri-l1-idx, AdvancedBridge.tri-l2-idx, AdvancedBridge.tri-l3-idx); } }
} }
} }
} }
@ -332,11 +333,11 @@ export component TabAdvanced inherits Rectangle {
Text { text: AdvancedBridge.tama-status; color: Theme.fg-primary; font-size: 11px; wrap: word-wrap; } Text { text: AdvancedBridge.tama-status; color: Theme.fg-primary; font-size: 11px; wrap: word-wrap; }
HorizontalLayout { HorizontalLayout {
spacing: 4px; spacing: 4px;
Button { text: "Feed"; clicked => { AdvancedBridge.tama-action("feed"); } } DarkButton { text: "Feed"; clicked => { AdvancedBridge.tama-action("feed"); } }
Button { text: "Play"; clicked => { AdvancedBridge.tama-action("play"); } } DarkButton { text: "Play"; clicked => { AdvancedBridge.tama-action("play"); } }
Button { text: "Sleep"; clicked => { AdvancedBridge.tama-action("sleep"); } } DarkButton { text: "Sleep"; clicked => { AdvancedBridge.tama-action("sleep"); } }
Button { text: "Meds"; clicked => { AdvancedBridge.tama-action("meds"); } } DarkButton { text: "Meds"; clicked => { AdvancedBridge.tama-action("meds"); } }
Button { text: "On/Off"; clicked => { AdvancedBridge.tama-action("toggle"); } } DarkButton { text: "On/Off"; clicked => { AdvancedBridge.tama-action("toggle"); } }
} }
} }
} }

View file

@ -1,5 +1,6 @@
import { Button, ComboBox, LineEdit } from "std-widgets.slint"; import { ComboBox, LineEdit } from "std-widgets.slint";
import { Theme } from "../theme.slint"; import { Theme } from "../theme.slint";
import { DarkButton } from "../components/dark_button.slint";
import { FlasherBridge } from "../globals.slint"; import { FlasherBridge } from "../globals.slint";
export component TabFlasher inherits Rectangle { export component TabFlasher inherits Rectangle {
@ -57,7 +58,7 @@ export component TabFlasher inherits Rectangle {
placeholder-text: "/dev/ttyUSB0"; placeholder-text: "/dev/ttyUSB0";
} }
Button { DarkButton {
text: "Refresh"; text: "Refresh";
clicked => { FlasherBridge.refresh-prog-ports(); } clicked => { FlasherBridge.refresh-prog-ports(); }
} }
@ -123,7 +124,7 @@ export component TabFlasher inherits Rectangle {
overflow: elide; overflow: elide;
} }
Button { DarkButton {
text: "Browse..."; text: "Browse...";
clicked => { FlasherBridge.browse-firmware(); } clicked => { FlasherBridge.browse-firmware(); }
} }
@ -143,7 +144,7 @@ export component TabFlasher inherits Rectangle {
HorizontalLayout { HorizontalLayout {
spacing: 12px; spacing: 12px;
Button { DarkButton {
text: FlasherBridge.flashing ? "Flashing..." : "Flash Firmware"; text: FlasherBridge.flashing ? "Flashing..." : "Flash Firmware";
enabled: !FlasherBridge.flashing enabled: !FlasherBridge.flashing
&& FlasherBridge.firmware-path != "" && FlasherBridge.firmware-path != ""

View file

@ -1,5 +1,6 @@
import { Button, LineEdit } from "std-widgets.slint"; import { LineEdit } from "std-widgets.slint";
import { Theme } from "../theme.slint"; import { Theme } from "../theme.slint";
import { DarkButton } from "../components/dark_button.slint";
import { KeymapBridge, AppState, ConnectionState } from "../globals.slint"; import { KeymapBridge, AppState, ConnectionState } from "../globals.slint";
import { KeyboardView } from "../components/keyboard_view.slint"; import { KeyboardView } from "../components/keyboard_view.slint";
@ -56,7 +57,7 @@ export component TabKeymap inherits VerticalLayout {
root.renaming = false; root.renaming = false;
} }
} }
Button { DarkButton {
text: "Cancel"; text: "Cancel";
clicked => { root.renaming = false; } clicked => { root.renaming = false; }
} }
@ -129,7 +130,7 @@ export component TabKeymap inherits VerticalLayout {
Rectangle { horizontal-stretch: 1; } Rectangle { horizontal-stretch: 1; }
Button { DarkButton {
text: "Change Key..."; text: "Change Key...";
clicked => { clicked => {
KeymapBridge.key-selector-open = true; KeymapBridge.key-selector-open = true;

View file

@ -1,5 +1,6 @@
import { Button, ComboBox, ScrollView, LineEdit } from "std-widgets.slint"; import { ComboBox, ScrollView, LineEdit } from "std-widgets.slint";
import { Theme } from "../theme.slint"; import { Theme } from "../theme.slint";
import { DarkButton } from "../components/dark_button.slint";
import { MacroBridge, AppState, ConnectionState, KeymapBridge } from "../globals.slint"; import { MacroBridge, AppState, ConnectionState, KeymapBridge } from "../globals.slint";
export component TabMacros inherits Rectangle { export component TabMacros inherits Rectangle {
@ -14,7 +15,7 @@ export component TabMacros inherits Rectangle {
spacing: 8px; spacing: 8px;
Text { text: "Macros"; color: Theme.fg-primary; font-size: 20px; font-weight: 700; vertical-alignment: center; } Text { text: "Macros"; color: Theme.fg-primary; font-size: 20px; font-weight: 700; vertical-alignment: center; }
Rectangle { horizontal-stretch: 1; } Rectangle { horizontal-stretch: 1; }
Button { DarkButton {
text: "Refresh"; text: "Refresh";
enabled: AppState.connection == ConnectionState.connected; enabled: AppState.connection == ConnectionState.connected;
clicked => { MacroBridge.refresh-macros(); } clicked => { MacroBridge.refresh-macros(); }
@ -87,7 +88,7 @@ export component TabMacros inherits Rectangle {
spacing: 6px; spacing: 6px;
alignment: start; alignment: start;
Button { DarkButton {
text: "Add Key"; text: "Add Key";
clicked => { clicked => {
KeymapBridge.selector-target = "macro-step"; KeymapBridge.selector-target = "macro-step";
@ -95,14 +96,14 @@ export component TabMacros inherits Rectangle {
} }
} }
Button { text: "T 50ms"; clicked => { MacroBridge.add-delay-step(50); } } DarkButton { text: "T 50ms"; clicked => { MacroBridge.add-delay-step(50); } }
Button { text: "T 100ms"; clicked => { MacroBridge.add-delay-step(100); } } DarkButton { text: "T 100ms"; clicked => { MacroBridge.add-delay-step(100); } }
Button { text: "T 200ms"; clicked => { MacroBridge.add-delay-step(200); } } DarkButton { text: "T 200ms"; clicked => { MacroBridge.add-delay-step(200); } }
Rectangle { horizontal-stretch: 1; } Rectangle { horizontal-stretch: 1; }
Button { text: "Undo"; clicked => { MacroBridge.remove-last-step(); } } DarkButton { text: "Undo"; clicked => { MacroBridge.remove-last-step(); } }
Button { text: "Clear"; clicked => { MacroBridge.clear-steps(); } } DarkButton { text: "Clear"; clicked => { MacroBridge.clear-steps(); } }
} }
// Save // Save
@ -110,7 +111,7 @@ export component TabMacros inherits Rectangle {
spacing: 8px; spacing: 8px;
alignment: start; alignment: start;
Button { DarkButton {
text: "Save Macro"; text: "Save Macro";
enabled: AppState.connection == ConnectionState.connected; enabled: AppState.connection == ConnectionState.connected;
clicked => { MacroBridge.save-macro(); } clicked => { MacroBridge.save-macro(); }
@ -153,7 +154,7 @@ export component TabMacros inherits Rectangle {
Text { text: "#" + macro.slot; color: Theme.accent-purple; font-size: 12px; vertical-alignment: center; width: 30px; } Text { text: "#" + macro.slot; color: Theme.accent-purple; font-size: 12px; vertical-alignment: center; width: 30px; }
Text { text: macro.name; color: Theme.fg-primary; font-size: 12px; font-weight: 600; vertical-alignment: center; width: 100px; } Text { text: macro.name; color: Theme.fg-primary; font-size: 12px; font-weight: 600; vertical-alignment: center; width: 100px; }
Text { text: macro.steps; color: Theme.fg-secondary; font-size: 10px; vertical-alignment: center; horizontal-stretch: 1; overflow: elide; } Text { text: macro.steps; color: Theme.fg-secondary; font-size: 10px; vertical-alignment: center; horizontal-stretch: 1; overflow: elide; }
Button { text: "Del"; clicked => { MacroBridge.delete-macro(macro.slot); } } DarkButton { text: "Del"; clicked => { MacroBridge.delete-macro(macro.slot); } }
} }
} }
} }

View file

@ -1,5 +1,6 @@
import { Button, ScrollView } from "std-widgets.slint"; import { ScrollView } from "std-widgets.slint";
import { Theme } from "../theme.slint"; import { Theme } from "../theme.slint";
import { DarkButton } from "../components/dark_button.slint";
import { StatsBridge, AppState, ConnectionState } from "../globals.slint"; import { StatsBridge, AppState, ConnectionState } from "../globals.slint";
component BarChart inherits Rectangle { component BarChart inherits Rectangle {
@ -63,7 +64,7 @@ export component TabStats inherits Rectangle {
vertical-alignment: center; vertical-alignment: center;
} }
Rectangle { horizontal-stretch: 1; } Rectangle { horizontal-stretch: 1; }
Button { DarkButton {
text: "Refresh"; text: "Refresh";
enabled: AppState.connection == ConnectionState.connected; enabled: AppState.connection == ConnectionState.connected;
clicked => { StatsBridge.refresh-stats(); } clicked => { StatsBridge.refresh-stats(); }