Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,9 @@ show_preset_toasts = true
# Show cursor tool preview bubble near the pointer
show_tool_preview = false

# Filter help overlay sections based on enabled features
help_overlay_context_filter = true

# Initial toolbar offsets (layer-shell/inline)
# Horizontal offset for the top toolbar
top_offset = 0.0
Expand All @@ -315,7 +318,10 @@ side_offset_x = 0.0

[ui.help_overlay_style]
# Font size for help overlay text
font_size = 16.0
font_size = 14.0

# Font family for help overlay text (comma-separated fallback list)
font_family = "Noto Sans, DejaVu Sans, Liberation Sans, Sans"

# Line height for help text
line_height = 22.0
Expand Down
12 changes: 12 additions & 0 deletions configurator/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1775,6 +1775,12 @@ impl ConfiguratorApp {
fn ui_help_overlay_tab(&self) -> Element<'_, Message> {
let column = column![
text("Help Overlay Style").size(18),
toggle_row(
"Filter sections by enabled features",
self.draft.help_context_filter,
self.defaults.help_context_filter,
ToggleField::UiHelpOverlayContextFilter,
),
color_quad_editor(
"Background RGBA (0-1)",
&self.draft.help_bg_color,
Expand All @@ -1793,6 +1799,12 @@ impl ConfiguratorApp {
&self.defaults.help_text_color,
QuadField::HelpText,
),
labeled_input(
"Font family",
&self.draft.help_font_family,
&self.defaults.help_font_family,
TextField::HelpFontFamily,
),
row![
labeled_input(
"Font size",
Expand Down
8 changes: 8 additions & 0 deletions configurator/src/models/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,15 @@ pub struct ConfigDraft {
pub click_highlight_fill_color: ColorQuadInput,
pub click_highlight_outline_color: ColorQuadInput,

pub help_font_family: String,
pub help_font_size: String,
pub help_line_height: String,
pub help_padding: String,
pub help_bg_color: ColorQuadInput,
pub help_border_color: ColorQuadInput,
pub help_border_width: String,
pub help_text_color: ColorQuadInput,
pub help_context_filter: bool,

pub board_enabled: bool,
pub board_default_mode: BoardModeOption,
Expand Down Expand Up @@ -512,13 +514,15 @@ impl ConfigDraft {
config.ui.click_highlight.outline_color,
),

help_font_family: config.ui.help_overlay_style.font_family.clone(),
help_font_size: format_float(config.ui.help_overlay_style.font_size),
help_line_height: format_float(config.ui.help_overlay_style.line_height),
help_padding: format_float(config.ui.help_overlay_style.padding),
help_bg_color: ColorQuadInput::from(config.ui.help_overlay_style.bg_color),
help_border_color: ColorQuadInput::from(config.ui.help_overlay_style.border_color),
help_border_width: format_float(config.ui.help_overlay_style.border_width),
help_text_color: ColorQuadInput::from(config.ui.help_overlay_style.text_color),
help_context_filter: config.ui.help_overlay_context_filter,

board_enabled: config.board.enabled,
board_default_mode: BoardModeOption::from_str(&config.board.default_mode)
Expand Down Expand Up @@ -812,6 +816,7 @@ impl ConfigDraft {
Err(err) => errors.push(err),
}

config.ui.help_overlay_style.font_family = self.help_font_family.trim().to_string();
parse_field(
&self.help_font_size,
"ui.help_overlay_style.font_size",
Expand Down Expand Up @@ -857,6 +862,7 @@ impl ConfigDraft {
Ok(values) => config.ui.help_overlay_style.text_color = values,
Err(err) => errors.push(err),
}
config.ui.help_overlay_context_filter = self.help_context_filter;

config.board.enabled = self.board_enabled;
config.board.default_mode = self.board_default_mode.as_str().to_string();
Expand Down Expand Up @@ -1007,6 +1013,7 @@ impl ConfigDraft {
ToggleField::PerformanceVsync => self.performance_enable_vsync = value,
ToggleField::UiShowStatusBar => self.ui_show_status_bar = value,
ToggleField::UiShowFrozenBadge => self.ui_show_frozen_badge = value,
ToggleField::UiHelpOverlayContextFilter => self.help_context_filter = value,
ToggleField::UiContextMenuEnabled => self.ui_context_menu_enabled = value,
ToggleField::UiXdgFullscreen => self.ui_xdg_fullscreen = value,
ToggleField::UiToolbarTopPinned => self.ui_toolbar_top_pinned = value,
Expand Down Expand Up @@ -1114,6 +1121,7 @@ impl ConfigDraft {
TextField::HighlightRadius => self.click_highlight_radius = value,
TextField::HighlightOutlineThickness => self.click_highlight_outline_thickness = value,
TextField::HighlightDurationMs => self.click_highlight_duration_ms = value,
TextField::HelpFontFamily => self.help_font_family = value,
TextField::HelpFontSize => self.help_font_size = value,
TextField::HelpLineHeight => self.help_line_height = value,
TextField::HelpPadding => self.help_padding = value,
Expand Down
2 changes: 2 additions & 0 deletions configurator/src/models/fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ pub enum ToggleField {
PerformanceVsync,
UiShowStatusBar,
UiShowFrozenBadge,
UiHelpOverlayContextFilter,
UiContextMenuEnabled,
UiXdgFullscreen,
UiToolbarTopPinned,
Expand Down Expand Up @@ -620,6 +621,7 @@ pub enum TextField {
HighlightRadius,
HighlightOutlineThickness,
HighlightDurationMs,
HelpFontFamily,
HelpFontSize,
HelpLineHeight,
HelpPadding,
Expand Down
6 changes: 5 additions & 1 deletion docs/CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ show_status_bar = true
# Show a small "FROZEN" badge when frozen mode is active
show_frozen_badge = true

# Filter help overlay sections based on enabled features
help_overlay_context_filter = true

# Status bar position
# Options: "top-left", "top-right", "bottom-left", "bottom-right"
status_bar_position = "bottom-left"
Expand All @@ -180,7 +183,8 @@ dot_radius = 4.0

# Help overlay styling
[ui.help_overlay_style]
font_size = 16.0
font_size = 14.0
font_family = "Noto Sans, DejaVu Sans, Liberation Sans, Sans"
line_height = 22.0
padding = 20.0
bg_color = [0.0, 0.0, 0.0, 0.85] # Darker background
Expand Down
4 changes: 1 addition & 3 deletions src/backend/wayland/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,7 @@ fn process_tray_action(state: &mut WaylandState) {
}
}
"toggle_help" => {
state.input_state.show_help = !state.input_state.show_help;
state.input_state.dirty_tracker.mark_full();
state.input_state.needs_redraw = true;
state.input_state.toggle_help_overlay();
}
other => warn!("Unknown tray action '{}'", other),
}
Expand Down
26 changes: 23 additions & 3 deletions src/backend/wayland/handlers/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,16 +357,36 @@ impl PointerHandler for WaylandState {
self.input_state.needs_redraw = true;
}
PointerEventKind::Axis { vertical, .. } => {
if on_toolbar || self.pointer_over_toolbar() {
continue;
}
let scroll_direction = if vertical.discrete != 0 {
vertical.discrete
} else if vertical.absolute.abs() > 0.1 {
if vertical.absolute > 0.0 { 1 } else { -1 }
} else {
0
};
if self.input_state.show_help {
if scroll_direction != 0 {
let delta = if scroll_direction > 0 { 1.0 } else { -1.0 };
let scroll_step = 48.0;
let max_scroll = self.input_state.help_overlay_scroll_max;
let mut next =
self.input_state.help_overlay_scroll + delta * scroll_step;
if max_scroll > 0.0 {
next = next.clamp(0.0, max_scroll);
} else {
next = next.max(0.0);
}
if (next - self.input_state.help_overlay_scroll).abs() > f64::EPSILON {
self.input_state.help_overlay_scroll = next;
self.input_state.dirty_tracker.mark_full();
self.input_state.needs_redraw = true;
}
}
continue;
}
if on_toolbar || self.pointer_over_toolbar() {
continue;
}
if self.input_state.modifiers.ctrl && self.input_state.modifiers.alt {
if scroll_direction != 0 {
let zoom_in = scroll_direction < 0;
Expand Down
1 change: 0 additions & 1 deletion src/backend/wayland/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ mod session;
mod state;
mod surface;
mod toolbar;
mod toolbar_icons;
mod toolbar_intent;
mod zoom;

Expand Down
22 changes: 20 additions & 2 deletions src/backend/wayland/state/render.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use crate::backend::wayland::toolbar_icons;
use crate::toolbar_icons;

impl WaylandState {
pub(in crate::backend::wayland) fn render(&mut self, qh: &QueueHandle<Self>) -> Result<bool> {
Expand Down Expand Up @@ -420,13 +420,31 @@ impl WaylandState {

// Render help overlay if toggled
if self.input_state.show_help {
crate::ui::render_help_overlay(
let page_prev_label = self
.input_state
.action_binding_label(crate::config::Action::PagePrev);
let page_next_label = self
.input_state
.action_binding_label(crate::config::Action::PageNext);
let scroll_max = crate::ui::render_help_overlay(
&ctx,
&self.config.ui.help_overlay_style,
width,
height,
self.frozen_enabled(),
self.input_state.help_overlay_view,
self.input_state.help_overlay_page,
page_prev_label.as_str(),
page_next_label.as_str(),
self.input_state.help_overlay_search.as_str(),
self.config.ui.help_overlay_context_filter,
self.input_state.board_config.enabled,
self.config.capture.enabled,
self.input_state.help_overlay_scroll,
);
self.input_state.help_overlay_scroll_max = scroll_max;
self.input_state.help_overlay_scroll =
self.input_state.help_overlay_scroll.clamp(0.0, scroll_max);
}

crate::ui::render_ui_toast(&ctx, &self.input_state, width, height);
Expand Down
2 changes: 1 addition & 1 deletion src/backend/wayland/toolbar/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
use anyhow::Result;

use crate::backend::wayland::toolbar::format_binding_label;
use crate::backend::wayland::toolbar_icons;
use crate::draw::{
BLACK, BLUE, Color, EraserKind, FontDescriptor, GREEN, ORANGE, PINK, RED, WHITE, YELLOW,
};
use crate::input::state::PresetFeedbackKind;
use crate::input::{EraserMode, Tool};
use crate::toolbar_icons;
use crate::ui::toolbar::{ToolbarEvent, ToolbarSnapshot};
use crate::util::color_to_name;

Expand Down
18 changes: 18 additions & 0 deletions src/config/keybindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fmt;

/// All possible actions that can be bound to keys.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
Expand Down Expand Up @@ -214,6 +215,23 @@ impl KeyBinding {
}
}

impl fmt::Display for KeyBinding {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut parts: Vec<&str> = Vec::new();
if self.ctrl {
parts.push("Ctrl");
}
if self.shift {
parts.push("Shift");
}
if self.alt {
parts.push("Alt");
}
parts.push(self.key.as_str());
write!(f, "{}", parts.join("+"))
}
}

/// Configuration for all keybindings.
///
/// Each action can have multiple keybindings. Users specify them in config.toml as:
Expand Down
22 changes: 20 additions & 2 deletions src/config/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ pub struct UiConfig {
#[serde(default)]
pub help_overlay_style: HelpOverlayStyle,

/// Filter help overlay sections based on enabled features
#[serde(default = "default_help_overlay_context_filter")]
pub help_overlay_context_filter: bool,

/// Preferred output name for the xdg-shell fallback overlay (GNOME).
/// Falls back to last entered output or first available.
#[serde(default)]
Expand Down Expand Up @@ -384,6 +388,7 @@ impl Default for UiConfig {
status_bar_position: default_status_position(),
status_bar_style: StatusBarStyle::default(),
help_overlay_style: HelpOverlayStyle::default(),
help_overlay_context_filter: default_help_overlay_context_filter(),
preferred_output: None,
xdg_fullscreen: default_xdg_fullscreen(),
click_highlight: ClickHighlightConfig::default(),
Expand Down Expand Up @@ -497,6 +502,10 @@ pub struct HelpOverlayStyle {
#[serde(default = "default_help_font_size")]
pub font_size: f64,

/// Font family for help overlay text (comma-separated fallback list)
#[serde(default = "default_help_font_family")]
pub font_family: String,

/// Line height for help text
#[serde(default = "default_help_line_height")]
pub line_height: f64,
Expand Down Expand Up @@ -526,6 +535,7 @@ impl Default for HelpOverlayStyle {
fn default() -> Self {
Self {
font_size: default_help_font_size(),
font_family: default_help_font_family(),
line_height: default_help_line_height(),
padding: default_help_padding(),
bg_color: default_help_bg_color(),
Expand Down Expand Up @@ -717,6 +727,10 @@ fn default_xdg_fullscreen() -> bool {
false
}

fn default_help_overlay_context_filter() -> bool {
true
}

fn default_status_position() -> StatusPosition {
StatusPosition::BottomLeft
}
Expand Down Expand Up @@ -744,11 +758,15 @@ fn default_status_dot_radius() -> f64 {

// Help overlay style defaults
fn default_help_font_size() -> f64 {
18.0
14.0
}

fn default_help_font_family() -> String {
"Noto Sans, DejaVu Sans, Liberation Sans, Sans".to_string()
}

fn default_help_line_height() -> f64 {
28.0
22.0
}

fn default_help_padding() -> f64 {
Expand Down
4 changes: 3 additions & 1 deletion src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ pub mod tool;
// Re-export commonly used types at module level
pub use board_mode::BoardMode;
pub use events::{Key, MouseButton};
pub use state::{ClickHighlightSettings, DrawingState, InputState, TextInputMode, ZoomAction};
pub use state::{
ClickHighlightSettings, DrawingState, HelpOverlayView, InputState, TextInputMode, ZoomAction,
};
#[cfg(tablet)]
#[allow(unused_imports)]
pub use tablet::TabletSettings;
Expand Down
Loading