Persist project and terminal panel sizes
This commit is contained in:
parent
146809eef0
commit
10e947cb5f
8 changed files with 139 additions and 54 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -4888,6 +4888,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"client",
|
"client",
|
||||||
"context_menu",
|
"context_menu",
|
||||||
|
"db",
|
||||||
"drag_and_drop",
|
"drag_and_drop",
|
||||||
"editor",
|
"editor",
|
||||||
"futures 0.3.28",
|
"futures 0.3.28",
|
||||||
|
|
|
@ -10,6 +10,7 @@ doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
context_menu = { path = "../context_menu" }
|
context_menu = { path = "../context_menu" }
|
||||||
|
db = { path = "../db" }
|
||||||
drag_and_drop = { path = "../drag_and_drop" }
|
drag_and_drop = { path = "../drag_and_drop" }
|
||||||
editor = { path = "../editor" }
|
editor = { path = "../editor" }
|
||||||
gpui = { path = "../gpui" }
|
gpui = { path = "../gpui" }
|
||||||
|
@ -23,6 +24,7 @@ postage.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
schemars.workspace = true
|
schemars.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
|
serde_json.workspace = true
|
||||||
unicase = "2.6"
|
unicase = "2.6"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
use context_menu::{ContextMenu, ContextMenuItem};
|
use context_menu::{ContextMenu, ContextMenuItem};
|
||||||
|
use db::kvp::KEY_VALUE_STORE;
|
||||||
use drag_and_drop::{DragAndDrop, Draggable};
|
use drag_and_drop::{DragAndDrop, Draggable};
|
||||||
use editor::{Cancel, Editor};
|
use editor::{Cancel, Editor};
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions,
|
actions,
|
||||||
anyhow::{anyhow, Result},
|
anyhow::{self, anyhow, Result},
|
||||||
elements::{
|
elements::{
|
||||||
AnchorCorner, ChildView, ComponentHost, ContainerStyle, Empty, Flex, MouseEventHandler,
|
AnchorCorner, ChildView, ComponentHost, ContainerStyle, Empty, Flex, MouseEventHandler,
|
||||||
ParentElement, ScrollTarget, Stack, Svg, UniformList, UniformListState,
|
ParentElement, ScrollTarget, Stack, Svg, UniformList, UniformListState,
|
||||||
|
@ -12,8 +13,8 @@ use gpui::{
|
||||||
geometry::vector::Vector2F,
|
geometry::vector::Vector2F,
|
||||||
keymap_matcher::KeymapContext,
|
keymap_matcher::KeymapContext,
|
||||||
platform::{CursorStyle, MouseButton, PromptLevel},
|
platform::{CursorStyle, MouseButton, PromptLevel},
|
||||||
AnyElement, AppContext, ClipboardItem, Element, Entity, ModelHandle, Task, View, ViewContext,
|
AnyElement, AppContext, AsyncAppContext, ClipboardItem, Element, Entity, ModelHandle, Task,
|
||||||
ViewHandle, WeakViewHandle, WindowContext,
|
View, ViewContext, ViewHandle, WeakViewHandle, WindowContext,
|
||||||
};
|
};
|
||||||
use menu::{Confirm, SelectNext, SelectPrev};
|
use menu::{Confirm, SelectNext, SelectPrev};
|
||||||
use project::{
|
use project::{
|
||||||
|
@ -33,11 +34,13 @@ use std::{
|
||||||
};
|
};
|
||||||
use theme::{ui::FileName, ProjectPanelEntry};
|
use theme::{ui::FileName, ProjectPanelEntry};
|
||||||
use unicase::UniCase;
|
use unicase::UniCase;
|
||||||
|
use util::{ResultExt, TryFutureExt};
|
||||||
use workspace::{
|
use workspace::{
|
||||||
dock::{DockPosition, Panel},
|
dock::{DockPosition, Panel},
|
||||||
Workspace,
|
Workspace,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PROJECT_PANEL_KEY: &'static str = "ProjectPanel";
|
||||||
const NEW_ENTRY_ID: ProjectEntryId = ProjectEntryId::MAX;
|
const NEW_ENTRY_ID: ProjectEntryId = ProjectEntryId::MAX;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -67,6 +70,7 @@ pub struct ProjectPanelSettingsContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum ProjectPanelDockPosition {
|
pub enum ProjectPanelDockPosition {
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
|
@ -87,6 +91,8 @@ pub struct ProjectPanel {
|
||||||
dragged_entry_destination: Option<Arc<Path>>,
|
dragged_entry_destination: Option<Arc<Path>>,
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
has_focus: bool,
|
has_focus: bool,
|
||||||
|
width: Option<f32>,
|
||||||
|
pending_serialization: Task<Option<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -183,8 +189,13 @@ pub enum Event {
|
||||||
Focus,
|
Focus,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct SerializedProjectPanel {
|
||||||
|
width: Option<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
impl ProjectPanel {
|
impl ProjectPanel {
|
||||||
pub fn new(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> ViewHandle<Self> {
|
fn new(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> ViewHandle<Self> {
|
||||||
let project = workspace.project().clone();
|
let project = workspace.project().clone();
|
||||||
let project_panel = cx.add_view(|cx: &mut ViewContext<Self>| {
|
let project_panel = cx.add_view(|cx: &mut ViewContext<Self>| {
|
||||||
cx.observe(&project, |this, _, cx| {
|
cx.observe(&project, |this, _, cx| {
|
||||||
|
@ -258,6 +269,8 @@ impl ProjectPanel {
|
||||||
dragged_entry_destination: None,
|
dragged_entry_destination: None,
|
||||||
workspace: workspace.weak_handle(),
|
workspace: workspace.weak_handle(),
|
||||||
has_focus: false,
|
has_focus: false,
|
||||||
|
width: None,
|
||||||
|
pending_serialization: Task::ready(None),
|
||||||
};
|
};
|
||||||
this.update_visible_entries(None, cx);
|
this.update_visible_entries(None, cx);
|
||||||
|
|
||||||
|
@ -311,6 +324,51 @@ impl ProjectPanel {
|
||||||
project_panel
|
project_panel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load(
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
|
cx: AsyncAppContext,
|
||||||
|
) -> Task<Result<ViewHandle<Self>>> {
|
||||||
|
cx.spawn(|mut cx| async move {
|
||||||
|
let serialized_panel = if let Some(panel) = cx
|
||||||
|
.background()
|
||||||
|
.spawn(async move { KEY_VALUE_STORE.read_kvp(PROJECT_PANEL_KEY) })
|
||||||
|
.await
|
||||||
|
.log_err()
|
||||||
|
.flatten()
|
||||||
|
{
|
||||||
|
Some(serde_json::from_str::<SerializedProjectPanel>(&panel)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
workspace.update(&mut cx, |workspace, cx| {
|
||||||
|
let panel = ProjectPanel::new(workspace, cx);
|
||||||
|
if let Some(serialized_panel) = serialized_panel {
|
||||||
|
panel.update(cx, |panel, cx| {
|
||||||
|
panel.width = serialized_panel.width;
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
panel
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
|
let width = self.width;
|
||||||
|
self.pending_serialization = cx.background().spawn(
|
||||||
|
async move {
|
||||||
|
KEY_VALUE_STORE
|
||||||
|
.write_kvp(
|
||||||
|
PROJECT_PANEL_KEY.into(),
|
||||||
|
serde_json::to_string(&SerializedProjectPanel { width })?,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
anyhow::Ok(())
|
||||||
|
}
|
||||||
|
.log_err(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn deploy_context_menu(
|
fn deploy_context_menu(
|
||||||
&mut self,
|
&mut self,
|
||||||
position: Vector2F,
|
position: Vector2F,
|
||||||
|
@ -1435,8 +1493,15 @@ impl workspace::dock::Panel for ProjectPanel {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_size(&self, cx: &WindowContext) -> f32 {
|
fn size(&self, cx: &WindowContext) -> f32 {
|
||||||
settings::get::<ProjectPanelSettings>(cx).default_width
|
self.width
|
||||||
|
.unwrap_or_else(|| settings::get::<ProjectPanelSettings>(cx).default_width)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_size(&mut self, size: f32, cx: &mut ViewContext<Self>) {
|
||||||
|
self.width = Some(size);
|
||||||
|
self.serialize(cx);
|
||||||
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_zoom_in_on_event(_: &Self::Event) -> bool {
|
fn should_zoom_in_on_event(_: &Self::Event) -> bool {
|
||||||
|
|
|
@ -120,6 +120,7 @@ pub fn init(cx: &mut AppContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum TerminalDockPosition {
|
pub enum TerminalDockPosition {
|
||||||
Left,
|
Left,
|
||||||
Bottom,
|
Bottom,
|
||||||
|
|
|
@ -37,12 +37,14 @@ pub struct TerminalPanel {
|
||||||
pane: ViewHandle<Pane>,
|
pane: ViewHandle<Pane>,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
|
width: Option<f32>,
|
||||||
|
height: Option<f32>,
|
||||||
pending_serialization: Task<Option<()>>,
|
pending_serialization: Task<Option<()>>,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TerminalPanel {
|
impl TerminalPanel {
|
||||||
pub fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
|
fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
|
||||||
let weak_self = cx.weak_handle();
|
let weak_self = cx.weak_handle();
|
||||||
let pane = cx.add_view(|cx| {
|
let pane = cx.add_view(|cx| {
|
||||||
let window_id = cx.window_id();
|
let window_id = cx.window_id();
|
||||||
|
@ -90,6 +92,8 @@ impl TerminalPanel {
|
||||||
fs: workspace.app_state().fs.clone(),
|
fs: workspace.app_state().fs.clone(),
|
||||||
workspace: workspace.weak_handle(),
|
workspace: workspace.weak_handle(),
|
||||||
pending_serialization: Task::ready(None),
|
pending_serialization: Task::ready(None),
|
||||||
|
width: None,
|
||||||
|
height: None,
|
||||||
_subscriptions: subscriptions,
|
_subscriptions: subscriptions,
|
||||||
};
|
};
|
||||||
let mut old_dock_position = this.position(cx);
|
let mut old_dock_position = this.position(cx);
|
||||||
|
@ -112,7 +116,9 @@ impl TerminalPanel {
|
||||||
let serialized_panel = if let Some(panel) = cx
|
let serialized_panel = if let Some(panel) = cx
|
||||||
.background()
|
.background()
|
||||||
.spawn(async move { KEY_VALUE_STORE.read_kvp(TERMINAL_PANEL_KEY) })
|
.spawn(async move { KEY_VALUE_STORE.read_kvp(TERMINAL_PANEL_KEY) })
|
||||||
.await?
|
.await
|
||||||
|
.log_err()
|
||||||
|
.flatten()
|
||||||
{
|
{
|
||||||
Some(serde_json::from_str::<SerializedTerminalPanel>(&panel)?)
|
Some(serde_json::from_str::<SerializedTerminalPanel>(&panel)?)
|
||||||
} else {
|
} else {
|
||||||
|
@ -122,6 +128,9 @@ impl TerminalPanel {
|
||||||
let panel = cx.add_view(|cx| TerminalPanel::new(workspace, cx));
|
let panel = cx.add_view(|cx| TerminalPanel::new(workspace, cx));
|
||||||
let items = if let Some(serialized_panel) = serialized_panel.as_ref() {
|
let items = if let Some(serialized_panel) = serialized_panel.as_ref() {
|
||||||
panel.update(cx, |panel, cx| {
|
panel.update(cx, |panel, cx| {
|
||||||
|
cx.notify();
|
||||||
|
panel.height = serialized_panel.height;
|
||||||
|
panel.width = serialized_panel.width;
|
||||||
panel.pane.update(cx, |_, cx| {
|
panel.pane.update(cx, |_, cx| {
|
||||||
serialized_panel
|
serialized_panel
|
||||||
.items
|
.items
|
||||||
|
@ -226,6 +235,8 @@ impl TerminalPanel {
|
||||||
.map(|item| item.id())
|
.map(|item| item.id())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let active_item_id = self.pane.read(cx).active_item().map(|item| item.id());
|
let active_item_id = self.pane.read(cx).active_item().map(|item| item.id());
|
||||||
|
let height = self.height;
|
||||||
|
let width = self.width;
|
||||||
self.pending_serialization = cx.background().spawn(
|
self.pending_serialization = cx.background().spawn(
|
||||||
async move {
|
async move {
|
||||||
KEY_VALUE_STORE
|
KEY_VALUE_STORE
|
||||||
|
@ -234,6 +245,8 @@ impl TerminalPanel {
|
||||||
serde_json::to_string(&SerializedTerminalPanel {
|
serde_json::to_string(&SerializedTerminalPanel {
|
||||||
items,
|
items,
|
||||||
active_item_id,
|
active_item_id,
|
||||||
|
height,
|
||||||
|
width,
|
||||||
})?,
|
})?,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -288,12 +301,23 @@ impl Panel for TerminalPanel {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_size(&self, cx: &WindowContext) -> f32 {
|
fn size(&self, cx: &WindowContext) -> f32 {
|
||||||
let settings = settings::get::<TerminalSettings>(cx);
|
let settings = settings::get::<TerminalSettings>(cx);
|
||||||
match self.position(cx) {
|
match self.position(cx) {
|
||||||
DockPosition::Left | DockPosition::Right => settings.default_width,
|
DockPosition::Left | DockPosition::Right => {
|
||||||
DockPosition::Bottom => settings.default_height,
|
self.width.unwrap_or_else(|| settings.default_width)
|
||||||
}
|
}
|
||||||
|
DockPosition::Bottom => self.height.unwrap_or_else(|| settings.default_height),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_size(&mut self, size: f32, cx: &mut ViewContext<Self>) {
|
||||||
|
match self.position(cx) {
|
||||||
|
DockPosition::Left | DockPosition::Right => self.width = Some(size),
|
||||||
|
DockPosition::Bottom => self.height = Some(size),
|
||||||
|
}
|
||||||
|
self.serialize(cx);
|
||||||
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_zoom_in_on_event(event: &Event) -> bool {
|
fn should_zoom_in_on_event(event: &Event) -> bool {
|
||||||
|
@ -360,4 +384,6 @@ impl Panel for TerminalPanel {
|
||||||
struct SerializedTerminalPanel {
|
struct SerializedTerminalPanel {
|
||||||
items: Vec<usize>,
|
items: Vec<usize>,
|
||||||
active_item_id: Option<usize>,
|
active_item_id: Option<usize>,
|
||||||
|
width: Option<f32>,
|
||||||
|
height: Option<f32>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@ pub trait Panel: View {
|
||||||
fn position(&self, cx: &WindowContext) -> DockPosition;
|
fn position(&self, cx: &WindowContext) -> DockPosition;
|
||||||
fn position_is_valid(&self, position: DockPosition) -> bool;
|
fn position_is_valid(&self, position: DockPosition) -> bool;
|
||||||
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>);
|
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>);
|
||||||
fn default_size(&self, cx: &WindowContext) -> f32;
|
fn size(&self, cx: &WindowContext) -> f32;
|
||||||
|
fn set_size(&mut self, size: f32, cx: &mut ViewContext<Self>);
|
||||||
fn icon_path(&self) -> &'static str;
|
fn icon_path(&self) -> &'static str;
|
||||||
fn icon_tooltip(&self) -> String;
|
fn icon_tooltip(&self) -> String;
|
||||||
fn icon_label(&self, _: &WindowContext) -> Option<String> {
|
fn icon_label(&self, _: &WindowContext) -> Option<String> {
|
||||||
|
@ -39,7 +40,8 @@ pub trait PanelHandle {
|
||||||
fn is_zoomed(&self, cx: &WindowContext) -> bool;
|
fn is_zoomed(&self, cx: &WindowContext) -> bool;
|
||||||
fn set_zoomed(&self, zoomed: bool, cx: &mut WindowContext);
|
fn set_zoomed(&self, zoomed: bool, cx: &mut WindowContext);
|
||||||
fn set_active(&self, active: bool, cx: &mut WindowContext);
|
fn set_active(&self, active: bool, cx: &mut WindowContext);
|
||||||
fn default_size(&self, cx: &WindowContext) -> f32;
|
fn size(&self, cx: &WindowContext) -> f32;
|
||||||
|
fn set_size(&self, size: f32, cx: &mut WindowContext);
|
||||||
fn icon_path(&self, cx: &WindowContext) -> &'static str;
|
fn icon_path(&self, cx: &WindowContext) -> &'static str;
|
||||||
fn icon_tooltip(&self, cx: &WindowContext) -> String;
|
fn icon_tooltip(&self, cx: &WindowContext) -> String;
|
||||||
fn icon_label(&self, cx: &WindowContext) -> Option<String>;
|
fn icon_label(&self, cx: &WindowContext) -> Option<String>;
|
||||||
|
@ -67,8 +69,12 @@ where
|
||||||
self.update(cx, |this, cx| this.set_position(position, cx))
|
self.update(cx, |this, cx| this.set_position(position, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_size(&self, cx: &WindowContext) -> f32 {
|
fn size(&self, cx: &WindowContext) -> f32 {
|
||||||
self.read(cx).default_size(cx)
|
self.read(cx).size(cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_size(&self, size: f32, cx: &mut WindowContext) {
|
||||||
|
self.update(cx, |this, cx| this.set_size(size, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_zoomed(&self, cx: &WindowContext) -> bool {
|
fn is_zoomed(&self, cx: &WindowContext) -> bool {
|
||||||
|
@ -151,7 +157,6 @@ impl DockPosition {
|
||||||
|
|
||||||
struct PanelEntry {
|
struct PanelEntry {
|
||||||
panel: Rc<dyn PanelHandle>,
|
panel: Rc<dyn PanelHandle>,
|
||||||
size: f32,
|
|
||||||
context_menu: ViewHandle<ContextMenu>,
|
context_menu: ViewHandle<ContextMenu>,
|
||||||
_subscriptions: [Subscription; 2],
|
_subscriptions: [Subscription; 2],
|
||||||
}
|
}
|
||||||
|
@ -271,10 +276,8 @@ impl Dock {
|
||||||
];
|
];
|
||||||
|
|
||||||
let dock_view_id = cx.view_id();
|
let dock_view_id = cx.view_id();
|
||||||
let size = panel.default_size(cx);
|
|
||||||
self.panel_entries.push(PanelEntry {
|
self.panel_entries.push(PanelEntry {
|
||||||
panel: Rc::new(panel),
|
panel: Rc::new(panel),
|
||||||
size,
|
|
||||||
context_menu: cx.add_view(|cx| {
|
context_menu: cx.add_view(|cx| {
|
||||||
let mut menu = ContextMenu::new(dock_view_id, cx);
|
let mut menu = ContextMenu::new(dock_view_id, cx);
|
||||||
menu.set_position_mode(OverlayPositionMode::Local);
|
menu.set_position_mode(OverlayPositionMode::Local);
|
||||||
|
@ -343,28 +346,18 @@ impl Dock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn panel_size(&self, panel: &dyn PanelHandle) -> Option<f32> {
|
pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option<f32> {
|
||||||
self.panel_entries
|
self.panel_entries
|
||||||
.iter()
|
.iter()
|
||||||
.find(|entry| entry.panel.id() == panel.id())
|
.find(|entry| entry.panel.id() == panel.id())
|
||||||
.map(|entry| entry.size)
|
.map(|entry| entry.panel.size(cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize_panel(&mut self, panel: &dyn PanelHandle, size: f32) {
|
pub fn active_panel_size(&self, cx: &WindowContext) -> Option<f32> {
|
||||||
let entry = self
|
|
||||||
.panel_entries
|
|
||||||
.iter_mut()
|
|
||||||
.find(|entry| entry.panel.id() == panel.id());
|
|
||||||
if let Some(entry) = entry {
|
|
||||||
entry.size = size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn active_panel_size(&self) -> Option<f32> {
|
|
||||||
if self.is_open {
|
if self.is_open {
|
||||||
self.panel_entries
|
self.panel_entries
|
||||||
.get(self.active_panel_index)
|
.get(self.active_panel_index)
|
||||||
.map(|entry| entry.size)
|
.map(|entry| entry.panel.size(cx))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -372,7 +365,7 @@ impl Dock {
|
||||||
|
|
||||||
pub fn resize_active_panel(&mut self, size: f32, cx: &mut ViewContext<Self>) {
|
pub fn resize_active_panel(&mut self, size: f32, cx: &mut ViewContext<Self>) {
|
||||||
if let Some(entry) = self.panel_entries.get_mut(self.active_panel_index) {
|
if let Some(entry) = self.panel_entries.get_mut(self.active_panel_index) {
|
||||||
entry.size = size;
|
entry.panel.set_size(size, cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,7 +379,7 @@ impl Dock {
|
||||||
.with_style(style.container)
|
.with_style(style.container)
|
||||||
.resizable(
|
.resizable(
|
||||||
self.position.to_resize_handle_side(),
|
self.position.to_resize_handle_side(),
|
||||||
active_entry.size,
|
active_entry.panel.size(cx),
|
||||||
|_, _, _| {},
|
|_, _, _| {},
|
||||||
)
|
)
|
||||||
.into_any()
|
.into_any()
|
||||||
|
@ -413,7 +406,7 @@ impl View for Dock {
|
||||||
.with_style(style.container)
|
.with_style(style.container)
|
||||||
.resizable(
|
.resizable(
|
||||||
self.position.to_resize_handle_side(),
|
self.position.to_resize_handle_side(),
|
||||||
active_entry.size,
|
active_entry.panel.size(cx),
|
||||||
|dock: &mut Self, size, cx| dock.resize_active_panel(size, cx),
|
|dock: &mut Self, size, cx| dock.resize_active_panel(size, cx),
|
||||||
)
|
)
|
||||||
.into_any()
|
.into_any()
|
||||||
|
@ -630,13 +623,17 @@ pub(crate) mod test {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_size(&self, _: &WindowContext) -> f32 {
|
fn size(&self, _: &WindowContext) -> f32 {
|
||||||
match self.position.axis() {
|
match self.position.axis() {
|
||||||
Axis::Horizontal => 300.,
|
Axis::Horizontal => 300.,
|
||||||
Axis::Vertical => 200.,
|
Axis::Vertical => 200.,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_size(&mut self, _: f32, _: &mut ViewContext<Self>) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
fn icon_path(&self) -> &'static str {
|
fn icon_path(&self) -> &'static str {
|
||||||
"icons/test_panel.svg"
|
"icons/test_panel.svg"
|
||||||
}
|
}
|
||||||
|
|
|
@ -853,11 +853,7 @@ impl Workspace {
|
||||||
if T::should_change_position_on_event(event) {
|
if T::should_change_position_on_event(event) {
|
||||||
let new_position = panel.read(cx).position(cx);
|
let new_position = panel.read(cx).position(cx);
|
||||||
let mut was_visible = false;
|
let mut was_visible = false;
|
||||||
let mut size = None;
|
|
||||||
dock.update(cx, |dock, cx| {
|
dock.update(cx, |dock, cx| {
|
||||||
if new_position.axis() == prev_position.axis() {
|
|
||||||
size = dock.panel_size(&panel);
|
|
||||||
}
|
|
||||||
prev_position = new_position;
|
prev_position = new_position;
|
||||||
|
|
||||||
was_visible = dock.is_open()
|
was_visible = dock.is_open()
|
||||||
|
@ -874,10 +870,6 @@ impl Workspace {
|
||||||
.clone();
|
.clone();
|
||||||
dock.update(cx, |dock, cx| {
|
dock.update(cx, |dock, cx| {
|
||||||
dock.add_panel(panel.clone(), cx);
|
dock.add_panel(panel.clone(), cx);
|
||||||
if let Some(size) = size {
|
|
||||||
dock.resize_panel(&panel, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if was_visible {
|
if was_visible {
|
||||||
dock.set_open(true, cx);
|
dock.set_open(true, cx);
|
||||||
dock.activate_panel(dock.panels_len() - 1, cx);
|
dock.activate_panel(dock.panels_len() - 1, cx);
|
||||||
|
@ -3961,8 +3953,8 @@ mod tests {
|
||||||
panel_1.id()
|
panel_1.id()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
left_dock.read(cx).active_panel_size().unwrap(),
|
left_dock.read(cx).active_panel_size(cx).unwrap(),
|
||||||
panel_1.default_size(cx)
|
panel_1.size(cx)
|
||||||
);
|
);
|
||||||
|
|
||||||
left_dock.update(cx, |left_dock, cx| left_dock.resize_active_panel(1337., cx));
|
left_dock.update(cx, |left_dock, cx| left_dock.resize_active_panel(1337., cx));
|
||||||
|
@ -3989,7 +3981,7 @@ mod tests {
|
||||||
right_dock.read(cx).active_panel().unwrap().id(),
|
right_dock.read(cx).active_panel().unwrap().id(),
|
||||||
panel_1.id()
|
panel_1.id()
|
||||||
);
|
);
|
||||||
assert_eq!(right_dock.read(cx).active_panel_size().unwrap(), 1337.);
|
assert_eq!(right_dock.read(cx).active_panel_size(cx).unwrap(), 1337.);
|
||||||
|
|
||||||
// Now we move panel_2 to the left
|
// Now we move panel_2 to the left
|
||||||
panel_2.set_position(DockPosition::Left, cx);
|
panel_2.set_position(DockPosition::Left, cx);
|
||||||
|
@ -4019,7 +4011,7 @@ mod tests {
|
||||||
left_dock.read(cx).active_panel().unwrap().id(),
|
left_dock.read(cx).active_panel().unwrap().id(),
|
||||||
panel_1.id()
|
panel_1.id()
|
||||||
);
|
);
|
||||||
assert_eq!(left_dock.read(cx).active_panel_size().unwrap(), 1337.);
|
assert_eq!(left_dock.read(cx).active_panel_size(cx).unwrap(), 1337.);
|
||||||
// And right the dock should be closed as it no longer has any panels.
|
// And right the dock should be closed as it no longer has any panels.
|
||||||
assert!(!workspace.right_dock().read(cx).is_open());
|
assert!(!workspace.right_dock().read(cx).is_open());
|
||||||
|
|
||||||
|
@ -4034,8 +4026,8 @@ mod tests {
|
||||||
// since the panel orientation changed from vertical to horizontal.
|
// since the panel orientation changed from vertical to horizontal.
|
||||||
let bottom_dock = workspace.bottom_dock();
|
let bottom_dock = workspace.bottom_dock();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bottom_dock.read(cx).active_panel_size().unwrap(),
|
bottom_dock.read(cx).active_panel_size(cx).unwrap(),
|
||||||
panel_1.default_size(cx),
|
panel_1.size(cx),
|
||||||
);
|
);
|
||||||
// Close bottom dock and move panel_1 back to the left.
|
// Close bottom dock and move panel_1 back to the left.
|
||||||
bottom_dock.update(cx, |bottom_dock, cx| bottom_dock.set_open(false, cx));
|
bottom_dock.update(cx, |bottom_dock, cx| bottom_dock.set_open(false, cx));
|
||||||
|
|
|
@ -335,8 +335,12 @@ pub fn initialize_workspace(
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
});
|
});
|
||||||
|
})?;
|
||||||
|
|
||||||
let project_panel = ProjectPanel::new(workspace, cx);
|
let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
|
||||||
|
let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
|
||||||
|
let (project_panel, terminal_panel) = futures::try_join!(project_panel, terminal_panel)?;
|
||||||
|
workspace_handle.update(&mut cx, |workspace, cx| {
|
||||||
let project_panel_position = project_panel.position(cx);
|
let project_panel_position = project_panel.position(cx);
|
||||||
workspace.add_panel(project_panel, cx);
|
workspace.add_panel(project_panel, cx);
|
||||||
if !was_deserialized
|
if !was_deserialized
|
||||||
|
@ -352,10 +356,7 @@ pub fn initialize_workspace(
|
||||||
{
|
{
|
||||||
workspace.toggle_dock(project_panel_position, cx);
|
workspace.toggle_dock(project_panel_position, cx);
|
||||||
}
|
}
|
||||||
})?;
|
|
||||||
|
|
||||||
let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone()).await?;
|
|
||||||
workspace_handle.update(&mut cx, |workspace, cx| {
|
|
||||||
workspace.add_panel(terminal_panel, cx)
|
workspace.add_panel(terminal_panel, cx)
|
||||||
})?;
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue