feat(ui): add viewport tooltips
Reuse ribbon tooltip styling for every viewport toolbar action and expose translated action names with related commands. Refs #482
This commit is contained in:
parent
7c893d8f5f
commit
44d0c65ae9
10 changed files with 115 additions and 17 deletions
|
|
@ -94,6 +94,10 @@ clipboard-no-supported-content = Die Zwischenablage enthält keinen unterstützt
|
||||||
clipboard-unavailable = Die Systemzwischenablage ist nicht verfügbar.
|
clipboard-unavailable = Die Systemzwischenablage ist nicht verfügbar.
|
||||||
clipboard-occupied = Die Systemzwischenablage wird gerade verwendet. Versuchen Sie es erneut.
|
clipboard-occupied = Die Systemzwischenablage wird gerade verwendet. Versuchen Sie es erneut.
|
||||||
clipboard-conversion-failed = Der Text in der Zwischenablage konnte nicht gelesen werden.
|
clipboard-conversion-failed = Der Text in der Zwischenablage konnte nicht gelesen werden.
|
||||||
|
viewport-split-vertical = Ansichtsfenster vertikal teilen
|
||||||
|
viewport-split-horizontal = Ansichtsfenster horizontal teilen
|
||||||
|
viewport-move = Ansichtsfenster verschieben
|
||||||
|
viewport-close = Ansichtsfenster schließen
|
||||||
modal-point-style = Punktstil
|
modal-point-style = Punktstil
|
||||||
modal-attribute-editor = Attribut-Editor
|
modal-attribute-editor = Attribut-Editor
|
||||||
modal-save-drawing-as = Zeichnung speichern als
|
modal-save-drawing-as = Zeichnung speichern als
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,10 @@ clipboard-no-supported-content = Clipboard does not contain supported text or dr
|
||||||
clipboard-unavailable = System clipboard is unavailable.
|
clipboard-unavailable = System clipboard is unavailable.
|
||||||
clipboard-occupied = System clipboard is currently in use. Try again.
|
clipboard-occupied = System clipboard is currently in use. Try again.
|
||||||
clipboard-conversion-failed = Clipboard text could not be read.
|
clipboard-conversion-failed = Clipboard text could not be read.
|
||||||
|
viewport-split-vertical = Split Viewport Vertically
|
||||||
|
viewport-split-horizontal = Split Viewport Horizontally
|
||||||
|
viewport-move = Move Viewport
|
||||||
|
viewport-close = Close Viewport
|
||||||
modal-point-style = Point Style
|
modal-point-style = Point Style
|
||||||
modal-attribute-editor = Attribute Editor
|
modal-attribute-editor = Attribute Editor
|
||||||
modal-save-drawing-as = Save Drawing As
|
modal-save-drawing-as = Save Drawing As
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,10 @@ clipboard-no-supported-content = Le presse-papiers ne contient aucun texte ni ob
|
||||||
clipboard-unavailable = Le presse-papiers système n’est pas disponible.
|
clipboard-unavailable = Le presse-papiers système n’est pas disponible.
|
||||||
clipboard-occupied = Le presse-papiers système est en cours d’utilisation. Réessayez.
|
clipboard-occupied = Le presse-papiers système est en cours d’utilisation. Réessayez.
|
||||||
clipboard-conversion-failed = Impossible de lire le texte du presse-papiers.
|
clipboard-conversion-failed = Impossible de lire le texte du presse-papiers.
|
||||||
|
viewport-split-vertical = Diviser la fenêtre verticalement
|
||||||
|
viewport-split-horizontal = Diviser la fenêtre horizontalement
|
||||||
|
viewport-move = Déplacer la fenêtre
|
||||||
|
viewport-close = Fermer la fenêtre
|
||||||
modal-point-style = Style de point
|
modal-point-style = Style de point
|
||||||
modal-attribute-editor = Éditeur d'attributs
|
modal-attribute-editor = Éditeur d'attributs
|
||||||
modal-save-drawing-as = Enregistrer le dessin sous
|
modal-save-drawing-as = Enregistrer le dessin sous
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,10 @@ clipboard-no-supported-content = क्लिपबोर्ड में सम
|
||||||
clipboard-unavailable = सिस्टम क्लिपबोर्ड उपलब्ध नहीं है।
|
clipboard-unavailable = सिस्टम क्लिपबोर्ड उपलब्ध नहीं है।
|
||||||
clipboard-occupied = सिस्टम क्लिपबोर्ड अभी उपयोग में है। फिर प्रयास करें।
|
clipboard-occupied = सिस्टम क्लिपबोर्ड अभी उपयोग में है। फिर प्रयास करें।
|
||||||
clipboard-conversion-failed = क्लिपबोर्ड का टेक्स्ट पढ़ा नहीं जा सका।
|
clipboard-conversion-failed = क्लिपबोर्ड का टेक्स्ट पढ़ा नहीं जा सका।
|
||||||
|
viewport-split-vertical = व्यूपोर्ट को लंबवत विभाजित करें
|
||||||
|
viewport-split-horizontal = व्यूपोर्ट को क्षैतिज विभाजित करें
|
||||||
|
viewport-move = व्यूपोर्ट ले जाएँ
|
||||||
|
viewport-close = व्यूपोर्ट बंद करें
|
||||||
modal-point-style = प्वाइंट स्टाइल
|
modal-point-style = प्वाइंट स्टाइल
|
||||||
modal-attribute-editor = विशेषता संपादक
|
modal-attribute-editor = विशेषता संपादक
|
||||||
modal-save-drawing-as = ड्रॉइंग इस रूप में सहेजें
|
modal-save-drawing-as = ड्रॉइंग इस रूप में सहेजें
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,10 @@ clipboard-no-supported-content = Het klembord bevat geen ondersteunde tekst of t
|
||||||
clipboard-unavailable = Het systeemklembord is niet beschikbaar.
|
clipboard-unavailable = Het systeemklembord is niet beschikbaar.
|
||||||
clipboard-occupied = Het systeemklembord is momenteel in gebruik. Probeer het opnieuw.
|
clipboard-occupied = Het systeemklembord is momenteel in gebruik. Probeer het opnieuw.
|
||||||
clipboard-conversion-failed = De tekst op het klembord kon niet worden gelezen.
|
clipboard-conversion-failed = De tekst op het klembord kon niet worden gelezen.
|
||||||
|
viewport-split-vertical = Viewport verticaal splitsen
|
||||||
|
viewport-split-horizontal = Viewport horizontaal splitsen
|
||||||
|
viewport-move = Viewport verplaatsen
|
||||||
|
viewport-close = Viewport sluiten
|
||||||
modal-point-style = Puntstijl
|
modal-point-style = Puntstijl
|
||||||
modal-attribute-editor = Kenmerkeditor
|
modal-attribute-editor = Kenmerkeditor
|
||||||
modal-save-drawing-as = Tekening opslaan als
|
modal-save-drawing-as = Tekening opslaan als
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,10 @@ clipboard-no-supported-content = Буфер обмена не содержит
|
||||||
clipboard-unavailable = Системный буфер обмена недоступен.
|
clipboard-unavailable = Системный буфер обмена недоступен.
|
||||||
clipboard-occupied = Системный буфер обмена сейчас используется. Повторите попытку.
|
clipboard-occupied = Системный буфер обмена сейчас используется. Повторите попытку.
|
||||||
clipboard-conversion-failed = Не удалось прочитать текст из буфера обмена.
|
clipboard-conversion-failed = Не удалось прочитать текст из буфера обмена.
|
||||||
|
viewport-split-vertical = Разделить видовой экран по вертикали
|
||||||
|
viewport-split-horizontal = Разделить видовой экран по горизонтали
|
||||||
|
viewport-move = Переместить видовой экран
|
||||||
|
viewport-close = Закрыть видовой экран
|
||||||
modal-point-style = Стиль точек
|
modal-point-style = Стиль точек
|
||||||
modal-attribute-editor = Редактор атрибутов
|
modal-attribute-editor = Редактор атрибутов
|
||||||
modal-save-drawing-as = Сохранить чертеж как
|
modal-save-drawing-as = Сохранить чертеж как
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,10 @@ clipboard-no-supported-content = Panoda desteklenen metin veya çizim nesnesi yo
|
||||||
clipboard-unavailable = Sistem panosuna erişilemiyor.
|
clipboard-unavailable = Sistem panosuna erişilemiyor.
|
||||||
clipboard-occupied = Sistem panosu şu anda kullanılıyor. Yeniden deneyin.
|
clipboard-occupied = Sistem panosu şu anda kullanılıyor. Yeniden deneyin.
|
||||||
clipboard-conversion-failed = Panodaki metin okunamadı.
|
clipboard-conversion-failed = Panodaki metin okunamadı.
|
||||||
|
viewport-split-vertical = Görünüm Penceresini Dikey Böl
|
||||||
|
viewport-split-horizontal = Görünüm Penceresini Yatay Böl
|
||||||
|
viewport-move = Görünüm Penceresini Taşı
|
||||||
|
viewport-close = Görünüm Penceresini Kapat
|
||||||
modal-point-style = Nokta Stili
|
modal-point-style = Nokta Stili
|
||||||
modal-attribute-editor = Öznitelik Düzenleyicisi
|
modal-attribute-editor = Öznitelik Düzenleyicisi
|
||||||
modal-save-drawing-as = Çizimi Farklı Kaydet
|
modal-save-drawing-as = Çizimi Farklı Kaydet
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,10 @@ clipboard-no-supported-content = 剪贴板中没有受支持的文本或图形
|
||||||
clipboard-unavailable = 系统剪贴板不可用。
|
clipboard-unavailable = 系统剪贴板不可用。
|
||||||
clipboard-occupied = 系统剪贴板当前正被使用,请重试。
|
clipboard-occupied = 系统剪贴板当前正被使用,请重试。
|
||||||
clipboard-conversion-failed = 无法读取剪贴板文本。
|
clipboard-conversion-failed = 无法读取剪贴板文本。
|
||||||
|
viewport-split-vertical = 垂直拆分视口
|
||||||
|
viewport-split-horizontal = 水平拆分视口
|
||||||
|
viewport-move = 移动视口
|
||||||
|
viewport-close = 关闭视口
|
||||||
modal-point-style = 点样式
|
modal-point-style = 点样式
|
||||||
modal-attribute-editor = 属性编辑器
|
modal-attribute-editor = 属性编辑器
|
||||||
modal-save-drawing-as = 图纸另存为
|
modal-save-drawing-as = 图纸另存为
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,26 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::super::document::{DynComponent, DynFieldEntry};
|
use super::super::document::{DynComponent, DynFieldEntry};
|
||||||
use super::super::Message;
|
use super::super::Message;
|
||||||
use iced::widget::{
|
use iced::widget::{button, container, mouse_area, row, tooltip};
|
||||||
button, container, mouse_area, row,
|
|
||||||
};
|
|
||||||
use iced::{Background, Border, Element, Theme};
|
use iced::{Background, Border, Element, Theme};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
fn viewport_tooltip<'a>(
|
||||||
|
control: impl Into<Element<'a, Message>>,
|
||||||
|
title: String,
|
||||||
|
command: &'static str,
|
||||||
|
) -> Element<'a, Message> {
|
||||||
|
let text = format!("{title}\n{} {command}", crate::t!("Command:"));
|
||||||
|
tooltip(
|
||||||
|
control,
|
||||||
|
crate::ui::ribbon::tooltip_content(text),
|
||||||
|
tooltip::Position::Bottom,
|
||||||
|
)
|
||||||
|
.gap(6.0)
|
||||||
|
.delay(Duration::from_millis(400))
|
||||||
|
.style(crate::ui::ribbon::tooltip_style)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn viewport_controls<'a>(
|
pub(super) fn viewport_controls<'a>(
|
||||||
render_mode: acadrust::entities::ViewportRenderMode,
|
render_mode: acadrust::entities::ViewportRenderMode,
|
||||||
|
|
@ -23,8 +39,11 @@ pub(super) fn viewport_controls<'a>(
|
||||||
RenderModeChoice(M::FlatShadedWithEdges),
|
RenderModeChoice(M::FlatShadedWithEdges),
|
||||||
RenderModeChoice(M::GouraudShadedWithEdges),
|
RenderModeChoice(M::GouraudShadedWithEdges),
|
||||||
];
|
];
|
||||||
let danger_btn = move |bytes: &'static [u8], msg: Message| {
|
let danger_btn = move |bytes: &'static [u8],
|
||||||
button(crate::ui::icons::themed_danger(bytes, 15.0))
|
msg: Message,
|
||||||
|
title: String,
|
||||||
|
command: &'static str| {
|
||||||
|
let button = button(crate::ui::icons::themed_danger(bytes, 15.0))
|
||||||
.on_press(msg)
|
.on_press(msg)
|
||||||
.padding([4, 6])
|
.padding([4, 6])
|
||||||
.style(move |theme: &Theme, status| iced::widget::button::Style {
|
.style(move |theme: &Theme, status| iced::widget::button::Style {
|
||||||
|
|
@ -33,26 +52,29 @@ pub(super) fn viewport_controls<'a>(
|
||||||
iced::widget::button::Status::Hovered
|
iced::widget::button::Status::Hovered
|
||||||
| iced::widget::button::Status::Pressed
|
| iced::widget::button::Status::Pressed
|
||||||
)
|
)
|
||||||
.then_some(Background::Color(
|
.then_some(Background::Color(theme.palette().danger.weak.color)),
|
||||||
theme.palette().danger.weak.color
|
|
||||||
)),
|
|
||||||
border: Border {
|
border: Border {
|
||||||
radius: 3.0.into(),
|
radius: 3.0.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
text_color: theme.palette().danger.base.color,
|
text_color: theme.palette().danger.base.color,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
});
|
||||||
|
viewport_tooltip(button, title, command)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Borderless icon button; an `active` toggle gets an accent tint + fill.
|
// Borderless icon button; an `active` toggle gets an accent tint + fill.
|
||||||
let icon_btn = move |bytes: &'static [u8], active: bool, msg: Message| {
|
let icon_btn = move |bytes: &'static [u8],
|
||||||
|
active: bool,
|
||||||
|
msg: Message,
|
||||||
|
title: String,
|
||||||
|
command: &'static str| {
|
||||||
let icon = if active {
|
let icon = if active {
|
||||||
crate::ui::icons::themed_primary(bytes, 15.0)
|
crate::ui::icons::themed_primary(bytes, 15.0)
|
||||||
} else {
|
} else {
|
||||||
crate::ui::icons::themed(bytes, 15.0)
|
crate::ui::icons::themed(bytes, 15.0)
|
||||||
};
|
};
|
||||||
button(icon)
|
let button = button(icon)
|
||||||
.on_press(msg)
|
.on_press(msg)
|
||||||
.padding([4, 6])
|
.padding([4, 6])
|
||||||
.style(move |theme: &Theme, status| {
|
.style(move |theme: &Theme, status| {
|
||||||
|
|
@ -75,7 +97,8 @@ pub(super) fn viewport_controls<'a>(
|
||||||
.unwrap_or(palette.background.base.text),
|
.unwrap_or(palette.background.base.text),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
viewport_tooltip(button, title, command)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Render-mode picker, restyled borderless so the outer chip frames it.
|
// Render-mode picker, restyled borderless so the outer chip frames it.
|
||||||
|
|
@ -100,6 +123,11 @@ pub(super) fn viewport_controls<'a>(
|
||||||
handle_color: text,
|
handle_color: text,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
let picker = viewport_tooltip(
|
||||||
|
picker,
|
||||||
|
crate::t!("Visual Style").into_owned(),
|
||||||
|
"VISUALSTYLES",
|
||||||
|
);
|
||||||
|
|
||||||
// Thin vertical divider between control groups.
|
// Thin vertical divider between control groups.
|
||||||
let sep = || {
|
let sep = || {
|
||||||
|
|
@ -117,17 +145,41 @@ pub(super) fn viewport_controls<'a>(
|
||||||
.spacing(3)
|
.spacing(3)
|
||||||
.align_y(iced::alignment::Vertical::Center);
|
.align_y(iced::alignment::Vertical::Center);
|
||||||
bar = bar
|
bar = bar
|
||||||
.push(icon_btn(crate::ui::icons::GRID, show_grid, Message::ToggleGrid))
|
.push(icon_btn(
|
||||||
|
crate::ui::icons::GRID,
|
||||||
|
show_grid,
|
||||||
|
Message::ToggleGrid,
|
||||||
|
crate::t!("Toggle Grid").into_owned(),
|
||||||
|
"GRID",
|
||||||
|
))
|
||||||
.push(sep())
|
.push(sep())
|
||||||
.push(icon_btn(crate::ui::icons::SNAP, snap_on, Message::ToggleGridSnap))
|
.push(icon_btn(
|
||||||
|
crate::ui::icons::SNAP,
|
||||||
|
snap_on,
|
||||||
|
Message::ToggleGridSnap,
|
||||||
|
crate::t!("Toggle Grid Snap").into_owned(),
|
||||||
|
"SNAP",
|
||||||
|
))
|
||||||
.push(sep())
|
.push(sep())
|
||||||
.push(picker);
|
.push(picker);
|
||||||
if include_split {
|
if include_split {
|
||||||
bar = bar
|
bar = bar
|
||||||
.push(sep())
|
.push(sep())
|
||||||
.push(icon_btn(crate::ui::icons::SPLIT_V, false, Message::SplitModelViewport(false)))
|
.push(icon_btn(
|
||||||
|
crate::ui::icons::SPLIT_V,
|
||||||
|
false,
|
||||||
|
Message::SplitModelViewport(false),
|
||||||
|
crate::tr!("viewport-split-vertical"),
|
||||||
|
"VPORTS 2V",
|
||||||
|
))
|
||||||
.push(sep())
|
.push(sep())
|
||||||
.push(icon_btn(crate::ui::icons::SPLIT_H, false, Message::SplitModelViewport(true)));
|
.push(icon_btn(
|
||||||
|
crate::ui::icons::SPLIT_H,
|
||||||
|
false,
|
||||||
|
Message::SplitModelViewport(true),
|
||||||
|
crate::tr!("viewport-split-horizontal"),
|
||||||
|
"VPORTS 2H",
|
||||||
|
));
|
||||||
// Drag handle + close: only meaningful with more than one model tile.
|
// Drag handle + close: only meaningful with more than one model tile.
|
||||||
// The handle is a `mouse_area` (not a button) so it fires on press-DOWN,
|
// The handle is a `mouse_area` (not a button) so it fires on press-DOWN,
|
||||||
// letting the drag continue onto the target pane to swap them (a button
|
// letting the drag continue onto the target pane to swap them (a button
|
||||||
|
|
@ -146,11 +198,17 @@ pub(super) fn viewport_controls<'a>(
|
||||||
)
|
)
|
||||||
.interaction(iced::mouse::Interaction::Grab)
|
.interaction(iced::mouse::Interaction::Grab)
|
||||||
.on_press(Message::PaneMoveStart);
|
.on_press(Message::PaneMoveStart);
|
||||||
|
let drag = viewport_tooltip(drag, crate::tr!("viewport-move"), "VPORTS");
|
||||||
bar = bar
|
bar = bar
|
||||||
.push(sep())
|
.push(sep())
|
||||||
.push(drag)
|
.push(drag)
|
||||||
.push(sep())
|
.push(sep())
|
||||||
.push(danger_btn(crate::ui::icons::CLOSE, Message::CloseModelViewport));
|
.push(danger_btn(
|
||||||
|
crate::ui::icons::CLOSE,
|
||||||
|
Message::CloseModelViewport,
|
||||||
|
crate::tr!("viewport-close"),
|
||||||
|
"VPORTS SINGLE",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,14 @@ pub use collapse::CollapseMode;
|
||||||
use crate::ui::wrap_bar::{PosReport, WrapBar, WrapFlow};
|
use crate::ui::wrap_bar::{PosReport, WrapBar, WrapFlow};
|
||||||
use crate::t;
|
use crate::t;
|
||||||
|
|
||||||
|
pub(crate) fn tooltip_content(text: String) -> Element<'static, Message> {
|
||||||
|
widgets::make_tip(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn tooltip_style(theme: &Theme) -> container::Style {
|
||||||
|
widgets::tip_style(theme)
|
||||||
|
}
|
||||||
|
|
||||||
// ── Ribbon state ───────────────────────────────────────────────────────────
|
// ── Ribbon state ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
pub struct Ribbon {
|
pub struct Ribbon {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue