diff --git a/src/app/config.rs b/src/app/config.rs index 312946204..a1e3544bf 100644 --- a/src/app/config.rs +++ b/src/app/config.rs @@ -20,6 +20,8 @@ pub struct AppConfig { pub settings: UserSettings, /// Recent-files list + retained count. pub recent: RecentConfig, + /// Last selected section on the tabbed Start page. + pub start: StartConfig, /// Which status-bar pills the user has hidden. pub statusbar: StatusBarConfig, /// Ribbon collapse density. @@ -34,6 +36,7 @@ impl Default for AppConfig { Self { settings: UserSettings::default(), recent: RecentConfig::default(), + start: StartConfig::default(), statusbar: StatusBarConfig::default(), ribbon: RibbonConfig::default(), plot: PlotDialogState::default(), @@ -59,6 +62,12 @@ impl Default for RecentConfig { } } +#[derive(Clone, PartialEq, Serialize, Deserialize, Default)] +#[serde(default)] +pub struct StartConfig { + pub section: super::StartSection, +} + #[derive(Clone, PartialEq, Serialize, Deserialize, Default)] #[serde(default)] pub struct RibbonConfig { diff --git a/src/app/mod.rs b/src/app/mod.rs index a9eeae223..492c373e9 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -211,7 +211,9 @@ struct AddSelectedRestore { } /// Which Start-page section a narrow (tabbed) Start page is showing. -#[derive(Clone, Copy, PartialEq, Eq, Default, Debug)] +#[derive( + Clone, Copy, PartialEq, Eq, Default, Debug, serde::Serialize, serde::Deserialize, +)] pub enum StartSection { Recent, Videos, diff --git a/src/app/update/file.rs b/src/app/update/file.rs index 05379579a..23555c023 100644 --- a/src/app/update/file.rs +++ b/src/app/update/file.rs @@ -292,6 +292,9 @@ impl OpenCADStudio { .collect(), limit: self.recent_limit, }, + start: crate::app::config::StartConfig { + section: self.start_section, + }, statusbar: self.statusbar_config.clone(), ribbon: crate::app::config::RibbonConfig { collapse: self.ribbon.collapse_mode(), @@ -317,6 +320,7 @@ impl OpenCADStudio { self.recent_limit_input = self.recent_limit.to_string(); // 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; self.statusbar_config = cfg.statusbar; self.ribbon.set_collapse_mode(cfg.ribbon.collapse); self.plot_dialog = cfg.plot; @@ -952,9 +956,14 @@ pub(super) fn on_open_file(&mut self) -> Task { self.tabs[i].current_path = Some(path.clone()); self.tabs[i].dirty = false; let _ = std::fs::remove_file(path.with_extension("sv$")); + let recent = self.push_recent(path.clone()); if self.save_dialog_for_unsaved { - return self.update(Message::UnsavedPickedSavePath(Some(path))); + return Task::batch([ + recent, + self.update(Message::UnsavedPickedSavePath(Some(path))), + ]); } + return recent; } Err(e) => self.command_line.push_error(&format!("Save failed: {e}")), } diff --git a/src/app/update/mod.rs b/src/app/update/mod.rs index 297f96cec..f413be24f 100644 --- a/src/app/update/mod.rs +++ b/src/app/update/mod.rs @@ -224,6 +224,7 @@ impl OpenCADStudio { Message::StartSectionSelect(section) => { self.start_section = section; + self.save_config(); Task::none() } diff --git a/src/app/view/mod.rs b/src/app/view/mod.rs index 1c09aeeb0..e1bbbd9f1 100644 --- a/src/app/view/mod.rs +++ b/src/app/view/mod.rs @@ -115,18 +115,21 @@ impl OpenCADStudio { // viewport draws the layout's own geometry (white sheet + entities + // borders) and the floating content viewports blit on top. let viewport_3d: Element<'_, Message> = if tab.is_start { - start_page_view( - &self.patrons, - &self.videos, - self.videos_loading, - &self.video_thumbs, - &self.recent_files, - &self.recent_thumbs, - self.recent_limit, - &self.recent_limit_input, - self.win_size.0, - self.start_section, - ) + responsive(|size| { + start_page_view( + &self.patrons, + &self.videos, + self.videos_loading, + &self.video_thumbs, + &self.recent_files, + &self.recent_thumbs, + self.recent_limit, + &self.recent_limit_input, + size.width, + self.start_section, + ) + }) + .into() } else if is_paper { shader(ViewportPane::model( &tab.scene, @@ -2504,7 +2507,17 @@ pub(super) fn start_page_view<'a>( let fits_all = avail >= recent_w + sup_w + 2.0 * 16.0 + welcome_min + 2.0 * (videos_w + 16.0); - let recent = recent_files_panel(recents, thumbs, recent_limit, recent_limit_input); + let recent = recent_files_panel( + recents, + thumbs, + recent_limit, + recent_limit_input, + if fits_all { + iced::Length::Fixed(recent_w) + } else { + iced::Length::Fill + }, + ); let welcome = container(content).width(Fill).height(Fill); // Tutorial-videos rail: the official playlist, fetched at boot (cached on @@ -2593,7 +2606,11 @@ pub(super) fn start_page_view<'a>( Space::new().height(iced::Length::Fixed(12.0)), playlist_btn, ]) - .width(iced::Length::Fixed(videos_w)) + .width(if fits_all { + iced::Length::Fixed(videos_w) + } else { + iced::Length::Fill + }) .height(Fill) .padding(16) .style(|_: &Theme| container::Style { @@ -2672,7 +2689,11 @@ pub(super) fn start_page_view<'a>( Space::new().height(iced::Length::Fixed(12.0)), support_btn, ]) - .width(iced::Length::Fixed(240.0)) + .width(if fits_all { + iced::Length::Fixed(sup_w) + } else { + iced::Length::Fill + }) .height(Fill) .padding(20) .style(|_: &Theme| container::Style { @@ -2804,6 +2825,7 @@ pub(super) fn recent_files_panel<'a>( >, limit: usize, limit_input: &'a str, + width: iced::Length, ) -> Element<'a, Message> { // Card chrome matches the Supporters rail (the canonical start-page card). const PANEL_BG: Color = Color { @@ -2993,7 +3015,7 @@ pub(super) fn recent_files_panel<'a>( ] .width(Fill), ) - .width(iced::Length::Fixed(280.0)) + .width(width) .height(Fill) .padding(20) .style(|_: &Theme| container::Style { @@ -3007,4 +3029,3 @@ pub(super) fn recent_files_panel<'a>( }) .into() } -