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
7 changes: 7 additions & 0 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,13 @@ side_offset_x = 0.0
# Force inline toolbars even when layer-shell is available
force_inline = false

[ui.toolbar.items]
# Checked in the configurator means shown; IDs listed here are hidden.
# The screenshot toolbar button is hidden by default.
hidden = [
"top.utility.screenshot",
]

# ───────────────────────────────────────────────────────────────────────────────
# Status Bar Styling
# ───────────────────────────────────────────────────────────────────────────────
Expand Down
22 changes: 22 additions & 0 deletions configurator/src/app/search/summary.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::app::state::ConfiguratorApp;
use crate::models::{KeybindingsTabId, SearchQuery, TabId, UiTabId};
use wayscriber::config::toolbar_item_definitions;

use super::terms::*;
use super::types::{AppSearchSummary, SearchArea, TabSearchSummary};
Expand Down Expand Up @@ -178,6 +179,7 @@ fn ui_matches(query: &SearchQuery, summary: &mut TabSearchSummary) {
.collect::<Vec<_>>();
if query.matches_parts_scoped_to_tab(TabId::Ui, identity_parts.iter().copied())
|| query.matches_parts(full_parts.iter().copied())
|| (tab == UiTabId::ToolbarVisibility && toolbar_item_matches(query))
|| (query.matches_any_raw_text(field_terms)
&& query.matches_parts_scoped_to_tab(TabId::Ui, full_parts.iter().copied()))
{
Expand All @@ -186,6 +188,26 @@ fn ui_matches(query: &SearchQuery, summary: &mut TabSearchSummary) {
}
}

fn toolbar_item_matches(query: &SearchQuery) -> bool {
toolbar_item_definitions().iter().any(|definition| {
query.matches_parts([
"toolbar item",
definition.label,
definition.id.as_str(),
definition.group.map_or("", |group| group.as_str()),
]) || query.matches_parts_scoped_to_tab(
TabId::Ui,
[
"toolbar visibility",
"toolbar item",
definition.label,
definition.id.as_str(),
definition.group.map_or("", |group| group.as_str()),
],
)
})
}

fn board_matches(app: &ConfiguratorApp, query: &SearchQuery, summary: &mut TabSearchSummary) {
add_area_if(
query,
Expand Down
25 changes: 25 additions & 0 deletions configurator/src/app/search/terms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub(super) fn tab_scope_aliases(tab: TabId) -> &'static [&'static str] {
pub(super) fn ui_tab_aliases(tab: UiTabId) -> &'static [&'static str] {
match tab {
UiTabId::Toolbar => &["tools", "palette", "drawer"],
UiTabId::ToolbarVisibility => &["toolbar items", "toolbar buttons", "show hide toolbar"],
UiTabId::StatusBar => &["status", "badge", "indicator"],
UiTabId::HelpOverlay => &["help", "quick help", "hints"],
UiTabId::ClickHighlight => &["click", "cursor", "highlight"],
Expand All @@ -57,6 +58,7 @@ pub(super) fn ui_tab_aliases(tab: UiTabId) -> &'static [&'static str] {
pub(super) fn ui_tab_terms(tab: UiTabId) -> &'static [&'static str] {
match tab {
UiTabId::Toolbar => UI_TOOLBAR_TERMS,
UiTabId::ToolbarVisibility => UI_TOOLBAR_VISIBILITY_TERMS,
UiTabId::StatusBar => UI_STATUS_BAR_TERMS,
UiTabId::HelpOverlay => UI_HELP_OVERLAY_TERMS,
UiTabId::ClickHighlight => UI_CLICK_HIGHLIGHT_TERMS,
Expand Down Expand Up @@ -193,6 +195,29 @@ pub(super) const UI_TOOLBAR_TERMS: &[&str] = &[
"side offset x",
"side offset y",
];
pub(super) const UI_TOOLBAR_VISIBILITY_TERMS: &[&str] = &[
"toolbar visibility",
"toolbar items",
"items",
"checked items are shown",
"hidden item overrides",
"hide toolbar buttons",
"show toolbar buttons",
"visible toolbar buttons",
"top toolbar",
"side toolbar",
"toolbar controls",
"tools",
"utilities",
"sections",
"actions",
"pages",
"boards",
"presets",
"settings",
"sessions",
"tool options",
];
pub(super) const UI_STATUS_BAR_TERMS: &[&str] = &[
"status bar",
"show status bar",
Expand Down
18 changes: 12 additions & 6 deletions configurator/src/app/search/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,17 @@ fn ui_nested_alias_matches_concrete_nested_tab() {
#[test]
fn parent_scoped_ui_queries_match_concrete_nested_tabs() {
let cases = [
("ui toolbar", UiTabId::Toolbar),
("ui layout mode", UiTabId::Toolbar),
("interface presenter", UiTabId::PresenterMode),
("interface status bar position", UiTabId::StatusBar),
(
"ui toolbar",
&[UiTabId::Toolbar, UiTabId::ToolbarVisibility][..],
),
("ui layout mode", &[UiTabId::Toolbar][..]),
("ui toolbar blur", &[UiTabId::ToolbarVisibility][..]),
("interface presenter", &[UiTabId::PresenterMode][..]),
("interface status bar position", &[UiTabId::StatusBar][..]),
];

for (query, expected_tab) in cases {
for (query, expected_tabs) in cases {
let (mut app, _task) = ConfiguratorApp::new_app();
app.search_query = SearchQuery::new(query);

Expand All @@ -275,7 +279,7 @@ fn parent_scoped_ui_queries_match_concrete_nested_tabs() {
assert!(!ui.show_all(), "query should not show all UI tabs: {query}");
assert_eq!(
ui.ui_tabs(),
&[expected_tab],
expected_tabs,
"query should show concrete nested UI tab: {query}",
);
}
Expand All @@ -285,6 +289,8 @@ fn parent_scoped_ui_queries_match_concrete_nested_tabs() {
fn ui_nested_visible_control_labels_match_concrete_nested_tabs() {
let cases = [
("layout mode", UiTabId::Toolbar),
("top.tool.blur", UiTabId::ToolbarVisibility),
("side.group.presets", UiTabId::ToolbarVisibility),
("status bar position", UiTabId::StatusBar),
("click highlight radius", UiTabId::ClickHighlight),
];
Expand Down
12 changes: 12 additions & 0 deletions configurator/src/app/update/fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::models::{
};
#[cfg(feature = "tablet-input")]
use crate::models::{PressureThicknessEditModeOption, PressureThicknessEntryModeOption};
use wayscriber::config::ToolbarItemId;

use super::super::state::{ConfiguratorApp, StatusMessage};

Expand Down Expand Up @@ -168,6 +169,17 @@ impl ConfiguratorApp {
Task::none()
}

pub(super) fn handle_toolbar_item_visibility_changed(
&mut self,
id: ToolbarItemId,
visible: bool,
) -> Task<Message> {
self.status = StatusMessage::idle();
self.draft.set_toolbar_item_visible(id, visible);
self.refresh_dirty_flag();
Task::none()
}

pub(super) fn handle_session_storage_mode_changed(
&mut self,
option: SessionStorageModeOption,
Expand Down
3 changes: 3 additions & 0 deletions configurator/src/app/update/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ impl ConfiguratorApp {
Message::ToolbarOverrideChanged(field, option) => {
self.handle_toolbar_override_changed(field, option)
}
Message::ToolbarItemVisibilityChanged(id, visible) => {
self.handle_toolbar_item_visibility_changed(id, visible)
}
Message::BoardsAddItem => self.handle_boards_add_item(),
Message::BoardsRemoveItem(index) => self.handle_boards_remove_item(index),
Message::BoardsMoveItemUp(index) => self.handle_boards_move_item(index, true),
Expand Down
1 change: 1 addition & 0 deletions configurator/src/app/view/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ impl ConfiguratorApp {

let content = match active_tab {
Some(UiTabId::Toolbar) => Some(self.ui_toolbar_tab()),
Some(UiTabId::ToolbarVisibility) => Some(self.ui_toolbar_visibility_tab()),
Some(UiTabId::StatusBar) => Some(self.ui_status_bar_tab()),
Some(UiTabId::HelpOverlay) => Some(self.ui_help_overlay_tab()),
Some(UiTabId::ClickHighlight) => Some(self.ui_click_highlight_tab()),
Expand Down
111 changes: 110 additions & 1 deletion configurator/src/app/view/ui/toolbar.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use iced::widget::{column, pick_list, row, scrollable, text};
use iced::widget::{checkbox, column, pick_list, row, scrollable, text};
use iced::{Element, Length};
use wayscriber::config::{
ResolvedToolbarItems, ToolbarItemCategory, ToolbarItemDefinition, ToolbarItemSurface,
ToolbarItemsConfig, toolbar_item_definitions,
};

use crate::app::scroll::CONTENT_SCROLL_ID;
use crate::app::state::ConfiguratorApp;
Expand Down Expand Up @@ -215,4 +219,109 @@ impl ConfiguratorApp {

scrollable(column).id(CONTENT_SCROLL_ID).into()
}

pub(super) fn ui_toolbar_visibility_tab(&self) -> Element<'_, Message> {
let column = column![
text("Toolbar Visibility").size(18),
text("Checked items are shown. Uncheck an item to hide it from toolbar sizing, drawing, and hit testing. Existing section toggles and mode overrides can still hide checked items.").size(12),
toolbar_item_visibility_section(
&self.draft.ui_toolbar_items,
&self.defaults.ui_toolbar_items,
),
]
.spacing(12);

scrollable(column).id(CONTENT_SCROLL_ID).into()
}
}

fn toolbar_item_visibility_section<'a>(
items: &ToolbarItemsConfig,
defaults: &ToolbarItemsConfig,
) -> Element<'a, Message> {
let resolved = items.resolved();
let default_resolved = defaults.resolved();
let mut rows = column![text("Items").size(16)].spacing(8);
let mut current_surface = None;
let mut current_category = None;

if !resolved.unknown_hidden.is_empty() {
rows = rows.push(
text(format!(
"Preserving {} unknown toolbar item id(s) from config.",
resolved.unknown_hidden.len()
))
.size(12),
);
}

for definition in toolbar_item_definitions() {
if current_surface != Some(definition.surface) {
current_surface = Some(definition.surface);
current_category = None;
rows = rows.push(text(toolbar_item_surface_label(definition.surface)).size(14));
}
if current_category != Some(definition.category) {
current_category = Some(definition.category);
rows = rows.push(text(toolbar_item_category_label(definition.category)).size(13));
}

rows = rows.push(toolbar_item_visibility_row(
definition,
&resolved,
&default_resolved,
));
}

rows.into()
}

fn toolbar_item_visibility_row<'a>(
definition: &ToolbarItemDefinition,
resolved: &ResolvedToolbarItems,
defaults: &ResolvedToolbarItems,
) -> Element<'a, Message> {
let id = definition.id;
let visible = !resolved.is_hidden(id);
let default = format!(
"default: {}",
visibility_override_label(!defaults.is_hidden(id))
);

row![
checkbox(visible)
.label(definition.label)
.on_toggle(move |value| Message::ToolbarItemVisibilityChanged(id, value)),
text(definition.id.as_str()).size(12).width(Length::Fill),
text(default).size(12),
]
.spacing(12)
.align_y(iced::Alignment::Center)
.into()
}

fn visibility_override_label(visible: bool) -> &'static str {
if visible { "shown" } else { "hidden" }
}

fn toolbar_item_surface_label(surface: ToolbarItemSurface) -> &'static str {
match surface {
ToolbarItemSurface::Top => "Top toolbar",
ToolbarItemSurface::Side => "Side toolbar",
}
}

fn toolbar_item_category_label(category: ToolbarItemCategory) -> &'static str {
match category {
ToolbarItemCategory::Chrome => "Toolbar controls",
ToolbarItemCategory::Tool => "Tools",
ToolbarItemCategory::Utility => "Utilities",
ToolbarItemCategory::Group => "Sections",
ToolbarItemCategory::Action => "Actions",
ToolbarItemCategory::Page => "Pages",
ToolbarItemCategory::Board => "Boards",
ToolbarItemCategory::Setting => "Settings",
ToolbarItemCategory::Session => "Sessions",
ToolbarItemCategory::ToolOption => "Tool options",
}
}
3 changes: 2 additions & 1 deletion configurator/src/messages.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::path::PathBuf;
use std::sync::Arc;

use wayscriber::config::Config;
use wayscriber::config::{Config, ToolbarItemId};

use crate::models::{
BoardBackgroundOption, BoardItemTextField, BoardItemToggleField, ColorMode, ColorPickerId,
Expand Down Expand Up @@ -73,6 +73,7 @@ pub enum Message {
ToolbarLayoutModeChanged(ToolbarLayoutModeOption),
ToolbarOverrideModeChanged(ToolbarLayoutModeOption),
ToolbarOverrideChanged(ToolbarOverrideField, OverrideOption),
ToolbarItemVisibilityChanged(ToolbarItemId, bool),
BoardsAddItem,
BoardsRemoveItem(usize),
BoardsMoveItemUp(usize),
Expand Down
1 change: 1 addition & 0 deletions configurator/src/models/config/draft/from_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ impl ConfigDraft {
ui_toolbar_layout_mode: ToolbarLayoutModeOption::from_mode(
config.ui.toolbar.layout_mode,
),
ui_toolbar_items: config.ui.toolbar.items.clone(),
ui_toolbar_show_presets: config.ui.toolbar.show_presets,
ui_toolbar_show_actions_section: config.ui.toolbar.show_actions_section,
ui_toolbar_show_actions_advanced: config.ui.toolbar.show_actions_advanced,
Expand Down
3 changes: 2 additions & 1 deletion configurator/src/models/config/draft/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use super::boards::BoardsDraft;
use super::presets::PresetsDraft;
use super::render_profiles::RenderProfilesDraft;
use super::toolbar_overrides::ToolbarModeOverridesDraft;
use wayscriber::config::MouseDragToolsConfig;
use wayscriber::config::{MouseDragToolsConfig, ToolbarItemsConfig};

#[derive(Debug, Clone, PartialEq)]
pub struct ConfigDraft {
Expand Down Expand Up @@ -76,6 +76,7 @@ pub struct ConfigDraft {
pub ui_toolbar_show_more_colors: bool,
pub ui_toolbar_show_preset_toasts: bool,
pub ui_toolbar_layout_mode: ToolbarLayoutModeOption,
pub ui_toolbar_items: ToolbarItemsConfig,
pub ui_toolbar_show_presets: bool,
pub ui_toolbar_show_actions_section: bool,
pub ui_toolbar_show_actions_advanced: bool,
Expand Down
5 changes: 5 additions & 0 deletions configurator/src/models/config/setters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::super::fields::{
ToolbarOverrideField, TripletField,
};
use super::draft::ConfigDraft;
use wayscriber::config::ToolbarItemId;

impl ConfigDraft {
pub fn apply_toolbar_layout_mode(&mut self, mode: ToolbarLayoutModeOption) {
Expand Down Expand Up @@ -31,6 +32,10 @@ impl ConfigDraft {
.set(field, value);
}

pub fn set_toolbar_item_visible(&mut self, id: ToolbarItemId, visible: bool) {
self.ui_toolbar_items.set_hidden(id, !visible);
}

pub fn set_mouse_drag_tool(
&mut self,
button: DragMouseButton,
Expand Down
Loading
Loading