dock: Fix to active prev tab, when current tab is invisible. (#517)
This commit is contained in:
parent
9eba97ddf6
commit
6851e53183
1 changed files with 73 additions and 65 deletions
|
|
@ -24,12 +24,13 @@ use super::{
|
||||||
StackPanel, ToggleZoom,
|
StackPanel, ToggleZoom,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone)]
|
||||||
struct TabState {
|
struct TabState {
|
||||||
closable: bool,
|
closable: bool,
|
||||||
zoomable: bool,
|
zoomable: bool,
|
||||||
draggable: bool,
|
draggable: bool,
|
||||||
droppable: bool,
|
droppable: bool,
|
||||||
|
active_panel: Option<Arc<dyn PanelView>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
@ -378,7 +379,7 @@ impl TabPanel {
|
||||||
!self.is_locked(cx)
|
!self.is_locked(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_toolbar(&self, state: TabState, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
fn render_toolbar(&self, state: &TabState, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||||
let is_zoomed = self.is_zoomed && state.zoomable;
|
let is_zoomed = self.is_zoomed && state.zoomable;
|
||||||
let view = cx.view().clone();
|
let view = cx.view().clone();
|
||||||
let build_popup_menu = move |this, cx: &WindowContext| view.read(cx).popup_menu(this, cx);
|
let build_popup_menu = move |this, cx: &WindowContext| view.read(cx).popup_menu(this, cx);
|
||||||
|
|
@ -411,20 +412,25 @@ impl TabPanel {
|
||||||
.icon(IconName::Ellipsis)
|
.icon(IconName::Ellipsis)
|
||||||
.xsmall()
|
.xsmall()
|
||||||
.ghost()
|
.ghost()
|
||||||
.popup_menu(move |this, cx| {
|
.popup_menu({
|
||||||
build_popup_menu(this, cx)
|
let zoomable = state.zoomable;
|
||||||
.when(state.zoomable, |this| {
|
let closable = state.closable;
|
||||||
let name = if is_zoomed {
|
|
||||||
t!("Dock.Zoom Out")
|
move |this, cx| {
|
||||||
} else {
|
build_popup_menu(this, cx)
|
||||||
t!("Dock.Zoom In")
|
.when(zoomable, |this| {
|
||||||
};
|
let name = if is_zoomed {
|
||||||
this.separator().menu(name, Box::new(ToggleZoom))
|
t!("Dock.Zoom Out")
|
||||||
})
|
} else {
|
||||||
.when(state.closable, |this| {
|
t!("Dock.Zoom In")
|
||||||
this.separator()
|
};
|
||||||
.menu(t!("Dock.Close"), Box::new(ClosePanel))
|
this.separator().menu(name, Box::new(ToggleZoom))
|
||||||
})
|
})
|
||||||
|
.when(closable, |this| {
|
||||||
|
this.separator()
|
||||||
|
.menu(t!("Dock.Close"), Box::new(ClosePanel))
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.anchor(Corner::TopRight),
|
.anchor(Corner::TopRight),
|
||||||
)
|
)
|
||||||
|
|
@ -511,7 +517,7 @@ impl TabPanel {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_title_bar(&self, state: TabState, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
fn render_title_bar(&self, state: &TabState, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||||
let view = cx.view().clone();
|
let view = cx.view().clone();
|
||||||
|
|
||||||
let Some(dock_area) = self.dock_area.upgrade() else {
|
let Some(dock_area) = self.dock_area.upgrade() else {
|
||||||
|
|
@ -584,7 +590,7 @@ impl TabPanel {
|
||||||
.flex_shrink_0()
|
.flex_shrink_0()
|
||||||
.ml_1()
|
.ml_1()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.child(self.render_toolbar(state, cx))
|
.child(self.render_toolbar(&state, cx))
|
||||||
.children(right_dock_button),
|
.children(right_dock_button),
|
||||||
)
|
)
|
||||||
.into_any_element();
|
.into_any_element();
|
||||||
|
|
@ -615,7 +621,7 @@ impl TabPanel {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.children(self.panels.iter().enumerate().filter_map(|(ix, panel)| {
|
.children(self.panels.iter().enumerate().filter_map(|(ix, panel)| {
|
||||||
let mut active = ix == self.active_ix;
|
let mut active = state.active_panel.as_ref() == Some(panel);
|
||||||
let disabled = self.is_collapsed;
|
let disabled = self.is_collapsed;
|
||||||
|
|
||||||
if !panel.visible(cx) {
|
if !panel.visible(cx) {
|
||||||
|
|
@ -702,56 +708,56 @@ impl TabPanel {
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_active_panel(&self, state: TabState, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
fn render_active_panel(
|
||||||
|
&self,
|
||||||
|
state: &TabState,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) -> impl IntoElement {
|
||||||
if self.is_collapsed {
|
if self.is_collapsed {
|
||||||
return Empty {}.into_any_element();
|
return Empty {}.into_any_element();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.active_panel(cx)
|
let Some(active_panel) = state.active_panel.as_ref() else {
|
||||||
.map(|panel| {
|
return Empty {}.into_any_element();
|
||||||
div()
|
};
|
||||||
.id("tab-content")
|
|
||||||
.group("")
|
div()
|
||||||
.overflow_y_scroll()
|
.id("tab-content")
|
||||||
.overflow_x_hidden()
|
.group("")
|
||||||
.flex_1()
|
.overflow_y_scroll()
|
||||||
.child(panel.view())
|
.overflow_x_hidden()
|
||||||
.when(state.droppable, |this| {
|
.flex_1()
|
||||||
this.on_drag_move(cx.listener(Self::on_panel_drag_move))
|
.child(active_panel.view())
|
||||||
.child(
|
.when(state.droppable, |this| {
|
||||||
div()
|
this.on_drag_move(cx.listener(Self::on_panel_drag_move))
|
||||||
.invisible()
|
.child(
|
||||||
.absolute()
|
div()
|
||||||
.bg(cx.theme().drop_target)
|
.invisible()
|
||||||
.map(|this| match self.will_split_placement {
|
.absolute()
|
||||||
Some(placement) => {
|
.bg(cx.theme().drop_target)
|
||||||
let size = DefiniteLength::Fraction(0.35);
|
.map(|this| match self.will_split_placement {
|
||||||
match placement {
|
Some(placement) => {
|
||||||
Placement::Left => {
|
let size = DefiniteLength::Fraction(0.35);
|
||||||
this.left_0().top_0().bottom_0().w(size)
|
match placement {
|
||||||
}
|
Placement::Left => this.left_0().top_0().bottom_0().w(size),
|
||||||
Placement::Right => {
|
Placement::Right => {
|
||||||
this.right_0().top_0().bottom_0().w(size)
|
this.right_0().top_0().bottom_0().w(size)
|
||||||
}
|
|
||||||
Placement::Top => {
|
|
||||||
this.top_0().left_0().right_0().h(size)
|
|
||||||
}
|
|
||||||
Placement::Bottom => {
|
|
||||||
this.bottom_0().left_0().right_0().h(size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None => this.top_0().left_0().size_full(),
|
Placement::Top => this.top_0().left_0().right_0().h(size),
|
||||||
})
|
Placement::Bottom => {
|
||||||
.group_drag_over::<DragPanel>("", |this| this.visible())
|
this.bottom_0().left_0().right_0().h(size)
|
||||||
.on_drop(cx.listener(|this, drag: &DragPanel, cx| {
|
}
|
||||||
this.on_drop(drag, None, true, cx)
|
}
|
||||||
})),
|
}
|
||||||
)
|
None => this.top_0().left_0().size_full(),
|
||||||
})
|
})
|
||||||
.into_any_element()
|
.group_drag_over::<DragPanel>("", |this| this.visible())
|
||||||
|
.on_drop(cx.listener(|this, drag: &DragPanel, cx| {
|
||||||
|
this.on_drop(drag, None, true, cx)
|
||||||
|
})),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.unwrap_or(Empty {}.into_any_element())
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate the split direction based on the current mouse position
|
/// Calculate the split direction based on the current mouse position
|
||||||
|
|
@ -976,11 +982,13 @@ impl EventEmitter<PanelEvent> for TabPanel {}
|
||||||
impl Render for TabPanel {
|
impl Render for TabPanel {
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl gpui::IntoElement {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl gpui::IntoElement {
|
||||||
let focus_handle = self.focus_handle(cx);
|
let focus_handle = self.focus_handle(cx);
|
||||||
|
let active_panel = self.active_panel(cx);
|
||||||
let mut state = TabState {
|
let mut state = TabState {
|
||||||
closable: self.closable(cx),
|
closable: self.closable(cx),
|
||||||
draggable: self.draggable(cx),
|
draggable: self.draggable(cx),
|
||||||
droppable: self.droppable(cx),
|
droppable: self.droppable(cx),
|
||||||
zoomable: self.zoomable(cx),
|
zoomable: self.zoomable(cx),
|
||||||
|
active_panel,
|
||||||
};
|
};
|
||||||
if !state.draggable {
|
if !state.draggable {
|
||||||
state.closable = false;
|
state.closable = false;
|
||||||
|
|
@ -994,7 +1002,7 @@ impl Render for TabPanel {
|
||||||
.size_full()
|
.size_full()
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.bg(cx.theme().background)
|
.bg(cx.theme().background)
|
||||||
.child(self.render_title_bar(state, cx))
|
.child(self.render_title_bar(&state, cx))
|
||||||
.child(self.render_active_panel(state, cx))
|
.child(self.render_active_panel(&state, cx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue