Allow customization of Pane
tab bar buttons
This commit is contained in:
parent
ad7f32d7d2
commit
634b699281
2 changed files with 114 additions and 86 deletions
|
@ -21,6 +21,7 @@ pub struct TerminalPanel {
|
||||||
|
|
||||||
impl TerminalPanel {
|
impl TerminalPanel {
|
||||||
pub fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
|
pub fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
|
||||||
|
let this = 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();
|
||||||
let mut pane = Pane::new(
|
let mut pane = Pane::new(
|
||||||
|
@ -36,6 +37,23 @@ impl TerminalPanel {
|
||||||
item.handle.act_as::<TerminalView>(cx).is_some()
|
item.handle.act_as::<TerminalView>(cx).is_some()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
pane.set_render_tab_bar_buttons(cx, move |_, cx| {
|
||||||
|
let this = this.clone();
|
||||||
|
Pane::render_tab_bar_button(
|
||||||
|
0,
|
||||||
|
"icons/plus_12.svg",
|
||||||
|
cx,
|
||||||
|
move |_, cx| {
|
||||||
|
let this = this.clone();
|
||||||
|
cx.window_context().defer(move |cx| {
|
||||||
|
if let Some(this) = this.upgrade(cx) {
|
||||||
|
this.update(cx, |this, cx| this.add_terminal(cx));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
});
|
||||||
pane
|
pane
|
||||||
});
|
});
|
||||||
let subscriptions = vec![
|
let subscriptions = vec![
|
||||||
|
@ -61,6 +79,33 @@ impl TerminalPanel {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_terminal(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
|
if let Some(workspace) = self.workspace.upgrade(cx) {
|
||||||
|
let working_directory_strategy = cx
|
||||||
|
.global::<Settings>()
|
||||||
|
.terminal_overrides
|
||||||
|
.working_directory
|
||||||
|
.clone()
|
||||||
|
.unwrap_or(WorkingDirectory::CurrentProjectDirectory);
|
||||||
|
let working_directory =
|
||||||
|
crate::get_working_directory(workspace.read(cx), cx, working_directory_strategy);
|
||||||
|
let window_id = cx.window_id();
|
||||||
|
if let Some(terminal) = self.project.update(cx, |project, cx| {
|
||||||
|
project
|
||||||
|
.create_terminal(working_directory, window_id, cx)
|
||||||
|
.log_err()
|
||||||
|
}) {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
let terminal =
|
||||||
|
Box::new(cx.add_view(|cx| {
|
||||||
|
TerminalView::new(terminal, workspace.database_id(), cx)
|
||||||
|
}));
|
||||||
|
Pane::add_item(workspace, &self.pane, terminal, true, true, None, cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for TerminalPanel {
|
impl Entity for TerminalPanel {
|
||||||
|
@ -78,32 +123,7 @@ impl View for TerminalPanel {
|
||||||
|
|
||||||
fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
|
fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
|
||||||
if self.pane.read(cx).items_len() == 0 {
|
if self.pane.read(cx).items_len() == 0 {
|
||||||
if let Some(workspace) = self.workspace.upgrade(cx) {
|
self.add_terminal(cx)
|
||||||
let working_directory_strategy = cx
|
|
||||||
.global::<Settings>()
|
|
||||||
.terminal_overrides
|
|
||||||
.working_directory
|
|
||||||
.clone()
|
|
||||||
.unwrap_or(WorkingDirectory::CurrentProjectDirectory);
|
|
||||||
let working_directory = crate::get_working_directory(
|
|
||||||
workspace.read(cx),
|
|
||||||
cx,
|
|
||||||
working_directory_strategy,
|
|
||||||
);
|
|
||||||
let window_id = cx.window_id();
|
|
||||||
if let Some(terminal) = self.project.update(cx, |project, cx| {
|
|
||||||
project
|
|
||||||
.create_terminal(working_directory, window_id, cx)
|
|
||||||
.log_err()
|
|
||||||
}) {
|
|
||||||
workspace.update(cx, |workspace, cx| {
|
|
||||||
let terminal = Box::new(cx.add_view(|cx| {
|
|
||||||
TerminalView::new(terminal, workspace.database_id(), cx)
|
|
||||||
}));
|
|
||||||
Pane::add_item(workspace, &self.pane, terminal, true, true, None, cx);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,7 @@ pub struct Pane {
|
||||||
has_focus: bool,
|
has_focus: bool,
|
||||||
can_drop: Rc<dyn Fn(&DragAndDrop<Workspace>, &WindowContext) -> bool>,
|
can_drop: Rc<dyn Fn(&DragAndDrop<Workspace>, &WindowContext) -> bool>,
|
||||||
can_split: bool,
|
can_split: bool,
|
||||||
|
render_tab_bar_buttons: Rc<dyn Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement<Pane>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ItemNavHistory {
|
pub struct ItemNavHistory {
|
||||||
|
@ -257,6 +258,27 @@ impl Pane {
|
||||||
has_focus: false,
|
has_focus: false,
|
||||||
can_drop: Rc::new(|_, _| true),
|
can_drop: Rc::new(|_, _| true),
|
||||||
can_split: true,
|
can_split: true,
|
||||||
|
render_tab_bar_buttons: Rc::new(|pane, cx| {
|
||||||
|
Flex::row()
|
||||||
|
// New menu
|
||||||
|
.with_child(Self::render_tab_bar_button(
|
||||||
|
0,
|
||||||
|
"icons/plus_12.svg",
|
||||||
|
cx,
|
||||||
|
|pane, cx| pane.deploy_new_menu(cx),
|
||||||
|
pane.tab_bar_context_menu
|
||||||
|
.handle_if_kind(TabBarContextMenuKind::New),
|
||||||
|
))
|
||||||
|
.with_child(Self::render_tab_bar_button(
|
||||||
|
2,
|
||||||
|
"icons/split_12.svg",
|
||||||
|
cx,
|
||||||
|
|pane, cx| pane.deploy_split_menu(cx),
|
||||||
|
pane.tab_bar_context_menu
|
||||||
|
.handle_if_kind(TabBarContextMenuKind::Split),
|
||||||
|
))
|
||||||
|
.into_any()
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,6 +311,14 @@ impl Pane {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_render_tab_bar_buttons<F>(&mut self, cx: &mut ViewContext<Self>, render: F)
|
||||||
|
where
|
||||||
|
F: 'static + Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement<Pane>,
|
||||||
|
{
|
||||||
|
self.render_tab_bar_buttons = Rc::new(render);
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn nav_history_for_item<T: Item>(&self, item: &ViewHandle<T>) -> ItemNavHistory {
|
pub fn nav_history_for_item<T: Item>(&self, item: &ViewHandle<T>) -> ItemNavHistory {
|
||||||
ItemNavHistory {
|
ItemNavHistory {
|
||||||
history: self.nav_history.clone(),
|
history: self.nav_history.clone(),
|
||||||
|
@ -1475,33 +1505,37 @@ impl Pane {
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_tab_bar_buttons(
|
pub fn render_tab_bar_button<F: 'static + Fn(&mut Pane, &mut EventContext<Pane>)>(
|
||||||
&mut self,
|
index: usize,
|
||||||
theme: &Theme,
|
icon: &'static str,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Pane>,
|
||||||
) -> AnyElement<Self> {
|
on_click: F,
|
||||||
Flex::row()
|
context_menu: Option<ViewHandle<ContextMenu>>,
|
||||||
// New menu
|
) -> AnyElement<Pane> {
|
||||||
.with_child(render_tab_bar_button(
|
enum TabBarButton {}
|
||||||
0,
|
|
||||||
"icons/plus_12.svg",
|
Stack::new()
|
||||||
cx,
|
.with_child(
|
||||||
|pane, cx| pane.deploy_new_menu(cx),
|
MouseEventHandler::<TabBarButton, _>::new(index, cx, |mouse_state, cx| {
|
||||||
self.tab_bar_context_menu
|
let theme = &cx.global::<Settings>().theme.workspace.tab_bar;
|
||||||
.handle_if_kind(TabBarContextMenuKind::New),
|
let style = theme.pane_button.style_for(mouse_state, false);
|
||||||
))
|
Svg::new(icon)
|
||||||
.with_child(render_tab_bar_button(
|
.with_color(style.color)
|
||||||
2,
|
.constrained()
|
||||||
"icons/split_12.svg",
|
.with_width(style.icon_width)
|
||||||
cx,
|
.aligned()
|
||||||
|pane, cx| pane.deploy_split_menu(cx),
|
.constrained()
|
||||||
self.tab_bar_context_menu
|
.with_width(style.button_width)
|
||||||
.handle_if_kind(TabBarContextMenuKind::Split),
|
.with_height(style.button_width)
|
||||||
))
|
})
|
||||||
.contained()
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.with_style(theme.workspace.tab_bar.pane_button_container)
|
.on_click(MouseButton::Left, move |_, pane, cx| on_click(pane, cx)),
|
||||||
|
)
|
||||||
|
.with_children(
|
||||||
|
context_menu.map(|menu| ChildView::new(&menu, cx).aligned().bottom().right()),
|
||||||
|
)
|
||||||
.flex(1., false)
|
.flex(1., false)
|
||||||
.into_any()
|
.into_any_named("tab bar button")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_blank_pane(&self, theme: &Theme, _cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
fn render_blank_pane(&self, theme: &Theme, _cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
||||||
|
@ -1554,7 +1588,14 @@ impl View for Pane {
|
||||||
.with_child(self.render_tabs(cx).flex(1., true).into_any_named("tabs"));
|
.with_child(self.render_tabs(cx).flex(1., true).into_any_named("tabs"));
|
||||||
|
|
||||||
if self.is_active {
|
if self.is_active {
|
||||||
tab_row.add_child(self.render_tab_bar_buttons(&theme, cx))
|
let render_tab_bar_buttons = self.render_tab_bar_buttons.clone();
|
||||||
|
tab_row.add_child(
|
||||||
|
(render_tab_bar_buttons)(self, cx)
|
||||||
|
.contained()
|
||||||
|
.with_style(theme.workspace.tab_bar.pane_button_container)
|
||||||
|
.flex(1., false)
|
||||||
|
.into_any(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
stack.add_child(tab_row);
|
stack.add_child(tab_row);
|
||||||
|
@ -1676,39 +1717,6 @@ impl View for Pane {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_tab_bar_button<F: 'static + Fn(&mut Pane, &mut EventContext<Pane>)>(
|
|
||||||
index: usize,
|
|
||||||
icon: &'static str,
|
|
||||||
cx: &mut ViewContext<Pane>,
|
|
||||||
on_click: F,
|
|
||||||
context_menu: Option<ViewHandle<ContextMenu>>,
|
|
||||||
) -> AnyElement<Pane> {
|
|
||||||
enum TabBarButton {}
|
|
||||||
|
|
||||||
Stack::new()
|
|
||||||
.with_child(
|
|
||||||
MouseEventHandler::<TabBarButton, _>::new(index, cx, |mouse_state, cx| {
|
|
||||||
let theme = &cx.global::<Settings>().theme.workspace.tab_bar;
|
|
||||||
let style = theme.pane_button.style_for(mouse_state, false);
|
|
||||||
Svg::new(icon)
|
|
||||||
.with_color(style.color)
|
|
||||||
.constrained()
|
|
||||||
.with_width(style.icon_width)
|
|
||||||
.aligned()
|
|
||||||
.constrained()
|
|
||||||
.with_width(style.button_width)
|
|
||||||
.with_height(style.button_width)
|
|
||||||
})
|
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
|
||||||
.on_click(MouseButton::Left, move |_, pane, cx| on_click(pane, cx)),
|
|
||||||
)
|
|
||||||
.with_children(
|
|
||||||
context_menu.map(|menu| ChildView::new(&menu, cx).aligned().bottom().right()),
|
|
||||||
)
|
|
||||||
.flex(1., false)
|
|
||||||
.into_any_named("tab bar button")
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ItemNavHistory {
|
impl ItemNavHistory {
|
||||||
pub fn push<D: 'static + Any>(&self, data: Option<D>, cx: &mut WindowContext) {
|
pub fn push<D: 'static + Any>(&self, data: Option<D>, cx: &mut WindowContext) {
|
||||||
self.history.borrow_mut().push(data, self.item.clone(), cx);
|
self.history.borrow_mut().push(data, self.item.clone(), cx);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue