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
4use db::kvp::KEY_VALUE_STORE;4use db::kvp::KEY_VALUE_STORE;
5use gpui::{5use gpui::{
6 actions, div, serde_json, AppContext, AsyncWindowContext, Div, Entity, EventEmitter,6 actions, div, serde_json, AppContext, AsyncWindowContext, Div, Entity, EventEmitter,
7 ExternalPaths, FocusHandle, FocusableView, ParentElement, Render, Styled, Subscription, Task,7 ExternalPaths, FocusHandle, FocusableView, IntoElement, ParentElement, Render, Styled,
8 View, ViewContext, VisualContext, WeakView, WindowContext,8 Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
9};9};
10use project::Fs;10use project::Fs;
11use serde::{Deserialize, Serialize};11use serde::{Deserialize, Serialize};
12use settings::{Settings, SettingsStore};12use settings::{Settings, SettingsStore};
13use terminal::terminal_settings::{TerminalDockPosition, TerminalSettings};13use terminal::terminal_settings::{TerminalDockPosition, TerminalSettings};
14use ui::{h_stack, ButtonCommon, Clickable, IconButton, IconSize, Selectable, Tooltip};
14use util::{ResultExt, TryFutureExt};15use util::{ResultExt, TryFutureExt};
15use workspace::{16use workspace::{
16 dock::{DockPosition, Panel, PanelEvent},17 dock::{DockPosition, Panel, PanelEvent},
@@ -51,9 +52,8 @@ pub struct TerminalPanel { · 34 unmodified lines
51 52
52impl TerminalPanel {53impl TerminalPanel {
53 fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {54 fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
54 let _weak_self = cx.view().downgrade();55 let terminal_panel = cx.view().clone();
55 let pane = cx.build_view(|cx| {56 let pane = cx.build_view(|cx| {
56 let _window = cx.window_handle();
57 let mut pane = Pane::new(57 let mut pane = Pane::new(
58 workspace.weak_handle(),58 workspace.weak_handle(),
59 workspace.project().clone(),59 workspace.project().clone(),
@@ -74,45 +74,31 @@ impl TerminalPanel { · 14 unmodified lines
74 );74 );
75 pane.set_can_split(false, cx);75 pane.set_can_split(false, cx);
76 pane.set_can_navigate(false, cx);76 pane.set_can_navigate(false, cx);
77 // todo!()77 pane.set_render_tab_bar_buttons(cx, move |pane, cx| {
78 // pane.set_render_tab_bar_buttons(cx, move |pane, cx| {78 h_stack()
79 // let this = weak_self.clone();79 .child(
80 // Flex::row()80 IconButton::new("plus", Icon::Plus)
81 // .with_child(Pane::render_tab_bar_button(81 .icon_size(IconSize::Small)
82 // 0,82 .on_click(cx.listener_for(&terminal_panel, |terminal_panel, _, cx| {
83 // "icons/plus.svg",83 terminal_panel.add_terminal(None, cx);
84 // false,84 }))
85 // Some(("New Terminal", Some(Box::new(workspace::NewTerminal)))),85 .tooltip(|cx| Tooltip::text("New Terminal", cx)),
86 // cx,86 )
87 // move |_, cx| {87 .child({
88 // let this = this.clone();88 let zoomed = pane.is_zoomed();
89 // cx.window_context().defer(move |cx| {89 IconButton::new("toggle_zoom", Icon::Maximize)
90 // if let Some(this) = this.upgrade() {90 .icon_size(IconSize::Small)
91 // this.update(cx, |this, cx| {91 .selected(zoomed)
92 // this.add_terminal(None, cx);92 .selected_icon(Icon::Minimize)
93 // });93 .on_click(cx.listener(|pane, _, cx| {
94 // }94 pane.toggle_zoom(&workspace::ToggleZoom, cx);
95 // })95 }))
96 // },96 .tooltip(move |cx| {
97 // |_, _| {},97 Tooltip::text(if zoomed { "Zoom Out" } else { "Zoom In" }, cx)
98 // None,98 })
99 // ))99 })
100 // .with_child(Pane::render_tab_bar_button(100 .into_any_element()
101 // 1,101 });
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 // });
116 // let buffer_search_bar = cx.build_view(search::BufferSearchBar::new);102 // let buffer_search_bar = cx.build_view(search::BufferSearchBar::new);
117 // pane.toolbar()103 // pane.toolbar()
118 // .update(cx, |toolbar, cx| toolbar.add_item(buffer_search_bar, cx));104 // .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
7use anyhow::Result;7use anyhow::Result;
8use collections::{HashMap, HashSet, VecDeque};8use collections::{HashMap, HashSet, VecDeque};
9use gpui::{9use gpui::{
10 actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AppContext,10 actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AnyElement, AppContext,
11 AsyncWindowContext, DismissEvent, Div, DragMoveEvent, EntityId, EventEmitter, FocusHandle,11 AsyncWindowContext, DismissEvent, Div, DragMoveEvent, EntityId, EventEmitter, FocusHandle,
12 Focusable, FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel,12 Focusable, FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel,
13 Render, ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakView,13 Render, ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakView,
@@ -21,6 +21,7 @@ use std::{ · 7 unmodified lines
21 any::Any,21 any::Any,
22 cmp, fmt, mem,22 cmp, fmt, mem,
23 path::{Path, PathBuf},23 path::{Path, PathBuf},
24 rc::Rc,
24 sync::{25 sync::{
25 atomic::{AtomicUsize, Ordering},26 atomic::{AtomicUsize, Ordering},
26 Arc,27 Arc,
@@ -183,7 +184,7 @@ pub struct Pane { · 156 unmodified lines
183 drag_split_direction: Option<SplitDirection>,184 drag_split_direction: Option<SplitDirection>,
184 can_drop_predicate: Option<Arc<dyn Fn(&dyn Any, &mut WindowContext) -> bool>>,185 can_drop_predicate: Option<Arc<dyn Fn(&dyn Any, &mut WindowContext) -> bool>>,
185 can_split: bool,186 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>,
187 _subscriptions: Vec<Subscription>,188 _subscriptions: Vec<Subscription>,
188 tab_bar_scroll_handle: ScrollHandle,189 tab_bar_scroll_handle: ScrollHandle,
189}190}
@@ -374,63 +375,66 @@ impl Pane { · 184 unmodified lines
374 project,375 project,
375 can_drop_predicate,376 can_drop_predicate,
376 can_split: true,377 can_split: true,
377 // render_tab_bar_buttons: Rc::new(move |pane, cx| {378 render_tab_bar_buttons: Rc::new(move |pane, cx| {
378 // Flex::row()379 h_stack()
379 // // New menu380 .child(
380 // .with_child(Self::render_tab_bar_button(381 IconButton::new("plus", Icon::Plus)
381 // 0,382 .icon_size(IconSize::Small)
382 // "icons/plus.svg",383 .on_click(cx.listener(|pane, _, cx| {
383 // false,384 let menu = ContextMenu::build(cx, |menu, _| {
384 // Some(("New...".into(), None)),385 menu.action("New File", NewFile.boxed_clone())
385 // cx,386 .action("New Terminal", NewCenterTerminal.boxed_clone())
386 // |pane, cx| pane.deploy_new_menu(cx),387 .action("New Search", NewSearch.boxed_clone())
387 // |pane, cx| {388 });
388 // pane.tab_bar_context_menu389 cx.subscribe(&menu, |pane, _, _: &DismissEvent, cx| {
389 // .handle390 pane.focus(cx);
390 // .update(cx, |menu, _| menu.delay_cancel())391 pane.new_item_menu = None;
391 // },392 })
392 // pane.tab_bar_context_menu393 .detach();
393 // .handle_if_kind(TabBarContextMenuKind::New),394 pane.new_item_menu = Some(menu);
394 // ))395 }))
395 // .with_child(Self::render_tab_bar_button(396 .tooltip(|cx| Tooltip::text("New...", cx)),
396 // 1,397 )
397 // "icons/split.svg",398 .when_some(pane.new_item_menu.as_ref(), |el, new_item_menu| {
398 // false,399 el.child(Self::render_menu_overlay(new_item_menu))
399 // Some(("Split Pane".into(), None)),400 })
400 // cx,401 .child(
401 // |pane, cx| pane.deploy_split_menu(cx),402 IconButton::new("split", Icon::Split)
402 // |pane, cx| {403 .icon_size(IconSize::Small)
403 // pane.tab_bar_context_menu404 .on_click(cx.listener(|pane, _, cx| {
404 // .handle405 let menu = ContextMenu::build(cx, |menu, _| {
405 // .update(cx, |menu, _| menu.delay_cancel())406 menu.action("Split Right", SplitRight.boxed_clone())
406 // },407 .action("Split Left", SplitLeft.boxed_clone())
407 // pane.tab_bar_context_menu408 .action("Split Up", SplitUp.boxed_clone())
408 // .handle_if_kind(TabBarContextMenuKind::Split),409 .action("Split Down", SplitDown.boxed_clone())
409 // ))410 });
410 // .with_child({411 cx.subscribe(&menu, |pane, _, _: &DismissEvent, cx| {
411 // let icon_path;412 pane.focus(cx);
412 // let tooltip_label;413 pane.split_item_menu = None;
413 // if pane.is_zoomed() {414 })
414 // icon_path = "icons/minimize.svg";415 .detach();
415 // tooltip_label = "Zoom In";416 pane.split_item_menu = Some(menu);
416 // } else {417 }))
417 // icon_path = "icons/maximize.svg";418 .tooltip(|cx| Tooltip::text("Split Pane", cx)),
418 // tooltip_label = "Zoom In";419 )
419 // }420 .child({
420 421 let zoomed = pane.is_zoomed();
421 // Pane::render_tab_bar_button(422 IconButton::new("toggle_zoom", Icon::Maximize)
422 // 2,423 .icon_size(IconSize::Small)
423 // icon_path,424 .selected(zoomed)
424 // pane.is_zoomed(),425 .selected_icon(Icon::Minimize)
425 // Some((tooltip_label, Some(Box::new(ToggleZoom)))),426 .on_click(cx.listener(|pane, _, cx| {
426 // cx,427 pane.toggle_zoom(&crate::ToggleZoom, cx);
427 // move |pane, cx| pane.toggle_zoom(&Default::default(), cx),428 }))
428 // move |_, _| {},429 .tooltip(move |cx| {
429 // None,430 Tooltip::text(if zoomed { "Zoom Out" } else { "Zoom In" }, cx)
430 // )431 })
431 // })432 })
432 // .into_any()433 .when_some(pane.split_item_menu.as_ref(), |el, split_item_menu| {
433 // }),434 el.child(Self::render_menu_overlay(split_item_menu))
435 })
436 .into_any_element()
437 }),
434 _subscriptions: subscriptions,438 _subscriptions: subscriptions,
435 }439 }
436 }440 }
@@ -510,13 +514,13 @@ impl Pane { · 73 unmodified lines
510 cx.notify();514 cx.notify();
511 }515 }
512 516
513 // pub fn set_render_tab_bar_buttons<F>(&mut self, cx: &mut ViewContext<Self>, render: F)517 pub fn set_render_tab_bar_buttons<F>(&mut self, cx: &mut ViewContext<Self>, render: F)
514 // where518 where
515 // F: 'static + Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement<Pane>,519 F: 'static + Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement,
516 // {520 {
517 // self.render_tab_bar_buttons = Rc::new(render);521 self.render_tab_bar_buttons = Rc::new(render);
518 // cx.notify();522 cx.notify();
519 // }523 }
520 524
521 pub fn nav_history_for_item<T: Item>(&self, item: &View<T>) -> ItemNavHistory {525 pub fn nav_history_for_item<T: Item>(&self, item: &View<T>) -> ItemNavHistory {
522 ItemNavHistory {526 ItemNavHistory {
@@ -1672,55 +1676,10 @@ impl Pane { · 1149 unmodified lines
1672 .disabled(!self.can_navigate_forward())1676 .disabled(!self.can_navigate_forward())
1673 .tooltip(|cx| Tooltip::for_action("Go Forward", &GoForward, cx)),1677 .tooltip(|cx| Tooltip::for_action("Go Forward", &GoForward, cx)),
1674 )1678 )
1675 .end_child(1679 .end_child({
1676 div()1680 let render_tab_buttons = self.render_tab_bar_buttons.clone();
1677 .child(1681 render_tab_buttons(self, cx)
1678 IconButton::new("plus", Icon::Plus)1682 })
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 )
1724 .children(1683 .children(
1725 self.items1684 self.items
1726 .iter()1685 .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