Add split controls row
This commit is contained in:
@@ -5,7 +5,10 @@ use gpui::{
|
|||||||
AnyElement, Context, InteractiveElement, IntoElement, ParentElement, SharedString,
|
AnyElement, Context, InteractiveElement, IntoElement, ParentElement, SharedString,
|
||||||
StatefulInteractiveElement, Styled, Window, div, px, rgb,
|
StatefulInteractiveElement, Styled, Window, div, px, rgb,
|
||||||
};
|
};
|
||||||
use gpui_component::{IconName, StyledExt};
|
use gpui_component::{
|
||||||
|
IconName, Sizable, StyledExt,
|
||||||
|
button::{Button, ButtonVariants},
|
||||||
|
};
|
||||||
|
|
||||||
use super::{ElyShell, ShellState};
|
use super::{ElyShell, ShellState};
|
||||||
use crate::SplitRight;
|
use crate::SplitRight;
|
||||||
@@ -47,6 +50,57 @@ impl ElyShell {
|
|||||||
self.split_right(window, cx);
|
self.split_right(window, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn swap_active_split_pane(&mut self, cx: &mut Context<Self>) {
|
||||||
|
if let ShellState::Ready(core) = &mut self.state
|
||||||
|
&& core.swap_active_split_pane().is_ok_and(|swapped| swapped)
|
||||||
|
{
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn duplicate_active_split_pane(
|
||||||
|
&mut self,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
if let ShellState::Ready(core) = &mut self.state
|
||||||
|
&& core.duplicate_active_split_pane().is_ok_and(|tab_id| tab_id.is_some())
|
||||||
|
{
|
||||||
|
self.sync_address_input(window, cx);
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn detach_active_split_pane(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
if let ShellState::Ready(core) = &mut self.state
|
||||||
|
&& core.detach_active_split_pane().is_ok_and(|detached| detached)
|
||||||
|
{
|
||||||
|
self.sync_address_input(window, cx);
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn save_active_split_view(&mut self, cx: &mut Context<Self>) {
|
||||||
|
if let ShellState::Ready(core) = &mut self.state
|
||||||
|
&& core.save_active_split_view().is_ok_and(|split_id| split_id.is_some())
|
||||||
|
{
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn close_active_saved_split_view(
|
||||||
|
&mut self,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
if let ShellState::Ready(core) = &mut self.state
|
||||||
|
&& core.close_active_saved_split_view().is_ok_and(|tab_id| tab_id.is_some())
|
||||||
|
{
|
||||||
|
self.sync_address_input(window, cx);
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn render_split_canvas(
|
fn render_split_canvas(
|
||||||
&mut self,
|
&mut self,
|
||||||
snapshot: &BrowserSnapshot,
|
snapshot: &BrowserSnapshot,
|
||||||
@@ -70,31 +124,29 @@ impl ElyShell {
|
|||||||
.min_w_0()
|
.min_w_0()
|
||||||
.p_3()
|
.p_3()
|
||||||
.gap_3()
|
.gap_3()
|
||||||
.overflow_hidden()
|
|
||||||
.bg(rgb(colors::CANVAS));
|
|
||||||
|
|
||||||
match layout.axis() {
|
|
||||||
SplitAxis::Horizontal => body
|
|
||||||
.flex()
|
|
||||||
.children(
|
|
||||||
panes
|
|
||||||
.into_iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(index, tab)| self.render_split_pane(index, tab, snapshot, cx)),
|
|
||||||
)
|
|
||||||
.into_any_element(),
|
|
||||||
SplitAxis::Vertical => body
|
|
||||||
.flex()
|
.flex()
|
||||||
.flex_col()
|
.flex_col()
|
||||||
.children(
|
.overflow_hidden()
|
||||||
|
.bg(rgb(colors::CANVAS));
|
||||||
|
let pane_area = div().flex_1().min_h_0().gap_3().overflow_hidden();
|
||||||
|
|
||||||
|
let panes = match layout.axis() {
|
||||||
|
SplitAxis::Horizontal => pane_area.flex().children(
|
||||||
panes
|
panes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(index, tab)| self.render_split_pane(index, tab, snapshot, cx)),
|
.map(|(index, tab)| self.render_split_pane(index, tab, snapshot, cx)),
|
||||||
)
|
),
|
||||||
.into_any_element(),
|
SplitAxis::Vertical => pane_area.flex().flex_col().children(
|
||||||
SplitAxis::Grid => self.render_split_grid(body, panes, snapshot, cx).into_any_element(),
|
panes
|
||||||
}
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(index, tab)| self.render_split_pane(index, tab, snapshot, cx)),
|
||||||
|
),
|
||||||
|
SplitAxis::Grid => self.render_split_grid(pane_area, panes, snapshot, cx),
|
||||||
|
};
|
||||||
|
|
||||||
|
body.child(panes).child(self.render_split_controls(cx)).into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_split_grid(
|
fn render_split_grid(
|
||||||
@@ -184,6 +236,83 @@ impl ElyShell {
|
|||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_split_controls(&mut self, cx: &mut Context<Self>) -> AnyElement {
|
||||||
|
div()
|
||||||
|
.min_h(px(36.0))
|
||||||
|
.px_2()
|
||||||
|
.gap_2()
|
||||||
|
.flex()
|
||||||
|
.items_center()
|
||||||
|
.justify_center()
|
||||||
|
.border_1()
|
||||||
|
.border_color(rgb(colors::HAIRLINE))
|
||||||
|
.rounded_md()
|
||||||
|
.bg(rgb(colors::CANVAS_SOFT))
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.text_xs()
|
||||||
|
.font_semibold()
|
||||||
|
.text_color(rgb(colors::MUTED))
|
||||||
|
.child("Split Controls"),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("swap-split-pane-control")
|
||||||
|
.ghost()
|
||||||
|
.xsmall()
|
||||||
|
.icon(IconName::ArrowRight)
|
||||||
|
.label("Swap")
|
||||||
|
.tooltip("Swap Pane")
|
||||||
|
.on_click(cx.listener(|shell, _, _, cx| {
|
||||||
|
shell.swap_active_split_pane(cx);
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("duplicate-split-pane-control")
|
||||||
|
.ghost()
|
||||||
|
.xsmall()
|
||||||
|
.icon(IconName::Copy)
|
||||||
|
.label("Duplicate")
|
||||||
|
.tooltip("Duplicate Pane")
|
||||||
|
.on_click(cx.listener(|shell, _, window, cx| {
|
||||||
|
shell.duplicate_active_split_pane(window, cx);
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("detach-split-pane-control")
|
||||||
|
.ghost()
|
||||||
|
.xsmall()
|
||||||
|
.icon(IconName::PanelRightOpen)
|
||||||
|
.label("Detach")
|
||||||
|
.tooltip("Detach Pane")
|
||||||
|
.on_click(cx.listener(|shell, _, window, cx| {
|
||||||
|
shell.detach_active_split_pane(window, cx);
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("save-split-view-control")
|
||||||
|
.ghost()
|
||||||
|
.xsmall()
|
||||||
|
.icon(IconName::Check)
|
||||||
|
.label("Save")
|
||||||
|
.tooltip("Save Split View")
|
||||||
|
.on_click(cx.listener(|shell, _, _, cx| {
|
||||||
|
shell.save_active_split_view(cx);
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("close-split-view-control")
|
||||||
|
.ghost()
|
||||||
|
.xsmall()
|
||||||
|
.icon(IconName::Close)
|
||||||
|
.label("Close")
|
||||||
|
.tooltip("Close Saved Split View")
|
||||||
|
.on_click(cx.listener(|shell, _, window, cx| {
|
||||||
|
shell.close_active_saved_split_view(window, cx);
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.into_any_element()
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn render_saved_split_row(
|
pub(super) fn render_saved_split_row(
|
||||||
&mut self,
|
&mut self,
|
||||||
layout: &SplitLayout,
|
layout: &SplitLayout,
|
||||||
|
|||||||
Reference in New Issue
Block a user