panel: Add toolbar_buttons to extend button to panel. (#406)

<img width="635" alt="image"
src="https://github.com/user-attachments/assets/42dc1cb4-a1dd-43c6-8fc3-9d404e86cb85">
This commit is contained in:
Jason Lee 2024-11-10 23:17:34 +08:00 committed by GitHub
parent ab772c04f1
commit 5149b8a714
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 44 additions and 7 deletions

View file

@ -44,6 +44,7 @@ use gpui::{
}; };
use ui::{ use ui::{
button::Button,
divider::Divider, divider::Divider,
dock::{register_panel, DockItemInfo, DockItemState, Panel, PanelEvent, TitleStyle}, dock::{register_panel, DockItemInfo, DockItemState, Panel, PanelEvent, TitleStyle},
h_flex, h_flex,
@ -51,7 +52,7 @@ use ui::{
notification::Notification, notification::Notification,
popup_menu::PopupMenu, popup_menu::PopupMenu,
theme::ActiveTheme, theme::ActiveTheme,
v_flex, ContextModal, v_flex, ContextModal, IconName,
}; };
const PANEL_NAME: &str = "StoryContainer"; const PANEL_NAME: &str = "StoryContainer";
@ -296,6 +297,19 @@ impl Panel for StoryContainer {
.menu("Info", Box::new(PanelInfo)) .menu("Info", Box::new(PanelInfo))
} }
fn toolbar_buttons(&self, _cx: &WindowContext) -> Vec<Button> {
vec![
Button::new("info").icon(IconName::Info).on_click(|_, cx| {
cx.push_notification("You have clicked info button");
}),
Button::new("search")
.icon(IconName::Search)
.on_click(|_, cx| {
cx.push_notification("You have clicked search button");
}),
]
}
fn dump(&self, _cx: &AppContext) -> DockItemState { fn dump(&self, _cx: &AppContext) -> DockItemState {
let mut state = DockItemState::new(self); let mut state = DockItemState::new(self);
let story_state = StoryState { let story_state = StoryState {

View file

@ -1,6 +1,6 @@
use std::{collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
use crate::popup_menu::PopupMenu; use crate::{button::Button, popup_menu::PopupMenu};
use gpui::{ use gpui::{
AnyElement, AnyView, AppContext, EventEmitter, FocusHandle, FocusableView, Global, Hsla, AnyElement, AnyView, AppContext, EventEmitter, FocusHandle, FocusableView, Global, Hsla,
IntoElement, SharedString, View, WeakView, WindowContext, IntoElement, SharedString, View, WeakView, WindowContext,
@ -58,6 +58,11 @@ pub trait Panel: EventEmitter<PanelEvent> + FocusableView {
this this
} }
/// The addition toolbar buttons of the panel used to show in the right of the title bar, default is `None`.
fn toolbar_buttons(&self, _cx: &WindowContext) -> Vec<Button> {
vec![]
}
/// Dump the panel, used to serialize the panel. /// Dump the panel, used to serialize the panel.
fn dump(&self, _cx: &AppContext) -> DockItemState { fn dump(&self, _cx: &AppContext) -> DockItemState {
DockItemState::new(self) DockItemState::new(self)
@ -72,6 +77,7 @@ pub trait PanelView: 'static + Send + Sync {
fn zoomable(&self, cx: &WindowContext) -> bool; fn zoomable(&self, cx: &WindowContext) -> bool;
fn collapsible(&self, cx: &WindowContext) -> bool; fn collapsible(&self, cx: &WindowContext) -> bool;
fn popup_menu(&self, menu: PopupMenu, cx: &WindowContext) -> PopupMenu; fn popup_menu(&self, menu: PopupMenu, cx: &WindowContext) -> PopupMenu;
fn toolbar_buttons(&self, cx: &WindowContext) -> Vec<Button>;
fn view(&self) -> AnyView; fn view(&self) -> AnyView;
fn focus_handle(&self, cx: &AppContext) -> FocusHandle; fn focus_handle(&self, cx: &AppContext) -> FocusHandle;
fn dump(&self, cx: &AppContext) -> DockItemState; fn dump(&self, cx: &AppContext) -> DockItemState;
@ -106,6 +112,10 @@ impl<T: Panel> PanelView for View<T> {
self.read(cx).popup_menu(menu, cx) self.read(cx).popup_menu(menu, cx)
} }
fn toolbar_buttons(&self, cx: &WindowContext) -> Vec<Button> {
self.read(cx).toolbar_buttons(cx)
}
fn view(&self) -> AnyView { fn view(&self) -> AnyView {
self.clone().into() self.clone().into()
} }

View file

@ -116,6 +116,14 @@ impl Panel for TabPanel {
} }
} }
fn toolbar_buttons(&self, cx: &WindowContext) -> Vec<Button> {
if let Some(panel) = self.active_panel() {
panel.toolbar_buttons(cx)
} else {
vec![]
}
}
fn dump(&self, cx: &AppContext) -> DockItemState { fn dump(&self, cx: &AppContext) -> DockItemState {
let mut state = DockItemState::new(self); let mut state = DockItemState::new(self);
for panel in self.panels.iter() { for panel in self.panels.iter() {
@ -269,7 +277,7 @@ impl TabPanel {
cx.notify(); cx.notify();
} }
fn render_menu_button(&self, cx: &mut ViewContext<Self>) -> impl IntoElement { fn render_toolbar(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
let closeable = self.closeable(cx); let closeable = self.closeable(cx);
let zoomable = self.zoomable(cx); let zoomable = self.zoomable(cx);
@ -283,6 +291,11 @@ impl TabPanel {
.gap_2() .gap_2()
.occlude() .occlude()
.items_center() .items_center()
.children(
self.toolbar_buttons(cx)
.into_iter()
.map(|btn| btn.xsmall().ghost()),
)
.when(self.is_zoomed, |this| { .when(self.is_zoomed, |this| {
this.child( this.child(
Button::new("zoom") Button::new("zoom")
@ -464,7 +477,7 @@ impl TabPanel {
) )
} }
fn render_tabs(&self, cx: &mut ViewContext<Self>) -> impl IntoElement { fn render_title_bar(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
let view = cx.view().clone(); let view = cx.view().clone();
let left_dock_button = self.render_dock_toggle_button(DockPlacement::Left, cx); let left_dock_button = self.render_dock_toggle_button(DockPlacement::Left, cx);
@ -527,7 +540,7 @@ impl TabPanel {
.flex_shrink_0() .flex_shrink_0()
.ml_1() .ml_1()
.gap_1() .gap_1()
.child(self.render_menu_button(cx)) .child(self.render_toolbar(cx))
.children(right_dock_button), .children(right_dock_button),
) )
.into_any_element(); .into_any_element();
@ -623,7 +636,7 @@ impl TabPanel {
.bg(cx.theme().tab_bar) .bg(cx.theme().tab_bar)
.px_2() .px_2()
.gap_1() .gap_1()
.child(self.render_menu_button(cx)) .child(self.render_toolbar(cx))
.when_some(right_dock_button, |this, btn| this.child(btn)), .when_some(right_dock_button, |this, btn| this.child(btn)),
) )
.into_any_element() .into_any_element()
@ -887,7 +900,7 @@ impl Render for TabPanel {
.size_full() .size_full()
.overflow_hidden() .overflow_hidden()
.bg(cx.theme().background) .bg(cx.theme().background)
.child(self.render_tabs(cx)) .child(self.render_title_bar(cx))
.child(self.render_active_panel(cx)) .child(self.render_active_panel(cx))
} }
} }