Add Progress (#21)
This commit is contained in:
parent
56eb7147d9
commit
e1aed0a03d
9 changed files with 166 additions and 14 deletions
|
|
@ -2,7 +2,7 @@ use gpui::*;
|
||||||
use prelude::FluentBuilder as _;
|
use prelude::FluentBuilder as _;
|
||||||
use story::{
|
use story::{
|
||||||
ButtonStory, CheckboxStory, DropdownStory, ImageStory, InputStory, ListStory, PickerStory,
|
ButtonStory, CheckboxStory, DropdownStory, ImageStory, InputStory, ListStory, PickerStory,
|
||||||
PopoverStory, StoryContainer, SwitchStory, TableStory, TooltipStory,
|
PopoverStory, ProgressStory, StoryContainer, SwitchStory, TableStory, TooltipStory,
|
||||||
};
|
};
|
||||||
use workspace::{dock::DockPosition, TitleBar, Workspace};
|
use workspace::{dock::DockPosition, TitleBar, Workspace};
|
||||||
|
|
||||||
|
|
@ -137,6 +137,15 @@ impl StoryWorkspace {
|
||||||
)
|
)
|
||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
|
StoryContainer::add_pane(
|
||||||
|
"Progress",
|
||||||
|
"Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.",
|
||||||
|
ProgressStory::view(cx).into(),
|
||||||
|
workspace.clone(),
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
.detach();
|
||||||
|
|
||||||
Self { workspace }
|
Self { workspace }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ mod input_story;
|
||||||
mod list_story;
|
mod list_story;
|
||||||
mod picker_story;
|
mod picker_story;
|
||||||
mod popover_story;
|
mod popover_story;
|
||||||
|
mod progress_story;
|
||||||
mod switch_story;
|
mod switch_story;
|
||||||
mod table_story;
|
mod table_story;
|
||||||
mod tooltip_story;
|
mod tooltip_story;
|
||||||
|
|
@ -18,15 +19,15 @@ pub use input_story::InputStory;
|
||||||
pub use list_story::ListStory;
|
pub use list_story::ListStory;
|
||||||
pub use picker_story::PickerStory;
|
pub use picker_story::PickerStory;
|
||||||
pub use popover_story::PopoverStory;
|
pub use popover_story::PopoverStory;
|
||||||
|
pub use progress_story::ProgressStory;
|
||||||
pub use switch_story::SwitchStory;
|
pub use switch_story::SwitchStory;
|
||||||
pub use table_story::TableStory;
|
pub use table_story::TableStory;
|
||||||
pub use tooltip_story::TooltipStory;
|
pub use tooltip_story::TooltipStory;
|
||||||
|
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, prelude::FluentBuilder as _, px, AnyElement, AnyView, AppContext, Div, EventEmitter,
|
div, prelude::FluentBuilder as _, px, AnyElement, AnyView, AppContext, Div, EventEmitter,
|
||||||
FocusableView, InteractiveElement, IntoElement, ParentElement, Pixels, Render,
|
FocusableView, InteractiveElement, IntoElement, ParentElement, Pixels, Render, SharedString,
|
||||||
SharedString, StatefulInteractiveElement, Styled as _, Task, View, ViewContext, VisualContext,
|
StatefulInteractiveElement, Styled as _, Task, View, ViewContext, VisualContext, WindowContext,
|
||||||
WindowContext,
|
|
||||||
};
|
};
|
||||||
use workspace::{
|
use workspace::{
|
||||||
dock::{DockPosition, Panel, PanelEvent},
|
dock::{DockPosition, Panel, PanelEvent},
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ impl Render for PopoverStory {
|
||||||
.trigger(Button::new("popup-menu-1", cx).icon(IconName::Info))
|
.trigger(Button::new("popup-menu-1", cx).icon(IconName::Info))
|
||||||
.content(move |cx| {
|
.content(move |cx| {
|
||||||
let focus_handle = focus_handle.clone();
|
let focus_handle = focus_handle.clone();
|
||||||
PopupMenu::build(cx, |mut this, cx| {
|
PopupMenu::build(cx, |mut this, _cx| {
|
||||||
this.content(focus_handle)
|
this.content(focus_handle)
|
||||||
.menu("Copy", Box::new(Copy))
|
.menu("Copy", Box::new(Copy))
|
||||||
.menu("Cut", Box::new(Cut))
|
.menu("Cut", Box::new(Cut))
|
||||||
|
|
|
||||||
78
crates/story/src/progress_story.rs
Normal file
78
crates/story/src/progress_story.rs
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
use gpui::{
|
||||||
|
div, IntoElement, ParentElement, Render, Styled, View, ViewContext, VisualContext,
|
||||||
|
WindowContext,
|
||||||
|
};
|
||||||
|
use ui::{button::Button, h_flex, progress::Progress, v_flex, Clickable, IconName};
|
||||||
|
|
||||||
|
pub struct ProgressStory {
|
||||||
|
value: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProgressStory {
|
||||||
|
pub fn view(cx: &mut WindowContext) -> View<Self> {
|
||||||
|
cx.new_view(|_| Self { value: 50. })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_value(&mut self, value: f32) {
|
||||||
|
self.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render for ProgressStory {
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||||
|
v_flex()
|
||||||
|
.items_center()
|
||||||
|
.gap_y_3()
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.gap_x_2()
|
||||||
|
.child(
|
||||||
|
Button::new("button-1", cx)
|
||||||
|
.label("0%")
|
||||||
|
.on_click(cx.listener(|this, _, _| {
|
||||||
|
this.set_value(0.);
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("button-2", cx)
|
||||||
|
.label("25%")
|
||||||
|
.on_click(cx.listener(|this, _, _| {
|
||||||
|
this.set_value(25.);
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("button-3", cx)
|
||||||
|
.label("75%")
|
||||||
|
.on_click(cx.listener(|this, _, _| {
|
||||||
|
this.set_value(75.);
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("button-4", cx)
|
||||||
|
.label("100%")
|
||||||
|
.on_click(cx.listener(|this, _, _| {
|
||||||
|
this.set_value(100.);
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(div().w_1_2().child(Progress::new().value(self.value)))
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.gap_x_2()
|
||||||
|
.child(
|
||||||
|
Button::new("button-5", cx)
|
||||||
|
.icon(IconName::Minus)
|
||||||
|
.on_click(cx.listener(|this, _, _| {
|
||||||
|
this.set_value(this.value - 1.);
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("button-6", cx)
|
||||||
|
.icon(IconName::Plus)
|
||||||
|
.on_click(cx.listener(|this, _, _| {
|
||||||
|
this.set_value(this.value + 1.);
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,7 +20,7 @@ pub enum IconName {
|
||||||
EllipsisVertical,
|
EllipsisVertical,
|
||||||
Search,
|
Search,
|
||||||
Delete,
|
Delete,
|
||||||
CicleX,
|
CircleX,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IconName {
|
impl IconName {
|
||||||
|
|
@ -40,7 +40,7 @@ impl IconName {
|
||||||
IconName::EllipsisVertical => "icons/ellipsis-vertical.svg",
|
IconName::EllipsisVertical => "icons/ellipsis-vertical.svg",
|
||||||
IconName::Search => "icons/search.svg",
|
IconName::Search => "icons/search.svg",
|
||||||
IconName::Delete => "icons/delete.svg",
|
IconName::Delete => "icons/delete.svg",
|
||||||
IconName::CicleX => "icons/circle-x.svg",
|
IconName::CircleX => "icons/circle-x.svg",
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,19 @@ mod svg_img;
|
||||||
|
|
||||||
pub mod button;
|
pub mod button;
|
||||||
pub mod checkbox;
|
pub mod checkbox;
|
||||||
pub mod label;
|
|
||||||
pub mod prelude;
|
|
||||||
pub mod theme;
|
|
||||||
pub use styled_ext::StyledExt;
|
|
||||||
pub mod divider;
|
pub mod divider;
|
||||||
pub mod dropdown;
|
pub mod dropdown;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
|
pub mod label;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod popover;
|
pub mod popover;
|
||||||
pub mod popup_menu;
|
pub mod popup_menu;
|
||||||
|
pub mod prelude;
|
||||||
|
pub mod progress;
|
||||||
pub mod switch;
|
pub mod switch;
|
||||||
pub mod tab;
|
pub mod tab;
|
||||||
pub mod table;
|
pub mod table;
|
||||||
|
pub mod theme;
|
||||||
pub mod tooltip;
|
pub mod tooltip;
|
||||||
|
|
||||||
pub use clickable::Clickable;
|
pub use clickable::Clickable;
|
||||||
|
|
@ -33,6 +33,7 @@ pub use disableable::Disableable;
|
||||||
pub use event::InterativeElementExt;
|
pub use event::InterativeElementExt;
|
||||||
pub use focusable::FocusableCycle;
|
pub use focusable::FocusableCycle;
|
||||||
pub use selectable::{Selectable, Selection};
|
pub use selectable::{Selectable, Selection};
|
||||||
|
pub use styled_ext::StyledExt;
|
||||||
|
|
||||||
pub use colors::*;
|
pub use colors::*;
|
||||||
pub use icon::*;
|
pub use icon::*;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use gpui::{
|
||||||
WindowContext,
|
WindowContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{h_flex, list::ListItem, theme::ActiveTheme, v_flex, Icon, StyledExt};
|
use crate::{h_flex, list::ListItem, theme::ActiveTheme, v_flex, Icon};
|
||||||
|
|
||||||
actions!(menu, [Confirm, Dismiss, SelectNext, SelectPrev]);
|
actions!(menu, [Confirm, Dismiss, SelectNext, SelectPrev]);
|
||||||
|
|
||||||
|
|
|
||||||
63
crates/ui/src/progress.rs
Normal file
63
crates/ui/src/progress.rs
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
use gpui::{
|
||||||
|
div, prelude::FluentBuilder, px, relative, IntoElement, ParentElement, RenderOnce, Styled,
|
||||||
|
WindowContext,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
h_flex,
|
||||||
|
theme::{ActiveTheme, Colorize},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(IntoElement)]
|
||||||
|
pub struct Progress {
|
||||||
|
value: f32,
|
||||||
|
height: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Progress {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Progress {
|
||||||
|
value: Default::default(),
|
||||||
|
height: 8.,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(mut self, value: f32) -> Self {
|
||||||
|
self.value = value;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderOnce for Progress {
|
||||||
|
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
|
||||||
|
let rounded = px(self.height / 2.);
|
||||||
|
let relative_w = relative(match self.value {
|
||||||
|
v if v < 0. => 0.,
|
||||||
|
v if v > 100. => 1.,
|
||||||
|
v => v / 100.,
|
||||||
|
});
|
||||||
|
|
||||||
|
h_flex()
|
||||||
|
.h(px(self.height))
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.map(|this| match self.value {
|
||||||
|
v if v >= 100. => this.rounded(rounded),
|
||||||
|
_ => this.rounded_l(rounded),
|
||||||
|
})
|
||||||
|
.h_full()
|
||||||
|
.w(relative_w)
|
||||||
|
.bg(cx.theme().primary),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.map(|this| match self.value {
|
||||||
|
v if v <= 0. => this.rounded(rounded),
|
||||||
|
_ => this.rounded_r(rounded),
|
||||||
|
})
|
||||||
|
.h_full()
|
||||||
|
.flex_1()
|
||||||
|
.bg(cx.theme().primary.opacity(0.2)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,8 +13,8 @@ use gpui::{
|
||||||
actions, div, impl_actions, prelude::FluentBuilder as _, px, AppContext, DefiniteLength,
|
actions, div, impl_actions, prelude::FluentBuilder as _, px, AppContext, DefiniteLength,
|
||||||
DragMoveEvent, Element as _, EntityId, EventEmitter, FocusHandle, FocusOutEvent, FocusableView,
|
DragMoveEvent, Element as _, EntityId, EventEmitter, FocusHandle, FocusOutEvent, FocusableView,
|
||||||
InteractiveElement as _, IntoElement, KeyContext, ParentElement, Pixels, Point, Render,
|
InteractiveElement as _, IntoElement, KeyContext, ParentElement, Pixels, Point, Render,
|
||||||
RenderOnce as _, ScrollHandle, StatefulInteractiveElement, Styled, Subscription, Task, View,
|
ScrollHandle, StatefulInteractiveElement, Styled, Subscription, Task, View, ViewContext,
|
||||||
ViewContext, VisualContext as _, WeakFocusHandle, WeakView, WindowContext,
|
VisualContext as _, WeakFocusHandle, WeakView, WindowContext,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue