Detailed changes
@@ -27,21 +27,24 @@ pub fn derive_element(input: TokenStream) -> TokenStream {
fn layout(
&mut self,
state: &mut #state_type,
- cx: &mut gpui3::ViewContext<V>,
+ cx: &mut gpui3::ViewContext<Self::State>,
) -> 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)?;
Ok((layout_id, rendered_element))
}
fn paint(
&mut self,
- layout: &gpui3::Layout,
- state: &mut #state_type,
+ layout: gpui3::Layout,
+ state: &mut Self::State,
rendered_element: &mut Self::FrameState,
- cx: &mut gpui3::ViewContext<V>,
- ) {
- rendered_element.paint(layout.origin, state, cx);
+ cx: &mut gpui3::ViewContext<Self::State>,
+ ) -> anyhow::Result<()> {
+ // 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 elements;
+pub mod prelude;
+mod tokens;
+pub use children::*;
pub use components::*;
pub use elements::*;
+pub use tokens::*;
@@ -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::*;
@@ -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};
@@ -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::{
collab_panel::{collab_panel, CollabPanel},
theme::theme,
@@ -33,12 +34,7 @@ impl Workspace {
.size_full()
.v_stack()
.fill(theme.lowest.base.default.background)
- .child(
- div()
- .size_full()
- .flex()
- .fill(theme.middle.positive.default.background),
- )
+ .child(Panel::new(ScrollState::default()))
.child(
div()
.size_full()