forked from 1b-agent/opencadstudio-upstream
Merge main into Select-Color-Redesign
Keep both sides: main's ViewBackground colour target and PREVIEW icon next to this branch's Interface target and LIST/SEARCH icons. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
This commit is contained in:
231 files changed
+32217
-3423
No files matched your search
+52
-20
@@ -9,7 +9,7 @@ use super::widgets::{
|
||||
make_icon, make_tip, muted_text_style, popup_panel_style, popup_row_style, tip_style,
|
||||
tool_btn_style, LARGE_DROPDOWN_ARROW_SIZE,
|
||||
};
|
||||
use super::{dropdown_backdrop, position_ribbon_dropdown, Ribbon};
|
||||
use super::{dropdown_backdrop, keytips, position_ribbon_dropdown, Ribbon};
|
||||
use crate::app::Message;
|
||||
use crate::modules::IconKind;
|
||||
use crate::t;
|
||||
@@ -248,6 +248,32 @@ fn panel_for_group(title: &str, group_ids: &[&'static str]) -> Option<Panel> {
|
||||
})
|
||||
}
|
||||
|
||||
/// The slide-out under the group `title`, if it has one.
|
||||
pub(super) fn slide_out_id(title: &str, group_ids: &[&'static str]) -> Option<&'static str> {
|
||||
panel_for_group(title, group_ids).map(|panel| panel.id)
|
||||
}
|
||||
|
||||
/// What the open slide-out or tool submenu `id` offers, as (dropdown id,
|
||||
/// command, opens a submenu) in display order.
|
||||
pub(super) fn keytip_items(id: &str) -> Vec<(&'static str, &'static str, bool)> {
|
||||
let Some(panel) = panel_for_dropdown(id) else {
|
||||
return Vec::new();
|
||||
};
|
||||
if panel.id == id {
|
||||
return panel
|
||||
.tools
|
||||
.iter()
|
||||
.map(|tool| (panel.id, tool.command, !tool.options.is_empty()))
|
||||
.collect();
|
||||
}
|
||||
panel
|
||||
.tools
|
||||
.iter()
|
||||
.filter(|tool| tool.command == id)
|
||||
.flat_map(|tool| tool.options.iter().map(|(cmd, _)| (tool.command, *cmd, false)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Every command the slide-out of the group `title` offers: each tool and
|
||||
/// each of its submenu options.
|
||||
pub(super) fn slide_out_commands(
|
||||
@@ -311,7 +337,8 @@ pub(super) fn group_title<'a>(
|
||||
if panel.id != REFERENCE_PANEL_ID {
|
||||
return title_button;
|
||||
}
|
||||
// The corner arrow opens the External References palette.
|
||||
// The corner arrow opens the External References palette, or closes it
|
||||
// when it is open.
|
||||
let launcher = tooltip(
|
||||
// A right arrow turned to point into the corner.
|
||||
button(
|
||||
@@ -323,10 +350,7 @@ pub(super) fn group_title<'a>(
|
||||
color: Some(theme.palette().background.base.text),
|
||||
}),
|
||||
)
|
||||
.on_press(Message::RibbonToolClick {
|
||||
tool_id: "EXTERNALREFERENCES".to_string(),
|
||||
event: crate::modules::ModuleEvent::Command("EXTERNALREFERENCES".to_string()),
|
||||
})
|
||||
.on_press(Message::ToggleXrefManager)
|
||||
.style(move |theme: &Theme, status| tool_btn_style(theme, false, status))
|
||||
.padding([0, 3]),
|
||||
make_tip(format!(
|
||||
@@ -339,6 +363,7 @@ pub(super) fn group_title<'a>(
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style);
|
||||
// Shrink-sized: a Fill here would make the panel claim the whole row.
|
||||
let launcher = keytips::anchor(keytips::XREF_LAUNCHER, launcher);
|
||||
row![title_button, launcher]
|
||||
.spacing(6)
|
||||
.align_y(iced::Center)
|
||||
@@ -364,6 +389,7 @@ fn tool_button(tool: &Tool, active: bool, panel_id: &'static str) -> Element<'st
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style)
|
||||
.into();
|
||||
let face = keytips::anchor_with(|| keytips::item_anchor(panel_id, tool.command), face);
|
||||
if !tool.options.is_empty() {
|
||||
row![
|
||||
face,
|
||||
@@ -403,6 +429,7 @@ fn reference_overlay<'a>(ribbon: &Ribbon, panel: Panel, win: (f32, f32)) -> Elem
|
||||
.style(popup_row_style)
|
||||
.width(Fill)
|
||||
.padding([3, 6]);
|
||||
let edit = keytips::anchor_with(|| keytips::item_anchor(panel.id, tool.command), edit);
|
||||
let fade = ribbon.xref_fade;
|
||||
let on = fade > 0;
|
||||
let switch = button(make_icon(
|
||||
@@ -413,18 +440,23 @@ fn reference_overlay<'a>(ribbon: &Ribbon, panel: Panel, win: (f32, f32)) -> Elem
|
||||
.style(move |theme: &Theme, status| tool_btn_style(theme, on, status))
|
||||
.padding(3);
|
||||
let amount = fade.unsigned_abs().min(90) as u8;
|
||||
let switch = tooltip(
|
||||
switch,
|
||||
make_tip(format!(
|
||||
"{}\n{} XDWGFADECTL",
|
||||
t!("Xref fading"),
|
||||
t!("Command:")
|
||||
)),
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style);
|
||||
let switch = keytips::anchor_with(
|
||||
|| keytips::item_anchor(panel.id, keytips::XREF_FADE),
|
||||
switch,
|
||||
);
|
||||
let fading = row![
|
||||
tooltip(
|
||||
switch,
|
||||
make_tip(format!(
|
||||
"{}\n{} XDWGFADECTL",
|
||||
t!("Xref fading"),
|
||||
t!("Command:")
|
||||
)),
|
||||
tooltip::Position::Bottom
|
||||
)
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style),
|
||||
switch,
|
||||
text(t!("Xref fading")).size(11),
|
||||
iced::widget::slider(0..=90u8, amount, Message::XrefFadeSlide)
|
||||
.on_release(Message::XrefFadeCommit)
|
||||
@@ -470,7 +502,7 @@ pub(super) fn overlay<'a>(ribbon: &Ribbon, id: &str, win: (f32, f32)) -> Element
|
||||
tool.options
|
||||
.iter()
|
||||
.map(|&(cmd, label)| {
|
||||
button(text(t!(label)).size(11))
|
||||
let item = button(text(t!(label)).size(11))
|
||||
.on_press(Message::DropdownSelectItem {
|
||||
dropdown_id: tool.command,
|
||||
cmd,
|
||||
@@ -478,8 +510,8 @@ pub(super) fn overlay<'a>(ribbon: &Ribbon, id: &str, win: (f32, f32)) -> Element
|
||||
.style(popup_row_style)
|
||||
.width(Fill)
|
||||
.height(OPTION_HEIGHT)
|
||||
.padding([3, 7])
|
||||
.into()
|
||||
.padding([3, 7]);
|
||||
keytips::anchor_with(|| keytips::item_anchor(tool.command, cmd), item)
|
||||
})
|
||||
.collect::<Vec<Element<'static, Message>>>(),
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
+6
-15
@@ -68,15 +68,11 @@ impl Ribbon {
|
||||
fn entries(&self) -> impl Iterator<Item = (usize, Entry<'_>)> {
|
||||
let order = std::iter::once(self.active)
|
||||
.chain((0..self.modules.len()).filter(move |i| *i != self.active));
|
||||
order
|
||||
.filter_map(|i| self.modules.get(i).map(|m| (i, m)))
|
||||
.flat_map(|(i, module)| {
|
||||
module
|
||||
.ribbon_groups()
|
||||
.iter()
|
||||
.flat_map(group_entries)
|
||||
.map(move |entry| (i, entry))
|
||||
})
|
||||
order.flat_map(|i| {
|
||||
self.groups_for(i)
|
||||
.flat_map(group_entries)
|
||||
.map(move |entry| (i, entry))
|
||||
})
|
||||
}
|
||||
|
||||
/// The button id that runs the command line `cmd`: an exact match first,
|
||||
@@ -111,12 +107,7 @@ impl Ribbon {
|
||||
/// module has no tab (its tools are on the side toolbar).
|
||||
pub(super) fn tab_holding_active_tool(&self) -> Option<usize> {
|
||||
let id = self.active_tool.as_deref()?;
|
||||
let holds = |i: usize| {
|
||||
self.modules[i]
|
||||
.ribbon_groups()
|
||||
.iter()
|
||||
.any(|group| group_holds(group, id))
|
||||
};
|
||||
let holds = |i: usize| self.groups_for(i).any(|group| group_holds(group, id));
|
||||
if self
|
||||
.modules
|
||||
.get(self.active)
|
||||
|
||||
+153
-42
@@ -31,6 +31,12 @@ use widgets::{StyleContext, *};
|
||||
pub(crate) use widgets::{REDO_HISTORY_ID, UNDO_HISTORY_ID};
|
||||
mod collapse;
|
||||
mod locate;
|
||||
mod keytips;
|
||||
pub use keytips::{
|
||||
active as keytips_active, key_pressed as keytip_key_pressed,
|
||||
key_released as keytip_key_released, pointer_pressed as keytip_pointer_pressed, KeyTipInput,
|
||||
KeyTipStep,
|
||||
};
|
||||
use crate::t;
|
||||
use crate::ui::wrap_bar::{PosReport, WrapBar, WrapFlow};
|
||||
pub use collapse::CollapseMode;
|
||||
@@ -120,8 +126,14 @@ pub struct Ribbon {
|
||||
xref_ctx: bool,
|
||||
/// Only point clouds are selected: whether the first shows its crops.
|
||||
point_cloud_ctx: Option<bool>,
|
||||
/// A block editor session is open: the tab that was active before the
|
||||
/// Block Editor tab took over.
|
||||
block_editing: Option<usize>,
|
||||
block_testing: Option<usize>,
|
||||
/// XDWGFADECTL as the Reference slide-out shows it (negative = off).
|
||||
pub xref_fade: i32,
|
||||
/// Open key tips (Alt).
|
||||
keytips: Option<keytips::State>,
|
||||
}
|
||||
|
||||
/// Per-layer display data shown in the ribbon layer dropdown.
|
||||
@@ -240,7 +252,10 @@ impl Ribbon {
|
||||
underlay_ctx: None,
|
||||
xref_ctx: false,
|
||||
point_cloud_ctx: None,
|
||||
block_editing: None,
|
||||
block_testing: None,
|
||||
xref_fade: 50,
|
||||
keytips: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,6 +329,62 @@ impl Ribbon {
|
||||
self.available_linetypes = items;
|
||||
}
|
||||
|
||||
/// Show the Block Editor tab while a block is being edited, and return to
|
||||
/// the previous tab when the editing ends.
|
||||
pub fn set_block_editing(&mut self, editing: bool) {
|
||||
let Some(index) = self.modules.iter().position(|module| module.id() == "block_editor")
|
||||
else {
|
||||
return;
|
||||
};
|
||||
match (editing, self.block_editing) {
|
||||
(true, None) => {
|
||||
self.block_editing = Some(self.active);
|
||||
self.active = index;
|
||||
}
|
||||
(false, Some(previous)) => {
|
||||
self.block_editing = None;
|
||||
if self.active == index {
|
||||
self.active = previous.min(self.modules.len().saturating_sub(1));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_block_testing(&mut self, testing: bool) {
|
||||
if testing != self.block_testing.is_some() {
|
||||
self.close_dropdown();
|
||||
let _ = self.hide_keytips();
|
||||
}
|
||||
let Some(index) = self.modules.iter().position(|module| module.id() == "draw") else {
|
||||
return;
|
||||
};
|
||||
match (testing, self.block_testing) {
|
||||
(true, None) => {
|
||||
self.block_testing = Some(self.active);
|
||||
self.active = index;
|
||||
}
|
||||
(false, Some(previous)) => {
|
||||
self.block_testing = None;
|
||||
if self.active == index {
|
||||
self.active = previous.min(self.modules.len().saturating_sub(1));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
/// Contextual panels share their normal tab with the drawing tools.
|
||||
fn groups_for(&self, index: usize) -> impl Iterator<Item = &RibbonGroup> {
|
||||
let testing = self.block_testing.is_some();
|
||||
self.modules.get(index).into_iter().flat_map(move |module| {
|
||||
module
|
||||
.ribbon_groups()
|
||||
.iter()
|
||||
.filter(move |group| module.id() != "draw" || group.title != "Close" || testing)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn select(&mut self, index: usize) {
|
||||
if index < self.modules.len() {
|
||||
self.active = index;
|
||||
@@ -571,12 +642,14 @@ impl Ribbon {
|
||||
|mut acc, (i, module)| {
|
||||
// The Layout module no longer has a ribbon tab — its paper-space
|
||||
// tools live in the right-edge side toolbar (see ui::side_toolbar).
|
||||
if module.id() == "layout" {
|
||||
if module.id() == "layout"
|
||||
|| (module.id() == "block_editor" && self.block_editing.is_none())
|
||||
{
|
||||
return acc;
|
||||
}
|
||||
|
||||
let is_active = i == self.active;
|
||||
let is_contextual = module.id() == "layout";
|
||||
let is_contextual = matches!(module.id(), "layout" | "block_editor");
|
||||
let holds_tool = holding_tab == Some(i);
|
||||
let btn = container(
|
||||
button(
|
||||
@@ -655,7 +728,7 @@ impl Ribbon {
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
acc.push(btn.into());
|
||||
acc.push(keytips::anchor_with(|| format!("tab:{}", module.id()), btn));
|
||||
acc
|
||||
},
|
||||
);
|
||||
@@ -717,38 +790,36 @@ impl Ribbon {
|
||||
} else {
|
||||
self.active
|
||||
};
|
||||
let tool_area: Element<'_, Message> =
|
||||
if let Some(module) = self.modules.get(effective_active) {
|
||||
let groups = module.ribbon_groups();
|
||||
let style_ctx = StyleContext {
|
||||
text_style_names: &self.text_style_names,
|
||||
active_text_style: &self.active_text_style,
|
||||
dim_style_names: &self.dim_style_names,
|
||||
active_dim_style: &self.active_dim_style,
|
||||
mleader_style_names: &self.mleader_style_names,
|
||||
active_mleader_style: &self.active_mleader_style,
|
||||
table_style_names: &self.table_style_names,
|
||||
active_table_style: &self.active_table_style,
|
||||
};
|
||||
|
||||
// Adaptive tool area: panels sit on one row; when they don't all
|
||||
// fit they degrade from the right — a panel's large buttons first
|
||||
// shrink to compact icon columns, then it collapses to a ▾ flyout
|
||||
// button. See `CollapsePanels`.
|
||||
let ts = self.toggle_state(show_block_palette);
|
||||
let panels: Vec<Panel<'_>> = groups
|
||||
.iter()
|
||||
.map(|g| self.panel(g, ts, &style_ctx, &|_| Vec::new()))
|
||||
.collect();
|
||||
CollapsePanels::new(panels, self.collapsed_open.clone(), TOOL_BAR_H)
|
||||
.report_height(self.tool_bar_h.clone())
|
||||
.report_tight(self.collapse_tight.clone())
|
||||
.mode(self.collapse_mode)
|
||||
.into()
|
||||
} else {
|
||||
text("").into()
|
||||
let tool_area: Element<'_, Message> = if self.modules.get(effective_active).is_some() {
|
||||
let groups = self.groups_for(effective_active);
|
||||
let style_ctx = StyleContext {
|
||||
text_style_names: &self.text_style_names,
|
||||
active_text_style: &self.active_text_style,
|
||||
dim_style_names: &self.dim_style_names,
|
||||
active_dim_style: &self.active_dim_style,
|
||||
mleader_style_names: &self.mleader_style_names,
|
||||
active_mleader_style: &self.active_mleader_style,
|
||||
table_style_names: &self.table_style_names,
|
||||
active_table_style: &self.active_table_style,
|
||||
};
|
||||
|
||||
// Adaptive tool area: panels sit on one row; when they don't all
|
||||
// fit they degrade from the right — a panel's large buttons first
|
||||
// shrink to compact icon columns, then it collapses to a ▾ flyout
|
||||
// button. See `CollapsePanels`.
|
||||
let ts = self.toggle_state(show_block_palette);
|
||||
let panels: Vec<Panel<'_>> = groups
|
||||
.map(|g| self.panel(g, ts, &style_ctx, &|_| Vec::new()))
|
||||
.collect();
|
||||
CollapsePanels::new(panels, self.collapsed_open.clone(), TOOL_BAR_H)
|
||||
.report_height(self.tool_bar_h.clone())
|
||||
.report_tight(self.collapse_tight.clone())
|
||||
.mode(self.collapse_mode)
|
||||
.into()
|
||||
} else {
|
||||
text("").into()
|
||||
};
|
||||
|
||||
let tool_bar: Element<'_, Message> = container(tool_area)
|
||||
.style(|theme: &Theme| container::Style {
|
||||
background: Some(Background::Color(theme.palette().background.weakest.color)),
|
||||
@@ -793,7 +864,7 @@ impl Ribbon {
|
||||
tool_bar
|
||||
};
|
||||
|
||||
column![tab_bar, tool_bar].into()
|
||||
keytips::ribbon_area(column![tab_bar, tool_bar])
|
||||
}
|
||||
|
||||
// ── Dropdown overlay ──────────────────────────────────────────────────
|
||||
@@ -915,8 +986,7 @@ impl Ribbon {
|
||||
return Some(ov);
|
||||
}
|
||||
|
||||
let module = self.modules.get(self.active)?;
|
||||
let groups = module.ribbon_groups();
|
||||
let groups = self.groups_for(self.active);
|
||||
let mut items_list: Option<Vec<(&'static str, &'static str, IconKind)>> = None;
|
||||
let mut dd_default = "";
|
||||
let mut dd_id: &'static str = "";
|
||||
@@ -964,7 +1034,7 @@ impl Ribbon {
|
||||
.then_some(theme.palette().background.base.text.scale_alpha(0.72)),
|
||||
});
|
||||
|
||||
button(
|
||||
let item = button(
|
||||
row![checkmark, icon_el, label_el]
|
||||
.spacing(4)
|
||||
.align_y(iced::Center),
|
||||
@@ -975,8 +1045,8 @@ impl Ribbon {
|
||||
}))
|
||||
.style(popup_row_style)
|
||||
.width(Fill)
|
||||
.padding([4, 10])
|
||||
.into()
|
||||
.padding([4, 10]);
|
||||
keytips::anchor_with(|| keytips::item_anchor(dd_id, cmd), item)
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -1145,7 +1215,7 @@ impl Ribbon {
|
||||
/// Draw-tab dropdowns — so the list grows to fit its entries instead of
|
||||
/// being clipped to the ribbon-row height. (#153)
|
||||
fn style_combo_overlay(&self, open_id: &str, win: (f32, f32)) -> Option<Element<'_, Message>> {
|
||||
let groups = self.modules.get(self.active)?.ribbon_groups();
|
||||
let groups = self.groups_for(self.active);
|
||||
|
||||
// Locate the open style combo; capture its style key + manager command.
|
||||
let mut found: Option<(crate::modules::StyleKey, Option<&'static str>)> = None;
|
||||
@@ -1568,7 +1638,10 @@ fn collapse_button<'a>(
|
||||
.style(opener_style(holds))
|
||||
.width(Fill)
|
||||
.padding([3, 5]);
|
||||
return automatic_large_button(localized_title, content.into());
|
||||
return keytips::anchor_with(
|
||||
|| keytips::collapsed_anchor(title),
|
||||
automatic_large_button(localized_title, content.into()),
|
||||
);
|
||||
}
|
||||
|
||||
// Collapsed (not yet tight): a large representative-tool face — a live button
|
||||
@@ -1633,7 +1706,10 @@ fn collapse_button<'a>(
|
||||
.style(opener_style(holds && !face_lit))
|
||||
.width(Fill)
|
||||
.padding([1, 4]);
|
||||
let opener = automatic_large_button(localized_title, opener.into());
|
||||
let opener = keytips::anchor_with(
|
||||
|| keytips::collapsed_anchor(title),
|
||||
automatic_large_button(localized_title, opener.into()),
|
||||
);
|
||||
|
||||
// The large face fills a fixed slot so a collapsed panel is shorter than a full
|
||||
// 3-row panel, letting `CollapsePanels` shrink the ribbon row.
|
||||
@@ -1659,6 +1735,41 @@ mod tests {
|
||||
use super::widgets::is_active_tool;
|
||||
use super::Ribbon;
|
||||
|
||||
#[test]
|
||||
fn block_test_close_panel_extends_draw_only_while_testing() {
|
||||
let mut ribbon = Ribbon::default();
|
||||
let draw = ribbon
|
||||
.modules
|
||||
.iter()
|
||||
.position(|module| module.id() == "draw")
|
||||
.unwrap();
|
||||
assert!(!ribbon
|
||||
.modules
|
||||
.iter()
|
||||
.any(|module| module.id() == "block_test"));
|
||||
let ordinary: Vec<_> = ribbon.groups_for(draw).map(|group| group.title).collect();
|
||||
assert!(!ordinary.contains(&"Close"));
|
||||
ribbon.set_block_editing(true);
|
||||
ribbon.set_block_editing(false);
|
||||
ribbon.set_block_testing(true);
|
||||
assert_eq!(ribbon.active, draw);
|
||||
let testing: Vec<_> = ribbon.groups_for(draw).map(|group| group.title).collect();
|
||||
assert_eq!(&testing[..ordinary.len()], ordinary.as_slice());
|
||||
assert_eq!(testing.last(), Some(&"Close"));
|
||||
ribbon.toggle_collapsed_panel("Close");
|
||||
ribbon.set_block_testing(false);
|
||||
assert!(ribbon.collapsed_open.is_none());
|
||||
assert_eq!(
|
||||
ribbon
|
||||
.groups_for(draw)
|
||||
.map(|group| group.title)
|
||||
.collect::<Vec<_>>(),
|
||||
ordinary
|
||||
);
|
||||
ribbon.set_block_editing(true);
|
||||
assert_eq!(ribbon.modules[ribbon.active].id(), "block_editor");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_palette_highlight_follows_the_app_state_passed_to_the_view() {
|
||||
// The Block Palette button highlight is derived from the app's
|
||||
|
||||
+35
-27
@@ -99,7 +99,7 @@ thread_local! {
|
||||
|
||||
/// Dropdown items that report a state and cannot be picked.
|
||||
pub(super) fn is_disabled_item(cmd: &str) -> bool {
|
||||
cmd == "FRAMES3"
|
||||
matches!(cmd, "FRAMES3" | "UOSNAP2")
|
||||
}
|
||||
|
||||
fn ribbon_label_bounds(
|
||||
@@ -543,11 +543,13 @@ pub(super) fn render_small<'a>(
|
||||
.width(Length::Fixed(SMALL_W))
|
||||
.height(ROW_H)
|
||||
.padding([4, 4]);
|
||||
tooltip(btn, make_tip(tip_text), TipPos::Right)
|
||||
.gap(6.0)
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style)
|
||||
.into()
|
||||
super::keytips::anchor(
|
||||
t.id,
|
||||
tooltip(btn, make_tip(tip_text), TipPos::Right)
|
||||
.gap(6.0)
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style),
|
||||
)
|
||||
}
|
||||
|
||||
RibbonItem::LabeledTool(t) => {
|
||||
@@ -568,11 +570,13 @@ pub(super) fn render_small<'a>(
|
||||
.width(Length::Fixed(LABELED_SMALL_W + ARROW_W))
|
||||
.height(ROW_H)
|
||||
.padding([3, 4]);
|
||||
tooltip(btn, make_tip(tip_text), TipPos::Right)
|
||||
.gap(6.0)
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style)
|
||||
.into()
|
||||
super::keytips::anchor(
|
||||
t.id,
|
||||
tooltip(btn, make_tip(tip_text), TipPos::Right)
|
||||
.gap(6.0)
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style),
|
||||
)
|
||||
}
|
||||
|
||||
RibbonItem::Dropdown {
|
||||
@@ -895,7 +899,7 @@ fn tool_row<'a>(tools: &[ToolDef], active_tool: &Option<String>) -> Element<'a,
|
||||
let event = t.event.clone();
|
||||
let icon_el: Element<Message> = make_icon(t.icon, 16.0);
|
||||
let msg = module_event_to_message(event);
|
||||
tooltip(
|
||||
let btn = tooltip(
|
||||
button(icon_el)
|
||||
.on_press(msg)
|
||||
.style(move |theme: &Theme, status| tool_btn_style(theme, is_active, status))
|
||||
@@ -905,8 +909,8 @@ fn tool_row<'a>(tools: &[ToolDef], active_tool: &Option<String>) -> Element<'a,
|
||||
)
|
||||
.gap(4.0)
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style)
|
||||
.into()
|
||||
.style(tip_style);
|
||||
super::keytips::anchor(t.id, btn)
|
||||
})
|
||||
.collect();
|
||||
row(btns).spacing(2).align_y(iced::Center).into()
|
||||
@@ -974,15 +978,17 @@ pub(super) fn render_large<'a>(item: &RibbonItem, ctx: &RenderCtx<'_>) -> Elemen
|
||||
bottom: 4.0,
|
||||
left: 4.0,
|
||||
});
|
||||
tooltip(
|
||||
automatic_large_button(label, btn.into()),
|
||||
make_tip(tip_text),
|
||||
TipPos::Right,
|
||||
super::keytips::anchor(
|
||||
t.id,
|
||||
tooltip(
|
||||
automatic_large_button(label, btn.into()),
|
||||
make_tip(tip_text),
|
||||
TipPos::Right,
|
||||
)
|
||||
.gap(6.0)
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style),
|
||||
)
|
||||
.gap(6.0)
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style)
|
||||
.into()
|
||||
}
|
||||
|
||||
RibbonItem::LargeDropdown {
|
||||
@@ -1313,11 +1319,13 @@ pub(super) fn quick_access_btn<'a>(
|
||||
.width(Length::Fixed(TOP_HIST_W))
|
||||
.height(24)
|
||||
.padding([2, 0]);
|
||||
tooltip(btn, make_tip(t!(label).into_owned()), TipPos::Bottom)
|
||||
.gap(6.0)
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style)
|
||||
.into()
|
||||
super::keytips::anchor_with(
|
||||
|| super::keytips::quick_access_anchor(cmd),
|
||||
tooltip(btn, make_tip(t!(label).into_owned()), TipPos::Bottom)
|
||||
.gap(6.0)
|
||||
.delay(Duration::from_millis(400))
|
||||
.style(tip_style),
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn render_history_control<'a>(
|
||||
|
||||
Reference in new issue
Block a user