WIP: Icons not yet rendering

This commit is contained in:
Nathan Sobo 2023-09-05 16:40:52 -06:00
parent 6cb9cf70b7
commit 85aedf9bed
8 changed files with 126 additions and 29 deletions

View file

@ -1291,9 +1291,6 @@ impl<'a> WindowContext<'a> {
pub fn push_text_style(&mut self, refinement: &TextStyleRefinement) -> Result<()> { pub fn push_text_style(&mut self, refinement: &TextStyleRefinement) -> Result<()> {
let mut style = self.text_style(); let mut style = self.text_style();
style.refine(refinement, self.font_cache())?; style.refine(refinement, self.font_cache())?;
dbg!(&style);
self.window.text_style_stack.push(style); self.window.text_style_stack.push(style);
Ok(()) Ok(())
} }

View file

@ -5,7 +5,7 @@ use gpui::geometry::vector::Vector2F;
pub use gpui::{Layout, LayoutId}; pub use gpui::{Layout, LayoutId};
use smallvec::SmallVec; use smallvec::SmallVec;
pub trait Element<V: 'static>: 'static { pub trait Element<V: 'static>: 'static + IntoElement<V> {
type PaintState; type PaintState;
fn layout( fn layout(

View file

@ -1,6 +1,8 @@
pub mod div; pub mod div;
pub mod hoverable; pub mod hoverable;
pub mod pressable; pub mod pressable;
pub mod svg;
pub mod text; pub mod text;
pub use div::div; pub use div::div;
pub use svg::svg;

View file

@ -0,0 +1,81 @@
use crate::{
self as gpui2, scene,
style::{Style, StyleHelpers, Styleable},
Element, IntoElement, Layout, LayoutId, Rgba,
};
use refineable::RefinementCascade;
use std::borrow::Cow;
#[derive(IntoElement)]
pub struct Svg {
path: Option<Cow<'static, str>>,
style: RefinementCascade<Style>,
}
pub fn svg() -> Svg {
Svg {
path: None,
style: RefinementCascade::<Style>::default(),
}
}
impl Svg {
pub fn path(mut self, path: impl Into<Cow<'static, str>>) -> Self {
self.path = Some(path.into());
self
}
}
impl<V: 'static> Element<V> for Svg {
type PaintState = ();
fn layout(
&mut self,
_: &mut V,
cx: &mut crate::LayoutContext<V>,
) -> anyhow::Result<(LayoutId, Self::PaintState)>
where
Self: Sized,
{
let style = self.computed_style();
Ok((cx.add_layout_node(style, [])?, ()))
}
fn paint(
&mut self,
_: &mut V,
layout: &Layout,
_: &mut Self::PaintState,
cx: &mut crate::paint_context::PaintContext<V>,
) where
Self: Sized,
{
let fill_color = self.computed_style().fill.and_then(|fill| fill.color());
if let Some((path, fill_color)) = self.path.as_ref().zip(fill_color) {
if let Ok(svg_tree) = cx.asset_cache.svg(path) {
let icon = scene::Icon {
bounds: layout.bounds,
svg: svg_tree,
path: path.clone(),
color: Rgba::from(fill_color).into(),
};
cx.scene.push_icon(icon);
}
}
}
}
impl Styleable for Svg {
type Style = Style;
fn style_cascade(&mut self) -> &mut refineable::RefinementCascade<Self::Style> {
&mut self.style
}
fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
self.style.base()
}
}
impl StyleHelpers for Svg {}

View file

@ -90,6 +90,14 @@ impl<V: 'static> Element<V> for Text {
} }
} }
impl<V: 'static> IntoElement<V> for Text {
type Element = Self;
fn into_element(self) -> Self::Element {
self
}
}
pub struct TextLayout { pub struct TextLayout {
line_layout: Arc<LineLayout>, line_layout: Arc<LineLayout>,
line_height: f32, line_height: f32,

View file

@ -1,5 +1,9 @@
use crate::theme::theme; use crate::theme::{theme, Theme};
use gpui2::{elements::div, style::StyleHelpers, Element, IntoElement, ParentElement, ViewContext}; use gpui2::{
elements::{div, svg},
style::StyleHelpers,
Element, IntoElement, ParentElement, ViewContext,
};
use std::marker::PhantomData; use std::marker::PhantomData;
#[derive(Element)] #[derive(Element)]
@ -112,10 +116,11 @@ impl<V: 'static> CollabPanelElement<V> {
) )
.child( .child(
div().flex().h_full().gap_1().items_center().child( div().flex().h_full().gap_1().items_center().child(
div() svg()
.w_3p5() .path("icons/radix/caret-down.svg")
.h_3p5() .h_3()
.fill(theme.middle.positive.default.foreground), .w_3()
.fill(theme.middle.variant.default.foreground),
), ),
), ),
) )
@ -159,23 +164,7 @@ impl<V: 'static> CollabPanelElement<V> {
.flex_col() .flex_col()
.gap_y_1() .gap_y_1()
// List Section Header // List Section Header
.child( .child(self.list_section_header(theme)),
div()
.h_7()
.px_2()
.flex()
.justify_between()
.items_center()
.child(div().flex().gap_1().text_sm().child("CHANNELS"))
.child(
div().flex().h_full().gap_1().items_center().child(
div()
.w_3p5()
.h_3p5()
.fill(theme.middle.positive.default.foreground),
),
),
),
) )
// Large List Item // Large List Item
.child( .child(
@ -196,4 +185,22 @@ impl<V: 'static> CollabPanelElement<V> {
), ),
) )
} }
fn list_section_header(&self, theme: &Theme) -> impl Element<V> {
div()
.h_7()
.px_2()
.flex()
.justify_between()
.items_center()
.child(div().flex().gap_1().text_sm().child("CHANNELS"))
.child(
div().flex().h_full().gap_1().items_center().child(
div()
.w_3p5()
.h_3p5()
.fill(theme.middle.positive.default.foreground),
),
)
}
} }

View file

@ -69,6 +69,7 @@ use rust_embed::RustEmbed;
#[folder = "../../assets"] #[folder = "../../assets"]
#[include = "themes/**/*"] #[include = "themes/**/*"]
#[include = "fonts/**/*"] #[include = "fonts/**/*"]
#[include = "icons/**/*"]
#[exclude = "*.DS_Store"] #[exclude = "*.DS_Store"]
pub struct Assets; pub struct Assets;

View file

@ -2,7 +2,7 @@ use gpui2::{
color::Hsla, color::Hsla,
element::{Element, PaintContext}, element::{Element, PaintContext},
layout_context::LayoutContext, layout_context::LayoutContext,
serde_json, AppContext, WindowContext, serde_json, AppContext, IntoElement, WindowContext,
}; };
use serde::{de::Visitor, Deserialize, Deserializer}; use serde::{de::Visitor, Deserialize, Deserializer};
use std::{collections::HashMap, fmt, marker::PhantomData}; use std::{collections::HashMap, fmt, marker::PhantomData};
@ -133,7 +133,8 @@ where
deserializer.deserialize_map(SyntaxVisitor) deserializer.deserialize_map(SyntaxVisitor)
} }
pub struct Themed<V: 'static, E> { #[derive(IntoElement)]
pub struct Themed<V: 'static, E: Element<V>> {
pub(crate) theme: Theme, pub(crate) theme: Theme,
pub(crate) child: E, pub(crate) child: E,
pub(crate) view_type: PhantomData<V>, pub(crate) view_type: PhantomData<V>,