panel: Support custom style for the panel title (#220)

This commit is contained in:
Floyd Wang 2024-09-05 11:36:59 +08:00 committed by GitHub
parent e1d6b3aaed
commit d6015f636c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 66 additions and 6 deletions

View file

@ -94,6 +94,7 @@ impl StoryWorkspace {
None,
None,
false,
None,
cx,
);
@ -105,6 +106,7 @@ impl StoryWorkspace {
None,
None,
false,
None,
cx,
);
@ -116,6 +118,7 @@ impl StoryWorkspace {
Some(Placement::Bottom),
Some(px(200.)),
true,
None,
cx,
);
@ -127,6 +130,7 @@ impl StoryWorkspace {
None,
None,
true,
None,
cx,
);
@ -138,6 +142,7 @@ impl StoryWorkspace {
None,
None,
true,
None,
cx,
);
@ -149,6 +154,7 @@ impl StoryWorkspace {
None,
None,
true,
None,
cx,
);
@ -160,6 +166,7 @@ impl StoryWorkspace {
None,
None,
true,
None,
cx,
);
@ -171,6 +178,7 @@ impl StoryWorkspace {
None,
None,
true,
None,
cx,
);
@ -182,6 +190,7 @@ impl StoryWorkspace {
None,
None,
true,
None,
cx,
);
@ -193,6 +202,7 @@ impl StoryWorkspace {
Some(Placement::Bottom),
Some(px(200.)),
true,
None,
cx,
);
@ -204,6 +214,7 @@ impl StoryWorkspace {
Some(Placement::Bottom),
None,
true,
Some(cx.theme().muted),
cx,
);
@ -223,6 +234,7 @@ impl StoryWorkspace {
None,
None,
true,
None,
cx,
);
@ -234,6 +246,7 @@ impl StoryWorkspace {
Some(Placement::Bottom),
Some(px(200.)),
true,
None,
cx,
);
@ -245,6 +258,7 @@ impl StoryWorkspace {
None,
None,
true,
None,
cx,
);
@ -256,6 +270,7 @@ impl StoryWorkspace {
None,
None,
true,
None,
cx,
);
@ -267,6 +282,7 @@ impl StoryWorkspace {
Some(Placement::Bottom),
None,
true,
None,
cx,
);

View file

@ -38,17 +38,19 @@ pub use webview_story::WebViewStory;
use gpui::{
actions, div, prelude::FluentBuilder as _, px, AnyView, AppContext, Div, EventEmitter,
FocusableView, InteractiveElement, IntoElement, ParentElement, Pixels, Render, SharedString,
StatefulInteractiveElement, Styled as _, View, ViewContext, VisualContext, WindowContext,
FocusableView, Hsla, InteractiveElement, IntoElement, ParentElement, Pixels, Render,
SharedString, StatefulInteractiveElement, Styled as _, View, ViewContext, VisualContext,
WindowContext,
};
use ui::{
divider::Divider,
dock::{Panel, PanelEvent, TabPanel},
dock::{Panel, PanelEvent, TabPanel, TitleStyle},
h_flex,
label::Label,
notification::Notification,
popup_menu::PopupMenu,
theme::ActiveTheme,
v_flex, ContextModal, Placement,
};
@ -80,6 +82,7 @@ pub fn section(title: impl IntoElement, cx: &WindowContext) -> Div {
pub struct StoryContainer {
focus_handle: gpui::FocusHandle,
name: SharedString,
title_bg: Option<Hsla>,
description: SharedString,
width: Option<gpui::Pixels>,
height: Option<gpui::Pixels>,
@ -106,6 +109,7 @@ impl StoryContainer {
Self {
focus_handle,
name: name.into(),
title_bg: None,
description: description.into(),
width: None,
height: None,
@ -123,13 +127,18 @@ impl StoryContainer {
placement: Option<Placement>,
size: Option<Pixels>,
closeable: bool,
title_bg: Option<Hsla>,
cx: &mut WindowContext,
) {
let name = name.into();
let description = description.into();
tab_panel.update(cx, |panel, cx| {
let view = cx.new_view(|cx| Self::new(name, description, closeable, cx).story(story));
let view = cx.new_view(|cx| {
Self::new(name, description, closeable, cx)
.story(story)
.title_bg(title_bg)
});
if let Some(placement) = placement {
panel.add_panel_at(Arc::new(view.clone()), placement, size, cx);
} else {
@ -154,6 +163,11 @@ impl StoryContainer {
self
}
pub fn title_bg(mut self, title_bg: Option<Hsla>) -> Self {
self.title_bg = title_bg;
self
}
fn on_action_panel_info(&mut self, _: &PanelInfo, cx: &mut ViewContext<Self>) {
struct Info;
let note = Notification::new(format!("You have clicked panel info on: {}", self.name))
@ -167,6 +181,17 @@ impl Panel for StoryContainer {
self.name.clone()
}
fn title_style(&self, cx: &WindowContext) -> Option<TitleStyle> {
if let Some(bg) = self.title_bg {
Some(TitleStyle {
background: bg,
foreground: cx.theme().foreground,
})
} else {
None
}
}
fn closeable(&self, _cx: &WindowContext) -> bool {
self.closeable
}

View file

@ -1,16 +1,26 @@
use gpui::{AnyView, EventEmitter, FocusableView, SharedString, View, WindowContext};
use gpui::{AnyView, EventEmitter, FocusableView, Hsla, SharedString, View, WindowContext};
use rust_i18n::t;
use crate::popup_menu::PopupMenu;
use super::PanelEvent;
pub struct TitleStyle {
pub background: Hsla,
pub foreground: Hsla,
}
pub trait Panel: EventEmitter<PanelEvent> + FocusableView {
/// The title of the panel, default is `None`.
fn title(&self, _cx: &WindowContext) -> SharedString {
t!("Dock.Unnamed").into()
}
/// The theme of the panel title, default is `None`.
fn title_style(&self, _cx: &WindowContext) -> Option<TitleStyle> {
None
}
/// Whether the panel can be closed, default is `true`.
fn closeable(&self, _cx: &WindowContext) -> bool {
true
@ -23,9 +33,10 @@ pub trait Panel: EventEmitter<PanelEvent> + FocusableView {
}
pub trait PanelView: 'static + Send + Sync {
/// The title of the panel, default is `None`.
fn title(&self, _cx: &WindowContext) -> SharedString;
fn title_style(&self, _cx: &WindowContext) -> Option<TitleStyle>;
fn closeable(&self, cx: &WindowContext) -> bool;
fn popup_menu(&self, menu: PopupMenu, cx: &WindowContext) -> PopupMenu;
@ -38,6 +49,10 @@ impl<T: Panel> PanelView for View<T> {
self.read(cx).title(cx)
}
fn title_style(&self, cx: &WindowContext) -> Option<TitleStyle> {
self.read(cx).title_style(cx)
}
fn closeable(&self, cx: &WindowContext) -> bool {
self.read(cx).closeable(cx)
}

View file

@ -242,12 +242,16 @@ impl TabPanel {
if self.panels.len() == 1 {
let panel = self.panels.get(0).unwrap();
let title = panel.title(cx);
let title_style = panel.title_style(cx);
return h_flex()
.justify_between()
.items_center()
.line_height(rems(1.0))
.pr_3()
.when_some(title_style, |this, theme| {
this.bg(theme.background).text_color(theme.foreground)
})
.child(
div()
.id("tab")