WIP: Panel
This commit is contained in:
parent
74ac6eb8a3
commit
30afc8b1d2
8 changed files with 201 additions and 16 deletions
|
@ -27,21 +27,24 @@ pub fn derive_element(input: TokenStream) -> TokenStream {
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut #state_type,
|
state: &mut #state_type,
|
||||||
cx: &mut gpui3::ViewContext<V>,
|
cx: &mut gpui3::ViewContext<Self::State>,
|
||||||
) -> anyhow::Result<(gpui3::LayoutId, Self::FrameState)> {
|
) -> anyhow::Result<(gpui3::LayoutId, Self::FrameState)> {
|
||||||
let mut rendered_element = self.render(state, cx).into_element().into_any();
|
use gpui3::IntoAnyElement;
|
||||||
|
|
||||||
|
let mut rendered_element = self.render(cx).into_any();
|
||||||
let layout_id = rendered_element.layout(state, cx)?;
|
let layout_id = rendered_element.layout(state, cx)?;
|
||||||
Ok((layout_id, rendered_element))
|
Ok((layout_id, rendered_element))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(
|
fn paint(
|
||||||
&mut self,
|
&mut self,
|
||||||
layout: &gpui3::Layout,
|
layout: gpui3::Layout,
|
||||||
state: &mut #state_type,
|
state: &mut Self::State,
|
||||||
rendered_element: &mut Self::FrameState,
|
rendered_element: &mut Self::FrameState,
|
||||||
cx: &mut gpui3::ViewContext<V>,
|
cx: &mut gpui3::ViewContext<Self::State>,
|
||||||
) {
|
) -> anyhow::Result<()> {
|
||||||
rendered_element.paint(layout.origin, state, cx);
|
// TODO: Where do we get the `offset` from?
|
||||||
|
rendered_element.paint(state, None, cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
pub mod prelude;
|
mod children;
|
||||||
mod components;
|
mod components;
|
||||||
mod elements;
|
mod elements;
|
||||||
|
pub mod prelude;
|
||||||
|
mod tokens;
|
||||||
|
|
||||||
|
pub use children::*;
|
||||||
pub use components::*;
|
pub use components::*;
|
||||||
pub use elements::*;
|
pub use elements::*;
|
||||||
|
pub use tokens::*;
|
||||||
|
|
7
crates/storybook2/src/ui/children.rs
Normal file
7
crates/storybook2/src/ui/children.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
|
use gpui3::{AnyElement, ViewContext};
|
||||||
|
|
||||||
|
pub type HackyChildren<S> = fn(&mut ViewContext<S>, &dyn Any) -> Vec<AnyElement<S>>;
|
||||||
|
|
||||||
|
pub type HackyChildrenPayload = Box<dyn Any>;
|
|
@ -0,0 +1,3 @@
|
||||||
|
mod panel;
|
||||||
|
|
||||||
|
pub use panel::*;
|
146
crates/storybook2/src/ui/components/panel.rs
Normal file
146
crates/storybook2/src/ui/components/panel.rs
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use gpui3::AbsoluteLength;
|
||||||
|
|
||||||
|
use crate::themes::rose_pine_dawn;
|
||||||
|
use crate::ui::prelude::*;
|
||||||
|
use crate::ui::{token, v_stack};
|
||||||
|
|
||||||
|
#[derive(Default, Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||||
|
pub enum PanelAllowedSides {
|
||||||
|
LeftOnly,
|
||||||
|
RightOnly,
|
||||||
|
BottomOnly,
|
||||||
|
#[default]
|
||||||
|
LeftAndRight,
|
||||||
|
All,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PanelAllowedSides {
|
||||||
|
/// Return a `HashSet` that contains the allowable `PanelSide`s.
|
||||||
|
pub fn allowed_sides(&self) -> HashSet<PanelSide> {
|
||||||
|
match self {
|
||||||
|
Self::LeftOnly => HashSet::from_iter([PanelSide::Left]),
|
||||||
|
Self::RightOnly => HashSet::from_iter([PanelSide::Right]),
|
||||||
|
Self::BottomOnly => HashSet::from_iter([PanelSide::Bottom]),
|
||||||
|
Self::LeftAndRight => HashSet::from_iter([PanelSide::Left, PanelSide::Right]),
|
||||||
|
Self::All => HashSet::from_iter([PanelSide::Left, PanelSide::Right, PanelSide::Bottom]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||||
|
pub enum PanelSide {
|
||||||
|
#[default]
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
Bottom,
|
||||||
|
}
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct Panel {
|
||||||
|
scroll_state: ScrollState,
|
||||||
|
current_side: PanelSide,
|
||||||
|
/// Defaults to PanelAllowedSides::LeftAndRight
|
||||||
|
allowed_sides: PanelAllowedSides,
|
||||||
|
initial_width: AbsoluteLength,
|
||||||
|
width: Option<AbsoluteLength>,
|
||||||
|
// children: HackyChildren<V>,
|
||||||
|
// payload: HackyChildrenPayload,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Panel {
|
||||||
|
pub fn new(
|
||||||
|
scroll_state: ScrollState,
|
||||||
|
// children: HackyChildren<S>,
|
||||||
|
// payload: HackyChildrenPayload,
|
||||||
|
) -> Self {
|
||||||
|
let token = token();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
scroll_state,
|
||||||
|
current_side: PanelSide::default(),
|
||||||
|
allowed_sides: PanelAllowedSides::default(),
|
||||||
|
initial_width: token.default_panel_size,
|
||||||
|
width: None,
|
||||||
|
// children,
|
||||||
|
// payload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn initial_width(mut self, initial_width: AbsoluteLength) -> Self {
|
||||||
|
self.initial_width = initial_width;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn width(mut self, width: AbsoluteLength) -> Self {
|
||||||
|
self.width = Some(width);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn allowed_sides(mut self, allowed_sides: PanelAllowedSides) -> Self {
|
||||||
|
self.allowed_sides = allowed_sides;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn side(mut self, side: PanelSide) -> Self {
|
||||||
|
let allowed_sides = self.allowed_sides.allowed_sides();
|
||||||
|
|
||||||
|
if allowed_sides.contains(&side) {
|
||||||
|
self.current_side = side;
|
||||||
|
} else {
|
||||||
|
panic!(
|
||||||
|
"The panel side {:?} was not added as allowed before it was set.",
|
||||||
|
side
|
||||||
|
);
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render<S: 'static + Send + Sync>(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
let token = token();
|
||||||
|
let theme = rose_pine_dawn();
|
||||||
|
|
||||||
|
let panel_base;
|
||||||
|
let current_width = self.width.unwrap_or(self.initial_width);
|
||||||
|
|
||||||
|
match self.current_side {
|
||||||
|
PanelSide::Left => {
|
||||||
|
panel_base = v_stack()
|
||||||
|
.flex_initial()
|
||||||
|
.h_full()
|
||||||
|
// .w(current_width)
|
||||||
|
.w_4()
|
||||||
|
.fill(theme.middle.base.default.background)
|
||||||
|
.border_r()
|
||||||
|
.border_color(theme.middle.base.default.border);
|
||||||
|
}
|
||||||
|
PanelSide::Right => {
|
||||||
|
panel_base = v_stack()
|
||||||
|
.flex_initial()
|
||||||
|
.h_full()
|
||||||
|
// .w(current_width)
|
||||||
|
.w_4()
|
||||||
|
.fill(theme.middle.base.default.background)
|
||||||
|
.border_l()
|
||||||
|
.border_color(theme.middle.base.default.border);
|
||||||
|
}
|
||||||
|
PanelSide::Bottom => {
|
||||||
|
panel_base = v_stack()
|
||||||
|
.flex_initial()
|
||||||
|
.w_full()
|
||||||
|
// .h(current_width)
|
||||||
|
.h_4()
|
||||||
|
.fill(theme.middle.base.default.background)
|
||||||
|
.border_t()
|
||||||
|
.border_color(theme.middle.base.default.border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panel_base
|
||||||
|
|
||||||
|
// panel_base.children_any((self.children)(cx, self.payload.as_ref()))
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1,3 @@
|
||||||
pub use gpui3::StyleHelpers;
|
pub use gpui3::{Element, ScrollState, StyleHelpers, ViewContext};
|
||||||
|
|
||||||
|
pub use crate::ui::{HackyChildren, HackyChildrenPayload};
|
||||||
|
|
24
crates/storybook2/src/ui/tokens.rs
Normal file
24
crates/storybook2/src/ui/tokens.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
use gpui3::{hsla, rems, AbsoluteLength, Hsla};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct Token {
|
||||||
|
pub list_indent_depth: AbsoluteLength,
|
||||||
|
pub default_panel_size: AbsoluteLength,
|
||||||
|
pub state_hover_background: Hsla,
|
||||||
|
pub state_active_background: Hsla,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Token {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
list_indent_depth: AbsoluteLength::Rems(rems(0.5)),
|
||||||
|
default_panel_size: AbsoluteLength::Rems(rems(16.)),
|
||||||
|
state_hover_background: hsla(0.0, 0.0, 0.0, 0.08),
|
||||||
|
state_active_background: hsla(0.0, 0.0, 0.0, 0.16),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn token() -> Token {
|
||||||
|
Token::default()
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::ui::Stack;
|
use crate::ui::prelude::*;
|
||||||
|
use crate::ui::{Panel, Stack};
|
||||||
use crate::{
|
use crate::{
|
||||||
collab_panel::{collab_panel, CollabPanel},
|
collab_panel::{collab_panel, CollabPanel},
|
||||||
theme::theme,
|
theme::theme,
|
||||||
|
@ -33,12 +34,7 @@ impl Workspace {
|
||||||
.size_full()
|
.size_full()
|
||||||
.v_stack()
|
.v_stack()
|
||||||
.fill(theme.lowest.base.default.background)
|
.fill(theme.lowest.base.default.background)
|
||||||
.child(
|
.child(Panel::new(ScrollState::default()))
|
||||||
div()
|
|
||||||
.size_full()
|
|
||||||
.flex()
|
|
||||||
.fill(theme.middle.positive.default.background),
|
|
||||||
)
|
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.size_full()
|
.size_full()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue