From e9151ea2f46cabfefa661c1ec6cc8d3830a7a3ac Mon Sep 17 00:00:00 2001 From: Karim Jerbi Date: Sun, 13 Sep 2026 23:16:44 +0100 Subject: [PATCH] feat(xref): wider panel default, Attach DWG/Image/PDF menu, status icons External References dock default 360 to 460 for the column-rich table. Attach split button reads Attach DWG with Attach Image and Attach PDF options, all menu rows full width. List view shows one distinct glyph and theme color per reference status. --- locales/ar-SA/opencadstudio.ftl | 2 + locales/bg-BG/opencadstudio.ftl | 2 + locales/cs-CZ/opencadstudio.ftl | 2 + locales/de-DE/opencadstudio.ftl | 2 + locales/el-GR/opencadstudio.ftl | 2 + locales/en-US/opencadstudio.ftl | 2 + locales/es-ES/opencadstudio.ftl | 2 + locales/fi-FI/opencadstudio.ftl | 2 + locales/fr-FR/opencadstudio.ftl | 2 + locales/hi-IN/opencadstudio.ftl | 2 + locales/hu-HU/opencadstudio.ftl | 2 + locales/it-IT/opencadstudio.ftl | 2 + locales/ja-JP/opencadstudio.ftl | 2 + locales/ko-KR/opencadstudio.ftl | 2 + locales/nl-NL/opencadstudio.ftl | 2 + locales/pl-PL/opencadstudio.ftl | 2 + locales/pt-BR/opencadstudio.ftl | 2 + locales/ru-RU/opencadstudio.ftl | 2 + locales/tr-TR/opencadstudio.ftl | 2 + locales/zh-CN/opencadstudio.ftl | 2 + locales/zh-TW/opencadstudio.ftl | 2 + src/locale_catalog.rs | 2 + src/ui/dock.rs | 6 +- src/ui/window/xref_manager.rs | 103 ++++++++++++++++++++++++++++---- 24 files changed, 137 insertions(+), 16 deletions(-) diff --git a/locales/ar-SA/opencadstudio.ftl b/locales/ar-SA/opencadstudio.ftl index a8c6e216d..373a2dc9a 100644 --- a/locales/ar-SA/opencadstudio.ftl +++ b/locales/ar-SA/opencadstudio.ftl @@ -3217,6 +3217,8 @@ insert = .xref-new-path-for-selection = مسار جديد للتحديد .xref-new-path-prefix = بادئة مسار جديدة .xref-old-path-prefix = بادئة المسار القديم + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF احفظ الرسم أولًا لحل مسارات المراجع الخارجية النسبية. .object-s-copied-to-clipboard-base-3-3 = نُسخ __ocs_fmt_0__ كائن إلى الحافظة (الأساس __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = نُسخ __ocs_fmt_0__ كائن إلى الحافظة. diff --git a/locales/bg-BG/opencadstudio.ftl b/locales/bg-BG/opencadstudio.ftl index 0b258d743..374def6ef 100644 --- a/locales/bg-BG/opencadstudio.ftl +++ b/locales/bg-BG/opencadstudio.ftl @@ -3204,6 +3204,8 @@ insert = .xref-new-path-for-selection = нов път за селекцията .xref-new-path-prefix = нов префикс на път .xref-old-path-prefix = стар префикс на път + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Първо запази чертежа, за да се разрешат относителните XREF пътища. .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ обект(а) копирани в клипборда (база __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = __ocs_fmt_0__ обект(а) копирани в клипборда. diff --git a/locales/cs-CZ/opencadstudio.ftl b/locales/cs-CZ/opencadstudio.ftl index 04dbf62a3..f3a1f3d95 100644 --- a/locales/cs-CZ/opencadstudio.ftl +++ b/locales/cs-CZ/opencadstudio.ftl @@ -3202,6 +3202,8 @@ insert = .xref-new-path-for-selection = nová cesta pro výběr .xref-new-path-prefix = nová předpona cesty .xref-old-path-prefix = stará předpona cesty + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Nejprve uložte výkres, abyste vyřešili relativní cesty XREF. .object-s-copied-to-clipboard-base-3-3 = Objekt(y) __ocs_fmt_0__ zkopírován do schránky (základna __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = Objekt(y) __ocs_fmt_0__ zkopírován do schránky. diff --git a/locales/de-DE/opencadstudio.ftl b/locales/de-DE/opencadstudio.ftl index 9c5b8664d..66d8fd7d2 100644 --- a/locales/de-DE/opencadstudio.ftl +++ b/locales/de-DE/opencadstudio.ftl @@ -3203,6 +3203,8 @@ insert = .xref-new-path-for-selection = neuer Pfad für die Auswahl .xref-new-path-prefix = neue Pfadpräfix .xref-old-path-prefix = alte Pfadpräfix + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Speichern Sie zuerst die Zeichnung, um relative XREF Pfade aufzulösen. .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ Objekt(e) kopiert ins Zwischenablage (Basis __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = __ocs_fmt_0__ Objekt(e) kopiert ins Clipboard. diff --git a/locales/el-GR/opencadstudio.ftl b/locales/el-GR/opencadstudio.ftl index 25682258e..4ec38ec7e 100644 --- a/locales/el-GR/opencadstudio.ftl +++ b/locales/el-GR/opencadstudio.ftl @@ -3215,6 +3215,8 @@ insert = .xref-new-path-for-selection = new path for selection .xref-new-path-prefix = new path prefix .xref-old-path-prefix = old path prefix + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ αντικείμενο(α) αντιγράφηκαν στο πρόχειρο (βάση __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = __ocs_fmt_0__ αντικείμενο(α) αντιγράφηκαν στο πρόχειρο. .object-s-cut-to-clipboard = __ocs_fmt_0__ αντικείμενο(α) αποκόπηκαν στο πρόχειρο. diff --git a/locales/en-US/opencadstudio.ftl b/locales/en-US/opencadstudio.ftl index 3e1b88a89..c34f880aa 100644 --- a/locales/en-US/opencadstudio.ftl +++ b/locales/en-US/opencadstudio.ftl @@ -3216,6 +3216,8 @@ insert = .xref-new-path-for-selection = new path for selection .xref-new-path-prefix = new path prefix .xref-old-path-prefix = old path prefix + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ object(s) copied to clipboard (base __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = __ocs_fmt_0__ object(s) copied to clipboard. .object-s-cut-to-clipboard = __ocs_fmt_0__ object(s) cut to clipboard. diff --git a/locales/es-ES/opencadstudio.ftl b/locales/es-ES/opencadstudio.ftl index eef59816e..cc858fc38 100644 --- a/locales/es-ES/opencadstudio.ftl +++ b/locales/es-ES/opencadstudio.ftl @@ -3205,6 +3205,8 @@ insert = .xref-new-path-for-selection = nueva ruta para la selección .xref-new-path-prefix = nuevo prefijo de ruta .xref-old-path-prefix = prefijo de ruta antiguo + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Guarde primero el dibujo para resolver las rutas relativas de referencias externas. .object-s-copied-to-clipboard-base-3-3 = Se copiaron __ocs_fmt_0__ objetos al portapapeles (base __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = Se copiaron __ocs_fmt_0__ objetos al portapapeles. diff --git a/locales/fi-FI/opencadstudio.ftl b/locales/fi-FI/opencadstudio.ftl index f87e281ea..c6bae9edd 100644 --- a/locales/fi-FI/opencadstudio.ftl +++ b/locales/fi-FI/opencadstudio.ftl @@ -3204,6 +3204,8 @@ insert = .xref-new-path-for-selection = uusi polku valinnalle .xref-new-path-prefix = uusi polun etuliite .xref-old-path-prefix = vanha polun etuliite + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Tallenna piirustus ensin määrittääksesi suhteelliset XREF-polut. .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ objekti(t) kopioitu leikepöydälle (perus __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = __ocs_fmt_0__ objekti(t) kopioitu leikepöydälle. diff --git a/locales/fr-FR/opencadstudio.ftl b/locales/fr-FR/opencadstudio.ftl index 8a310c1a4..57d8f48bd 100644 --- a/locales/fr-FR/opencadstudio.ftl +++ b/locales/fr-FR/opencadstudio.ftl @@ -3205,6 +3205,8 @@ insert = .xref-new-path-for-selection = nouveau chemin pour la sélection .xref-new-path-prefix = nouveau préfixe de chemin .xref-old-path-prefix = ancien préfixe de chemin + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Enregistrez d’abord le dessin afin de résoudre les chemins XREF relatifs. .object-s-copied-to-clipboard-base-3-3 = Objets copiés dans le presse-papiers : __ocs_fmt_0__ (point de base __ocs_fmt_1__, __ocs_fmt_2__). .object-s-copied-to-clipboard = Objets copiés dans le presse-papiers : __ocs_fmt_0__. diff --git a/locales/hi-IN/opencadstudio.ftl b/locales/hi-IN/opencadstudio.ftl index 97bec1c6e..ead31defb 100644 --- a/locales/hi-IN/opencadstudio.ftl +++ b/locales/hi-IN/opencadstudio.ftl @@ -3193,6 +3193,8 @@ insert = .xref-new-path-for-selection = चयन के लिए नया पथ .xref-new-path-prefix = नया पथ उपसर्ग .xref-old-path-prefix = पुराना पथ उपसर्ग + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF सापेक्ष पथ निर्धारित करने के लिए पहले ड्रॉइंग सहेजें। .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ ऑब्जेक्ट (s) क्लिपबोर्ड (बेस __ocs_fmt_1__, __ocs_fmt_2__) को कॉपी किया गया। .object-s-copied-to-clipboard = __ocs_fmt_0__ ऑब्जेक्ट (s) क्लिपबोर्ड पर कॉपी किया गया। diff --git a/locales/hu-HU/opencadstudio.ftl b/locales/hu-HU/opencadstudio.ftl index 135319ef3..faaee7c01 100644 --- a/locales/hu-HU/opencadstudio.ftl +++ b/locales/hu-HU/opencadstudio.ftl @@ -3204,6 +3204,8 @@ insert = .xref-new-path-for-selection = új útvonal a kijelöléshez .xref-new-path-prefix = új útvonal-előtag .xref-old-path-prefix = régi útvonal-előtag + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Először mentse a rajzot a relatív XREF útvonalak feloldásához. .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ objektum(ok) a vágólapra másolva (alap __ocs_fmt_1__, __ocs_fmt_2__). .object-s-copied-to-clipboard = __ocs_fmt_0__ objektum(ok) a vágólapra másolva. diff --git a/locales/it-IT/opencadstudio.ftl b/locales/it-IT/opencadstudio.ftl index c178da5a6..c6bb58edf 100644 --- a/locales/it-IT/opencadstudio.ftl +++ b/locales/it-IT/opencadstudio.ftl @@ -3204,6 +3204,8 @@ insert = .xref-new-path-for-selection = nuovo percorso per la selezione .xref-new-path-prefix = nuovo prefisso percorso .xref-old-path-prefix = vecchio prefisso percorso + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Salvare prima il disegno per risolvere i percorsi XREF relativi. .object-s-copied-to-clipboard-base-3-3 = Oggetto/i __ocs_fmt_0__ copiati negli appunti (base __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = __ocs_fmt_0__ oggetto/i copiati negli appunti. diff --git a/locales/ja-JP/opencadstudio.ftl b/locales/ja-JP/opencadstudio.ftl index 10d6d99c5..f0386a21c 100644 --- a/locales/ja-JP/opencadstudio.ftl +++ b/locales/ja-JP/opencadstudio.ftl @@ -3193,6 +3193,8 @@ insert = .xref-new-path-for-selection = 選択に対する新しいパス .xref-new-path-prefix = 新しいパスプレフィックス .xref-old-path-prefix = 古いパスプレフィックス + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF 相対 XREF パスを解決するには、先に図面を保存してください。 .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ 個のオブジェクトをクリップボードにコピーしました(基点 __ocs_fmt_1__,__ocs_fmt_2__)。 .object-s-copied-to-clipboard = __ocs_fmt_0__ 個のオブジェクトをクリップボードにコピーしました。 diff --git a/locales/ko-KR/opencadstudio.ftl b/locales/ko-KR/opencadstudio.ftl index 60d6e8576..c6e31fcf2 100644 --- a/locales/ko-KR/opencadstudio.ftl +++ b/locales/ko-KR/opencadstudio.ftl @@ -3204,6 +3204,8 @@ insert = .xref-new-path-for-selection = 선택 항목에 대한 새 경로 .xref-new-path-prefix = 새 경로 접두어 .xref-old-path-prefix = 이전 경로 접두어 + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF 상대 XREF 경로를 확인하려면 먼저 도면을 저장하십시오. .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ 개체가 클립보드에 복사되었습니다(기본 __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = __ocs_fmt_0__ 개체가 클립보드에 복사되었습니다. diff --git a/locales/nl-NL/opencadstudio.ftl b/locales/nl-NL/opencadstudio.ftl index dfdc94ec6..d832c891c 100644 --- a/locales/nl-NL/opencadstudio.ftl +++ b/locales/nl-NL/opencadstudio.ftl @@ -3203,6 +3203,8 @@ insert = .xref-new-path-for-selection = nieuw pad voor selectie .xref-new-path-prefix = nieuw padprefix .xref-old-path-prefix = oud padprefix + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Sla de tekening eerst op om relatieve XREF paden op te lossen. .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ object(en) naar het klembord gekopieerd (basispunt __ocs_fmt_1__, __ocs_fmt_2__). .object-s-copied-to-clipboard = __ocs_fmt_0__ object(en) naar het klembord gekopieerd. diff --git a/locales/pl-PL/opencadstudio.ftl b/locales/pl-PL/opencadstudio.ftl index 29abc4f1d..da9cd13fd 100644 --- a/locales/pl-PL/opencadstudio.ftl +++ b/locales/pl-PL/opencadstudio.ftl @@ -3204,6 +3204,8 @@ insert = .xref-new-path-for-selection = nowa ścieżka dla zaznaczenia .xref-new-path-prefix = nowy prefiks ścieżki .xref-old-path-prefix = stary prefiks ścieżki + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Zapisz najpierw rysunek, aby ustalić względne ścieżki XREF. .object-s-copied-to-clipboard-base-3-3 = Obiekt(y) __ocs_fmt_0__ skopiowano do schowka (bazowe __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = Obiekt(y) __ocs_fmt_0__ skopiowano do schowka. diff --git a/locales/pt-BR/opencadstudio.ftl b/locales/pt-BR/opencadstudio.ftl index 63644359b..b8ba82d1d 100644 --- a/locales/pt-BR/opencadstudio.ftl +++ b/locales/pt-BR/opencadstudio.ftl @@ -3206,6 +3206,8 @@ insert = .xref-new-path-for-selection = novo caminho para seleção .xref-new-path-prefix = novo prefixo de caminho .xref-old-path-prefix = prefixo de caminho antigo + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Salve primeiro o desenho para resolver os caminhos relativos das referências externas. .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ objetos copiados para a área de transferência (base __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = __ocs_fmt_0__ objetos copiados para a área de transferência. diff --git a/locales/ru-RU/opencadstudio.ftl b/locales/ru-RU/opencadstudio.ftl index 2d87598e9..89e787366 100644 --- a/locales/ru-RU/opencadstudio.ftl +++ b/locales/ru-RU/opencadstudio.ftl @@ -3206,6 +3206,8 @@ insert = .xref-new-path-for-selection = новый путь для выбора .xref-new-path-prefix = новый префикс пути .xref-old-path-prefix = старый префикс пути + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Сначала сохраните чертёж, чтобы определить относительные пути внешних ссылок. .object-s-copied-to-clipboard-base-3-3 = В буфер обмена скопировано объектов: __ocs_fmt_0__ (базовая точка: __ocs_fmt_1__, __ocs_fmt_2__). .object-s-copied-to-clipboard = В буфер обмена скопировано объектов: __ocs_fmt_0__. diff --git a/locales/tr-TR/opencadstudio.ftl b/locales/tr-TR/opencadstudio.ftl index 9bf56ec2b..b79f3ec26 100644 --- a/locales/tr-TR/opencadstudio.ftl +++ b/locales/tr-TR/opencadstudio.ftl @@ -3172,6 +3172,8 @@ insert = .xref-new-path-for-selection = seçim için yeni yol .xref-new-path-prefix = yeni yol öneki .xref-old-path-prefix = eski yol öneki + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF Göreli XREF yollarını çözümlemek için önce çizimi kaydedin. .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ nesne panoya kopyalandı (taban __ocs_fmt_1__,__ocs_fmt_2__). .object-s-copied-to-clipboard = __ocs_fmt_0__ nesne panoya kopyalandı. diff --git a/locales/zh-CN/opencadstudio.ftl b/locales/zh-CN/opencadstudio.ftl index 7904af03f..edc701612 100644 --- a/locales/zh-CN/opencadstudio.ftl +++ b/locales/zh-CN/opencadstudio.ftl @@ -3188,6 +3188,8 @@ insert = .xref-new-path-for-selection = 选择的新路径 .xref-new-path-prefix = 新路径前缀 .xref-old-path-prefix = 旧路径前缀 + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF 先保存绘图以解析相亲的XREF路径 。 .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ 对象已复制到剪贴板( 基准 __ocs_fmt_1__,__ocs_fmt_2__) 。 .object-s-copied-to-clipboard = __ocs_fmt_0__ 对象被复制到剪贴板。 diff --git a/locales/zh-TW/opencadstudio.ftl b/locales/zh-TW/opencadstudio.ftl index 79a82c39d..75d39427d 100644 --- a/locales/zh-TW/opencadstudio.ftl +++ b/locales/zh-TW/opencadstudio.ftl @@ -3200,6 +3200,8 @@ insert = .xref-new-path-for-selection = 選擇的新路徑 .xref-new-path-prefix = 新路徑前綴 .xref-old-path-prefix = 舊路徑前綴 + .xref-attach-dwg = Attach DWG + .xref-attach-image = Attach Image .xref-save-the-drawing-first-to-resolve-relativ = XREF 先儲存繪圖以解析相親的XREF路徑 。 .object-s-copied-to-clipboard-base-3-3 = __ocs_fmt_0__ 物件已複製到剪貼簿( 基準 __ocs_fmt_1__,__ocs_fmt_2__) 。 .object-s-copied-to-clipboard = __ocs_fmt_0__ 物件被複製到剪貼簿。 diff --git a/src/locale_catalog.rs b/src/locale_catalog.rs index 927480dcf..48ed487b9 100644 --- a/src/locale_catalog.rs +++ b/src/locale_catalog.rs @@ -3158,6 +3158,8 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static "XREF: cannot bind nested reference '{}'. Bind it in its host drawing." => Some(("insert", "xref-cannot-bind-nested-reference")), "Unreferenced" => Some(("insert", "unreferenced")), "File References" => Some(("insert", "xref-file-references")), + "Attach DWG" => Some(("insert", "xref-attach-dwg")), + "Attach Image" => Some(("insert", "xref-attach-image")), "Change Path" => Some(("insert", "xref-change-path")), "Make Absolute" => Some(("insert", "xref-make-absolute")), "Make Relative" => Some(("insert", "xref-make-relative")), diff --git a/src/ui/dock.rs b/src/ui/dock.rs index a0bf67f38..475fa0023 100644 --- a/src/ui/dock.rs +++ b/src/ui/dock.rs @@ -59,7 +59,7 @@ impl PanelId { match self { PanelId::Properties => 250.0, PanelId::BlockPalette => 260.0, - PanelId::ExternalReferences => 360.0, + PanelId::ExternalReferences => 460.0, } } @@ -239,9 +239,9 @@ mod tests { fn external_references_allows_double_max_width() { let mut state = DockState::default(); state.ensure_settings(); - // Slightly wider default than the 300-era panels, double the maximum. + // Wider default for the column-rich references table, double the maximum. // (The 45%-of-window rule still dominates on narrow windows.) - assert_eq!(state.width(PanelId::ExternalReferences, 3000.0), 360.0); + assert_eq!(state.width(PanelId::ExternalReferences, 3000.0), 460.0); state.set_width(PanelId::ExternalReferences, 5000.0); assert_eq!(state.width(PanelId::ExternalReferences, 3000.0), DOCK_MAX_W * 2.0); // Other panels keep the shared maximum. diff --git a/src/ui/window/xref_manager.rs b/src/ui/window/xref_manager.rs index 1e865d641..231ec70eb 100644 --- a/src/ui/window/xref_manager.rs +++ b/src/ui/window/xref_manager.rs @@ -135,7 +135,7 @@ pub struct XrefManagerPanel { /// Default reference-table column widths: Reference, Status, Size, Type, /// Date, Saved Path. -pub const DEFAULT_COL_WIDTHS: [f32; 6] = [150.0, 88.0, 76.0, 76.0, 96.0, 200.0]; +pub const DEFAULT_COL_WIDTHS: [f32; 6] = [150.0, 104.0, 76.0, 76.0, 96.0, 200.0]; /// Narrowest any reference-table column drags to. pub const COL_MIN_W: f32 = 48.0; /// Widest any reference-table column drags to. @@ -591,21 +591,21 @@ impl XrefManagerPanel { // (DWF/DGN/point clouds/coordination models) are omitted, not dead. let web_tip = crate::t!("File attach is not available on web — the reference list below is read-only.").into_owned(); let attach = if IS_WASM { - toolbar_tip(crate::t!("Attach").into_owned(), web_tip.clone()) + toolbar_tip(crate::t!("Attach DWG").into_owned(), web_tip.clone(), false) } else { split_button( - crate::t!("Attach").into_owned(), + crate::t!("Attach DWG").into_owned(), Some(Message::XAttachPick), self.attach_open, Message::XrefManagerAttachMenu, vec![ menu_item( - crate::t!("Image").into_owned(), + crate::t!("Attach Image").into_owned(), Some(Message::ImagePick), None, ), menu_item( - crate::t!("PDF").into_owned(), + crate::t!("Attach PDF").into_owned(), Some(Message::PdfAttachPick), None, ), @@ -613,7 +613,7 @@ impl XrefManagerPanel { ) }; let refresh = if IS_WASM { - toolbar_tip(crate::t!("Refresh").into_owned(), web_tip.clone()) + toolbar_tip(crate::t!("Refresh").into_owned(), web_tip.clone(), false) } else { split_button( crate::t!("Refresh").into_owned(), @@ -708,7 +708,7 @@ impl XrefManagerPanel { } }); let change_path = match path_group_gate { - Some(reason) => toolbar_tip(crate::t!("Change Path").into_owned(), reason), + Some(reason) => toolbar_tip(crate::t!("Change Path").into_owned(), reason, false), None => { let relative_gate = if host_saved { None @@ -767,6 +767,7 @@ impl XrefManagerPanel { let help = toolbar_tip( crate::t!("Help").into_owned(), crate::t!("Reference Manager — select rows, then Detach, Unload, Reload, Bind, Overlay, or a Change Path mode.").into_owned(), + false, ); let toolbar = container( row![ @@ -987,6 +988,7 @@ impl XrefManagerPanel { } else { None }, + false, ); let preview_tab = toolbar_btn( crate::t!("Preview").into_owned(), @@ -995,6 +997,7 @@ impl XrefManagerPanel { } else { Some(Message::XrefManagerTogglePreview) }, + false, ); let pane_tabs = row![details_tab, preview_tab] .spacing(4) @@ -1154,6 +1157,45 @@ fn status_text(status: RefStatus) -> std::borrow::Cow<'static, str> { } } +/// Status icon for the list view: one distinct glyph + theme color per +/// lifecycle state, drawn from the shared monochrome chrome set so the +/// artwork stays font-independent on the web build. +fn status_icon(status: RefStatus) -> Element<'static, Message> { + use crate::ui::icons; + let (bytes, tone) = status_icon_key(status); + match tone { + StatusTone::Success => icons::themed_success(bytes, 12.0), + StatusTone::Secondary => icons::themed_secondary(bytes, 12.0), + StatusTone::Warning => icons::themed_warning(bytes, 12.0), + StatusTone::Danger => icons::themed_danger(bytes, 12.0), + } +} + +/// Icon tone: which theme color a status glyph renders in. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum StatusTone { + Success, + Secondary, + Warning, + Danger, +} + +/// Pure status → (glyph bytes, tone) mapping behind [`status_icon`]. +/// Every lifecycle state resolves to a distinct pair. +fn status_icon_key(status: RefStatus) -> (&'static [u8], StatusTone) { + use crate::ui::icons; + use StatusTone as T; + match status { + RefStatus::Loaded => (icons::CHECK, T::Success), + RefStatus::Unloaded => (icons::MINUS, T::Secondary), + RefStatus::Stale => (icons::DIRTY_DOT, T::Warning), + RefStatus::NotFound => (icons::CLOSE, T::Danger), + RefStatus::Failed => (icons::DOT, T::Danger), + RefStatus::Orphaned => (icons::DOT, T::Warning), + RefStatus::Unreferenced => (icons::DOC, T::Secondary), + } +} + fn type_text(entry: &ReferenceEntry) -> std::borrow::Cow<'static, str> { match entry.kind { RefKind::DwgXref => match entry.ref_type { @@ -1244,7 +1286,7 @@ fn row_button_style(selected: bool, index: usize) -> impl Fn(&Theme, button::Sta } } -fn toolbar_btn(label: String, msg: Option) -> Element<'static, Message> { +fn toolbar_btn(label: String, msg: Option, fill: bool) -> Element<'static, Message> { let mut b = button(text(label).size(11)) .style(|theme: &Theme, status| { let palette = theme.palette(); @@ -1266,6 +1308,9 @@ fn toolbar_btn(label: String, msg: Option) -> Element<'static, Message> } }) .padding([4, 10]); + if fill { + b = b.width(Fill); + } if let Some(m) = msg { b = b.on_press(m); } @@ -1274,7 +1319,7 @@ fn toolbar_btn(label: String, msg: Option) -> Element<'static, Message> /// Disabled toolbar affordance with an explanatory tooltip (gated /// operations, nested-selection blocks, or web-gated mutations). -fn toolbar_tip(label: String, tip: String) -> Element<'static, Message> { +fn toolbar_tip(label: String, tip: String, fill: bool) -> Element<'static, Message> { let b = button(text(label).size(11).style(|theme: &Theme| { iced::widget::text::Style { color: Some( @@ -1301,6 +1346,7 @@ fn toolbar_tip(label: String, tip: String) -> Element<'static, Message> { } }) .padding([4, 10]); + let b = if fill { b.width(Fill) } else { b }; tooltip(b, text(tip).size(11), tooltip::Position::Bottom).into() } @@ -1410,8 +1456,8 @@ fn split_button( /// otherwise greyed text carrying the reason. fn menu_item(label: String, msg: Option, gate: Option) -> Element<'static, Message> { match (msg, gate) { - (Some(m), None) => toolbar_btn(label, Some(m)), - (_, reason) => toolbar_tip(label, reason.unwrap_or_default()), + (Some(m), None) => toolbar_btn(label, Some(m), true), + (_, reason) => toolbar_tip(label, reason.unwrap_or_default(), true), } } @@ -1440,7 +1486,7 @@ fn row_menu_for(index: usize) -> Element<'static, Message> { item(&crate::t!("Reload").into_owned(), XrefPaletteOp::Reload), item(&crate::t!("Bind").into_owned(), XrefPaletteOp::Bind), item(&crate::t!("Overlay").into_owned(), XrefPaletteOp::Overlay), - item(&crate::t!("Attach").into_owned(), XrefPaletteOp::Attach), + item(&crate::t!("Attach DWG").into_owned(), XrefPaletteOp::Attach), ] .spacing(2) .padding(4), @@ -1497,10 +1543,18 @@ fn xref_row<'a>( let name_text: Element<'_, Message> = text(name).size(FONT_SZ).into(); name_cell = name_cell.push(name_text); let gutter = || iced::widget::Space::new().width(Length::Fixed(COL_GUTTER)); + let status_cell: Element<'_, Message> = row![ + container(status_icon(entry.status)).align_y(iced::Center), + text(status_text(entry.status)).size(FONT_SZ).width(Fill), + ] + .spacing(4) + .align_y(iced::Center) + .width(Length::Fixed(cw[1])) + .into(); let content = row![ name_cell.width(Length::Fixed(cw[0])), gutter(), - text(status_text(entry.status)).size(FONT_SZ).width(Length::Fixed(cw[1])), + status_cell, gutter(), text(format_size(entry.size_bytes)).size(FONT_SZ).width(Length::Fixed(cw[2])), gutter(), @@ -1977,6 +2031,29 @@ mod tests { assert_eq!(panel.table_h, super::TABLE_MIN_H); } + #[test] + fn status_icons_are_unique_per_status() { + use super::{status_icon_key, RefStatus}; + let all = [ + RefStatus::Loaded, + RefStatus::Unloaded, + RefStatus::NotFound, + RefStatus::Failed, + RefStatus::Stale, + RefStatus::Orphaned, + RefStatus::Unreferenced, + ]; + let mut seen = std::collections::HashSet::new(); + for status in all { + let (bytes, tone) = status_icon_key(status); + assert!( + seen.insert((bytes.as_ptr(), tone)), + "status {status:?} shares its icon with another state" + ); + } + assert_eq!(seen.len(), all.len()); + } + #[test] fn image_format_reads_extension() { assert_eq!(image_format("C:/exa/plan.BMP"), "BMP");