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::{
button::Button,
divider::Divider,
dock::{register_panel, DockItemInfo, DockItemState, Panel, PanelEvent, TitleStyle},
h_flex,
@ -51,7 +52,7 @@ use ui::{
notification::Notification,
popup_menu::PopupMenu,
theme::ActiveTheme,
v_flex, ContextModal,
v_flex, ContextModal, IconName,
};
const PANEL_NAME: &str = "StoryContainer";
@ -296,6 +297,19 @@ impl Panel for StoryContainer {
.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 {
let mut state = DockItemState::new(self);
let story_state = StoryState {

View file

@ -1,6 +1,6 @@
use std::{collections::HashMap, sync::Arc};
use crate::popup_menu::PopupMenu;
use crate::{button::Button, popup_menu::PopupMenu};
use gpui::{
AnyElement, AnyView, AppContext, EventEmitter, FocusHandle, FocusableView, Global, Hsla,
IntoElement, SharedString, View, WeakView, WindowContext,
@ -58,6 +58,11 @@ pub trait Panel: EventEmitter<PanelEvent> + FocusableView {
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.
fn dump(&self, _cx: &AppContext) -> DockItemState {
DockItemState::new(self)
@ -72,6 +77,7 @@ pub trait PanelView: 'static + Send + Sync {
fn zoomable(&self, cx: &WindowContext) -> bool;
fn collapsible(&self, cx: &WindowContext) -> bool;
fn popup_menu(&self, menu: PopupMenu, cx: &WindowContext) -> PopupMenu;
fn toolbar_buttons(&self, cx: &WindowContext) -> Vec<Button>;
fn view(&self) -> AnyView;
fn focus_handle(&self, cx: &AppContext) -> FocusHandle;
fn dump(&self, cx: &AppContext) -> DockItemState;
@ -106,6 +112,10 @@ impl<T: Panel> PanelView for View<T> {
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 {
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 {
let mut state = DockItemState::new(self);
for panel in self.panels.iter() {
@ -269,7 +277,7 @@ impl TabPanel {
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 zoomable = self.zoomable(cx);
@ -283,6 +291,11 @@ impl TabPanel {
.gap_2()
.occlude()
.items_center()
.children(
self.toolbar_buttons(cx)
.into_iter()
.map(|btn| btn.xsmall().ghost()),
)
.when(self.is_zoomed, |this| {
this.child(
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 left_dock_button = self.render_dock_toggle_button(DockPlacement::Left, cx);
@ -527,7 +540,7 @@ impl TabPanel {
.flex_shrink_0()
.ml_1()
.gap_1()
.child(self.render_menu_button(cx))
.child(self.render_toolbar(cx))
.children(right_dock_button),
)
.into_any_element();
@ -623,7 +636,7 @@ impl TabPanel {
.bg(cx.theme().tab_bar)
.px_2()
.gap_1()
.child(self.render_menu_button(cx))
.child(self.render_toolbar(cx))
.when_some(right_dock_button, |this, btn| this.child(btn)),
)
.into_any_element()
@ -887,7 +900,7 @@ impl Render for TabPanel {
.size_full()
.overflow_hidden()
.bg(cx.theme().background)
.child(self.render_tabs(cx))
.child(self.render_title_bar(cx))
.child(self.render_active_panel(cx))
}
}