dock: Reduce dock item member (#223)
This commit is contained in:
parent
83aecf1293
commit
9baada4fb4
20 changed files with 346 additions and 241 deletions
|
|
@ -59,18 +59,8 @@ impl StoryWorkspace {
|
|||
DockItem::split(
|
||||
Axis::Vertical,
|
||||
vec![
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Icon",
|
||||
"Icon use examples",
|
||||
IconStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Calendar",
|
||||
"A calendar component.",
|
||||
CalendarStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::tab(StoryContainer::panel::<IconStory>(cx), &dock_area, cx),
|
||||
DockItem::tab(StoryContainer::panel::<CalendarStory>(cx), &dock_area, cx),
|
||||
],
|
||||
&dock_area,
|
||||
cx,
|
||||
|
|
@ -80,83 +70,18 @@ impl StoryWorkspace {
|
|||
vec![
|
||||
DockItem::tabs(
|
||||
vec![
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Button",
|
||||
"Displays a button or a component that looks like a button.",
|
||||
ButtonStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Input",
|
||||
"A control that allows the user to input text.",
|
||||
InputStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Dropdown",
|
||||
"Displays a list of options for the user to pick from—triggered by a button.",
|
||||
DropdownStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Modal",
|
||||
"Modal & Drawer use examples",
|
||||
ModalStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Popup",
|
||||
"A popup displays content on top of the main page.",
|
||||
PopupStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::tabs(
|
||||
vec![DockItem::panel(StoryContainer::panel(
|
||||
"List",
|
||||
"A list displays a series of items.",
|
||||
ListStory::view(cx).into(),
|
||||
cx,
|
||||
))],
|
||||
None,
|
||||
&dock_area,
|
||||
cx,
|
||||
),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Switch",
|
||||
"A control that allows the user to toggle between two states.",
|
||||
SwitchStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Progress",
|
||||
"Progress use examples",
|
||||
ProgressStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Table",
|
||||
"Table use examples",
|
||||
TableStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Image",
|
||||
"Image use examples",
|
||||
ImageStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Resizable",
|
||||
"Resizable use examples",
|
||||
ResizableStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Scrollable",
|
||||
"Scrollable use examples",
|
||||
ScrollableStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
StoryContainer::panel::<ButtonStory>(cx),
|
||||
StoryContainer::panel::<InputStory>(cx),
|
||||
StoryContainer::panel::<DropdownStory>(cx),
|
||||
StoryContainer::panel::<ModalStory>(cx),
|
||||
StoryContainer::panel::<PopupStory>(cx),
|
||||
StoryContainer::panel::<ListStory>(cx),
|
||||
StoryContainer::panel::<SwitchStory>(cx),
|
||||
StoryContainer::panel::<ProgressStory>(cx),
|
||||
StoryContainer::panel::<TableStory>(cx),
|
||||
StoryContainer::panel::<ImageStory>(cx),
|
||||
StoryContainer::panel::<ResizableStory>(cx),
|
||||
StoryContainer::panel::<ScrollableStory>(cx),
|
||||
],
|
||||
None,
|
||||
&dock_area,
|
||||
|
|
@ -164,48 +89,29 @@ impl StoryWorkspace {
|
|||
),
|
||||
DockItem::tabs(
|
||||
vec![
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Progress",
|
||||
"Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.",
|
||||
ProgressStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Text",
|
||||
"Links, paragraphs, checkboxes, and more.",
|
||||
TextStory::view(cx).into(),
|
||||
cx,
|
||||
))],
|
||||
StoryContainer::panel::<ProgressStory>(cx),
|
||||
StoryContainer::panel::<TextStory>(cx),
|
||||
],
|
||||
None,
|
||||
&dock_area,
|
||||
cx,
|
||||
),
|
||||
],
|
||||
vec![None, Some(px(300.))],
|
||||
vec![None, None, Some(px(300.))],
|
||||
&dock_area,
|
||||
cx,
|
||||
),
|
||||
DockItem::split_with_sizes(
|
||||
Axis::Vertical,
|
||||
vec![
|
||||
DockItem::tab(StoryContainer::panel::<TooltipStory>(cx), &dock_area, cx),
|
||||
DockItem::tab(StoryContainer::panel::<CalendarStory>(cx), &dock_area, cx),
|
||||
DockItem::tab(StoryContainer::panel::<ImageStory>(cx), &dock_area, cx),
|
||||
],
|
||||
vec![None, None, Some(px(300.))],
|
||||
&dock_area,
|
||||
cx,
|
||||
),
|
||||
DockItem::split_with_sizes(Axis::Vertical, vec![
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Tooltip",
|
||||
"Displays a short message when users hover over an element.",
|
||||
TooltipStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Calendar",
|
||||
"A calendar component.",
|
||||
CalendarStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
DockItem::panel(StoryContainer::panel(
|
||||
"Image",
|
||||
"Render SVG image and Chart",
|
||||
ImageStory::view(cx).into(),
|
||||
cx,
|
||||
)),
|
||||
], vec![None, None, Some(px(300.))], &dock_area, cx),
|
||||
|
||||
],
|
||||
vec![Some(px(300.)), None, Some(px(350.))],
|
||||
&dock_area,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,24 @@ impl ButtonStory {
|
|||
}
|
||||
}
|
||||
|
||||
impl super::Story for ButtonStory {
|
||||
fn title() -> &'static str {
|
||||
"Button"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"Displays a button or a component that looks like a button."
|
||||
}
|
||||
|
||||
fn closeable() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ButtonStory {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
let disabled = self.disabled;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,20 @@ pub struct CalendarStory {
|
|||
default_range_mode_picker: View<DatePicker>,
|
||||
}
|
||||
|
||||
impl super::Story for CalendarStory {
|
||||
fn title() -> &'static str {
|
||||
"Calendar"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"A date picker and calendar component."
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl CalendarStory {
|
||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||
cx.new_view(Self::new)
|
||||
|
|
|
|||
|
|
@ -55,6 +55,20 @@ pub struct DropdownStory {
|
|||
disabled_dropdown: View<Dropdown<Vec<SharedString>>>,
|
||||
}
|
||||
|
||||
impl super::Story for DropdownStory {
|
||||
fn title() -> &'static str {
|
||||
"Dropdown"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"Displays a list of options for the user to pick from—triggered by a button."
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl DropdownStory {
|
||||
fn new(cx: &mut WindowContext) -> View<Self> {
|
||||
let countries = vec![
|
||||
|
|
|
|||
|
|
@ -18,6 +18,20 @@ impl IconStory {
|
|||
}
|
||||
}
|
||||
|
||||
impl super::Story for IconStory {
|
||||
fn title() -> &'static str {
|
||||
"Icon"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"Icon use examples"
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for IconStory {
|
||||
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl gpui::IntoElement {
|
||||
v_flex().gap_3().child(
|
||||
|
|
|
|||
|
|
@ -10,6 +10,16 @@ pub struct ImageStory {
|
|||
inbox_img: SvgImg,
|
||||
}
|
||||
|
||||
impl super::Story for ImageStory {
|
||||
fn title() -> &'static str {
|
||||
"Image"
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ImageStory {
|
||||
pub fn new(_: &WindowContext) -> Self {
|
||||
let chart = charts_rs::PieChart::from_json(PIE_JSON).unwrap();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
use gpui::{actions, div, px, AppContext, FocusHandle, InteractiveElement, IntoElement, KeyBinding, ParentElement as _, Render, SharedString, Styled, View, ViewContext, VisualContext, WindowContext};
|
||||
use gpui::{
|
||||
actions, div, px, AppContext, FocusHandle, InteractiveElement, IntoElement, KeyBinding,
|
||||
ParentElement as _, Render, SharedString, Styled, View, ViewContext, VisualContext,
|
||||
WindowContext,
|
||||
};
|
||||
|
||||
use crate::section;
|
||||
use ui::{
|
||||
|
|
@ -8,11 +12,7 @@ use ui::{
|
|||
input::{InputEvent, OtpInput, TextInput},
|
||||
prelude::FluentBuilder as _,
|
||||
scroll::ScrollbarAxis,
|
||||
v_flex,
|
||||
FocusableCycle,
|
||||
IconName,
|
||||
Sizable,
|
||||
StyledExt,
|
||||
v_flex, FocusableCycle, IconName, Sizable, StyledExt,
|
||||
};
|
||||
|
||||
actions!(input_story, [Tab, TabPrev]);
|
||||
|
|
@ -44,6 +44,24 @@ pub struct InputStory {
|
|||
opt_input_sized: View<OtpInput>,
|
||||
}
|
||||
|
||||
impl super::Story for InputStory {
|
||||
fn title() -> &'static str {
|
||||
"Input"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"A control that allows the user to input text."
|
||||
}
|
||||
|
||||
fn closeable() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl InputStory {
|
||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||
cx.new_view(Self::new)
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ mod text_story;
|
|||
mod tooltip_story;
|
||||
mod webview_story;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub use button_story::ButtonStory;
|
||||
pub use calendar_story::CalendarStory;
|
||||
pub use dropdown_story::DropdownStory;
|
||||
|
|
@ -38,20 +36,19 @@ pub use webview_story::WebViewStory;
|
|||
|
||||
use gpui::{
|
||||
actions, div, prelude::FluentBuilder as _, px, AnyView, AppContext, Div, EventEmitter,
|
||||
FocusableView, Hsla, InteractiveElement, IntoElement, ParentElement, Pixels, Render,
|
||||
SharedString, StatefulInteractiveElement, Styled as _, View, ViewContext, VisualContext,
|
||||
WindowContext,
|
||||
FocusableView, Hsla, InteractiveElement, IntoElement, ParentElement, Render, SharedString,
|
||||
StatefulInteractiveElement, Styled as _, View, ViewContext, VisualContext, WindowContext,
|
||||
};
|
||||
|
||||
use ui::{
|
||||
divider::Divider,
|
||||
dock::{Panel, PanelEvent, TabPanel, TitleStyle},
|
||||
dock::{Panel, PanelEvent, TitleStyle},
|
||||
h_flex,
|
||||
label::Label,
|
||||
notification::Notification,
|
||||
popup_menu::PopupMenu,
|
||||
theme::ActiveTheme,
|
||||
v_flex, ContextModal, Placement,
|
||||
v_flex, ContextModal,
|
||||
};
|
||||
|
||||
pub fn init(cx: &mut AppContext) {
|
||||
|
|
@ -87,6 +84,7 @@ pub struct StoryContainer {
|
|||
width: Option<gpui::Pixels>,
|
||||
height: Option<gpui::Pixels>,
|
||||
story: Option<AnyView>,
|
||||
story_klass: Option<SharedString>,
|
||||
closeable: bool,
|
||||
}
|
||||
|
||||
|
|
@ -95,66 +93,59 @@ pub enum ContainerEvent {
|
|||
Close,
|
||||
}
|
||||
|
||||
pub trait Story {
|
||||
fn klass() -> &'static str {
|
||||
std::any::type_name::<Self>()
|
||||
}
|
||||
|
||||
fn title() -> &'static str;
|
||||
fn description() -> &'static str {
|
||||
""
|
||||
}
|
||||
fn closeable() -> bool {
|
||||
true
|
||||
}
|
||||
fn title_bg() -> Option<Hsla> {
|
||||
None
|
||||
}
|
||||
fn new_view(cx: &mut WindowContext) -> AnyView;
|
||||
}
|
||||
|
||||
impl EventEmitter<ContainerEvent> for StoryContainer {}
|
||||
|
||||
impl StoryContainer {
|
||||
pub fn new(
|
||||
name: impl Into<SharedString>,
|
||||
description: impl Into<SharedString>,
|
||||
closeable: bool,
|
||||
cx: &mut WindowContext,
|
||||
) -> Self {
|
||||
pub fn new(closeable: bool, cx: &mut WindowContext) -> Self {
|
||||
let focus_handle = cx.focus_handle();
|
||||
|
||||
Self {
|
||||
focus_handle,
|
||||
name: name.into(),
|
||||
name: "".into(),
|
||||
title_bg: None,
|
||||
description: description.into(),
|
||||
description: "".into(),
|
||||
width: None,
|
||||
height: None,
|
||||
story: None,
|
||||
story_klass: None,
|
||||
closeable,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn panel(
|
||||
name: impl Into<SharedString>,
|
||||
description: impl Into<SharedString>,
|
||||
story: AnyView,
|
||||
cx: &mut WindowContext,
|
||||
) -> View<Self> {
|
||||
cx.new_view(|cx| Self::new(name, description, true, cx).story(story))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn add_panel(
|
||||
name: impl Into<SharedString>,
|
||||
description: impl Into<SharedString>,
|
||||
story: AnyView,
|
||||
tab_panel: View<TabPanel>,
|
||||
placement: Option<Placement>,
|
||||
size: Option<Pixels>,
|
||||
closeable: bool,
|
||||
title_bg: Option<Hsla>,
|
||||
cx: &mut WindowContext,
|
||||
) {
|
||||
let name = name.into();
|
||||
let description = description.into();
|
||||
pub fn panel<S: Story>(cx: &mut WindowContext) -> View<Self> {
|
||||
let name = S::title();
|
||||
let description = S::description();
|
||||
let story = S::new_view(cx);
|
||||
let story_klass = S::klass();
|
||||
|
||||
tab_panel.update(cx, |panel, cx| {
|
||||
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 {
|
||||
panel.add_panel(Arc::new(view.clone()), cx);
|
||||
}
|
||||
view
|
||||
let view = cx.new_view(|cx| {
|
||||
let mut story = Self::new(S::closeable(), cx).story(story, story_klass);
|
||||
story.name = name.into();
|
||||
story.description = description.into();
|
||||
story.title_bg = S::title_bg();
|
||||
story
|
||||
});
|
||||
|
||||
view
|
||||
}
|
||||
|
||||
pub fn width(mut self, width: gpui::Pixels) -> Self {
|
||||
|
|
@ -167,13 +158,9 @@ impl StoryContainer {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn story(mut self, story: AnyView) -> Self {
|
||||
pub fn story(mut self, story: AnyView, story_klass: impl Into<SharedString>) -> Self {
|
||||
self.story = Some(story);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn title_bg(mut self, title_bg: Option<Hsla>) -> Self {
|
||||
self.title_bg = title_bg;
|
||||
self.story_klass = Some(story_klass.into());
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -196,6 +196,20 @@ pub struct ListStory {
|
|||
selected_company: Option<Company>,
|
||||
}
|
||||
|
||||
impl super::Story for ListStory {
|
||||
fn title() -> &'static str {
|
||||
"List"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"A list displays a series of items."
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ListStory {
|
||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||
cx.new_view(Self::new)
|
||||
|
|
|
|||
|
|
@ -151,6 +151,20 @@ pub struct ModalStory {
|
|||
model_padding: bool,
|
||||
}
|
||||
|
||||
impl super::Story for ModalStory {
|
||||
fn title() -> &'static str {
|
||||
"Modal"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"Modal & Drawer use examples"
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalStory {
|
||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||
cx.new_view(Self::new)
|
||||
|
|
|
|||
|
|
@ -79,6 +79,20 @@ pub struct PopupStory {
|
|||
window_mode: bool,
|
||||
}
|
||||
|
||||
impl super::Story for PopupStory {
|
||||
fn title() -> &'static str {
|
||||
"Popup"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"A popup displays content on top of the main page."
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl PopupStory {
|
||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||
cx.new_view(Self::new)
|
||||
|
|
@ -199,9 +213,10 @@ impl Render for PopupStory {
|
|||
.small(),
|
||||
)
|
||||
.into_any()
|
||||
}).max_w(px(600.))
|
||||
})
|
||||
.max_w(px(600.))
|
||||
})
|
||||
})
|
||||
}),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
|
|
@ -209,7 +224,7 @@ impl Render for PopupStory {
|
|||
.anchor(AnchorCorner::TopRight)
|
||||
.trigger(Button::new("info-top-right", cx).label("Top Right"))
|
||||
.content(|cx| {
|
||||
cx.new_view(|cx|
|
||||
cx.new_view(|cx| {
|
||||
PopoverContent::new(cx, |cx| {
|
||||
v_flex()
|
||||
.gap_4()
|
||||
|
|
@ -223,7 +238,8 @@ impl Render for PopupStory {
|
|||
.small(),
|
||||
)
|
||||
.into_any()
|
||||
}))
|
||||
})
|
||||
})
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
|
@ -284,11 +300,13 @@ impl Render for PopupStory {
|
|||
.w(px(300.)),
|
||||
)
|
||||
.content(|cx| {
|
||||
cx.new_view(|cx|
|
||||
cx.new_view(|cx| {
|
||||
PopoverContent::new(cx, |cx| {
|
||||
v_flex()
|
||||
.gap_4()
|
||||
.child("Hello, this is a Popover on the Bottom Right.")
|
||||
.child(
|
||||
"Hello, this is a Popover on the Bottom Right.",
|
||||
)
|
||||
.child(Divider::horizontal())
|
||||
.child(
|
||||
Button::new("info1", cx)
|
||||
|
|
@ -297,7 +315,8 @@ impl Render for PopupStory {
|
|||
.small(),
|
||||
)
|
||||
.into_any()
|
||||
}))
|
||||
})
|
||||
})
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -21,6 +21,16 @@ pub struct ProgressStory {
|
|||
slider2_value: f32,
|
||||
}
|
||||
|
||||
impl super::Story for ProgressStory {
|
||||
fn title() -> &'static str {
|
||||
"Progress"
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ProgressStory {
|
||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||
cx.new_view(Self::new)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,20 @@ pub struct ResizableStory {
|
|||
group2: View<ResizablePanelGroup>,
|
||||
}
|
||||
|
||||
impl super::Story for ResizableStory {
|
||||
fn title() -> &'static str {
|
||||
"Resizable"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"The resizable panels."
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ResizableStory {
|
||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||
cx.new_view(|cx| Self::new(cx))
|
||||
|
|
|
|||
|
|
@ -60,6 +60,20 @@ impl ScrollableStory {
|
|||
}
|
||||
}
|
||||
|
||||
impl super::Story for ScrollableStory {
|
||||
fn title() -> &'static str {
|
||||
"Scrollable"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"Add vertical or horizontal, or both scrollbars to a container."
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ScrollableStory {
|
||||
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl gpui::IntoElement {
|
||||
let view = cx.view().clone();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,20 @@ pub struct SwitchStory {
|
|||
switch3: bool,
|
||||
}
|
||||
|
||||
impl super::Story for SwitchStory {
|
||||
fn title() -> &'static str {
|
||||
"Switch"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"A control that allows the user to toggle between two states."
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl SwitchStory {
|
||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||
cx.new_view(|cx| Self::new(cx))
|
||||
|
|
|
|||
|
|
@ -362,6 +362,20 @@ pub struct TableStory {
|
|||
table: View<Table<CustomerTableDelegate>>,
|
||||
}
|
||||
|
||||
impl super::Story for TableStory {
|
||||
fn title() -> &'static str {
|
||||
"Table"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"A complex data table with selection, sorting, column moving, and loading more."
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TableStory {
|
||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||
cx.new_view(Self::new)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,20 @@ pub struct TextStory {
|
|||
masked: bool,
|
||||
}
|
||||
|
||||
impl super::Story for TextStory {
|
||||
fn title() -> &'static str {
|
||||
"Text"
|
||||
}
|
||||
|
||||
fn description() -> &'static str {
|
||||
"The text render testing and examples"
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TextStory {
|
||||
pub(crate) fn new(_cx: &mut WindowContext) -> Self {
|
||||
Self {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,16 @@ impl TooltipStory {
|
|||
}
|
||||
}
|
||||
|
||||
impl super::Story for TooltipStory {
|
||||
fn title() -> &'static str {
|
||||
"Tooltip"
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for TooltipStory {
|
||||
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl gpui::IntoElement {
|
||||
v_flex()
|
||||
|
|
|
|||
|
|
@ -18,6 +18,16 @@ pub struct WebViewStory {
|
|||
address_input: View<TextInput>,
|
||||
}
|
||||
|
||||
impl super::Story for WebViewStory {
|
||||
fn title() -> &'static str {
|
||||
"WebView"
|
||||
}
|
||||
|
||||
fn new_view(cx: &mut WindowContext) -> gpui::AnyView {
|
||||
Self::view(cx).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl WebViewStory {
|
||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||
let focus_handle = cx.focus_handle();
|
||||
|
|
|
|||
|
|
@ -32,13 +32,10 @@ pub enum DockItem {
|
|||
view: View<StackPanel>,
|
||||
},
|
||||
Tabs {
|
||||
items: Vec<DockItem>,
|
||||
items: Vec<Arc<dyn PanelView>>,
|
||||
active_ix: usize,
|
||||
view: View<TabPanel>,
|
||||
},
|
||||
Panel {
|
||||
view: Arc<dyn PanelView>,
|
||||
},
|
||||
}
|
||||
|
||||
impl DockItem {
|
||||
|
|
@ -68,26 +65,12 @@ impl DockItem {
|
|||
let stack_panel = cx.new_view(|cx| {
|
||||
let mut stack_panel = StackPanel::new(axis, cx);
|
||||
for (i, item) in items.iter_mut().enumerate() {
|
||||
// Always convert DockItem::Panel to DockItem::Tabs in split layout.
|
||||
// This makes they can subscribe the Zoom event.
|
||||
match item {
|
||||
DockItem::Panel { .. } => {
|
||||
*item = DockItem::tabs(vec![item.clone()], None, &dock_area, cx);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let view = item.view();
|
||||
let size = sizes.get(i).copied().flatten();
|
||||
stack_panel.add_panel(view.clone(), size, dock_area.downgrade(), cx)
|
||||
}
|
||||
|
||||
for (i, item) in items.iter().enumerate() {
|
||||
let item = match item {
|
||||
DockItem::Panel { .. } => Self::tabs(vec![item.clone()], None, &dock_area, cx),
|
||||
_ => item.clone(),
|
||||
};
|
||||
|
||||
let view = item.view();
|
||||
let size = sizes.get(i).copied().flatten();
|
||||
stack_panel.add_panel(view.clone(), size, dock_area.downgrade(), cx)
|
||||
|
|
@ -106,8 +89,30 @@ impl DockItem {
|
|||
/// Create DockItem with tabs layout, items are displayed as tabs.
|
||||
///
|
||||
/// The `active_ix` is the index of the active tab, if `None` the first tab is active.
|
||||
pub fn tabs(
|
||||
items: Vec<DockItem>,
|
||||
pub fn tabs<P: Panel>(
|
||||
items: Vec<View<P>>,
|
||||
active_ix: Option<usize>,
|
||||
dock_area: &View<DockArea>,
|
||||
cx: &mut WindowContext,
|
||||
) -> Self {
|
||||
let mut new_items: Vec<Arc<dyn PanelView>> = vec![];
|
||||
for item in items.into_iter() {
|
||||
let item: Arc<dyn PanelView> = Arc::new(item);
|
||||
new_items.push(item)
|
||||
}
|
||||
Self::new_tabs(new_items, active_ix, dock_area, cx)
|
||||
}
|
||||
|
||||
pub fn tab<P: Panel>(
|
||||
item: View<P>,
|
||||
dock_area: &View<DockArea>,
|
||||
cx: &mut WindowContext,
|
||||
) -> Self {
|
||||
Self::new_tabs(vec![Arc::new(item.clone())], None, dock_area, cx)
|
||||
}
|
||||
|
||||
fn new_tabs(
|
||||
items: Vec<Arc<dyn PanelView>>,
|
||||
active_ix: Option<usize>,
|
||||
dock_area: &View<DockArea>,
|
||||
cx: &mut WindowContext,
|
||||
|
|
@ -115,10 +120,8 @@ impl DockItem {
|
|||
let active_ix = active_ix.unwrap_or(0);
|
||||
let tab_panel = cx.new_view(|cx| {
|
||||
let mut tab_panel = TabPanel::new(None, dock_area.downgrade(), cx);
|
||||
|
||||
for item in items.iter() {
|
||||
let view = item.view();
|
||||
tab_panel.add_panel(view, cx)
|
||||
tab_panel.add_panel(item.clone(), cx)
|
||||
}
|
||||
|
||||
tab_panel
|
||||
|
|
@ -131,22 +134,11 @@ impl DockItem {
|
|||
}
|
||||
}
|
||||
|
||||
/// Create DockItem with a single panel, the `view` must implement `Panel`.
|
||||
pub fn panel<P>(view: View<P>) -> Self
|
||||
where
|
||||
P: Panel,
|
||||
{
|
||||
Self::Panel {
|
||||
view: Arc::new(view),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the views of the dock item.
|
||||
fn view(&self) -> Arc<dyn PanelView> {
|
||||
match self {
|
||||
Self::Split { view, .. } => Arc::new(view.clone()),
|
||||
Self::Tabs { view, .. } => Arc::new(view.clone()),
|
||||
Self::Panel { view } => view.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -156,16 +148,7 @@ impl DockItem {
|
|||
Self::Split { items, .. } => {
|
||||
items.iter().find_map(|item| item.find_panel(panel.clone()))
|
||||
}
|
||||
Self::Tabs { items, .. } => {
|
||||
items.iter().find_map(|item| item.find_panel(panel.clone()))
|
||||
}
|
||||
Self::Panel { view } => {
|
||||
if view == &panel {
|
||||
Some(view.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
Self::Tabs { items, .. } => items.iter().find(|item| *item == &panel).cloned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -245,11 +228,6 @@ impl DockArea {
|
|||
// Because we always wrap the DockItem::Panel in a DockItem::Tabs
|
||||
subscribe_zoom(view, dock_area.clone(), cx);
|
||||
}
|
||||
DockItem::Panel { .. } => {
|
||||
// The DockItem::Panel is not need to handle the zoom events
|
||||
// Because the DockItem::Panel is always wrapped in a DockItem::Tabs
|
||||
// So we only need to subscribe the zoom events on the TabPanel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -272,7 +250,6 @@ impl DockArea {
|
|||
match &self.items {
|
||||
DockItem::Split { view, .. } => view.clone().into_any_element(),
|
||||
DockItem::Tabs { view, .. } => view.clone().into_any_element(),
|
||||
DockItem::Panel { view } => view.view().into_any_element(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue