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(
|
DockItem::split(
|
||||||
Axis::Vertical,
|
Axis::Vertical,
|
||||||
vec![
|
vec![
|
||||||
DockItem::panel(StoryContainer::panel(
|
DockItem::tab(StoryContainer::panel::<IconStory>(cx), &dock_area, cx),
|
||||||
"Icon",
|
DockItem::tab(StoryContainer::panel::<CalendarStory>(cx), &dock_area, cx),
|
||||||
"Icon use examples",
|
|
||||||
IconStory::view(cx).into(),
|
|
||||||
cx,
|
|
||||||
)),
|
|
||||||
DockItem::panel(StoryContainer::panel(
|
|
||||||
"Calendar",
|
|
||||||
"A calendar component.",
|
|
||||||
CalendarStory::view(cx).into(),
|
|
||||||
cx,
|
|
||||||
)),
|
|
||||||
],
|
],
|
||||||
&dock_area,
|
&dock_area,
|
||||||
cx,
|
cx,
|
||||||
|
|
@ -80,83 +70,18 @@ impl StoryWorkspace {
|
||||||
vec![
|
vec![
|
||||||
DockItem::tabs(
|
DockItem::tabs(
|
||||||
vec![
|
vec![
|
||||||
DockItem::panel(StoryContainer::panel(
|
StoryContainer::panel::<ButtonStory>(cx),
|
||||||
"Button",
|
StoryContainer::panel::<InputStory>(cx),
|
||||||
"Displays a button or a component that looks like a button.",
|
StoryContainer::panel::<DropdownStory>(cx),
|
||||||
ButtonStory::view(cx).into(),
|
StoryContainer::panel::<ModalStory>(cx),
|
||||||
cx,
|
StoryContainer::panel::<PopupStory>(cx),
|
||||||
)),
|
StoryContainer::panel::<ListStory>(cx),
|
||||||
DockItem::panel(StoryContainer::panel(
|
StoryContainer::panel::<SwitchStory>(cx),
|
||||||
"Input",
|
StoryContainer::panel::<ProgressStory>(cx),
|
||||||
"A control that allows the user to input text.",
|
StoryContainer::panel::<TableStory>(cx),
|
||||||
InputStory::view(cx).into(),
|
StoryContainer::panel::<ImageStory>(cx),
|
||||||
cx,
|
StoryContainer::panel::<ResizableStory>(cx),
|
||||||
)),
|
StoryContainer::panel::<ScrollableStory>(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,
|
|
||||||
)),
|
|
||||||
],
|
],
|
||||||
None,
|
None,
|
||||||
&dock_area,
|
&dock_area,
|
||||||
|
|
@ -164,48 +89,29 @@ impl StoryWorkspace {
|
||||||
),
|
),
|
||||||
DockItem::tabs(
|
DockItem::tabs(
|
||||||
vec![
|
vec![
|
||||||
DockItem::panel(StoryContainer::panel(
|
StoryContainer::panel::<ProgressStory>(cx),
|
||||||
"Progress",
|
StoryContainer::panel::<TextStory>(cx),
|
||||||
"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,
|
|
||||||
))],
|
|
||||||
None,
|
None,
|
||||||
&dock_area,
|
&dock_area,
|
||||||
cx,
|
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,
|
&dock_area,
|
||||||
cx,
|
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.))],
|
vec![Some(px(300.)), None, Some(px(350.))],
|
||||||
&dock_area,
|
&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 {
|
impl Render for ButtonStory {
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||||
let disabled = self.disabled;
|
let disabled = self.disabled;
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,20 @@ pub struct CalendarStory {
|
||||||
default_range_mode_picker: View<DatePicker>,
|
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 {
|
impl CalendarStory {
|
||||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||||
cx.new_view(Self::new)
|
cx.new_view(Self::new)
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,20 @@ pub struct DropdownStory {
|
||||||
disabled_dropdown: View<Dropdown<Vec<SharedString>>>,
|
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 {
|
impl DropdownStory {
|
||||||
fn new(cx: &mut WindowContext) -> View<Self> {
|
fn new(cx: &mut WindowContext) -> View<Self> {
|
||||||
let countries = vec![
|
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 {
|
impl Render for IconStory {
|
||||||
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl gpui::IntoElement {
|
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl gpui::IntoElement {
|
||||||
v_flex().gap_3().child(
|
v_flex().gap_3().child(
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,16 @@ pub struct ImageStory {
|
||||||
inbox_img: SvgImg,
|
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 {
|
impl ImageStory {
|
||||||
pub fn new(_: &WindowContext) -> Self {
|
pub fn new(_: &WindowContext) -> Self {
|
||||||
let chart = charts_rs::PieChart::from_json(PIE_JSON).unwrap();
|
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 crate::section;
|
||||||
use ui::{
|
use ui::{
|
||||||
|
|
@ -8,11 +12,7 @@ use ui::{
|
||||||
input::{InputEvent, OtpInput, TextInput},
|
input::{InputEvent, OtpInput, TextInput},
|
||||||
prelude::FluentBuilder as _,
|
prelude::FluentBuilder as _,
|
||||||
scroll::ScrollbarAxis,
|
scroll::ScrollbarAxis,
|
||||||
v_flex,
|
v_flex, FocusableCycle, IconName, Sizable, StyledExt,
|
||||||
FocusableCycle,
|
|
||||||
IconName,
|
|
||||||
Sizable,
|
|
||||||
StyledExt,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
actions!(input_story, [Tab, TabPrev]);
|
actions!(input_story, [Tab, TabPrev]);
|
||||||
|
|
@ -44,6 +44,24 @@ pub struct InputStory {
|
||||||
opt_input_sized: View<OtpInput>,
|
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 {
|
impl InputStory {
|
||||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||||
cx.new_view(Self::new)
|
cx.new_view(Self::new)
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@ mod text_story;
|
||||||
mod tooltip_story;
|
mod tooltip_story;
|
||||||
mod webview_story;
|
mod webview_story;
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
pub use button_story::ButtonStory;
|
pub use button_story::ButtonStory;
|
||||||
pub use calendar_story::CalendarStory;
|
pub use calendar_story::CalendarStory;
|
||||||
pub use dropdown_story::DropdownStory;
|
pub use dropdown_story::DropdownStory;
|
||||||
|
|
@ -38,20 +36,19 @@ pub use webview_story::WebViewStory;
|
||||||
|
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, prelude::FluentBuilder as _, px, AnyView, AppContext, Div, EventEmitter,
|
actions, div, prelude::FluentBuilder as _, px, AnyView, AppContext, Div, EventEmitter,
|
||||||
FocusableView, Hsla, InteractiveElement, IntoElement, ParentElement, Pixels, Render,
|
FocusableView, Hsla, InteractiveElement, IntoElement, ParentElement, Render, SharedString,
|
||||||
SharedString, StatefulInteractiveElement, Styled as _, View, ViewContext, VisualContext,
|
StatefulInteractiveElement, Styled as _, View, ViewContext, VisualContext, WindowContext,
|
||||||
WindowContext,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use ui::{
|
use ui::{
|
||||||
divider::Divider,
|
divider::Divider,
|
||||||
dock::{Panel, PanelEvent, TabPanel, TitleStyle},
|
dock::{Panel, PanelEvent, TitleStyle},
|
||||||
h_flex,
|
h_flex,
|
||||||
label::Label,
|
label::Label,
|
||||||
notification::Notification,
|
notification::Notification,
|
||||||
popup_menu::PopupMenu,
|
popup_menu::PopupMenu,
|
||||||
theme::ActiveTheme,
|
theme::ActiveTheme,
|
||||||
v_flex, ContextModal, Placement,
|
v_flex, ContextModal,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
|
|
@ -87,6 +84,7 @@ pub struct StoryContainer {
|
||||||
width: Option<gpui::Pixels>,
|
width: Option<gpui::Pixels>,
|
||||||
height: Option<gpui::Pixels>,
|
height: Option<gpui::Pixels>,
|
||||||
story: Option<AnyView>,
|
story: Option<AnyView>,
|
||||||
|
story_klass: Option<SharedString>,
|
||||||
closeable: bool,
|
closeable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,66 +93,59 @@ pub enum ContainerEvent {
|
||||||
Close,
|
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 EventEmitter<ContainerEvent> for StoryContainer {}
|
||||||
|
|
||||||
impl StoryContainer {
|
impl StoryContainer {
|
||||||
pub fn new(
|
pub fn new(closeable: bool, cx: &mut WindowContext) -> Self {
|
||||||
name: impl Into<SharedString>,
|
|
||||||
description: impl Into<SharedString>,
|
|
||||||
closeable: bool,
|
|
||||||
cx: &mut WindowContext,
|
|
||||||
) -> Self {
|
|
||||||
let focus_handle = cx.focus_handle();
|
let focus_handle = cx.focus_handle();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
focus_handle,
|
focus_handle,
|
||||||
name: name.into(),
|
name: "".into(),
|
||||||
title_bg: None,
|
title_bg: None,
|
||||||
description: description.into(),
|
description: "".into(),
|
||||||
width: None,
|
width: None,
|
||||||
height: None,
|
height: None,
|
||||||
story: None,
|
story: None,
|
||||||
|
story_klass: None,
|
||||||
closeable,
|
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)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn add_panel(
|
pub fn panel<S: Story>(cx: &mut WindowContext) -> View<Self> {
|
||||||
name: impl Into<SharedString>,
|
let name = S::title();
|
||||||
description: impl Into<SharedString>,
|
let description = S::description();
|
||||||
story: AnyView,
|
let story = S::new_view(cx);
|
||||||
tab_panel: View<TabPanel>,
|
let story_klass = S::klass();
|
||||||
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| {
|
||||||
let view = cx.new_view(|cx| {
|
let mut story = Self::new(S::closeable(), cx).story(story, story_klass);
|
||||||
Self::new(name, description, closeable, cx)
|
story.name = name.into();
|
||||||
.story(story)
|
story.description = description.into();
|
||||||
.title_bg(title_bg)
|
story.title_bg = S::title_bg();
|
||||||
});
|
story
|
||||||
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
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
view
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn width(mut self, width: gpui::Pixels) -> Self {
|
pub fn width(mut self, width: gpui::Pixels) -> Self {
|
||||||
|
|
@ -167,13 +158,9 @@ impl StoryContainer {
|
||||||
self
|
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.story = Some(story);
|
||||||
self
|
self.story_klass = Some(story_klass.into());
|
||||||
}
|
|
||||||
|
|
||||||
pub fn title_bg(mut self, title_bg: Option<Hsla>) -> Self {
|
|
||||||
self.title_bg = title_bg;
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,20 @@ pub struct ListStory {
|
||||||
selected_company: Option<Company>,
|
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 {
|
impl ListStory {
|
||||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||||
cx.new_view(Self::new)
|
cx.new_view(Self::new)
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,20 @@ pub struct ModalStory {
|
||||||
model_padding: bool,
|
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 {
|
impl ModalStory {
|
||||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||||
cx.new_view(Self::new)
|
cx.new_view(Self::new)
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,20 @@ pub struct PopupStory {
|
||||||
window_mode: bool,
|
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 {
|
impl PopupStory {
|
||||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||||
cx.new_view(Self::new)
|
cx.new_view(Self::new)
|
||||||
|
|
@ -199,9 +213,10 @@ impl Render for PopupStory {
|
||||||
.small(),
|
.small(),
|
||||||
)
|
)
|
||||||
.into_any()
|
.into_any()
|
||||||
}).max_w(px(600.))
|
})
|
||||||
|
.max_w(px(600.))
|
||||||
})
|
})
|
||||||
})
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
|
|
@ -209,7 +224,7 @@ impl Render for PopupStory {
|
||||||
.anchor(AnchorCorner::TopRight)
|
.anchor(AnchorCorner::TopRight)
|
||||||
.trigger(Button::new("info-top-right", cx).label("Top Right"))
|
.trigger(Button::new("info-top-right", cx).label("Top Right"))
|
||||||
.content(|cx| {
|
.content(|cx| {
|
||||||
cx.new_view(|cx|
|
cx.new_view(|cx| {
|
||||||
PopoverContent::new(cx, |cx| {
|
PopoverContent::new(cx, |cx| {
|
||||||
v_flex()
|
v_flex()
|
||||||
.gap_4()
|
.gap_4()
|
||||||
|
|
@ -223,7 +238,8 @@ impl Render for PopupStory {
|
||||||
.small(),
|
.small(),
|
||||||
)
|
)
|
||||||
.into_any()
|
.into_any()
|
||||||
}))
|
})
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -284,11 +300,13 @@ impl Render for PopupStory {
|
||||||
.w(px(300.)),
|
.w(px(300.)),
|
||||||
)
|
)
|
||||||
.content(|cx| {
|
.content(|cx| {
|
||||||
cx.new_view(|cx|
|
cx.new_view(|cx| {
|
||||||
PopoverContent::new(cx, |cx| {
|
PopoverContent::new(cx, |cx| {
|
||||||
v_flex()
|
v_flex()
|
||||||
.gap_4()
|
.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(Divider::horizontal())
|
||||||
.child(
|
.child(
|
||||||
Button::new("info1", cx)
|
Button::new("info1", cx)
|
||||||
|
|
@ -297,7 +315,8 @@ impl Render for PopupStory {
|
||||||
.small(),
|
.small(),
|
||||||
)
|
)
|
||||||
.into_any()
|
.into_any()
|
||||||
}))
|
})
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,16 @@ pub struct ProgressStory {
|
||||||
slider2_value: f32,
|
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 {
|
impl ProgressStory {
|
||||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||||
cx.new_view(Self::new)
|
cx.new_view(Self::new)
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,20 @@ pub struct ResizableStory {
|
||||||
group2: View<ResizablePanelGroup>,
|
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 {
|
impl ResizableStory {
|
||||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||||
cx.new_view(|cx| Self::new(cx))
|
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 {
|
impl Render for ScrollableStory {
|
||||||
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl gpui::IntoElement {
|
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl gpui::IntoElement {
|
||||||
let view = cx.view().clone();
|
let view = cx.view().clone();
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,20 @@ pub struct SwitchStory {
|
||||||
switch3: bool,
|
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 {
|
impl SwitchStory {
|
||||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||||
cx.new_view(|cx| Self::new(cx))
|
cx.new_view(|cx| Self::new(cx))
|
||||||
|
|
|
||||||
|
|
@ -362,6 +362,20 @@ pub struct TableStory {
|
||||||
table: View<Table<CustomerTableDelegate>>,
|
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 {
|
impl TableStory {
|
||||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||||
cx.new_view(Self::new)
|
cx.new_view(Self::new)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,20 @@ pub struct TextStory {
|
||||||
masked: bool,
|
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 {
|
impl TextStory {
|
||||||
pub(crate) fn new(_cx: &mut WindowContext) -> Self {
|
pub(crate) fn new(_cx: &mut WindowContext) -> Self {
|
||||||
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 {
|
impl Render for TooltipStory {
|
||||||
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl gpui::IntoElement {
|
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl gpui::IntoElement {
|
||||||
v_flex()
|
v_flex()
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,16 @@ pub struct WebViewStory {
|
||||||
address_input: View<TextInput>,
|
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 {
|
impl WebViewStory {
|
||||||
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||||
let focus_handle = cx.focus_handle();
|
let focus_handle = cx.focus_handle();
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,10 @@ pub enum DockItem {
|
||||||
view: View<StackPanel>,
|
view: View<StackPanel>,
|
||||||
},
|
},
|
||||||
Tabs {
|
Tabs {
|
||||||
items: Vec<DockItem>,
|
items: Vec<Arc<dyn PanelView>>,
|
||||||
active_ix: usize,
|
active_ix: usize,
|
||||||
view: View<TabPanel>,
|
view: View<TabPanel>,
|
||||||
},
|
},
|
||||||
Panel {
|
|
||||||
view: Arc<dyn PanelView>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DockItem {
|
impl DockItem {
|
||||||
|
|
@ -68,26 +65,12 @@ impl DockItem {
|
||||||
let stack_panel = cx.new_view(|cx| {
|
let stack_panel = cx.new_view(|cx| {
|
||||||
let mut stack_panel = StackPanel::new(axis, cx);
|
let mut stack_panel = StackPanel::new(axis, cx);
|
||||||
for (i, item) in items.iter_mut().enumerate() {
|
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 view = item.view();
|
||||||
let size = sizes.get(i).copied().flatten();
|
let size = sizes.get(i).copied().flatten();
|
||||||
stack_panel.add_panel(view.clone(), size, dock_area.downgrade(), cx)
|
stack_panel.add_panel(view.clone(), size, dock_area.downgrade(), cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, item) in items.iter().enumerate() {
|
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 view = item.view();
|
||||||
let size = sizes.get(i).copied().flatten();
|
let size = sizes.get(i).copied().flatten();
|
||||||
stack_panel.add_panel(view.clone(), size, dock_area.downgrade(), cx)
|
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.
|
/// 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.
|
/// The `active_ix` is the index of the active tab, if `None` the first tab is active.
|
||||||
pub fn tabs(
|
pub fn tabs<P: Panel>(
|
||||||
items: Vec<DockItem>,
|
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>,
|
active_ix: Option<usize>,
|
||||||
dock_area: &View<DockArea>,
|
dock_area: &View<DockArea>,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
|
|
@ -115,10 +120,8 @@ impl DockItem {
|
||||||
let active_ix = active_ix.unwrap_or(0);
|
let active_ix = active_ix.unwrap_or(0);
|
||||||
let tab_panel = cx.new_view(|cx| {
|
let tab_panel = cx.new_view(|cx| {
|
||||||
let mut tab_panel = TabPanel::new(None, dock_area.downgrade(), cx);
|
let mut tab_panel = TabPanel::new(None, dock_area.downgrade(), cx);
|
||||||
|
|
||||||
for item in items.iter() {
|
for item in items.iter() {
|
||||||
let view = item.view();
|
tab_panel.add_panel(item.clone(), cx)
|
||||||
tab_panel.add_panel(view, cx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tab_panel
|
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.
|
/// Returns the views of the dock item.
|
||||||
fn view(&self) -> Arc<dyn PanelView> {
|
fn view(&self) -> Arc<dyn PanelView> {
|
||||||
match self {
|
match self {
|
||||||
Self::Split { view, .. } => Arc::new(view.clone()),
|
Self::Split { view, .. } => Arc::new(view.clone()),
|
||||||
Self::Tabs { 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, .. } => {
|
Self::Split { items, .. } => {
|
||||||
items.iter().find_map(|item| item.find_panel(panel.clone()))
|
items.iter().find_map(|item| item.find_panel(panel.clone()))
|
||||||
}
|
}
|
||||||
Self::Tabs { items, .. } => {
|
Self::Tabs { items, .. } => items.iter().find(|item| *item == &panel).cloned(),
|
||||||
items.iter().find_map(|item| item.find_panel(panel.clone()))
|
|
||||||
}
|
|
||||||
Self::Panel { view } => {
|
|
||||||
if view == &panel {
|
|
||||||
Some(view.clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -245,11 +228,6 @@ impl DockArea {
|
||||||
// Because we always wrap the DockItem::Panel in a DockItem::Tabs
|
// Because we always wrap the DockItem::Panel in a DockItem::Tabs
|
||||||
subscribe_zoom(view, dock_area.clone(), cx);
|
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 {
|
match &self.items {
|
||||||
DockItem::Split { view, .. } => view.clone().into_any_element(),
|
DockItem::Split { view, .. } => view.clone().into_any_element(),
|
||||||
DockItem::Tabs { 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