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
3 changes: 3 additions & 0 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,9 @@ toggle_status_bar = ["F12", "F4"]
# Toggle fill for rectangle/ellipse
toggle_fill = []

# Toggle selection properties panel
toggle_selection_properties = ["Ctrl+Alt+P"]

# Toggle context menu (keyboard alternative to right-click)
open_context_menu = ["Shift+F10", "Menu"]

Expand Down
3 changes: 3 additions & 0 deletions docs/CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,9 @@ toggle_click_highlight = ["Ctrl+Shift+H"]
# Toggle highlight-only drawing tool
toggle_highlight_tool = ["Ctrl+Alt+H"]

# Toggle selection properties panel
toggle_selection_properties = ["Ctrl+Alt+P"]

# Toggle eraser behavior (brush vs stroke)
toggle_eraser_mode = ["Ctrl+Shift+E"]

Expand Down
7 changes: 7 additions & 0 deletions src/backend/wayland/state/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,12 @@ impl WaylandState {
crate::ui::render_preset_toast(&ctx, &self.input_state, width, height);

if !self.zoom.active {
if self.input_state.is_properties_panel_open() {
self.input_state
.update_properties_panel_layout(&ctx, width, height);
} else {
self.input_state.clear_properties_panel_layout();
}
crate::ui::render_properties_panel(&ctx, &self.input_state, width, height);

if self.input_state.is_context_menu_open() {
Expand All @@ -438,6 +444,7 @@ impl WaylandState {
crate::ui::render_context_menu(&ctx, &self.input_state, width, height);
} else {
self.input_state.clear_context_menu_layout();
self.input_state.clear_properties_panel_layout();
}

// Inline toolbars (xdg fallback) render directly into main surface when layer-shell is unavailable.
Expand Down
12 changes: 12 additions & 0 deletions src/config/keybindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ pub enum Action {
ToggleToolbar,
ToggleHighlightTool,
ToggleFill,
ToggleSelectionProperties,
OpenContextMenu,

// Configurator
Expand Down Expand Up @@ -367,6 +368,8 @@ pub struct KeybindingsConfig {

#[serde(default = "default_toggle_highlight_tool")]
pub toggle_highlight_tool: Vec<String>,
#[serde(default = "default_toggle_selection_properties")]
pub toggle_selection_properties: Vec<String>,
#[serde(default = "default_open_context_menu")]
pub open_context_menu: Vec<String>,

Expand Down Expand Up @@ -531,6 +534,7 @@ impl Default for KeybindingsConfig {
toggle_toolbar: default_toggle_toolbar(),
toggle_fill: default_toggle_fill(),
toggle_highlight_tool: default_toggle_highlight_tool(),
toggle_selection_properties: default_toggle_selection_properties(),
open_context_menu: default_open_context_menu(),
open_configurator: default_open_configurator(),
set_color_red: default_set_color_red(),
Expand Down Expand Up @@ -819,6 +823,10 @@ impl KeybindingsConfig {
insert_binding(binding_str, Action::ToggleHighlightTool)?;
}

for binding_str in &self.toggle_selection_properties {
insert_binding(binding_str, Action::ToggleSelectionProperties)?;
}

for binding_str in &self.open_context_menu {
insert_binding(binding_str, Action::OpenContextMenu)?;
}
Expand Down Expand Up @@ -1165,6 +1173,10 @@ fn default_toggle_highlight_tool() -> Vec<String> {
vec!["Ctrl+Alt+H".to_string()]
}

fn default_toggle_selection_properties() -> Vec<String> {
vec!["Ctrl+Alt+P".to_string()]
}

fn default_open_context_menu() -> Vec<String> {
vec!["Shift+F10".to_string(), "Menu".to_string()]
}
Expand Down
44 changes: 41 additions & 3 deletions src/input/state/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::util;
use log::{info, warn};
const KEYBOARD_NUDGE_SMALL: i32 = 8;
const KEYBOARD_NUDGE_LARGE: i32 = 32;
const PROPERTIES_PANEL_COARSE_STEP: i32 = 5;

use super::{
DrawingState, InputState, MAX_STROKE_THICKNESS, MIN_STROKE_THICKNESS, SelectionAxis,
Expand Down Expand Up @@ -45,8 +46,31 @@ impl InputState {
_ => {}
}

if matches!(key, Key::Escape) && self.properties_panel().is_some() {
self.close_properties_panel();
if self.is_properties_panel_open() {
let adjust_step = if self.modifiers.shift {
PROPERTIES_PANEL_COARSE_STEP
} else {
1
};
let handled = match key {
Key::Escape => {
self.close_properties_panel();
true
}
Key::Up => self.focus_previous_properties_entry(),
Key::Down => self.focus_next_properties_entry(),
Key::Home => self.focus_first_properties_entry(),
Key::End => self.focus_last_properties_entry(),
Key::Return | Key::Space => self.activate_properties_panel_entry(),
Key::Left => self.adjust_properties_panel_entry(-adjust_step),
Key::Right => self.adjust_properties_panel_entry(adjust_step),
Key::Char('+') | Key::Char('=') => self.adjust_properties_panel_entry(adjust_step),
Key::Char('-') | Key::Char('_') => self.adjust_properties_panel_entry(-adjust_step),
_ => false,
};
if handled {
return;
}
return;
}

Expand Down Expand Up @@ -341,7 +365,10 @@ impl InputState {

/// Handle an action triggered by a keybinding.
pub(super) fn handle_action(&mut self, action: Action) {
if !matches!(action, Action::OpenContextMenu) {
if !matches!(
action,
Action::OpenContextMenu | Action::ToggleSelectionProperties
) {
self.close_properties_panel();
}

Expand Down Expand Up @@ -755,6 +782,17 @@ impl InputState {
self.toggle_context_menu_via_keyboard();
}
}
Action::ToggleSelectionProperties => {
if matches!(self.state, DrawingState::Idle) {
if self.properties_panel().is_some() {
self.close_properties_panel();
} else if self.show_properties_panel() {
self.close_context_menu();
} else {
self.set_ui_toast(UiToastKind::Warning, "No selection to edit.");
}
}
}
Action::OpenConfigurator => {
self.launch_configurator();
}
Expand Down
11 changes: 10 additions & 1 deletion src/input/state/core/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub const UI_TOAST_DURATION_MS: u64 = 5000;
use super::{
index::SpatialGrid,
menus::{ContextMenuLayout, ContextMenuState},
properties::ShapePropertiesPanel,
properties::{PropertiesPanelLayout, ShapePropertiesPanel},
selection::SelectionState,
};
use crate::config::{Action, BoardConfig, KeyBinding, PRESET_SLOTS_MAX, ToolPresetConfig};
Expand Down Expand Up @@ -315,6 +315,12 @@ pub struct InputState {
pub(super) pending_menu_hover_recalc: bool,
/// Optional properties panel describing the current selection
pub(super) shape_properties_panel: Option<ShapePropertiesPanel>,
/// Cached layout details for the current properties panel
pub properties_panel_layout: Option<PropertiesPanelLayout>,
/// Recompute properties hover next time layout is available
pub(super) pending_properties_hover_recalc: bool,
/// Refresh properties panel entries on the next layout pass
pub(super) properties_panel_needs_refresh: bool,
/// Whether frozen mode is currently active
pub(super) frozen_active: bool,
/// Pending toggle request for the backend (handled in the Wayland loop)
Expand Down Expand Up @@ -489,6 +495,9 @@ impl InputState {
last_pointer_position: (0, 0),
pending_menu_hover_recalc: false,
shape_properties_panel: None,
properties_panel_layout: None,
pending_properties_hover_recalc: false,
properties_panel_needs_refresh: false,
frozen_active: false,
pending_frozen_toggle: false,
zoom_active: false,
Expand Down
3 changes: 3 additions & 0 deletions src/input/state/core/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ impl InputState {
}

fn mark_dirty_from_action(&mut self, action: &UndoAction) {
if self.is_properties_panel_open() {
self.properties_panel_needs_refresh = true;
}
match action {
UndoAction::Create { shapes } | UndoAction::Delete { shapes } => {
for (_, shape) in shapes {
Expand Down
Loading