diff --git a/locales/de-DE/opencadstudio.ftl b/locales/de-DE/opencadstudio.ftl index b7114711..79346055 100644 --- a/locales/de-DE/opencadstudio.ftl +++ b/locales/de-DE/opencadstudio.ftl @@ -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 diff --git a/locales/en-US/opencadstudio.ftl b/locales/en-US/opencadstudio.ftl index 03521a4f..3b765265 100644 --- a/locales/en-US/opencadstudio.ftl +++ b/locales/en-US/opencadstudio.ftl @@ -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 diff --git a/locales/fr-FR/opencadstudio.ftl b/locales/fr-FR/opencadstudio.ftl index 06832dca..d676f979 100644 --- a/locales/fr-FR/opencadstudio.ftl +++ b/locales/fr-FR/opencadstudio.ftl @@ -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 diff --git a/locales/hi-IN/opencadstudio.ftl b/locales/hi-IN/opencadstudio.ftl index db28b85d..fc039232 100644 --- a/locales/hi-IN/opencadstudio.ftl +++ b/locales/hi-IN/opencadstudio.ftl @@ -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 = ड्रॉइंग इस रूप में सहेजें diff --git a/locales/nl-NL/opencadstudio.ftl b/locales/nl-NL/opencadstudio.ftl index 2833fb01..d3bd2418 100644 --- a/locales/nl-NL/opencadstudio.ftl +++ b/locales/nl-NL/opencadstudio.ftl @@ -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 diff --git a/locales/ru-RU/opencadstudio.ftl b/locales/ru-RU/opencadstudio.ftl index 7ad2fcf2..5de47427 100644 --- a/locales/ru-RU/opencadstudio.ftl +++ b/locales/ru-RU/opencadstudio.ftl @@ -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 = Сохранить чертеж как diff --git a/locales/tr-TR/opencadstudio.ftl b/locales/tr-TR/opencadstudio.ftl index dd8824b9..2c37fa60 100644 --- a/locales/tr-TR/opencadstudio.ftl +++ b/locales/tr-TR/opencadstudio.ftl @@ -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 diff --git a/locales/zh-CN/opencadstudio.ftl b/locales/zh-CN/opencadstudio.ftl index 5ee38a8f..92be5420 100644 --- a/locales/zh-CN/opencadstudio.ftl +++ b/locales/zh-CN/opencadstudio.ftl @@ -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 = 图纸另存为 diff --git a/src/app/view/controls.rs b/src/app/view/controls.rs index 6c83a9c7..8b877c03 100644 --- a/src/app/view/controls.rs +++ b/src/app/view/controls.rs @@ -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>, + 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", + )); } } diff --git a/src/ui/ribbon/mod.rs b/src/ui/ribbon/mod.rs index 69e3a034..a002cf64 100644 --- a/src/ui/ribbon/mod.rs +++ b/src/ui/ribbon/mod.rs @@ -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 {