Merge pull request #1810 from ramox81/codex/insert-import-panel

Insert ribbon: Import panel

# Conflicts:
#	locales/ar-SA/opencadstudio.ftl
#	locales/bg-BG/opencadstudio.ftl
#	locales/cs-CZ/opencadstudio.ftl
#	locales/de-DE/opencadstudio.ftl
#	locales/el-GR/opencadstudio.ftl
#	locales/en-US/opencadstudio.ftl
#	locales/es-ES/opencadstudio.ftl
#	locales/fi-FI/opencadstudio.ftl
#	locales/fr-FR/opencadstudio.ftl
#	locales/hi-IN/opencadstudio.ftl
#	locales/hu-HU/opencadstudio.ftl
#	locales/it-IT/opencadstudio.ftl
#	locales/ja-JP/opencadstudio.ftl
#	locales/ko-KR/opencadstudio.ftl
#	locales/lo-LA/opencadstudio.ftl
#	locales/nl-NL/opencadstudio.ftl
#	locales/pl-PL/opencadstudio.ftl
#	locales/pt-BR/opencadstudio.ftl
#	locales/ru-RU/opencadstudio.ftl
#	locales/tr-TR/opencadstudio.ftl
#	locales/zh-CN/opencadstudio.ftl
#	locales/zh-TW/opencadstudio.ftl
#	src/modules/insert/mod.rs
#	src/ui/ribbon/draw_panel.rs
This commit is contained in:
Hakan Seven committed 2026-10-15 16:47:38 +03:00
commit 443d3ec13d
33 files changed
+285 -42

No files matched your search

+7
View File
@@ -6691,3 +6691,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = استيراد DGN
.recognize-shx = التعرف على نص SHX
.recognition-settings = إعدادات التعرف
.combine-text = دمج النص
.land-xml = Land XML
.import-file-header = استيراد ملف — يشغّل الزر آخر خيار محدد
+7
View File
@@ -6679,3 +6679,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = Импортиране на DGN
.recognize-shx = Разпознаване на SHX текст
.recognition-settings = Настройки за разпознаване
.combine-text = Обединяване на текст
.land-xml = Land XML
.import-file-header = Импортиране на файл — бутонът изпълнява последно избраното
+7
View File
@@ -6676,3 +6676,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = Import DGN
.recognize-shx = Rozpoznat text SHX
.recognition-settings = Nastavení rozpoznávání
.combine-text = Sloučit text
.land-xml = Land XML
.import-file-header = Importovat soubor — tlačítko spustí naposledy zvolenou položku
+7
View File
@@ -6677,3 +6677,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = DGN-Import
.recognize-shx = SHX-Text erkennen
.recognition-settings = Erkennungseinstellungen
.combine-text = Text kombinieren
.land-xml = Land XML
.import-file-header = Datei importieren — die Schaltfläche führt den zuletzt gewählten Eintrag aus
+7
View File
@@ -6679,3 +6679,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = Εισαγωγή DGN
.recognize-shx = Αναγνώριση κειμένου SHX
.recognition-settings = Ρυθμίσεις αναγνώρισης
.combine-text = Συνδυασμός κειμένου
.land-xml = Land XML
.import-file-header = Εισαγωγή αρχείου — το κουμπί εκτελεί την τελευταία επιλογή
+7
View File
@@ -6678,3 +6678,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = DGN Import
.recognize-shx = Recognize SHX Text
.recognition-settings = Recognition Settings
.combine-text = Combine Text
.land-xml = Land XML
.import-file-header = Import File — the face runs the last one chosen
+7
View File
@@ -6679,3 +6679,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = Importar DGN
.recognize-shx = Reconocer texto SHX
.recognition-settings = Parámetros de reconocimiento
.combine-text = Combinar texto
.land-xml = Land XML
.import-file-header = Importar archivo — el botón ejecuta la última opción elegida
+7
View File
@@ -6676,3 +6676,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = DGN-tuonti
.recognize-shx = Tunnista SHX-teksti
.recognition-settings = Tunnistusasetukset
.combine-text = Yhdistä teksti
.land-xml = Land XML
.import-file-header = Tuo tiedosto — painike suorittaa viimeksi valitun
+7
View File
@@ -6679,3 +6679,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = Import DGN
.recognize-shx = Reconnaître le texte SHX
.recognition-settings = Paramètres de reconnaissance
.combine-text = Combiner le texte
.land-xml = Land XML
.import-file-header = Importer un fichier — le bouton exécute le dernier choix
+7
View File
@@ -6667,3 +6667,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = DGN आयात
.recognize-shx = SHX टेक्स्ट पहचानें
.recognition-settings = पहचान सेटिंग्स
.combine-text = टेक्स्ट मिलाएँ
.land-xml = Land XML
.import-file-header = फ़ाइल आयात — बटन अंतिम चुना गया विकल्प चलाता है
+7
View File
@@ -6663,3 +6663,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = DGN-importálás
.recognize-shx = SHX-szöveg felismerése
.recognition-settings = Felismerési beállítások
.combine-text = Szöveg egyesítése
.land-xml = Land XML
.import-file-header = Fájl importálása — a gomb a legutóbb választottat futtatja
+7
View File
@@ -6678,3 +6678,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = Importa DGN
.recognize-shx = Riconosci testo SHX
.recognition-settings = Impostazioni di riconoscimento
.combine-text = Combina testo
.land-xml = Land XML
.import-file-header = Importa file — il pulsante esegue l'ultima scelta
+7
View File
@@ -6667,3 +6667,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = DGN 読み込み
.recognize-shx = SHX 文字を認識
.recognition-settings = 認識設定
.combine-text = 文字を結合
.land-xml = Land XML
.import-file-header = ファイル読み込み — ボタンは最後に選んだ項目を実行します
+7
View File
@@ -6678,3 +6678,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = DGN 가져오기
.recognize-shx = SHX 문자 인식
.recognition-settings = 인식 설정
.combine-text = 문자 결합
.land-xml = Land XML
.import-file-header = 파일 가져오기 — 버튼은 마지막으로 선택한 항목을 실행합니다
+7
View File
@@ -6679,3 +6679,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = ນໍາເຂົ້າ DGN
.recognize-shx = ຮັບຮູ້ຂໍ້ຄວາມ SHX
.recognition-settings = ການຕັ້ງຄ່າການຮັບຮູ້
.combine-text = ລວມຂໍ້ຄວາມ
.land-xml = Land XML
.import-file-header = ນໍາເຂົ້າໄຟລ໌ — ປຸ່ມຈະເຮັດລາຍການທີ່ເລືອກລ່າສຸດ
+7
View File
@@ -6677,3 +6677,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = DGN importeren
.recognize-shx = SHX-tekst herkennen
.recognition-settings = Herkenningsinstellingen
.combine-text = Tekst combineren
.land-xml = Land XML
.import-file-header = Bestand importeren — de knop voert de laatste keuze uit
+7
View File
@@ -6678,3 +6678,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = Import DGN
.recognize-shx = Rozpoznaj tekst SHX
.recognition-settings = Ustawienia rozpoznawania
.combine-text = Połącz tekst
.land-xml = Land XML
.import-file-header = Importuj plik — przycisk uruchamia ostatnio wybraną pozycję
+7
View File
@@ -6679,3 +6679,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = Importar DGN
.recognize-shx = Reconhecer texto SHX
.recognition-settings = Configurações de reconhecimento
.combine-text = Combinar texto
.land-xml = Land XML
.import-file-header = Importar arquivo — o botão executa a última opção escolhida
+7
View File
@@ -6680,3 +6680,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = Импорт DGN
.recognize-shx = Распознать текст SHX
.recognition-settings = Параметры распознавания
.combine-text = Объединить текст
.land-xml = Land XML
.import-file-header = Импорт файла — кнопка запускает последний выбранный пункт
+7
View File
@@ -6600,3 +6600,10 @@ dgn-import =
.help-import = Seçilen biçimdeki dosyayı o biçimin içe aktarıcısıyla içe aktarır.
.blank = Dosya adı boş olamaz
.invalid-dgn = Geçersiz veya desteklenmeyen DGN dosyası.
import-panel =
.dgn-import = DGN İçe Aktar
.recognize-shx = SHX Metnini Tanı
.recognition-settings = Tanıma Ayarları
.combine-text = Metni Birleştir
.land-xml = Arazi XML
.import-file-header = Dosya İçe Aktar — yüz son seçileni çalıştırır
+7
View File
@@ -6662,3 +6662,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = DGN 输入
.recognize-shx = 识别 SHX 文字
.recognition-settings = 识别设置
.combine-text = 合并文字
.land-xml = Land XML
.import-file-header = 输入文件 — 按钮运行上次选择的项
+7
View File
@@ -6674,3 +6674,10 @@ dgn-import =
.help-import = Imports a file of the chosen format with the format's importer.
.blank = Filename cannot be blank
.invalid-dgn = Invalid or unsupported DGN file.
import-panel =
.dgn-import = DGN 匯入
.recognize-shx = 辨識 SHX 文字
.recognition-settings = 辨識設定
.combine-text = 合併文字
.land-xml = Land XML
.import-file-header = 匯入檔案 — 按鈕執行上次選取的項目
+19
View File
@@ -109,6 +109,25 @@ impl OpenCADStudio {
task
}
/// Run a ribbon command. A `;` stands for Enter, as in a menu macro: each
/// part answers the running command's prompt, or starts a command when
/// none runs (`PDFIMPORT;FILE`).
pub(super) fn dispatch_ribbon_command(&mut self, cmd: &str) -> Task<Message> {
if !cmd.contains(';') {
return self.dispatch_command(cmd);
}
let i = self.active_tab;
let mut tasks = Vec::new();
for part in cmd.split(';') {
tasks.push(if self.tabs[i].active_cmd.is_some() {
self.feed_active_cmd(part)
} else {
self.dispatch_command(part)
});
}
Task::batch(tasks)
}
/// Turn the ribbon highlight off when the command just dispatched left
/// nothing running: no interactive command, dialog or navigation mode.
/// One-shot commands (view changes, clipboard, toggles, audits…) would
+1 -1
View File
@@ -133,7 +133,7 @@ impl OpenCADStudio {
match event {
// `dispatch_command` turns a one-shot tool's highlight off
// again once nothing is left running (#355).
ModuleEvent::Command(cmd) => return self.dispatch_command(&cmd),
ModuleEvent::Command(cmd) => return self.dispatch_ribbon_command(&cmd),
ModuleEvent::OpenFileDialog => {
self.command_line
.push_info(crate::t!("Open DWG/DXF: not yet implemented.").as_ref());
+1 -1
View File
@@ -6704,7 +6704,7 @@ impl OpenCADStudio {
};
self.ribbon.select_dropdown_item(dropdown_id, face);
self.ribbon.activate_tool(cmd);
self.dispatch_command(cmd)
self.dispatch_ribbon_command(cmd)
}
Message::DeleteSelected => {
+6
View File
@@ -6143,6 +6143,12 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
"Remote image \"{url}\" could not be fetched: the server returned HTTP {status}." => Some(("common", "remote-image-url-could-not-be-fetched-the-server-returned-http-status")),
"Remote image \"{url}\" was not loaded: it exceeds the 64 MB remote-image limit." => Some(("common", "remote-image-url-was-not-loaded-it-exceeds-the-64-mb-remote-image-limit")),
"Remote image \"{url}\" could not be fetched: the request timed out." => Some(("common", "remote-image-url-could-not-be-fetched-the-request-timed-out")),
"DGN Import" => Some(("import-panel", "dgn-import")),
"Recognize SHX Text" => Some(("import-panel", "recognize-shx")),
"Recognition Settings" => Some(("import-panel", "recognition-settings")),
"Combine Text" => Some(("import-panel", "combine-text")),
"Land XML" => Some(("import-panel", "land-xml")),
"Import File — the face runs the last one chosen" => Some(("import-panel", "import-file-header")),
_ => None,
}
}
-10
View File
@@ -1,10 +0,0 @@
use crate::modules::{IconKind, ModuleEvent, ToolDef};
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/landxml.svg"));
pub fn tool() -> ToolDef {
ToolDef {
id: "LANDXMLIMPORT",
label: "Land\nXML",
icon: ICON,
event: ModuleEvent::Command("LANDXMLIMPORT".to_string()),
}
}
+40 -6
View File
@@ -12,10 +12,8 @@ pub(crate) mod dgn_import;
pub(crate) mod edit_block;
pub(crate) mod image_transparency;
pub(crate) mod insert_block;
mod landxml;
pub mod minsert;
mod mview_block;
mod open_obj;
pub(crate) mod pc_attach;
pub(crate) mod pc_crop;
pub(crate) mod pc_extract;
@@ -33,11 +31,13 @@ pub(crate) mod xattach;
pub(crate) mod xclip;
pub(crate) mod xref_cmd;
use crate::modules::{CadModule, IconKind, RibbonGroup, RibbonItem, ToolDef};
use crate::modules::{CadModule, IconKind, ModuleEvent, RibbonGroup, RibbonItem, ToolDef};
/// Insert > Block Definition: the Create Block / Write Block split button.
pub(crate) const CREATE_BLOCK_DROPDOWN: &str = "CREATE_BLOCK_DROPDOWN";
const IMPORT_ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/import_obj.svg"));
const FRAMES_ICON: IconKind =
IconKind::Svg(include_bytes!("../../../assets/icons/underlay_frames.svg"));
@@ -164,12 +164,46 @@ impl CadModule for InsertModule {
},
],
},
// ── Import ────────────────────────────────────────────────────────
// ── Import (slide-out: Land XML) ──────────────────────────────────
RibbonGroup {
title: "Import",
tools: vec![
RibbonItem::LargeTool(open_obj::tool()),
RibbonItem::LargeTool(landxml::tool()),
// The face names and runs the last one chosen. A `;`
// answers the started command's prompt, as in a menu
// macro.
RibbonItem::LargeDropdown {
id: "IMPORT_FILE",
label: "",
icon: IMPORT_ICON,
items: vec![
("PDFIMPORT;FILE", "PDF Import", underlay_layers::ICON),
("DGNIMPORT", "DGN Import", underlay_layers::ICON),
("IMPORT", "Import…", IMPORT_ICON),
],
default: "PDFIMPORT;FILE",
},
RibbonItem::LabeledTool(ToolDef {
id: "PDFSHXTEXT",
label: "Recognize SHX Text",
icon: IconKind::Svg(include_bytes!("../../../assets/icons/text.svg")),
event: ModuleEvent::Command("PDFSHXTEXT".to_string()),
}),
RibbonItem::LabeledTool(ToolDef {
id: "PDFSHXTEXT_SETTINGS",
label: "Recognition Settings",
icon: IconKind::Svg(include_bytes!(
"../../../assets/icons/options_tool.svg"
)),
event: ModuleEvent::Command(
"PDFSHXTEXTSETTINGS 1;PDFSHXTEXT;SETTINGS".to_string(),
),
}),
RibbonItem::LargeTool(ToolDef {
id: "TXT2MTXT",
label: "Combine Text",
icon: IconKind::Svg(include_bytes!("../../../assets/icons/mtext.svg")),
event: ModuleEvent::Command("TXT2MTXT".to_string()),
}),
],
},
// ── Content ───────────────────────────────────────────────────────
-9
View File
@@ -1,9 +0,0 @@
use crate::modules::{IconKind, ModuleEvent, ToolDef};
pub fn tool() -> ToolDef {
ToolDef {
id: "OPEN",
label: "Open",
icon: IconKind::Svg(include_bytes!("../../../assets/icons/import_obj.svg")),
event: ModuleEvent::OpenFileDialog,
}
}
+34 -14
View File
@@ -173,6 +173,14 @@ const BLOCK_DEFINITION_TOOLS: &[Tool] = &[
),
];
/// Insert > Import slide-out, its tools named beside their icons.
const IMPORT_TOOLS: &[Tool] = &[icon_tool(
"LANDXMLIMPORT",
"Land XML",
include_bytes!("../../../assets/icons/landxml.svg"),
)];
const IMPORT_PANEL_ID: &str = "import_extension";
const PANELS: &[Panel] = &[
Panel {
id: PANEL_ID,
@@ -209,6 +217,13 @@ const PANELS: &[Panel] = &[
title: "Block Definition",
tools: BLOCK_DEFINITION_TOOLS,
},
Panel {
id: IMPORT_PANEL_ID,
anchor: None,
title_id: "import_extension_title",
title: "Import",
tools: IMPORT_TOOLS,
},
];
/// Command, label and icon of every tool in the expanded Draw and Modify
@@ -417,19 +432,14 @@ fn tool_button(tool: &Tool, active: bool, panel_id: &'static str) -> Element<'st
}
}
/// The Reference slide-out: Edit Reference, and xref fading on/off with its
/// amount (XDWGFADECTL; the switch keeps the amount as a negative value).
fn reference_overlay<'a>(ribbon: &Ribbon, panel: Panel, win: (f32, f32)) -> Element<'a, Message> {
let width: f32 = 260.0_f32.min((win.0 - 8.0).max(120.0));
let (_, x, anchor_top) = ribbon.dd_anchor(panel.id, width, win.0);
let left = x.clamp(0.0, (win.0 - width).max(0.0));
let top = anchor_top.min((win.1 - 80.0).max(0.0));
let tool = &panel.tools[0];
let edit = button(
/// A slide-out tool as one row: its icon, then its name.
fn labeled_row(panel_id: &'static str, tool: &Tool) -> Element<'static, Message> {
let command = tool.command;
let row = button(
row![
make_icon(IconKind::Svg(tool.icon), 16.0),
keytips::label_anchor(
|| keytips::label_id(&keytips::item_anchor(panel.id, tool.command)),
move || keytips::label_id(&keytips::item_anchor(panel_id, command)),
text(t!(tool.label)).size(11),
),
]
@@ -437,13 +447,23 @@ fn reference_overlay<'a>(ribbon: &Ribbon, panel: Panel, win: (f32, f32)) -> Elem
.align_y(iced::Center),
)
.on_press(Message::DropdownSelectItem {
dropdown_id: panel.id,
cmd: tool.command,
dropdown_id: panel_id,
cmd: command,
})
.style(popup_row_style)
.width(Fill)
.padding([3, 6]);
let edit = keytips::anchor_with(|| keytips::item_anchor(panel.id, tool.command), edit);
keytips::anchor_with(move || keytips::item_anchor(panel_id, command), row)
}
/// The Reference slide-out: Edit Reference, and xref fading on/off with its
/// amount (XDWGFADECTL; the switch keeps the amount as a negative value).
fn reference_overlay<'a>(ribbon: &Ribbon, panel: Panel, win: (f32, f32)) -> Element<'a, Message> {
let width: f32 = 260.0_f32.min((win.0 - 8.0).max(120.0));
let (_, x, anchor_top) = ribbon.dd_anchor(panel.id, width, win.0);
let left = x.clamp(0.0, (win.0 - width).max(0.0));
let top = anchor_top.min((win.1 - 80.0).max(0.0));
let edit = labeled_row(panel.id, &panel.tools[0]);
let fade = ribbon.xref_fade;
let on = fade > 0;
let switch = button(make_icon(
@@ -541,7 +561,7 @@ pub(super) fn overlay<'a>(ribbon: &Ribbon, id: &str, win: (f32, f32)) -> Element
if panel.id == REFERENCE_PANEL_ID {
return reference_overlay(ribbon, panel, win);
}
if panel.id == BLOCK_DEFINITION_PANEL_ID {
if panel.id == BLOCK_DEFINITION_PANEL_ID || panel.id == IMPORT_PANEL_ID {
return labeled_overlay(ribbon, panel, win);
}
let tools = panel.tools;
+7
View File
@@ -405,6 +405,13 @@ const CODES: &[(&str, &str, &str)] = &[
("insert", "UOSNAP_DROPDOWN", "SN"),
("reference_extension", "REFEDIT", "ER"),
("reference_extension", XREF_FADE, "XF"),
("insert", "IMPORT_FILE", "IF"),
("IMPORT_FILE", "PDFIMPORT;FILE", "PI"),
("IMPORT_FILE", "DGNIMPORT", "DI"),
("IMPORT_FILE", "IMPORT", "OI"),
("insert", "PDFSHXTEXT", "PS"),
("insert", "PDFSHXTEXT_SETTINGS", "PT"),
("insert", "TXT2MTXT", "TM"),
// Annotate.
("annotate", "Text", "TE"),
("annotate", "ANNOTATE_TEXT", "MT"),
+17 -1
View File
@@ -50,6 +50,11 @@ pub(crate) fn tooltip_style(theme: &Theme) -> container::Style {
widgets::tip_style(theme)
}
/// A line over the items of a split button whose face names the chosen item.
fn dropdown_header(id: &str) -> Option<&'static str> {
(id == "IMPORT_FILE").then_some("Import File — the face runs the last one chosen")
}
// ── Ribbon state ───────────────────────────────────────────────────────────
pub struct Ribbon {
@@ -1069,11 +1074,22 @@ impl Ribbon {
.iter()
.map(|(_, label, _)| t!(*label).to_string())
.collect();
let header = dropdown_header(dd_id).map(|header| t!(header).into_owned());
let mut rows = rows;
if let Some(header) = &header {
rows.insert(
0,
container(text(header.clone()).size(10).style(muted_text_style))
.padding([4, 10])
.into(),
);
}
let panel_w = crate::ui::style::common::dropdown_popup_width(
labels.iter().map(|s| s.as_str()),
11.0,
68.0,
190.0,
// A header wraps rather than widening the menu.
if header.is_some() { 240.0 } else { 190.0 },
);
let panel = container(column(rows))
+6
View File
@@ -501,6 +501,8 @@ fn tool_description(id: &str) -> Option<&'static str> {
/// A tool's tooltip: its name, its description when one is known, and the
/// command it runs.
fn tool_tip_text(label: &str, id: &str) -> String {
// A macro (`PDFIMPORT;FILE`) shows the command it starts.
let id = id.split(';').next().unwrap_or(id);
match tool_description(id) {
Some(description) => format!("{label}\n{}\n{} {id}", t!(description), t!("Command:")),
None => format!("{label}\n{} {id}", t!("Command:")),
@@ -827,6 +829,10 @@ pub(super) fn render_large_dropdown<'a>(
})
.or_else(|| items.first().map(|(_, lbl, _)| *lbl))
.unwrap_or(id);
// An empty label: the face keeps its own icon and names the chosen item.
let names_item = explicit_label == Some("");
let cur_icon = if names_item { icon } else { cur_icon };
let explicit_label = explicit_label.filter(|label| !label.is_empty());
let label = t!(explicit_label.unwrap_or(cur_label)).into_owned();
let tip_text = tool_tip_text(&t!(cur_label), last);
let arr_tip = format!("{} {}", label, t!("options"));