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.
This commit is contained in:
Karim Jerbi committed 2026-09-15 23:56:31 +01:00
1 parent 22a9bd602c
commit e9151ea2f4
24 files changed
+137 -16

No files matched your search

+2
View File
@@ -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__ كائن إلى الحافظة.
+2
View File
@@ -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__ обект(а) копирани в клипборда.
+2
View File
@@ -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.
+2
View File
@@ -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.
+2
View File
@@ -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__ αντικείμενο(α) αποκόπηκαν στο πρόχειρο.
+2
View File
@@ -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.
+2
View File
@@ -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.
+2
View File
@@ -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.
+2
View File
@@ -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__.
+2
View File
@@ -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) क्लिपबोर्ड पर कॉपी किया गया।
+2
View File
@@ -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.
+2
View File
@@ -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.
+2
View File
@@ -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__ 個のオブジェクトをクリップボードにコピーしました。
+2
View File
@@ -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__ 개체가 클립보드에 복사되었습니다.
+2
View File
@@ -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.
+2
View File
@@ -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.
+2
View File
@@ -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.
+2
View File
@@ -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__.
+2
View File
@@ -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ı.
+2
View File
@@ -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__ 对象被复制到剪贴板。
+2
View File
@@ -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__ 物件被複製到剪貼簿。
+2
View File
@@ -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")),
+3 -3
View File
@@ -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.
+90 -13
View File
@@ -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<Message>) -> Element<'static, Message> {
fn toolbar_btn(label: String, msg: Option<Message>, 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<Message>) -> 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<Message>) -> 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<Message>, gate: Option<String>) -> 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");