diff --git a/assets/icons/ui/preview.svg b/assets/icons/ui/preview.svg new file mode 100644 index 000000000..53a5513ba --- /dev/null +++ b/assets/icons/ui/preview.svg @@ -0,0 +1 @@ + diff --git a/locales/ar-SA/opencadstudio.ftl b/locales/ar-SA/opencadstudio.ftl index eea138efa..6d2ac29c9 100644 --- a/locales/ar-SA/opencadstudio.ftl +++ b/locales/ar-SA/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = ستظهر الملفات التي تفتحها هنا. .browser-storage = تخزين المتصفح .keep-recent-files = الاحتفاظ بالملفات الأخيرة + .view-list = قائمة + .view-icons = أيقونات + .view-preview = معاينات كبيرة donation = .title = طلب تبرع diff --git a/locales/bg-BG/opencadstudio.ftl b/locales/bg-BG/opencadstudio.ftl index feee17bdc..51416c159 100644 --- a/locales/bg-BG/opencadstudio.ftl +++ b/locales/bg-BG/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Файловете, които отвориш, ще се появят тук. .browser-storage = Хранилище на браузъра .keep-recent-files = Пази скорошните файлове + .view-list = Списък + .view-icons = Икони + .view-preview = Големи прегледи donation = .title = Призив за дарение diff --git a/locales/cs-CZ/opencadstudio.ftl b/locales/cs-CZ/opencadstudio.ftl index a32db3547..ed1c7361c 100644 --- a/locales/cs-CZ/opencadstudio.ftl +++ b/locales/cs-CZ/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Otevřené soubory se zobrazí zde. .browser-storage = Úložiště prohlížeče .keep-recent-files = Uchovávat nedávné soubory + .view-list = Seznam + .view-icons = Ikony + .view-preview = Velké náhledy donation = .title = Žádost o dar diff --git a/locales/de-DE/opencadstudio.ftl b/locales/de-DE/opencadstudio.ftl index 42ce8800d..dca8a43f3 100644 --- a/locales/de-DE/opencadstudio.ftl +++ b/locales/de-DE/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Geöffnete Dateien werden hier angezeigt. .browser-storage = Browserspeicher .keep-recent-files = Zuletzt verwendete Dateien behalten + .view-list = Liste + .view-icons = Symbole + .view-preview = Große Vorschau donation = .title = Spendenaufruf diff --git a/locales/el-GR/opencadstudio.ftl b/locales/el-GR/opencadstudio.ftl index f5646e118..1fd456d23 100644 --- a/locales/el-GR/opencadstudio.ftl +++ b/locales/el-GR/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Τα αρχεία που ανοίγετε θα εμφανίζονται εδώ. .browser-storage = Αποθηκευτικός χώρος προγράμματος περιήγησης .keep-recent-files = Διατήρηση πρόσφατων αρχείων + .view-list = Λίστα + .view-icons = Εικονίδια + .view-preview = Μεγάλες προεπισκοπήσεις donation = .title = Έκκληση για δωρεά diff --git a/locales/en-US/opencadstudio.ftl b/locales/en-US/opencadstudio.ftl index f2539ea74..2a0ba9794 100644 --- a/locales/en-US/opencadstudio.ftl +++ b/locales/en-US/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Files you open will show up here. .browser-storage = Browser storage .keep-recent-files = Keep recent files + .view-list = List + .view-icons = Icons + .view-preview = Large previews donation = .title = Request for Donation diff --git a/locales/es-ES/opencadstudio.ftl b/locales/es-ES/opencadstudio.ftl index 47ec91dcf..8905c5bad 100644 --- a/locales/es-ES/opencadstudio.ftl +++ b/locales/es-ES/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Los archivos que abra aparecerán aquí. .browser-storage = Almacenamiento del navegador .keep-recent-files = Conservar archivos recientes + .view-list = Lista + .view-icons = Iconos + .view-preview = Vistas previas grandes donation = .title = Solicitud de donación diff --git a/locales/fi-FI/opencadstudio.ftl b/locales/fi-FI/opencadstudio.ftl index 1eb2acba2..4fb9f5857 100644 --- a/locales/fi-FI/opencadstudio.ftl +++ b/locales/fi-FI/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Avaamasi tiedostot näkyvät tässä. .browser-storage = Selaimen tallennustila .keep-recent-files = Säilytä viimeisimmät tiedostot + .view-list = Luettelo + .view-icons = Kuvakkeet + .view-preview = Suuret esikatselut donation = .title = Lahjoituspyyntö diff --git a/locales/fr-FR/opencadstudio.ftl b/locales/fr-FR/opencadstudio.ftl index 1193628d7..788e2d1d9 100644 --- a/locales/fr-FR/opencadstudio.ftl +++ b/locales/fr-FR/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Les fichiers que vous ouvrez apparaîtront ici. .browser-storage = Stockage du navigateur .keep-recent-files = Conserver les fichiers récents + .view-list = Liste + .view-icons = Icônes + .view-preview = Grands aperçus donation = .title = Appel aux dons diff --git a/locales/hi-IN/opencadstudio.ftl b/locales/hi-IN/opencadstudio.ftl index d3a7193ef..e86a264ed 100644 --- a/locales/hi-IN/opencadstudio.ftl +++ b/locales/hi-IN/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = आपके द्वारा खोली गई फ़ाइलें यहाँ दिखाई देंगी। .browser-storage = ब्राउज़र संग्रहण .keep-recent-files = हाल की फ़ाइलें रखें + .view-list = सूची + .view-icons = आइकन + .view-preview = बड़े पूर्वावलोकन donation = .title = दान का अनुरोध diff --git a/locales/hu-HU/opencadstudio.ftl b/locales/hu-HU/opencadstudio.ftl index a5e19f84a..0985d048b 100644 --- a/locales/hu-HU/opencadstudio.ftl +++ b/locales/hu-HU/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = A megnyitott fájlok itt jelennek meg. .browser-storage = Böngésző tárhelye .keep-recent-files = Legutóbbi fájlok megőrzése + .view-list = Lista + .view-icons = Ikonok + .view-preview = Nagy előnézetek donation = .title = Adománykérés diff --git a/locales/it-IT/opencadstudio.ftl b/locales/it-IT/opencadstudio.ftl index ee88209fc..2b332964b 100644 --- a/locales/it-IT/opencadstudio.ftl +++ b/locales/it-IT/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = I file aperti verranno visualizzati qui. .browser-storage = Memoria del browser .keep-recent-files = Conserva i file recenti + .view-list = Elenco + .view-icons = Icone + .view-preview = Anteprime grandi donation = .title = Richiesta di donazione diff --git a/locales/ja-JP/opencadstudio.ftl b/locales/ja-JP/opencadstudio.ftl index c404bf79d..79204dbf6 100644 --- a/locales/ja-JP/opencadstudio.ftl +++ b/locales/ja-JP/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = 開いたファイルがここに表示されます。 .browser-storage = ブラウザーストレージ .keep-recent-files = 最近使ったファイルを保持 + .view-list = 一覧 + .view-icons = アイコン + .view-preview = 大きいプレビュー donation = .title = 寄付のお願い diff --git a/locales/ko-KR/opencadstudio.ftl b/locales/ko-KR/opencadstudio.ftl index 9b090c1b2..e8846e9f1 100644 --- a/locales/ko-KR/opencadstudio.ftl +++ b/locales/ko-KR/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = 연 파일이 여기에 표시됩니다. .browser-storage = 브라우저 저장소 .keep-recent-files = 최근 파일 유지 + .view-list = 목록 + .view-icons = 아이콘 + .view-preview = 큰 미리 보기 donation = .title = 기부 요청 diff --git a/locales/lo-LA/opencadstudio.ftl b/locales/lo-LA/opencadstudio.ftl index daa8e1ac4..5a4f3bb7c 100644 --- a/locales/lo-LA/opencadstudio.ftl +++ b/locales/lo-LA/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = ໄຟລ໌ທີ່ທ່ານເປີດຈະສະແດງຢູ່ນີ້. .browser-storage = ບ່ອນເກັບຂໍ້ມູນບຣາວເຊີ .keep-recent-files = ຮັກສາໄຟລ໌ຫຼ້າສຸດໄວ້ + .view-list = ລາຍການ + .view-icons = ໄອຄອນ + .view-preview = ຕົວຢ່າງຂະໜາດໃຫຍ່ donation = .title = ຄຳຮ້ອງຂໍການບໍລິຈາກ diff --git a/locales/nl-NL/opencadstudio.ftl b/locales/nl-NL/opencadstudio.ftl index aa2947764..f93aea618 100644 --- a/locales/nl-NL/opencadstudio.ftl +++ b/locales/nl-NL/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Bestanden die u opent, verschijnen hier. .browser-storage = Browseropslag .keep-recent-files = Recente bestanden bewaren + .view-list = Lijst + .view-icons = Pictogrammen + .view-preview = Grote voorbeelden donation = .title = Verzoek om een donatie diff --git a/locales/pl-PL/opencadstudio.ftl b/locales/pl-PL/opencadstudio.ftl index e14539fb9..c635f4201 100644 --- a/locales/pl-PL/opencadstudio.ftl +++ b/locales/pl-PL/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Otwarte pliki pojawią się tutaj. .browser-storage = Pamięć przeglądarki .keep-recent-files = Zachowuj ostatnie pliki + .view-list = Lista + .view-icons = Ikony + .view-preview = Duże podglądy donation = .title = Prośba o darowiznę diff --git a/locales/pt-BR/opencadstudio.ftl b/locales/pt-BR/opencadstudio.ftl index a27c55e6f..676a14478 100644 --- a/locales/pt-BR/opencadstudio.ftl +++ b/locales/pt-BR/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Os arquivos que você abrir aparecerão aqui. .browser-storage = Armazenamento do navegador .keep-recent-files = Manter arquivos recentes + .view-list = Lista + .view-icons = Ícones + .view-preview = Visualizações grandes donation = .title = Pedido de doação diff --git a/locales/ru-RU/opencadstudio.ftl b/locales/ru-RU/opencadstudio.ftl index 8ce95ea49..b463a4cb8 100644 --- a/locales/ru-RU/opencadstudio.ftl +++ b/locales/ru-RU/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Открытые вами файлы появятся здесь. .browser-storage = Хранилище браузера .keep-recent-files = Хранить недавние файлы + .view-list = Список + .view-icons = Значки + .view-preview = Крупные эскизы donation = .title = Просьба о пожертвовании diff --git a/locales/tr-TR/opencadstudio.ftl b/locales/tr-TR/opencadstudio.ftl index 5230c586a..72f197167 100644 --- a/locales/tr-TR/opencadstudio.ftl +++ b/locales/tr-TR/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = Açtığınız dosyalar burada görünür. .browser-storage = Tarayıcı depolama alanı .keep-recent-files = Son dosyaları sakla + .view-list = Liste + .view-icons = Simgeler + .view-preview = Büyük önizlemeler donation = .title = Bağış Talebi diff --git a/locales/zh-CN/opencadstudio.ftl b/locales/zh-CN/opencadstudio.ftl index 87f586862..a7aad2382 100644 --- a/locales/zh-CN/opencadstudio.ftl +++ b/locales/zh-CN/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = 您打开的文件将显示在此处。 .browser-storage = 浏览器存储 .keep-recent-files = 保留最近文件 + .view-list = 列表 + .view-icons = 图标 + .view-preview = 大预览 donation = .title = 捐款请求 diff --git a/locales/zh-TW/opencadstudio.ftl b/locales/zh-TW/opencadstudio.ftl index 57e1801ad..7aead8aac 100644 --- a/locales/zh-TW/opencadstudio.ftl +++ b/locales/zh-TW/opencadstudio.ftl @@ -99,6 +99,9 @@ start = .no-recent-files = 您開啟的檔案將顯示在此處。 .browser-storage = 瀏覽器儲存空間 .keep-recent-files = 保留最近檔案 + .view-list = 清單 + .view-icons = 圖示 + .view-preview = 大型預覽 donation = .title = 捐款請求 diff --git a/src/app/config.rs b/src/app/config.rs index c86c27920..22a6c52f7 100644 --- a/src/app/config.rs +++ b/src/app/config.rs @@ -518,6 +518,8 @@ pub struct RecentConfig { pub files: Vec, /// How many recent files to keep. pub limit: usize, + /// List, icons or large previews. + pub view: super::RecentView, } impl Default for RecentConfig { @@ -525,6 +527,7 @@ impl Default for RecentConfig { Self { files: Vec::new(), limit: super::recent::RECENT_DEFAULT, + view: super::RecentView::default(), } } } diff --git a/src/app/mod.rs b/src/app/mod.rs index d28b02525..75b493be0 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -433,6 +433,15 @@ pub enum StartSection { Supporters, } +/// How the Start page lists recent files. +#[derive(Clone, Copy, PartialEq, Eq, Default, Debug, serde::Serialize, serde::Deserialize)] +pub enum RecentView { + #[default] + List, + Icons, + Preview, +} + /// What the Space / Enter keys currently mean at the command line. One /// decision point (`OpenCADStudio::text_entry_mode`) for every keyboard /// route that used to re-derive the answer from editor state. @@ -472,6 +481,7 @@ pub(super) struct OpenCADStudio { /// Live text of the recent-limit input box (may differ from `recent_limit` /// mid-edit; applied on Enter). Kept in sync when the +/- buttons change it. recent_limit_input: String, + recent_view: RecentView, command_line: CommandLine, /// Recent Patreon supporters shown on the Start page (name, USD cents), /// fetched once at boot, highest payment first. @@ -2449,6 +2459,7 @@ pub enum Message { RecentRemove(PathBuf), /// Set how many recent documents to keep (persisted). SetRecentLimit(usize), + SetRecentView(RecentView), /// Live edit of the recent-limit input box (not applied until Enter). RecentLimitInput(String), /// User clicked Cancel on the loading overlay. The parser thread keeps @@ -4488,6 +4499,7 @@ impl OpenCADStudio { recent_thumbs: std::collections::HashMap::new(), recent_limit: recent::RECENT_DEFAULT, recent_limit_input: recent::RECENT_DEFAULT.to_string(), + recent_view: RecentView::default(), command_line: CommandLine::new(), patrons: Vec::new(), videos: Vec::new(), diff --git a/src/app/update/file.rs b/src/app/update/file.rs index d21327744..3b9a478eb 100644 --- a/src/app/update/file.rs +++ b/src/app/update/file.rs @@ -1326,6 +1326,7 @@ impl OpenCADStudio { .map(|p| p.to_string_lossy().into_owned()) .collect(), limit: self.recent_limit, + view: self.recent_view, }, start: crate::app::config::StartConfig { section: self.start_section, @@ -1397,6 +1398,7 @@ impl OpenCADStudio { ); self.recent_files.truncate(self.recent_limit); self.recent_limit_input = self.recent_limit.to_string(); + self.recent_view = cfg.recent.view; // Thumbnails are decoded by a background task queued at boot // (`refresh_recent_thumbs`) — never here on the boot path. self.start_section = cfg.start.section; diff --git a/src/app/update/mod.rs b/src/app/update/mod.rs index 421b2076a..ebce21b8e 100644 --- a/src/app/update/mod.rs +++ b/src/app/update/mod.rs @@ -1153,6 +1153,12 @@ impl OpenCADStudio { Task::none() } + Message::SetRecentView(view) => { + self.recent_view = view; + self.save_config(); + Task::none() + } + Message::RecentLimitInput(s) => { // Keep only digits while typing; applied on Enter (SetRecentLimit). self.recent_limit_input = s.chars().filter(|c| c.is_ascii_digit()).collect(); diff --git a/src/app/view/mod.rs b/src/app/view/mod.rs index d6515b5e1..7919d8246 100644 --- a/src/app/view/mod.rs +++ b/src/app/view/mod.rs @@ -339,6 +339,7 @@ impl OpenCADStudio { &self.recent_thumbs, self.recent_limit, &self.recent_limit_input, + self.recent_view, self.start_action_w.clone(), self.start_section, ) @@ -3098,6 +3099,7 @@ pub(super) fn start_page_view<'a>( thumbs: &'a std::collections::HashMap>, recent_limit: usize, recent_limit_input: &'a str, + recent_view: super::RecentView, action_width_out: std::sync::Arc, active: super::StartSection, ) -> Element<'a, Message> { @@ -3113,6 +3115,7 @@ pub(super) fn start_page_view<'a>( thumbs, recent_limit, recent_limit_input, + recent_view, size.width, action_width_out.clone(), active, @@ -3132,6 +3135,7 @@ fn start_page_content<'a>( thumbs: &'a std::collections::HashMap>, recent_limit: usize, recent_limit_input: &'a str, + recent_view: super::RecentView, avail_w: f32, action_width_out: std::sync::Arc, active: super::StartSection, @@ -3355,6 +3359,7 @@ fn start_page_content<'a>( thumbs, recent_limit, recent_limit_input, + recent_view, match start_layout { StartLayout::AllPanels | StartLayout::WithoutVideos @@ -3792,16 +3797,149 @@ fn start_page_content<'a>( // Properties panel normally occupies, but only when the active tab is the // Start tab. The list is restored from disk at boot and re-saved on every // open — entries persist across sessions. +/// Recent files as tiles: small thumbnails wrapping across the panel, or one +/// large preview per row. A tile opens its file; the list view keeps the +/// remove buttons. +fn recent_tiles<'a>( + recents: &'a [std::path::PathBuf], + thumbs: &'a std::collections::HashMap>, + large: bool, +) -> iced::widget::Column<'a, Message> { + let (thumb_w, thumb_h, name_chars) = if large { + (Fill, iced::Length::Fixed(180.0), 40) + } else { + (iced::Length::Fixed(72.0), iced::Length::Fixed(54.0), 11) + }; + let tile = |path: &'a std::path::PathBuf| -> Element<'a, Message> { + let name = path + .file_name() + .map(|n| n.to_string_lossy().into_owned()) + .unwrap_or_else(|| path.to_string_lossy().into_owned()); + let picture: Element<'a, Message> = match thumbs.get(path).and_then(|o| o.as_ref()) { + Some(h) => iced::widget::image(h.clone()) + .content_fit(iced::ContentFit::Contain) + .width(Fill) + .height(Fill) + .into(), + None => crate::ui::icons::themed_secondary(crate::ui::icons::DOC, 28.0), + }; + let picture = container(picture) + .width(thumb_w) + .height(thumb_h) + .center_x(thumb_w) + .center_y(thumb_h) + .style(|theme: &Theme| container::Style { + background: Some(Background::Color(theme.palette().background.base.color)), + border: Border { + color: theme.palette().background.neutral.color, + width: 1.0, + radius: 4.0.into(), + }, + ..Default::default() + }); + let mut label = column![text(crate::ui::text_util::elide(&name, name_chars)).size(12)]; + if large { + let dir = path + .parent() + .map(|p| p.to_string_lossy().into_owned()) + .unwrap_or_default(); + label = label.push( + text(crate::ui::text_util::elide(&dir, 52)) + .size(10) + .style(start_muted_style), + ); + } + button(column![picture, label.spacing(2)].spacing(4)) + .on_press(Message::OpenRecent(path.clone())) + .padding(6) + .width(if large { Fill } else { iced::Length::Shrink }) + .style(|theme: &Theme, status| { + let palette = theme.palette(); + button::Style { + background: matches!(status, button::Status::Hovered) + .then_some(Background::Color(palette.background.strong.color)), + text_color: palette.background.base.text, + border: Border { + radius: 4.0.into(), + ..Default::default() + }, + ..Default::default() + } + }) + .into() + }; + if large { + column(recents.iter().map(tile)).spacing(6) + } else { + column![iced::widget::Row::with_children(recents.iter().map(tile)) + .spacing(4) + .wrap()] + .width(Fill) + } +} + pub(super) fn recent_files_panel<'a>( recents: &'a [std::path::PathBuf], thumbs: &'a std::collections::HashMap>, limit: usize, limit_input: &'a str, + view: super::RecentView, width: iced::Length, ) -> Element<'a, Message> { + use super::RecentView; // Title mirrors the Supporters rail: size 15 in the bright text colour, - // followed by a 12px gap before the content. - let title = text(crate::tr!("start", "recent-documents")).size(15); + // followed by a 12px gap before the content. The view-mode toggles sit + // on the title's right. + let mode_button = |icon: &'static [u8], mode: RecentView, tip: String| { + let active = view == mode; + iced::widget::tooltip( + button(crate::ui::icons::themed(icon, 13.0)) + .on_press(Message::SetRecentView(mode)) + .padding([3, 5]) + .style(move |theme: &Theme, status| { + let palette = theme.palette(); + let background = if active { + Some(palette.primary.weak.color) + } else { + matches!(status, button::Status::Hovered) + .then_some(palette.background.strong.color) + }; + button::Style { + background: background.map(Background::Color), + text_color: palette.background.base.text, + border: Border { + radius: 3.0.into(), + ..Default::default() + }, + ..Default::default() + } + }), + container(text(tip).size(11)).padding([2, 6]).style(container::rounded_box), + iced::widget::tooltip::Position::Bottom, + ) + }; + let title = row![ + text(crate::tr!("start", "recent-documents")) + .size(15) + .width(Fill), + mode_button( + crate::ui::icons::MENU, + RecentView::List, + crate::tr!("start", "view-list"), + ), + mode_button( + crate::ui::icons::GRID, + RecentView::Icons, + crate::tr!("start", "view-icons"), + ), + mode_button( + crate::ui::icons::PREVIEW, + RecentView::Preview, + crate::tr!("start", "view-preview"), + ), + ] + .spacing(2) + .align_y(iced::Center); let body: Element<'a, Message> = if recents.is_empty() { container( @@ -3811,6 +3949,18 @@ pub(super) fn recent_files_panel<'a>( ) .height(Fill) .into() + } else if view != RecentView::List { + iced::widget::scrollable( + recent_tiles(recents, thumbs, view == RecentView::Preview).padding( + iced::Padding { + right: 12.0, + ..iced::Padding::ZERO + }, + ), + ) + .width(Fill) + .height(Fill) + .into() } else { // Right padding reserves a gutter for the scrollbar so it doesn't sit on // top of the row's ✕ remove button. @@ -4020,6 +4170,7 @@ mod tests { &std::collections::HashMap::new(), 50, "18446744073709551615", + super::super::RecentView::default(), 800.0, std::sync::Arc::new(std::sync::atomic::AtomicU32::new(0)), super::super::StartSection::default(), diff --git a/src/ui/icons.rs b/src/ui/icons.rs index 02416477c..02ca8dfd9 100644 --- a/src/ui/icons.rs +++ b/src/ui/icons.rs @@ -80,6 +80,7 @@ pub static PIN_ACTIVE: &[u8] = include_bytes!("../../assets/icons/ui/pin_active. pub static SPLIT_V: &[u8] = include_bytes!("../../assets/icons/ui/split_v.svg"); pub static SPLIT_H: &[u8] = include_bytes!("../../assets/icons/ui/split_h.svg"); pub static GRID: &[u8] = include_bytes!("../../assets/icons/ui/grid.svg"); +pub static PREVIEW: &[u8] = include_bytes!("../../assets/icons/ui/preview.svg"); pub static SNAP: &[u8] = include_bytes!("../../assets/icons/ui/snap.svg"); pub static DOC_NEW: &[u8] = include_bytes!("../../assets/icons/ui/doc_new.svg"); pub static DOC: &[u8] = include_bytes!("../../assets/icons/ui/doc.svg");