Improve layout save details for example app.

This commit is contained in:
Jason Lee 2024-09-09 14:03:51 +08:00
parent ac83fad692
commit 33f0291f6d
4 changed files with 53 additions and 16 deletions

View file

@ -1,4 +1,4 @@
use std::{sync::Arc, thread}; use std::sync::Arc;
use anyhow::Result; use anyhow::Result;
use app_state::AppState; use app_state::AppState;

View file

@ -2,7 +2,7 @@ use anyhow::Result;
use gpui::*; use gpui::*;
use prelude::FluentBuilder as _; use prelude::FluentBuilder as _;
use private::serde::Deserialize; use private::serde::Deserialize;
use std::sync::Arc; use std::{sync::Arc, time::Duration};
use story::{ use story::{
ButtonStory, CalendarStory, DropdownStory, IconStory, ImageStory, InputStory, ListStory, ButtonStory, CalendarStory, DropdownStory, IconStory, ImageStory, InputStory, ListStory,
ModalStory, PopupStory, ProgressStory, ResizableStory, ScrollableStory, StoryContainer, ModalStory, PopupStory, ProgressStory, ResizableStory, ScrollableStory, StoryContainer,
@ -42,6 +42,8 @@ pub struct StoryWorkspace {
dock_area: View<DockArea>, dock_area: View<DockArea>,
locale_selector: View<LocaleSelector>, locale_selector: View<LocaleSelector>,
theme_color_picker: View<ColorPicker>, theme_color_picker: View<ColorPicker>,
last_layout_state: Option<DockItemState>,
_save_layout_task: Option<Task<()>>,
} }
impl StoryWorkspace { impl StoryWorkspace {
@ -64,15 +66,19 @@ impl StoryWorkspace {
dock_area.update(cx, |view, cx| view.set_root(dock_item, cx)); dock_area.update(cx, |view, cx| view.set_root(dock_item, cx));
cx.subscribe(&dock_area, |_, dock_area, ev: &DockEvent, cx| match ev { cx.subscribe(&dock_area, |this, dock_area, ev: &DockEvent, cx| match ev {
DockEvent::LayoutChanged => { DockEvent::LayoutChanged => this.save_layout(dock_area, cx),
// Make debounce })
.detach();
println!("Saving layout..."); let dock_area1 = dock_area.clone();
let json = dock_area.read(cx).dump(cx).unwrap(); cx.on_app_quit(move |cx| {
// Save layout json to app dir layout.json let state = dock_area1.read(cx).dump(cx);
std::fs::write("layout.json", json).unwrap();
} cx.background_executor().spawn(async move {
// Save layout before quitting
Self::save_state(&state).unwrap();
})
}) })
.detach(); .detach();
@ -106,9 +112,39 @@ impl StoryWorkspace {
dock_area, dock_area,
locale_selector, locale_selector,
theme_color_picker, theme_color_picker,
last_layout_state: None,
_save_layout_task: None,
} }
} }
fn save_layout(&mut self, dock_area: View<DockArea>, cx: &mut ViewContext<Self>) {
self._save_layout_task = Some(cx.spawn(|this, mut cx| async move {
Timer::after(Duration::from_secs(1)).await;
let _ = cx.update(|cx| {
let dock_area = dock_area.read(cx);
let state = dock_area.dump(cx);
let last_layout_state = this.upgrade().unwrap().read(cx).last_layout_state.clone();
if Some(&state) == last_layout_state.as_ref() {
return;
}
Self::save_state(&state).unwrap();
let _ = this.update(cx, |this, _| {
this.last_layout_state = Some(state);
});
});
}));
}
fn save_state(state: &DockItemState) -> Result<()> {
println!("Save layout...");
let json = serde_json::to_string(state)?;
std::fs::write("layout.json", json)?;
Ok(())
}
fn load_layout(dock_area: &WeakView<DockArea>, cx: &mut WindowContext) -> Result<DockItem> { fn load_layout(dock_area: &WeakView<DockArea>, cx: &mut WindowContext) -> Result<DockItem> {
let fname = "layout.json"; let fname = "layout.json";
let json = std::fs::read_to_string(fname)?; let json = std::fs::read_to_string(fname)?;

View file

@ -191,11 +191,12 @@ impl DockArea {
cx.notify(); cx.notify();
} }
/// Dump the dock panels layout to JSON string. /// Dump the dock panels layout to DockItemState.
pub fn dump(&self, cx: &AppContext) -> Result<String, serde_json::Error> { ///
/// See also `DockItemState::to_item` for the load DockItem from DockItemState.
pub fn dump(&self, cx: &AppContext) -> DockItemState {
let root = self.items.view(); let root = self.items.view();
let state = root.dump(cx); root.dump(cx)
serde_json::to_string_pretty(&state)
} }
/// Subscribe event on the panels /// Subscribe event on the panels

View file

@ -111,14 +111,14 @@ impl PartialEq for dyn PanelView {
} }
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct DockItemState { pub struct DockItemState {
pub panel_name: String, pub panel_name: String,
pub children: Vec<DockItemState>, pub children: Vec<DockItemState>,
pub info: DockItemInfo, pub info: DockItemInfo,
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum DockItemInfo { pub enum DockItemInfo {
#[serde(rename = "stack")] #[serde(rename = "stack")]
Stack { Stack {