mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-24 01:11:51 +00:00
WIP: Add persistence to new docks
This commit is contained in:
parent
4898417617
commit
89d8bb1425
7 changed files with 181 additions and 26 deletions
|
@ -222,21 +222,21 @@ impl Bind for WindowBounds {
|
|||
fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
|
||||
let (region, next_index) = match self {
|
||||
WindowBounds::Fullscreen => {
|
||||
let next_index = statement.bind("Fullscreen", start_index)?;
|
||||
let next_index = statement.bind(&"Fullscreen", start_index)?;
|
||||
(None, next_index)
|
||||
}
|
||||
WindowBounds::Maximized => {
|
||||
let next_index = statement.bind("Maximized", start_index)?;
|
||||
let next_index = statement.bind(&"Maximized", start_index)?;
|
||||
(None, next_index)
|
||||
}
|
||||
WindowBounds::Fixed(region) => {
|
||||
let next_index = statement.bind("Fixed", start_index)?;
|
||||
let next_index = statement.bind(&"Fixed", start_index)?;
|
||||
(Some(*region), next_index)
|
||||
}
|
||||
};
|
||||
|
||||
statement.bind(
|
||||
region.map(|region| {
|
||||
®ion.map(|region| {
|
||||
(
|
||||
region.min_x(),
|
||||
region.min_y(),
|
||||
|
|
|
@ -27,7 +27,7 @@ impl StaticColumnCount for bool {}
|
|||
impl Bind for bool {
|
||||
fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
|
||||
statement
|
||||
.bind(self.then_some(1).unwrap_or(0), start_index)
|
||||
.bind(&self.then_some(1).unwrap_or(0), start_index)
|
||||
.with_context(|| format!("Failed to bind bool at index {start_index}"))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -236,7 +236,7 @@ impl<'a> Statement<'a> {
|
|||
Ok(str::from_utf8(slice)?)
|
||||
}
|
||||
|
||||
pub fn bind<T: Bind>(&self, value: T, index: i32) -> Result<i32> {
|
||||
pub fn bind<T: Bind>(&self, value: &T, index: i32) -> Result<i32> {
|
||||
debug_assert!(index > 0);
|
||||
Ok(value.bind(self, index)?)
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ impl<'a> Statement<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn with_bindings(&mut self, bindings: impl Bind) -> Result<&mut Self> {
|
||||
pub fn with_bindings(&mut self, bindings: &impl Bind) -> Result<&mut Self> {
|
||||
self.bind(bindings, 1)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
@ -464,7 +464,7 @@ mod test {
|
|||
connection
|
||||
.exec(indoc! {"
|
||||
CREATE TABLE texts (
|
||||
text TEXT
|
||||
text TEXT
|
||||
)"})
|
||||
.unwrap()()
|
||||
.unwrap();
|
||||
|
|
|
@ -29,7 +29,7 @@ impl Connection {
|
|||
query: &str,
|
||||
) -> Result<impl 'a + FnMut(B) -> Result<()>> {
|
||||
let mut statement = Statement::prepare(self, query)?;
|
||||
Ok(move |bindings| statement.with_bindings(bindings)?.exec())
|
||||
Ok(move |bindings| statement.with_bindings(&bindings)?.exec())
|
||||
}
|
||||
|
||||
/// Prepare a statement which has no bindings and returns a `Vec<C>`.
|
||||
|
@ -55,7 +55,7 @@ impl Connection {
|
|||
query: &str,
|
||||
) -> Result<impl 'a + FnMut(B) -> Result<Vec<C>>> {
|
||||
let mut statement = Statement::prepare(self, query)?;
|
||||
Ok(move |bindings| statement.with_bindings(bindings)?.rows::<C>())
|
||||
Ok(move |bindings| statement.with_bindings(&bindings)?.rows::<C>())
|
||||
}
|
||||
|
||||
/// Prepare a statement that selects a single row from the database.
|
||||
|
@ -87,7 +87,7 @@ impl Connection {
|
|||
let mut statement = Statement::prepare(self, query)?;
|
||||
Ok(move |bindings| {
|
||||
statement
|
||||
.with_bindings(bindings)
|
||||
.with_bindings(&bindings)
|
||||
.context("Bindings failed")?
|
||||
.maybe_row::<C>()
|
||||
.context("Maybe row failed")
|
||||
|
|
|
@ -18,6 +18,9 @@ use model::{
|
|||
WorkspaceLocation,
|
||||
};
|
||||
|
||||
use self::model::DockStructure;
|
||||
|
||||
|
||||
define_connection! {
|
||||
// Current schema shape using pseudo-rust syntax:
|
||||
//
|
||||
|
@ -151,6 +154,15 @@ define_connection! {
|
|||
INSERT INTO workspaces_2 SELECT * FROM workspaces;
|
||||
DROP TABLE workspaces;
|
||||
ALTER TABLE workspaces_2 RENAME TO workspaces;
|
||||
),
|
||||
// Add panels related information
|
||||
sql!(
|
||||
ALTER TABLE workspaces ADD COLUMN left_dock_visible INTEGER; //bool
|
||||
ALTER TABLE workspaces ADD COLUMN left_dock_size REAL;
|
||||
ALTER TABLE workspaces ADD COLUMN right_dock_visible INTEGER; //bool
|
||||
ALTER TABLE workspaces ADD COLUMN right_dock_size REAL;
|
||||
ALTER TABLE workspaces ADD COLUMN bottom_dock_visible INTEGER; //bool
|
||||
ALTER TABLE workspaces ADD COLUMN bottom_dock_size REAL;
|
||||
)];
|
||||
}
|
||||
|
||||
|
@ -166,12 +178,13 @@ impl WorkspaceDb {
|
|||
|
||||
// Note that we re-assign the workspace_id here in case it's empty
|
||||
// and we've grabbed the most recent workspace
|
||||
let (workspace_id, workspace_location, left_sidebar_open, bounds, display): (
|
||||
let (workspace_id, workspace_location, left_sidebar_open, bounds, display, docks): (
|
||||
WorkspaceId,
|
||||
WorkspaceLocation,
|
||||
bool,
|
||||
Option<WindowBounds>,
|
||||
Option<Uuid>,
|
||||
DockStructure
|
||||
) = self
|
||||
.select_row_bound(sql! {
|
||||
SELECT
|
||||
|
@ -183,7 +196,13 @@ impl WorkspaceDb {
|
|||
window_y,
|
||||
window_width,
|
||||
window_height,
|
||||
display
|
||||
display,
|
||||
left_dock_visible,
|
||||
left_dock_size,
|
||||
right_dock_visible,
|
||||
right_dock_size,
|
||||
bottom_dock_visible,
|
||||
bottom_dock_size
|
||||
FROM workspaces
|
||||
WHERE workspace_location = ?
|
||||
})
|
||||
|
@ -202,6 +221,7 @@ impl WorkspaceDb {
|
|||
left_sidebar_open,
|
||||
bounds,
|
||||
display,
|
||||
docks
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -227,15 +247,27 @@ impl WorkspaceDb {
|
|||
workspace_id,
|
||||
workspace_location,
|
||||
left_sidebar_open,
|
||||
left_dock_visible,
|
||||
left_dock_size,
|
||||
right_dock_visible,
|
||||
right_dock_size,
|
||||
bottom_dock_visible,
|
||||
bottom_dock_size,
|
||||
timestamp
|
||||
)
|
||||
VALUES (?1, ?2, ?3, CURRENT_TIMESTAMP)
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, CURRENT_TIMESTAMP)
|
||||
ON CONFLICT DO
|
||||
UPDATE SET
|
||||
workspace_location = ?2,
|
||||
left_sidebar_open = ?3,
|
||||
left_dock_visible = ?4,
|
||||
left_dock_size = ?5,
|
||||
right_dock_visible = ?6,
|
||||
right_dock_size = ?7,
|
||||
bottom_dock_visible = ?8,
|
||||
bottom_dock_size = ?9,
|
||||
timestamp = CURRENT_TIMESTAMP
|
||||
))?((workspace.id, &workspace.location))
|
||||
))?((workspace.id, &workspace.location, workspace.left_sidebar_open, workspace.docks))
|
||||
.context("Updating workspace")?;
|
||||
|
||||
// Save center pane group
|
||||
|
@ -549,19 +581,22 @@ mod tests {
|
|||
let mut workspace_1 = SerializedWorkspace {
|
||||
id: 1,
|
||||
location: (["/tmp", "/tmp2"]).into(),
|
||||
center_group: Default::default(),
|
||||
left_sidebar_open: true,
|
||||
center_group: Default::default(),
|
||||
bounds: Default::default(),
|
||||
display: Default::default(),
|
||||
docks: Default::default()
|
||||
};
|
||||
|
||||
let mut _workspace_2 = SerializedWorkspace {
|
||||
id: 2,
|
||||
location: (["/tmp"]).into(),
|
||||
center_group: Default::default(),
|
||||
left_sidebar_open: false,
|
||||
center_group: Default::default(),
|
||||
bounds: Default::default(),
|
||||
display: Default::default(),
|
||||
docks: Default::default()
|
||||
|
||||
};
|
||||
|
||||
db.save_workspace(workspace_1.clone()).await;
|
||||
|
@ -659,6 +694,7 @@ mod tests {
|
|||
left_sidebar_open: true,
|
||||
bounds: Default::default(),
|
||||
display: Default::default(),
|
||||
docks: Default::default()
|
||||
};
|
||||
|
||||
db.save_workspace(workspace.clone()).await;
|
||||
|
@ -687,6 +723,7 @@ mod tests {
|
|||
left_sidebar_open: true,
|
||||
bounds: Default::default(),
|
||||
display: Default::default(),
|
||||
docks: Default::default()
|
||||
};
|
||||
|
||||
let mut workspace_2 = SerializedWorkspace {
|
||||
|
@ -696,6 +733,7 @@ mod tests {
|
|||
left_sidebar_open: false,
|
||||
bounds: Default::default(),
|
||||
display: Default::default(),
|
||||
docks: Default::default()
|
||||
};
|
||||
|
||||
db.save_workspace(workspace_1.clone()).await;
|
||||
|
@ -732,6 +770,7 @@ mod tests {
|
|||
left_sidebar_open: false,
|
||||
bounds: Default::default(),
|
||||
display: Default::default(),
|
||||
docks: Default::default()
|
||||
};
|
||||
|
||||
db.save_workspace(workspace_3.clone()).await;
|
||||
|
@ -765,6 +804,7 @@ mod tests {
|
|||
left_sidebar_open: true,
|
||||
bounds: Default::default(),
|
||||
display: Default::default(),
|
||||
docks: Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,65 @@ pub struct SerializedWorkspace {
|
|||
pub left_sidebar_open: bool,
|
||||
pub bounds: Option<WindowBounds>,
|
||||
pub display: Option<Uuid>,
|
||||
pub docks: DockStructure,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Default)]
|
||||
pub struct DockStructure {
|
||||
pub(crate) left: DockData,
|
||||
pub(crate) right: DockData,
|
||||
pub(crate) bottom: DockData,
|
||||
}
|
||||
|
||||
impl Column for DockStructure {
|
||||
fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
|
||||
let (left, next_index) = DockData::column(statement, start_index)?;
|
||||
let (right, next_index) = DockData::column(statement, next_index)?;
|
||||
let (bottom, next_index) = DockData::column(statement, next_index)?;
|
||||
Ok((
|
||||
DockStructure {
|
||||
left,
|
||||
right,
|
||||
bottom,
|
||||
},
|
||||
next_index,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl Bind for DockStructure {
|
||||
fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
|
||||
let next_index = statement.bind(&self.left, start_index)?;
|
||||
let next_index = statement.bind(&self.right, next_index)?;
|
||||
statement.bind(&self.bottom, next_index)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Default)]
|
||||
pub struct DockData {
|
||||
pub(crate) visible: bool,
|
||||
pub(crate) size: Option<f32>,
|
||||
}
|
||||
|
||||
impl Column for DockData {
|
||||
fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
|
||||
let (visible, next_index) = Option::<bool>::column(statement, start_index)?;
|
||||
let (size, next_index) = Option::<f32>::column(statement, next_index)?;
|
||||
Ok((
|
||||
DockData {
|
||||
visible: visible.unwrap_or(false),
|
||||
size,
|
||||
},
|
||||
next_index,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl Bind for DockData {
|
||||
fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
|
||||
let next_index = statement.bind(&self.visible, start_index)?;
|
||||
statement.bind(&self.size, next_index)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
|
@ -251,9 +310,9 @@ impl StaticColumnCount for SerializedItem {
|
|||
}
|
||||
impl Bind for &SerializedItem {
|
||||
fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
|
||||
let next_index = statement.bind(self.kind.clone(), start_index)?;
|
||||
let next_index = statement.bind(self.item_id, next_index)?;
|
||||
statement.bind(self.active, next_index)
|
||||
let next_index = statement.bind(&self.kind, start_index)?;
|
||||
let next_index = statement.bind(&self.item_id, next_index)?;
|
||||
statement.bind(&self.active, next_index)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,9 @@ use std::{
|
|||
|
||||
use crate::{
|
||||
notifications::simple_message_notification::MessageNotification,
|
||||
persistence::model::{SerializedPane, SerializedPaneGroup, SerializedWorkspace},
|
||||
persistence::model::{
|
||||
DockData, DockStructure, SerializedPane, SerializedPaneGroup, SerializedWorkspace,
|
||||
},
|
||||
};
|
||||
use dock::{Dock, DockPosition, Panel, PanelButtons, PanelHandle, TogglePanel};
|
||||
use lazy_static::lazy_static;
|
||||
|
@ -2575,12 +2577,51 @@ impl Workspace {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_serialized_docks(this: &Workspace, cx: &AppContext) -> DockStructure {
|
||||
let left_dock = this.left_dock.read(cx);
|
||||
let left_visible = left_dock.is_open();
|
||||
let left_size = left_dock
|
||||
.active_panel()
|
||||
.map(|panel| left_dock.panel_size(panel.as_ref()))
|
||||
.flatten();
|
||||
|
||||
let right_dock = this.right_dock.read(cx);
|
||||
let right_visible = right_dock.is_open();
|
||||
let right_size = right_dock
|
||||
.active_panel()
|
||||
.map(|panel| right_dock.panel_size(panel.as_ref()))
|
||||
.flatten();
|
||||
|
||||
let bottom_dock = this.bottom_dock.read(cx);
|
||||
let bottom_visible = bottom_dock.is_open();
|
||||
let bottom_size = bottom_dock
|
||||
.active_panel()
|
||||
.map(|panel| bottom_dock.panel_size(panel.as_ref()))
|
||||
.flatten();
|
||||
|
||||
DockStructure {
|
||||
left: DockData {
|
||||
visible: left_visible,
|
||||
size: left_size,
|
||||
},
|
||||
right: DockData {
|
||||
visible: right_visible,
|
||||
size: right_size,
|
||||
},
|
||||
bottom: DockData {
|
||||
visible: bottom_visible,
|
||||
size: bottom_size,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(location) = self.location(cx) {
|
||||
// Load bearing special case:
|
||||
// - with_local_workspace() relies on this to not have other stuff open
|
||||
// when you open your log
|
||||
if !location.paths().is_empty() {
|
||||
let center_group = build_serialized_pane_group(&self.center.root, cx);
|
||||
let docks = build_serialized_docks(self, cx);
|
||||
|
||||
let serialized_workspace = SerializedWorkspace {
|
||||
id: self.database_id,
|
||||
|
@ -2589,6 +2630,7 @@ impl Workspace {
|
|||
left_sidebar_open: self.left_dock.read(cx).is_open(),
|
||||
bounds: Default::default(),
|
||||
display: Default::default(),
|
||||
docks,
|
||||
};
|
||||
|
||||
cx.background()
|
||||
|
@ -2642,11 +2684,25 @@ impl Workspace {
|
|||
}
|
||||
}
|
||||
|
||||
if workspace.left_dock().read(cx).is_open()
|
||||
!= serialized_workspace.left_sidebar_open
|
||||
{
|
||||
workspace.toggle_dock(DockPosition::Left, cx);
|
||||
}
|
||||
let docks = serialized_workspace.docks;
|
||||
workspace.left_dock.update(cx, |dock, cx| {
|
||||
dock.set_open(docks.left.visible, cx);
|
||||
if let Some(size) = docks.left.size {
|
||||
dock.resize_active_panel(size, cx);
|
||||
}
|
||||
});
|
||||
workspace.right_dock.update(cx, |dock, cx| {
|
||||
dock.set_open(docks.right.visible, cx);
|
||||
if let Some(size) = docks.right.size {
|
||||
dock.resize_active_panel(size, cx);
|
||||
}
|
||||
});
|
||||
workspace.bottom_dock.update(cx, |dock, cx| {
|
||||
dock.set_open(docks.bottom.visible, cx);
|
||||
if let Some(size) = docks.bottom.size {
|
||||
dock.resize_active_panel(size, cx);
|
||||
}
|
||||
});
|
||||
|
||||
cx.notify();
|
||||
})?;
|
||||
|
|
Loading…
Reference in a new issue