Use slider toggles for boolean controls

This commit is contained in:
Georg Bauer
2026-07-28 18:38:30 +02:00
parent 9cf1c70a67
commit 00af0335ff
5 changed files with 28 additions and 23 deletions

View File

@@ -20,9 +20,9 @@ use crate::model::{
use crate::settings::{GIB, REASONING_MODES};
use iced::theme::{Palette, palette};
use iced::widget::{
Button, Space, Svg, Tooltip, button, checkbox, column, container, image, markdown, mouse_area,
opaque, pick_list, progress_bar, row, rule, scrollable, slider, stack, svg, text, text_editor,
text_input, tooltip,
Button, Space, Svg, Tooltip, button, column, container, image, markdown, mouse_area, opaque,
pick_list, progress_bar, row, rule, scrollable, slider, stack, svg, text, text_editor,
text_input, toggler, tooltip,
};
use iced::{Alignment, Background, Border, Color, Element, Length, Padding, Theme, window};
use std::collections::VecDeque;
@@ -984,6 +984,10 @@ fn danger_button<'a>(content: impl Into<Element<'a, Message>>) -> Button<'a, Mes
button(content).padding([8, 14]).style(danger_button_style)
}
fn toggle<'a>(checked: bool) -> iced::widget::Toggler<'a, Message> {
toggler(checked).size(18).spacing(8)
}
fn action_button_style(_: &Theme, status: button::Status) -> button::Style {
let (background, text_color) = match status {
button::Status::Active | button::Status::Pressed => {

View File

@@ -495,10 +495,10 @@ impl App {
&surface.data,
context,
));
let checkbox = checkbox(checked).label(label);
let control = toggle(checked).label(label);
if let Some(path) = local_path(binding_path(binding), context_path.as_deref()) {
let surface_id = surface.id.clone();
checkbox
control
.on_toggle(move |value| {
Message::A2uiDataChanged(
surface_id.clone(),
@@ -508,7 +508,7 @@ impl App {
})
.into()
} else {
checkbox.into()
control.into()
}
}
"Slider" => {
@@ -617,7 +617,7 @@ impl App {
}
chips = chips.push(choice);
} else if multiple {
let mut choice = checkbox(is_selected).label(label);
let mut choice = toggle(is_selected).label(label);
if let Some(path) = path.clone() {
let surface_id = surface.id.clone();
let option_value = option_value.clone();

View File

@@ -59,7 +59,7 @@ impl App {
file_list = file_list.push(rule::horizontal(1)).push(
container(
row![
checkbox(selected).on_toggle({
toggle(selected).on_toggle({
let path = path.clone();
move |_| Message::ToggleGitFile(path.clone())
}),

View File

@@ -9,7 +9,7 @@ impl App {
.supports_dspark()
.then_some(Message::PreferenceLegacyMtpChanged);
let legacy_mtp = hint(
checkbox(self.preference_draft.legacy_mtp_enabled)
toggle(self.preference_draft.legacy_mtp_enabled)
.label("Enable legacy MTP for this model")
.on_toggle_maybe(legacy_mtp_toggle),
"Uses the managed one-stage MTP support GGUF. The target model verifies every drafted token; it is mutually exclusive with DSpark.",
@@ -20,7 +20,7 @@ impl App {
.supports_dspark()
.then_some(Message::PreferenceDsparkChanged);
let dspark = hint(
checkbox(self.preference_draft.dspark_enabled)
toggle(self.preference_draft.dspark_enabled)
.label("Enable DSpark for this model")
.on_toggle_maybe(dspark_toggle),
"Speculative decoding with the managed DSpark draft artifact: a small model proposes tokens that the main model verifies in one pass. Usually a large speedup; the target model may also stream routed experts from SSD.",
@@ -121,7 +121,7 @@ impl App {
.align_y(Alignment::Center),
text("Enter a whole number from 1 to 1440.").size(12),
hint(
checkbox(self.preference_draft.a2ui_enabled)
toggle(self.preference_draft.a2ui_enabled)
.label("Enable interactive A2UI chat surfaces")
.on_toggle(Message::PreferenceA2uiChanged),
"Lets the local model build validated native charts, tables, forms and other interactive chat surfaces. Turning it off removes the A2UI catalog from the system prompt.",
@@ -134,7 +134,7 @@ impl App {
"LOCAL ENDPOINT",
column![
hint(
checkbox(self.preference_draft.endpoint_enabled)
toggle(self.preference_draft.endpoint_enabled)
.label("Enable OpenAI-compatible endpoint")
.on_toggle(Message::PreferenceEndpointEnabledChanged),
"Serves the loaded model over an OpenAI-style HTTP API, so editors, scripts and agents on this machine can use it. Turned off, only this window can generate.",
@@ -146,7 +146,7 @@ impl App {
.on_input(Message::PreferenceEndpointPortChanged),
),
hint(
checkbox(self.preference_draft.endpoint_cors)
toggle(self.preference_draft.endpoint_cors)
.label("Allow browser clients (CORS)")
.on_toggle(Message::PreferenceEndpointCorsChanged),
"Answers with permissive CORS headers so JavaScript running in a web page may call the endpoint. Leave it off when only native tools connect.",
@@ -161,7 +161,7 @@ impl App {
"DEV BRAIN",
column![
hint(
checkbox(self.preference_draft.dev_brain_enabled)
toggle(self.preference_draft.dev_brain_enabled)
.label("Enable project-backed LLM wiki")
.on_toggle(Message::PreferenceDevBrainEnabledChanged),
"Lets the agent use its normal file tools on managed pages in a dedicated Obsidian vault, with indexed search and validation. Disabled means no Dev Brain access or prompt instructions.",
@@ -228,13 +228,13 @@ impl App {
.spacing(12)
.align_y(Alignment::Center),
hint(
checkbox(self.preference_draft.git_indent_heuristic)
toggle(self.preference_draft.git_indent_heuristic)
.label("Use indentation heuristic")
.on_toggle(Message::PreferenceGitIndentHeuristicChanged),
"Shift ambiguous hunk boundaries toward indentation changes, which usually makes source-code diffs easier to read.",
),
hint(
checkbox(self.preference_draft.git_ignore_blank_lines)
toggle(self.preference_draft.git_ignore_blank_lines)
.label("Ignore blank-line changes")
.on_toggle(Message::PreferenceGitIgnoreBlankLinesChanged),
"Hide hunks whose changed lines are all blank.",
@@ -348,13 +348,13 @@ impl App {
prefill,
),
hint(
checkbox(self.preference_draft.quality)
toggle(self.preference_draft.quality)
.label("Prefer exact quality kernels")
.on_toggle(Message::PreferenceQualityChanged),
"Runs the exact Metal kernels instead of the fast approximations. Slightly slower, and it removes the small numeric differences those approximations introduce.",
),
hint(
checkbox(self.preference_draft.warm_weights)
toggle(self.preference_draft.warm_weights)
.label("Warm mapped weights at load time")
.on_toggle(Message::PreferenceWarmWeightsChanged),
"Reads every mapped weight page once at load, so the first reply is not interrupted by page faults from disk. Loading takes longer and memory pressure rises immediately.",
@@ -402,13 +402,13 @@ impl App {
.on_input(Message::PreferenceMtpMarginChanged),
),
hint(
checkbox(self.preference_draft.glm_mtp)
toggle(self.preference_draft.glm_mtp)
.label("Enable integrated GLM MTP")
.on_toggle_maybe(glm_mtp_toggle),
"Uses the prediction head built into GLM 5.2 for speculative decoding, so no separate draft model is loaded. Available for GLM 5.2 only.",
),
hint(
checkbox(self.preference_draft.glm_mtp_timing)
toggle(self.preference_draft.glm_mtp_timing)
.label("Log GLM MTP timing counters")
.on_toggle_maybe(glm_mtp_timing_toggle),
"Records per-stage timings of the speculative path to the log, to show where the acceleration actually goes. A diagnostic aid that costs a little throughput.",
@@ -421,7 +421,7 @@ impl App {
dspark_confidence,
),
hint(
checkbox(self.preference_draft.dspark_strict)
toggle(self.preference_draft.dspark_strict)
.label("DSpark target-only decode")
.on_toggle_maybe(dspark_strict_toggle),
"Lets the draft model only propose, never decide: every token is sampled by the full model. Gives up some of the speedup in exchange for output identical to non-speculative decoding.",
@@ -457,13 +457,13 @@ impl App {
Space::new().height(6),
text("SSD STREAMING").size(11).color(muted_text()),
hint(
checkbox(self.preference_draft.ssd_streaming)
toggle(self.preference_draft.ssd_streaming)
.label("Enable SSD-backed model streaming")
.on_toggle(Message::PreferenceSsdChanged),
"Leaves the routed expert weights on disk and pages them in as they are needed, so a model larger than this machine's memory still runs. Every cache miss waits for the SSD; speculative support weights remain resident while target experts stream.",
),
hint(
checkbox(self.preference_draft.ssd_streaming_cold)
toggle(self.preference_draft.ssd_streaming_cold)
.label("Skip automatic expert preload")
.on_toggle(Message::PreferenceSsdColdChanged),
"Starts with an empty expert cache instead of reading the likely experts up front. The model is ready sooner and uses less memory, at the price of slow first replies.",