forked from 1b-agent/opencadstudio-upstream
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:
1 parent
7c893d8f5f
commit
44d0c65ae9
10 files changed
+115
-17
No files matched your search
@@ -94,6 +94,10 @@ clipboard-no-supported-content = Die Zwischenablage enthält keinen unterstützt
|
||||
clipboard-unavailable = Die Systemzwischenablage ist nicht verfügbar.
|
||||
clipboard-occupied = Die Systemzwischenablage wird gerade verwendet. Versuchen Sie es erneut.
|
||||
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-attribute-editor = Attribut-Editor
|
||||
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-occupied = System clipboard is currently in use. Try again.
|
||||
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-attribute-editor = Attribute Editor
|
||||
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-occupied = Le presse-papiers système est en cours d’utilisation. Réessayez.
|
||||
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-attribute-editor = Éditeur d'attributs
|
||||
modal-save-drawing-as = Enregistrer le dessin sous
|
||||
|
||||
@@ -94,6 +94,10 @@ clipboard-no-supported-content = क्लिपबोर्ड में सम
|
||||
clipboard-unavailable = सिस्टम क्लिपबोर्ड उपलब्ध नहीं है।
|
||||
clipboard-occupied = सिस्टम क्लिपबोर्ड अभी उपयोग में है। फिर प्रयास करें।
|
||||
clipboard-conversion-failed = क्लिपबोर्ड का टेक्स्ट पढ़ा नहीं जा सका।
|
||||
viewport-split-vertical = व्यूपोर्ट को लंबवत विभाजित करें
|
||||
viewport-split-horizontal = व्यूपोर्ट को क्षैतिज विभाजित करें
|
||||
viewport-move = व्यूपोर्ट ले जाएँ
|
||||
viewport-close = व्यूपोर्ट बंद करें
|
||||
modal-point-style = प्वाइंट स्टाइल
|
||||
modal-attribute-editor = विशेषता संपादक
|
||||
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-occupied = Het systeemklembord is momenteel in gebruik. Probeer het opnieuw.
|
||||
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-attribute-editor = Kenmerkeditor
|
||||
modal-save-drawing-as = Tekening opslaan als
|
||||
|
||||
@@ -94,6 +94,10 @@ clipboard-no-supported-content = Буфер обмена не содержит
|
||||
clipboard-unavailable = Системный буфер обмена недоступен.
|
||||
clipboard-occupied = Системный буфер обмена сейчас используется. Повторите попытку.
|
||||
clipboard-conversion-failed = Не удалось прочитать текст из буфера обмена.
|
||||
viewport-split-vertical = Разделить видовой экран по вертикали
|
||||
viewport-split-horizontal = Разделить видовой экран по горизонтали
|
||||
viewport-move = Переместить видовой экран
|
||||
viewport-close = Закрыть видовой экран
|
||||
modal-point-style = Стиль точек
|
||||
modal-attribute-editor = Редактор атрибутов
|
||||
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-occupied = Sistem panosu şu anda kullanılıyor. Yeniden deneyin.
|
||||
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-attribute-editor = Öznitelik Düzenleyicisi
|
||||
modal-save-drawing-as = Çizimi Farklı Kaydet
|
||||
|
||||
@@ -94,6 +94,10 @@ clipboard-no-supported-content = 剪贴板中没有受支持的文本或图形
|
||||
clipboard-unavailable = 系统剪贴板不可用。
|
||||
clipboard-occupied = 系统剪贴板当前正被使用,请重试。
|
||||
clipboard-conversion-failed = 无法读取剪贴板文本。
|
||||
viewport-split-vertical = 垂直拆分视口
|
||||
viewport-split-horizontal = 水平拆分视口
|
||||
viewport-move = 移动视口
|
||||
viewport-close = 关闭视口
|
||||
modal-point-style = 点样式
|
||||
modal-attribute-editor = 属性编辑器
|
||||
modal-save-drawing-as = 图纸另存为
|
||||
|
||||
+75
-17
@@ -1,10 +1,26 @@
|
||||
use super::*;
|
||||
use super::super::document::{DynComponent, DynFieldEntry};
|
||||
use super::super::Message;
|
||||
use iced::widget::{
|
||||
button, container, mouse_area, row,
|
||||
};
|
||||
use iced::widget::{button, container, mouse_area, row, tooltip};
|
||||
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>(
|
||||
render_mode: acadrust::entities::ViewportRenderMode,
|
||||
@@ -23,8 +39,11 @@ pub(super) fn viewport_controls<'a>(
|
||||
RenderModeChoice(M::FlatShadedWithEdges),
|
||||
RenderModeChoice(M::GouraudShadedWithEdges),
|
||||
];
|
||||
let danger_btn = move |bytes: &'static [u8], msg: Message| {
|
||||
button(crate::ui::icons::themed_danger(bytes, 15.0))
|
||||
let danger_btn = move |bytes: &'static [u8],
|
||||
msg: Message,
|
||||
title: String,
|
||||
command: &'static str| {
|
||||
let button = button(crate::ui::icons::themed_danger(bytes, 15.0))
|
||||
.on_press(msg)
|
||||
.padding([4, 6])
|
||||
.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::Pressed
|
||||
)
|
||||
.then_some(Background::Color(
|
||||
theme.palette().danger.weak.color
|
||||
)),
|
||||
.then_some(Background::Color(theme.palette().danger.weak.color)),
|
||||
border: Border {
|
||||
radius: 3.0.into(),
|
||||
..Default::default()
|
||||
},
|
||||
text_color: theme.palette().danger.base.color,
|
||||
..Default::default()
|
||||
})
|
||||
});
|
||||
viewport_tooltip(button, title, command)
|
||||
};
|
||||
|
||||
// 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 {
|
||||
crate::ui::icons::themed_primary(bytes, 15.0)
|
||||
} else {
|
||||
crate::ui::icons::themed(bytes, 15.0)
|
||||
};
|
||||
button(icon)
|
||||
let button = button(icon)
|
||||
.on_press(msg)
|
||||
.padding([4, 6])
|
||||
.style(move |theme: &Theme, status| {
|
||||
@@ -75,7 +97,8 @@ pub(super) fn viewport_controls<'a>(
|
||||
.unwrap_or(palette.background.base.text),
|
||||
..Default::default()
|
||||
}
|
||||
})
|
||||
});
|
||||
viewport_tooltip(button, title, command)
|
||||
};
|
||||
|
||||
// Render-mode picker, restyled borderless so the outer chip frames it.
|
||||
@@ -100,6 +123,11 @@ pub(super) fn viewport_controls<'a>(
|
||||
handle_color: text,
|
||||
}
|
||||
});
|
||||
let picker = viewport_tooltip(
|
||||
picker,
|
||||
crate::t!("Visual Style").into_owned(),
|
||||
"VISUALSTYLES",
|
||||
);
|
||||
|
||||
// Thin vertical divider between control groups.
|
||||
let sep = || {
|
||||
@@ -117,17 +145,41 @@ pub(super) fn viewport_controls<'a>(
|
||||
.spacing(3)
|
||||
.align_y(iced::alignment::Vertical::Center);
|
||||
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(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(picker);
|
||||
if include_split {
|
||||
bar = bar
|
||||
.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(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.
|
||||
// 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
|
||||
@@ -146,11 +198,17 @@ pub(super) fn viewport_controls<'a>(
|
||||
)
|
||||
.interaction(iced::mouse::Interaction::Grab)
|
||||
.on_press(Message::PaneMoveStart);
|
||||
let drag = viewport_tooltip(drag, crate::tr!("viewport-move"), "VPORTS");
|
||||
bar = bar
|
||||
.push(sep())
|
||||
.push(drag)
|
||||
.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::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 ───────────────────────────────────────────────────────────
|
||||
|
||||
pub struct Ribbon {
|
||||
|
||||
Reference in new issue
Block a user