History

Restore zoom buttons in pane tab bars, fix + button in the terminal one (#3780)

Release Notes: - N/A

Kirill Bulatov committed 2 years ago

Commit 4e3337f2 parents 061bcf1 420253a2 files · +103 −158Browse files

Unified · Split

2 files
  1. crates/terminal_view2/src/terminal_panel.rs +29 −43
  2. crates/workspace2/src/pane.rs +74 −115
crates/terminal_view2/src/terminal_panel.rs+29−43
@@ -4,13 +4,14 @@ use crate::TerminalView; · 3 unmodified lines
44 use db::kvp::KEY_VALUE_STORE;
55 use gpui::{
66 actions, div, serde_json, AppContext, AsyncWindowContext, Div, Entity, EventEmitter,
7− ExternalPaths, FocusHandle, FocusableView, ParentElement, Render, Styled, Subscription, Task,
8− View, ViewContext, VisualContext, WeakView, WindowContext,
7+ ExternalPaths, FocusHandle, FocusableView, IntoElement, ParentElement, Render, Styled,
8+ Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
99 };
1010 use project::Fs;
1111 use serde::{Deserialize, Serialize};
1212 use settings::{Settings, SettingsStore};
1313 use terminal::terminal_settings::{TerminalDockPosition, TerminalSettings};
14+use ui::{h_stack, ButtonCommon, Clickable, IconButton, IconSize, Selectable, Tooltip};
1415 use util::{ResultExt, TryFutureExt};
1516 use workspace::{
1617 dock::{DockPosition, Panel, PanelEvent},
@@ -51,9 +52,8 @@ pub struct TerminalPanel { · 34 unmodified lines
5152
5253 impl TerminalPanel {
5354 fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
54− let _weak_self = cx.view().downgrade();
55+ let terminal_panel = cx.view().clone();
5556 let pane = cx.build_view(|cx| {
56− let _window = cx.window_handle();
5757 let mut pane = Pane::new(
5858 workspace.weak_handle(),
5959 workspace.project().clone(),
@@ -74,45 +74,31 @@ impl TerminalPanel { · 14 unmodified lines
7474 );
7575 pane.set_can_split(false, cx);
7676 pane.set_can_navigate(false, cx);
77− // todo!()
78− // pane.set_render_tab_bar_buttons(cx, move |pane, cx| {
79− // let this = weak_self.clone();
80− // Flex::row()
81− // .with_child(Pane::render_tab_bar_button(
82− // 0,
83− // "icons/plus.svg",
84− // false,
85− // Some(("New Terminal", Some(Box::new(workspace::NewTerminal)))),
86− // cx,
87− // move |_, cx| {
88− // let this = this.clone();
89− // cx.window_context().defer(move |cx| {
90− // if let Some(this) = this.upgrade() {
91− // this.update(cx, |this, cx| {
92− // this.add_terminal(None, cx);
93− // });
94− // }
95− // })
96− // },
97− // |_, _| {},
98− // None,
99− // ))
100− // .with_child(Pane::render_tab_bar_button(
101− // 1,
102− // if pane.is_zoomed() {
103− // "icons/minimize.svg"
104− // } else {
105− // "icons/maximize.svg"
106− // },
107− // pane.is_zoomed(),
108− // Some(("Toggle Zoom".into(), Some(Box::new(workspace::ToggleZoom)))),
109− // cx,
110− // move |pane, cx| pane.toggle_zoom(&Default::default(), cx),
111− // |_, _| {},
112− // None,
113− // ))
114− // .into_any()
115− // });
77+ pane.set_render_tab_bar_buttons(cx, move |pane, cx| {
78+ h_stack()
79+ .child(
80+ IconButton::new("plus", Icon::Plus)
81+ .icon_size(IconSize::Small)
82+ .on_click(cx.listener_for(&terminal_panel, |terminal_panel, _, cx| {
83+ terminal_panel.add_terminal(None, cx);
84+ }))
85+ .tooltip(|cx| Tooltip::text("New Terminal", cx)),
86+ )
87+ .child({
88+ let zoomed = pane.is_zoomed();
89+ IconButton::new("toggle_zoom", Icon::Maximize)
90+ .icon_size(IconSize::Small)
91+ .selected(zoomed)
92+ .selected_icon(Icon::Minimize)
93+ .on_click(cx.listener(|pane, _, cx| {
94+ pane.toggle_zoom(&workspace::ToggleZoom, cx);
95+ }))
96+ .tooltip(move |cx| {
97+ Tooltip::text(if zoomed { "Zoom Out" } else { "Zoom In" }, cx)
98+ })
99+ })
100+ .into_any_element()
101+ });
116102 // let buffer_search_bar = cx.build_view(search::BufferSearchBar::new);
117103 // pane.toolbar()
118104 // .update(cx, |toolbar, cx| toolbar.add_item(buffer_search_bar, cx));
crates/workspace2/src/pane.rs+74−115
@@ -7,7 +7,7 @@ use crate::{ · 6 unmodified lines
77 use anyhow::Result;
88 use collections::{HashMap, HashSet, VecDeque};
99 use gpui::{
10− actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AppContext,
10+ actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AnyElement, AppContext,
1111 AsyncWindowContext, DismissEvent, Div, DragMoveEvent, EntityId, EventEmitter, FocusHandle,
1212 Focusable, FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel,
1313 Render, ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakView,
@@ -21,6 +21,7 @@ use std::{ · 7 unmodified lines
2121 any::Any,
2222 cmp, fmt, mem,
2323 path::{Path, PathBuf},
24+ rc::Rc,
2425 sync::{
2526 atomic::{AtomicUsize, Ordering},
2627 Arc,
@@ -183,7 +184,7 @@ pub struct Pane { · 156 unmodified lines
183184 drag_split_direction: Option<SplitDirection>,
184185 can_drop_predicate: Option<Arc<dyn Fn(&dyn Any, &mut WindowContext) -> bool>>,
185186 can_split: bool,
186− // render_tab_bar_buttons: Rc<dyn Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement<Pane>>,
187+ render_tab_bar_buttons: Rc<dyn Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement>,
187188 _subscriptions: Vec<Subscription>,
188189 tab_bar_scroll_handle: ScrollHandle,
189190 }
@@ -374,63 +375,66 @@ impl Pane { · 184 unmodified lines
374375 project,
375376 can_drop_predicate,
376377 can_split: true,
377− // render_tab_bar_buttons: Rc::new(move |pane, cx| {
378− // Flex::row()
379− // // New menu
380− // .with_child(Self::render_tab_bar_button(
381− // 0,
382− // "icons/plus.svg",
383− // false,
384− // Some(("New...".into(), None)),
385− // cx,
386− // |pane, cx| pane.deploy_new_menu(cx),
387− // |pane, cx| {
388− // pane.tab_bar_context_menu
389− // .handle
390− // .update(cx, |menu, _| menu.delay_cancel())
391− // },
392− // pane.tab_bar_context_menu
393− // .handle_if_kind(TabBarContextMenuKind::New),
394− // ))
395− // .with_child(Self::render_tab_bar_button(
396− // 1,
397− // "icons/split.svg",
398− // false,
399− // Some(("Split Pane".into(), None)),
400− // cx,
401− // |pane, cx| pane.deploy_split_menu(cx),
402− // |pane, cx| {
403− // pane.tab_bar_context_menu
404− // .handle
405− // .update(cx, |menu, _| menu.delay_cancel())
406− // },
407− // pane.tab_bar_context_menu
408− // .handle_if_kind(TabBarContextMenuKind::Split),
409− // ))
410− // .with_child({
411− // let icon_path;
412− // let tooltip_label;
413− // if pane.is_zoomed() {
414− // icon_path = "icons/minimize.svg";
415− // tooltip_label = "Zoom In";
416− // } else {
417− // icon_path = "icons/maximize.svg";
418− // tooltip_label = "Zoom In";
419− // }
420−
421− // Pane::render_tab_bar_button(
422− // 2,
423− // icon_path,
424− // pane.is_zoomed(),
425− // Some((tooltip_label, Some(Box::new(ToggleZoom)))),
426− // cx,
427− // move |pane, cx| pane.toggle_zoom(&Default::default(), cx),
428− // move |_, _| {},
429− // None,
430− // )
431− // })
432− // .into_any()
433− // }),
378+ render_tab_bar_buttons: Rc::new(move |pane, cx| {
379+ h_stack()
380+ .child(
381+ IconButton::new("plus", Icon::Plus)
382+ .icon_size(IconSize::Small)
383+ .on_click(cx.listener(|pane, _, cx| {
384+ let menu = ContextMenu::build(cx, |menu, _| {
385+ menu.action("New File", NewFile.boxed_clone())
386+ .action("New Terminal", NewCenterTerminal.boxed_clone())
387+ .action("New Search", NewSearch.boxed_clone())
388+ });
389+ cx.subscribe(&menu, |pane, _, _: &DismissEvent, cx| {
390+ pane.focus(cx);
391+ pane.new_item_menu = None;
392+ })
393+ .detach();
394+ pane.new_item_menu = Some(menu);
395+ }))
396+ .tooltip(|cx| Tooltip::text("New...", cx)),
397+ )
398+ .when_some(pane.new_item_menu.as_ref(), |el, new_item_menu| {
399+ el.child(Self::render_menu_overlay(new_item_menu))
400+ })
401+ .child(
402+ IconButton::new("split", Icon::Split)
403+ .icon_size(IconSize::Small)
404+ .on_click(cx.listener(|pane, _, cx| {
405+ let menu = ContextMenu::build(cx, |menu, _| {
406+ menu.action("Split Right", SplitRight.boxed_clone())
407+ .action("Split Left", SplitLeft.boxed_clone())
408+ .action("Split Up", SplitUp.boxed_clone())
409+ .action("Split Down", SplitDown.boxed_clone())
410+ });
411+ cx.subscribe(&menu, |pane, _, _: &DismissEvent, cx| {
412+ pane.focus(cx);
413+ pane.split_item_menu = None;
414+ })
415+ .detach();
416+ pane.split_item_menu = Some(menu);
417+ }))
418+ .tooltip(|cx| Tooltip::text("Split Pane", cx)),
419+ )
420+ .child({
421+ let zoomed = pane.is_zoomed();
422+ IconButton::new("toggle_zoom", Icon::Maximize)
423+ .icon_size(IconSize::Small)
424+ .selected(zoomed)
425+ .selected_icon(Icon::Minimize)
426+ .on_click(cx.listener(|pane, _, cx| {
427+ pane.toggle_zoom(&crate::ToggleZoom, cx);
428+ }))
429+ .tooltip(move |cx| {
430+ Tooltip::text(if zoomed { "Zoom Out" } else { "Zoom In" }, cx)
431+ })
432+ })
433+ .when_some(pane.split_item_menu.as_ref(), |el, split_item_menu| {
434+ el.child(Self::render_menu_overlay(split_item_menu))
435+ })
436+ .into_any_element()
437+ }),
434438 _subscriptions: subscriptions,
435439 }
436440 }
@@ -510,13 +514,13 @@ impl Pane { · 73 unmodified lines
510514 cx.notify();
511515 }
512516
513− // pub fn set_render_tab_bar_buttons<F>(&mut self, cx: &mut ViewContext<Self>, render: F)
514− // where
515− // F: 'static + Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement<Pane>,
516− // {
517− // self.render_tab_bar_buttons = Rc::new(render);
518− // cx.notify();
519− // }
517+ pub fn set_render_tab_bar_buttons<F>(&mut self, cx: &mut ViewContext<Self>, render: F)
518+ where
519+ F: 'static + Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement,
520+ {
521+ self.render_tab_bar_buttons = Rc::new(render);
522+ cx.notify();
523+ }
520524
521525 pub fn nav_history_for_item<T: Item>(&self, item: &View<T>) -> ItemNavHistory {
522526 ItemNavHistory {
@@ -1672,55 +1676,10 @@ impl Pane { · 1149 unmodified lines
16721676 .disabled(!self.can_navigate_forward())
16731677 .tooltip(|cx| Tooltip::for_action("Go Forward", &GoForward, cx)),
16741678 )
1675− .end_child(
1676− div()
1677− .child(
1678− IconButton::new("plus", Icon::Plus)
1679− .icon_size(IconSize::Small)
1680− .on_click(cx.listener(|this, _, cx| {
1681− let menu = ContextMenu::build(cx, |menu, _| {
1682− menu.action("New File", NewFile.boxed_clone())
1683− .action("New Terminal", NewCenterTerminal.boxed_clone())
1684− .action("New Search", NewSearch.boxed_clone())
1685− });
1686− cx.subscribe(&menu, |this, _, _: &DismissEvent, cx| {
1687− this.focus(cx);
1688− this.new_item_menu = None;
1689− })
1690− .detach();
1691− this.new_item_menu = Some(menu);
1692− }))
1693− .tooltip(|cx| Tooltip::text("New...", cx)),
1694− )
1695− .when_some(self.new_item_menu.as_ref(), |el, new_item_menu| {
1696− el.child(Self::render_menu_overlay(new_item_menu))
1697− }),
1698− )
1699− .end_child(
1700− div()
1701− .child(
1702− IconButton::new("split", Icon::Split)
1703− .icon_size(IconSize::Small)
1704− .on_click(cx.listener(|this, _, cx| {
1705− let menu = ContextMenu::build(cx, |menu, _| {
1706− menu.action("Split Right", SplitRight.boxed_clone())
1707− .action("Split Left", SplitLeft.boxed_clone())
1708− .action("Split Up", SplitUp.boxed_clone())
1709− .action("Split Down", SplitDown.boxed_clone())
1710− });
1711− cx.subscribe(&menu, |this, _, _: &DismissEvent, cx| {
1712− this.focus(cx);
1713− this.split_item_menu = None;
1714− })
1715− .detach();
1716− this.split_item_menu = Some(menu);
1717− }))
1718− .tooltip(|cx| Tooltip::text("Split Pane", cx)),
1719− )
1720− .when_some(self.split_item_menu.as_ref(), |el, split_item_menu| {
1721− el.child(Self::render_menu_overlay(split_item_menu))
1722− }),
1723− )
1679+ .end_child({
1680+ let render_tab_buttons = self.render_tab_bar_buttons.clone();
1681+ render_tab_buttons(self, cx)
1682+ })
17241683 .children(
17251684 self.items
17261685 .iter()

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t