forked from 1b-agent/opencadstudio-upstream
feat(ribbon): highlight the running command's button
A command started from the command line, an alias, a shortcut or Repeat now lights the same ribbon button a click on it would, so users learn where the tools they type live. A button inside a dropdown lights the dropdown, a slide-out tool lights its group title, a tool hidden in a collapsed panel lights the panel's opener, and a button on another tab lights that tab's header. Always on, in the existing active-button blue. Buttons are matched by the command they dispatch, so ids that differ from their command still resolve; the tab on show wins when a command appears twice, and a clicked button keeps its highlight. Transparent commands leave the running command lit. The #355 rule that a highlight lasts only while something runs moves from the ribbon click handler into dispatch_command, so typed commands are cleared the same way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3f54f2f494
commit
1093900a49
11 files changed
+425
-33
No files matched your search
@@ -207,22 +207,52 @@ pub(super) fn parent_panel(id: &str) -> Option<&'static str> {
|
||||
panel_for_dropdown(id).map(|panel| panel.id)
|
||||
}
|
||||
|
||||
pub(super) fn group_title<'a>(
|
||||
title: &'static str,
|
||||
group_ids: &[&'static str],
|
||||
open: &Option<String>,
|
||||
) -> Element<'a, Message> {
|
||||
let Some(panel) = PANELS.iter().copied().find(|panel| {
|
||||
/// The slide-out under the title of the ribbon group `title`, whose items
|
||||
/// are `group_ids`.
|
||||
fn panel_for_group(title: &str, group_ids: &[&'static str]) -> Option<Panel> {
|
||||
PANELS.iter().copied().find(|panel| {
|
||||
panel.title == title
|
||||
&& !panel.tools.is_empty()
|
||||
&& panel.anchor.is_none_or(|anchor| group_ids.contains(&anchor))
|
||||
})
|
||||
else {
|
||||
}
|
||||
|
||||
/// Every command the slide-out of the group `title` offers: each tool and
|
||||
/// each of its submenu options.
|
||||
pub(super) fn slide_out_commands(
|
||||
title: &str,
|
||||
group_ids: &[&'static str],
|
||||
) -> impl Iterator<Item = &'static str> {
|
||||
panel_for_group(title, group_ids)
|
||||
.into_iter()
|
||||
.flat_map(|panel| panel.tools)
|
||||
.flat_map(|tool| {
|
||||
std::iter::once(tool.command).chain(tool.options.iter().map(|(cmd, _)| *cmd))
|
||||
})
|
||||
}
|
||||
|
||||
/// A slide-out tool is lit while it or one of its submenu options runs.
|
||||
fn tool_is_active(tool: &Tool, active_tool: Option<&str>) -> bool {
|
||||
active_tool.is_some_and(|active| {
|
||||
tool.command == active || tool.options.iter().any(|(cmd, _)| *cmd == active)
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn group_title<'a>(
|
||||
title: &'static str,
|
||||
group_ids: &[&'static str],
|
||||
open: &Option<String>,
|
||||
active_tool: Option<&str>,
|
||||
) -> Element<'a, Message> {
|
||||
let Some(panel) = panel_for_group(title, group_ids) else {
|
||||
return container(text(t!(title)).size(9).style(muted_text_style))
|
||||
.padding([1, 4])
|
||||
.into();
|
||||
};
|
||||
let expanded = open.as_deref().and_then(parent_panel) == Some(panel.id);
|
||||
// A command running from the closed slide-out lights its title, the way a
|
||||
// dropdown lights while one of its items runs.
|
||||
let lit = expanded || panel.tools.iter().any(|tool| tool_is_active(tool, active_tool));
|
||||
let arrow = if expanded {
|
||||
icons::themed_arrow_up(GROUP_TITLE_ARROW_SIZE)
|
||||
} else {
|
||||
@@ -239,7 +269,7 @@ pub(super) fn group_title<'a>(
|
||||
.align_y(iced::Center),
|
||||
)
|
||||
.on_press(Message::ToggleRibbonDropdown(panel.id.to_string()))
|
||||
.style(move |theme: &Theme, status| tool_btn_style(theme, expanded, status))
|
||||
.style(move |theme: &Theme, status| tool_btn_style(theme, lit, status))
|
||||
.padding([1, 4]),
|
||||
)
|
||||
.into();
|
||||
@@ -421,7 +451,7 @@ pub(super) fn overlay<'a>(ribbon: &Ribbon, id: &str, win: (f32, f32)) -> Element
|
||||
.map(|tool| {
|
||||
tool_button(
|
||||
tool,
|
||||
ribbon.active_tool.as_deref() == Some(tool.command),
|
||||
tool_is_active(tool, ribbon.active_tool.as_deref()),
|
||||
panel.id,
|
||||
)
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user