wip: refactor
This commit is contained in:
@@ -138,10 +138,18 @@ impl Dock {
|
||||
Self::subscribe_panel_events(dock_area.clone(), &panel, cx);
|
||||
|
||||
if !open {
|
||||
if let DockItem::Tabs { view, .. } = panel.clone() {
|
||||
view.update(cx, |panel, cx| {
|
||||
panel.set_collapsed(true, cx);
|
||||
});
|
||||
match panel.clone() {
|
||||
DockItem::Tabs { view, .. } => {
|
||||
view.update(cx, |panel, cx| {
|
||||
panel.set_collapsed(true, cx);
|
||||
});
|
||||
}
|
||||
DockItem::Split { items, .. } => {
|
||||
for item in items {
|
||||
item.set_collapsed(true, cx);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use gpui::{
|
||||
div, prelude::FluentBuilder, px, rems, AnchorCorner, AppContext, DefiniteLength, DismissEvent,
|
||||
DragMoveEvent, Empty, Entity, EventEmitter, FocusHandle, FocusableView,
|
||||
@@ -7,7 +5,12 @@ use gpui::{
|
||||
SharedString, StatefulInteractiveElement, Styled, View, ViewContext, VisualContext as _,
|
||||
WeakView, WindowContext,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{
|
||||
ClosePanel, DockArea, DockItemState, DockPlacement, Panel, PanelEvent, PanelStyle, PanelView,
|
||||
StackPanel, ToggleZoom,
|
||||
};
|
||||
use crate::{
|
||||
button::{Button, ButtonVariants as _},
|
||||
dock::DockItemInfo,
|
||||
@@ -18,11 +21,6 @@ use crate::{
|
||||
v_flex, AxisExt, IconName, Placement, Selectable, Sizable,
|
||||
};
|
||||
|
||||
use super::{
|
||||
ClosePanel, DockArea, DockItemState, DockPlacement, Panel, PanelEvent, PanelStyle, PanelView,
|
||||
StackPanel, ToggleZoom,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct TabState {
|
||||
closeable: bool,
|
||||
@@ -173,6 +171,15 @@ impl TabPanel {
|
||||
|
||||
/// Add a panel to the end of the tabs
|
||||
pub fn add_panel(&mut self, panel: Arc<dyn PanelView>, cx: &mut ViewContext<Self>) {
|
||||
self.add_panel_with_active(panel, true, cx);
|
||||
}
|
||||
|
||||
fn add_panel_with_active(
|
||||
&mut self,
|
||||
panel: Arc<dyn PanelView>,
|
||||
active: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
assert_ne!(
|
||||
panel.panel_name(cx),
|
||||
"StackPanel",
|
||||
@@ -189,7 +196,9 @@ impl TabPanel {
|
||||
|
||||
self.panels.push(panel);
|
||||
// set the active panel to the new panel
|
||||
self.set_active_ix(self.panels.len() - 1, cx);
|
||||
if active {
|
||||
self.set_active_ix(self.panels.len() - 1, cx);
|
||||
}
|
||||
cx.emit(PanelEvent::LayoutChanged);
|
||||
cx.notify();
|
||||
}
|
||||
@@ -543,6 +552,7 @@ impl TabPanel {
|
||||
)
|
||||
.children(self.panels.iter().enumerate().map(|(ix, panel)| {
|
||||
let mut active = ix == self.active_ix;
|
||||
let disabled = self.is_collapsed;
|
||||
|
||||
// Always not show active tab style, if the panel is collapsed
|
||||
if self.is_collapsed {
|
||||
@@ -552,31 +562,34 @@ impl TabPanel {
|
||||
Tab::new(("tab", ix), panel.title(cx))
|
||||
.py_2()
|
||||
.selected(active)
|
||||
.on_click(cx.listener(move |view, _, cx| {
|
||||
view.set_active_ix(ix, cx);
|
||||
}))
|
||||
.when(state.draggable, |this| {
|
||||
this.on_drag(
|
||||
DragPanel::new(panel.clone(), view.clone()),
|
||||
|drag, _, cx| {
|
||||
cx.stop_propagation();
|
||||
cx.new_view(|_| drag.clone())
|
||||
},
|
||||
)
|
||||
})
|
||||
.when(state.droppable, |this| {
|
||||
this.drag_over::<DragPanel>(|this, _, cx| {
|
||||
this.rounded_l_none()
|
||||
.border_l_2()
|
||||
.border_r_0()
|
||||
.border_color(cx.theme().drag_border)
|
||||
.disabled(disabled)
|
||||
.when(!disabled, |this| {
|
||||
this.on_click(cx.listener(move |view, _, cx| {
|
||||
view.set_active_ix(ix, cx);
|
||||
}))
|
||||
.when(state.draggable, |this| {
|
||||
this.on_drag(
|
||||
DragPanel::new(panel.clone(), view.clone()),
|
||||
|drag, _, cx| {
|
||||
cx.stop_propagation();
|
||||
cx.new_view(|_| drag.clone())
|
||||
},
|
||||
)
|
||||
})
|
||||
.when(state.droppable, |this| {
|
||||
this.drag_over::<DragPanel>(|this, _, cx| {
|
||||
this.rounded_l_none()
|
||||
.border_l_2()
|
||||
.border_r_0()
|
||||
.border_color(cx.theme().drag_border)
|
||||
})
|
||||
.on_drop(cx.listener(
|
||||
move |this, drag: &DragPanel, cx| {
|
||||
this.will_split_placement = None;
|
||||
this.on_drop(drag, Some(ix), true, cx)
|
||||
},
|
||||
))
|
||||
})
|
||||
.on_drop(cx.listener(
|
||||
move |this, drag: &DragPanel, cx| {
|
||||
this.will_split_placement = None;
|
||||
this.on_drop(drag, Some(ix), cx)
|
||||
},
|
||||
))
|
||||
})
|
||||
}))
|
||||
.child(
|
||||
@@ -597,7 +610,7 @@ impl TabPanel {
|
||||
None
|
||||
};
|
||||
|
||||
this.on_drop(drag, ix, cx)
|
||||
this.on_drop(drag, ix, false, cx)
|
||||
}))
|
||||
}),
|
||||
)
|
||||
@@ -620,6 +633,10 @@ impl TabPanel {
|
||||
}
|
||||
|
||||
fn render_active_panel(&self, state: TabState, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
if self.is_collapsed {
|
||||
return Empty {}.into_any_element();
|
||||
}
|
||||
|
||||
self.active_panel()
|
||||
.map(|panel| {
|
||||
div()
|
||||
@@ -658,7 +675,7 @@ impl TabPanel {
|
||||
})
|
||||
.group_drag_over::<DragPanel>("", |this| this.visible())
|
||||
.on_drop(cx.listener(|this, drag: &DragPanel, cx| {
|
||||
this.on_drop(drag, None, cx)
|
||||
this.on_drop(drag, None, true, cx)
|
||||
})),
|
||||
)
|
||||
})
|
||||
@@ -688,17 +705,28 @@ impl TabPanel {
|
||||
cx.notify()
|
||||
}
|
||||
|
||||
fn on_drop(&mut self, drag: &DragPanel, ix: Option<usize>, cx: &mut ViewContext<Self>) {
|
||||
/// Handle the drop event when dragging a panel
|
||||
///
|
||||
/// - `active` - When true, the panel will be active after the drop
|
||||
fn on_drop(
|
||||
&mut self,
|
||||
drag: &DragPanel,
|
||||
ix: Option<usize>,
|
||||
active: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
let panel = drag.panel.clone();
|
||||
let is_same_tab = drag.tab_panel == *cx.view();
|
||||
|
||||
// If target is same tab, and it is only one panel, do nothing.
|
||||
if is_same_tab && ix.is_none() {
|
||||
#[allow(clippy::if_same_then_else)]
|
||||
if self.will_split_placement.is_none() {
|
||||
return;
|
||||
} else if self.panels.len() == 1 {
|
||||
return;
|
||||
} else {
|
||||
#[allow(clippy::collapsible_else_if)]
|
||||
if self.panels.len() == 1 {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -721,7 +749,7 @@ impl TabPanel {
|
||||
} else if let Some(ix) = ix {
|
||||
self.insert_panel_at(panel, ix, cx)
|
||||
} else {
|
||||
self.add_panel(panel, cx)
|
||||
self.add_panel_with_active(panel, active, cx)
|
||||
}
|
||||
|
||||
self.remove_self_if_empty(cx);
|
||||
|
||||
@@ -81,7 +81,7 @@ pub trait DropdownDelegate: Sized {
|
||||
}
|
||||
|
||||
fn perform_search(&mut self, _query: &str, _cx: &mut ViewContext<Dropdown<Self>>) -> Task<()> {
|
||||
Task::Ready(Some(()))
|
||||
Task::ready(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,11 +178,9 @@ where
|
||||
}
|
||||
|
||||
fn perform_search(&mut self, query: &str, cx: &mut ViewContext<List<Self>>) -> Task<()> {
|
||||
self.dropdown
|
||||
.upgrade()
|
||||
.map_or(Task::Ready(None), |dropdown| {
|
||||
dropdown.update(cx, |_, cx| self.delegate.perform_search(query, cx))
|
||||
})
|
||||
self.dropdown.upgrade().map_or(Task::ready(()), |dropdown| {
|
||||
dropdown.update(cx, |_, cx| self.delegate.perform_search(query, cx))
|
||||
})
|
||||
}
|
||||
|
||||
fn set_selected_index(&mut self, ix: Option<usize>, _: &mut ViewContext<List<Self>>) {
|
||||
@@ -285,7 +283,7 @@ impl<T: DropdownItem + Clone> DropdownDelegate for SearchableVec<T> {
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
Task::Ready(Some(()))
|
||||
Task::ready(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ pub mod skeleton;
|
||||
pub mod slider;
|
||||
pub mod switch;
|
||||
pub mod tab;
|
||||
pub mod table;
|
||||
pub mod theme;
|
||||
pub mod tooltip;
|
||||
|
||||
@@ -78,5 +77,4 @@ pub fn init(cx: &mut gpui::AppContext) {
|
||||
modal::init(cx);
|
||||
popover::init(cx);
|
||||
popup_menu::init(cx);
|
||||
table::init(cx);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ pub trait ListDelegate: Sized + 'static {
|
||||
/// When Query Input change, this method will be called.
|
||||
/// You can perform search here.
|
||||
fn perform_search(&mut self, query: &str, cx: &mut ViewContext<List<Self>>) -> Task<()> {
|
||||
Task::Ready(Some(()))
|
||||
Task::ready(())
|
||||
}
|
||||
|
||||
/// Return the number of items in the list.
|
||||
@@ -126,7 +126,7 @@ where
|
||||
enable_scrollbar: true,
|
||||
loading: false,
|
||||
size: Size::default(),
|
||||
_search_task: Task::Ready(None),
|
||||
_search_task: Task::ready(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ impl Element for ScrollableMask {
|
||||
bounds,
|
||||
border_widths: Edges::all(px(1.0)),
|
||||
border_color: color,
|
||||
background: gpui::transparent_white(),
|
||||
background: gpui::transparent_white().into(),
|
||||
corner_radii: Corners::all(px(0.)),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -597,7 +597,7 @@ impl Element for Scrollbar {
|
||||
cx.paint_quad(PaintQuad {
|
||||
bounds,
|
||||
corner_radii: (0.).into(),
|
||||
background: gpui::transparent_black(),
|
||||
background: gpui::transparent_black().into(),
|
||||
border_widths: if is_vertical {
|
||||
Edges {
|
||||
top: px(0.),
|
||||
|
||||
@@ -42,6 +42,12 @@ impl Tab {
|
||||
self.suffix = Some(suffix.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Set disabled state to the tab
|
||||
pub fn disabled(mut self, disabled: bool) -> Self {
|
||||
self.disabled = disabled;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Selectable for Tab {
|
||||
@@ -72,9 +78,11 @@ impl Styled for Tab {
|
||||
impl RenderOnce for Tab {
|
||||
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
|
||||
let (text_color, bg_color) = match (self.selected, self.disabled) {
|
||||
(true, _) => (cx.theme().tab_active_foreground, cx.theme().tab_active),
|
||||
(false, true) => (cx.theme().tab_foreground.opacity(0.5), cx.theme().tab),
|
||||
(true, false) => (cx.theme().tab_active_foreground, cx.theme().tab_active),
|
||||
(false, false) => (cx.theme().muted_foreground, cx.theme().tab),
|
||||
// disabled
|
||||
(true, true) => (cx.theme().muted_foreground, cx.theme().tab_active),
|
||||
(false, true) => (cx.theme().muted_foreground, cx.theme().tab),
|
||||
};
|
||||
|
||||
self.base
|
||||
@@ -89,7 +97,6 @@ impl RenderOnce for Tab {
|
||||
.border_color(cx.theme().transparent)
|
||||
.when(self.selected, |this| this.border_color(cx.theme().border))
|
||||
.text_sm()
|
||||
.when(self.disabled, |this| this)
|
||||
.when_some(self.prefix, |this, prefix| {
|
||||
this.child(prefix).text_color(text_color)
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user