Skip to content

Commit

Permalink
dock: Add PanelControl for pinning the toolbar button (#537)
Browse files Browse the repository at this point in the history
  • Loading branch information
madcodelife committed Jan 9, 2025
1 parent de42cc4 commit ceba66c
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 43 deletions.
5 changes: 3 additions & 2 deletions crates/story/src/icon_story.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use gpui::{
};
use ui::{
button::{Button, ButtonVariant, ButtonVariants},
dock::PanelControl,
h_flex,
theme::ActiveTheme as _,
v_flex, Icon, IconName,
Expand Down Expand Up @@ -33,8 +34,8 @@ impl super::Story for IconStory {
Self::view(cx)
}

fn zoomable() -> bool {
false
fn zoomable() -> Option<PanelControl> {
None
}
}

Expand Down
6 changes: 5 additions & 1 deletion crates/story/src/image_story.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use gpui::{px, ParentElement as _, Render, Styled, View, VisualContext as _, WindowContext};
use ui::{h_flex, v_flex, SvgImg};
use ui::{dock::PanelControl, h_flex, v_flex, SvgImg};

const GOOGLE_LOGO: &str = include_str!("./fixtures/google.svg");
const PIE_JSON: &str = include_str!("./fixtures/pie.json");
Expand All @@ -19,6 +19,10 @@ impl super::Story for ImageStory {
fn new_view(cx: &mut WindowContext) -> View<impl gpui::FocusableView> {
Self::view(cx)
}

fn zoomable() -> Option<PanelControl> {
Some(PanelControl::Toolbar)
}
}

impl ImageStory {
Expand Down
20 changes: 13 additions & 7 deletions crates/story/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use gpui::{
use ui::{
button::Button,
divider::Divider,
dock::{register_panel, Panel, PanelEvent, PanelInfo, PanelState, TitleStyle},
dock::{register_panel, Panel, PanelControl, PanelEvent, PanelInfo, PanelState, TitleStyle},
h_flex,
label::Label,
notification::Notification,
Expand Down Expand Up @@ -147,7 +147,7 @@ pub struct StoryContainer {
story: Option<AnyView>,
story_klass: Option<SharedString>,
closable: bool,
zoomable: bool,
zoomable: Option<PanelControl>,
}

#[derive(Debug)]
Expand All @@ -167,8 +167,8 @@ pub trait Story: FocusableView {
fn closable() -> bool {
true
}
fn zoomable() -> bool {
true
fn zoomable() -> Option<PanelControl> {
Some(PanelControl::default())
}
fn title_bg() -> Option<Hsla> {
None
Expand All @@ -192,7 +192,7 @@ impl StoryContainer {
story: None,
story_klass: None,
closable: true,
zoomable: true,
zoomable: Some(PanelControl::default()),
}
}

Expand Down Expand Up @@ -260,7 +260,13 @@ impl StoryState {
fn to_story(
&self,
cx: &mut WindowContext,
) -> (&'static str, &'static str, bool, bool, AnyView) {
) -> (
&'static str,
&'static str,
bool,
Option<PanelControl>,
AnyView,
) {
macro_rules! story {
($klass:tt) => {
(
Expand Down Expand Up @@ -324,7 +330,7 @@ impl Panel for StoryContainer {
self.closable
}

fn zoomable(&self, _cx: &AppContext) -> bool {
fn zoomable(&self, _cx: &AppContext) -> Option<PanelControl> {
self.zoomable
}

Expand Down
4 changes: 0 additions & 4 deletions crates/story/src/sidebar_story.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,6 @@ impl super::Story for SidebarStory {
fn new_view(cx: &mut WindowContext) -> View<impl gpui::FocusableView> {
Self::view(cx)
}

fn zoomable() -> bool {
true
}
}
impl gpui::FocusableView for SidebarStory {
fn focus_handle(&self, _: &gpui::AppContext) -> gpui::FocusHandle {
Expand Down
5 changes: 3 additions & 2 deletions crates/story/src/tooltip_story.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use gpui::{
use ui::{
button::{Button, ButtonVariant, ButtonVariants},
checkbox::Checkbox,
dock::PanelControl,
h_flex,
label::Label,
tooltip::Tooltip,
Expand Down Expand Up @@ -37,8 +38,8 @@ impl super::Story for TooltipStory {
Self::view(cx)
}

fn zoomable() -> bool {
false
fn zoomable() -> Option<PanelControl> {
None
}
}
impl gpui::FocusableView for TooltipStory {
Expand Down
30 changes: 25 additions & 5 deletions crates/ui/src/dock/panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,26 @@ pub struct TitleStyle {
pub foreground: Hsla,
}

#[derive(Clone, Copy, Default)]
pub enum PanelControl {
Both,
#[default]
Menu,
Toolbar,
}

impl PanelControl {
#[inline]
pub fn toolbar_visible(&self) -> bool {
matches!(self, PanelControl::Both | PanelControl::Toolbar)
}

#[inline]
pub fn menu_visible(&self) -> bool {
matches!(self, PanelControl::Both | PanelControl::Menu)
}
}

/// The Panel trait used to define the panel.
#[allow(unused_variables)]
pub trait Panel: EventEmitter<PanelEvent> + FocusableView {
Expand All @@ -56,11 +76,11 @@ pub trait Panel: EventEmitter<PanelEvent> + FocusableView {
true
}

/// Return true if the panel is zoomable, default is `false`.
/// Return `PanelControl` if the panel is zoomable, default is `None`.
///
/// This method called in Panel render, we should make sure it is fast.
fn zoomable(&self, cx: &AppContext) -> bool {
true
fn zoomable(&self, cx: &AppContext) -> Option<PanelControl> {
Some(PanelControl::Menu)
}

/// Return false to hide panel, true to show panel, default is `true`.
Expand Down Expand Up @@ -108,7 +128,7 @@ pub trait PanelView: 'static + Send + Sync {
fn title(&self, cx: &WindowContext) -> AnyElement;
fn title_style(&self, cx: &AppContext) -> Option<TitleStyle>;
fn closable(&self, cx: &AppContext) -> bool;
fn zoomable(&self, cx: &AppContext) -> bool;
fn zoomable(&self, cx: &AppContext) -> Option<PanelControl>;
fn visible(&self, cx: &AppContext) -> bool;
fn set_active(&self, active: bool, cx: &mut WindowContext);
fn set_zoomed(&self, zoomed: bool, cx: &mut WindowContext);
Expand Down Expand Up @@ -136,7 +156,7 @@ impl<T: Panel> PanelView for View<T> {
self.read(cx).closable(cx)
}

fn zoomable(&self, cx: &AppContext) -> bool {
fn zoomable(&self, cx: &AppContext) -> Option<PanelControl> {
self.read(cx).zoomable(cx)
}

Expand Down
54 changes: 32 additions & 22 deletions crates/ui/src/dock/tab_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ use crate::{
};

use super::{
ClosePanel, DockArea, DockPlacement, Panel, PanelEvent, PanelState, PanelStyle, PanelView,
StackPanel, ToggleZoom,
ClosePanel, DockArea, DockPlacement, Panel, PanelControl, PanelEvent, PanelState, PanelStyle,
PanelView, StackPanel, ToggleZoom,
};

#[derive(Clone)]
struct TabState {
closable: bool,
zoomable: bool,
zoomable: Option<PanelControl>,
draggable: bool,
droppable: bool,
active_panel: Option<Arc<dyn PanelView>>,
Expand Down Expand Up @@ -104,10 +104,8 @@ impl Panel for TabPanel {
.unwrap_or(false)
}

fn zoomable(&self, cx: &AppContext) -> bool {
self.active_panel(cx)
.map(|panel| panel.zoomable(cx))
.unwrap_or(false)
fn zoomable(&self, cx: &AppContext) -> Option<PanelControl> {
self.active_panel(cx).and_then(|panel| panel.zoomable(cx))
}

fn visible(&self, cx: &AppContext) -> bool {
Expand Down Expand Up @@ -377,38 +375,50 @@ impl TabPanel {
}

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;
let view = cx.view().clone();
let build_popup_menu = move |this, cx: &WindowContext| view.read(cx).popup_menu(this, cx);
let zoomable_toolbar_visible = state.zoomable.map_or(false, |v| v.toolbar_visible());

// TODO: Do not show MenuButton if there is no menu items

h_flex()
.gap_2()
.occlude()
.items_center()
.when_some(self.toolbar_buttons(cx), |this, buttons| {
this.children(buttons.into_iter().map(|btn| btn.xsmall().ghost()))
})
.when(self.is_zoomed, |this| {
this.child(
Button::new("zoom")
.icon(IconName::Minimize)
.xsmall()
.ghost()
.tooltip(t!("Dock.Zoom Out"))
.on_click(
cx.listener(|view, _, cx| view.on_action_toggle_zoom(&ToggleZoom, cx)),
),
)
.map(|this| {
let value = if is_zoomed {
Some(("zoom-out", IconName::Minimize, t!("Dock.Zoom Out")))
} else if zoomable_toolbar_visible {
Some(("zoom-in", IconName::Maximize, t!("Dock.Zoom In")))
} else {
None
};

if let Some((id, icon, tooltip)) = value {
this.child(
Button::new(id)
.icon(icon)
.xsmall()
.ghost()
.tooltip(tooltip)
.on_click(cx.listener(|view, _, cx| {
view.on_action_toggle_zoom(&ToggleZoom, cx)
})),
)
} else {
this
}
})
.child(
Button::new("menu")
.icon(IconName::Ellipsis)
.xsmall()
.ghost()
.popup_menu({
let zoomable = state.zoomable;
let zoomable = state.zoomable.map_or(false, |v| v.menu_visible());
let closable = state.closable;

move |this, cx| {
Expand Down Expand Up @@ -932,7 +942,7 @@ impl TabPanel {
}

fn on_action_toggle_zoom(&mut self, _: &ToggleZoom, cx: &mut ViewContext<Self>) {
if !self.zoomable(cx) {
if self.zoomable(cx).is_none() {
return;
}

Expand Down

0 comments on commit ceba66c

Please sign in to comment.