WIP
This commit is contained in:
@@ -77,7 +77,7 @@ impl<S: 'static> Element for Div<S> {
|
||||
// }
|
||||
|
||||
for child in &mut self.children {
|
||||
child.paint(scrolled_origin, state, cx);
|
||||
child.paint(scrolled_origin, state, cx)?;
|
||||
}
|
||||
|
||||
// if pop_layer {
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
use super::{Element, Handle, Layout, LayoutId, Result, SharedString, ViewContext};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub fn field<S>(editor: Handle<Editor>) -> EditorElement<S> {
|
||||
EditorElement {
|
||||
editor,
|
||||
field: true,
|
||||
placeholder_text: None,
|
||||
parent_state: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EditorElement<S> {
|
||||
editor: Handle<Editor>,
|
||||
field: bool,
|
||||
placeholder_text: Option<SharedString>,
|
||||
parent_state: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<S> EditorElement<S> {
|
||||
pub fn field(mut self) -> Self {
|
||||
self.field = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn placeholder_text(mut self, text: impl Into<SharedString>) -> Self {
|
||||
self.placeholder_text = Some(text.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: 'static> Element for EditorElement<S> {
|
||||
type State = S;
|
||||
type FrameState = ();
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
_: &mut Self::State,
|
||||
cx: &mut ViewContext<Self::State>,
|
||||
) -> Result<(LayoutId, Self::FrameState)> {
|
||||
self.editor.update(cx, |_editor, _cx| todo!())
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
_layout: Layout,
|
||||
_state: &mut Self::State,
|
||||
_frame_state: &mut Self::FrameState,
|
||||
cx: &mut ViewContext<Self::State>,
|
||||
) -> Result<()> {
|
||||
self.editor.update(cx, |_editor, _cx| todo!())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Editor {}
|
||||
|
||||
impl Editor {
|
||||
pub fn new(_: &mut ViewContext<Self>) -> Self {
|
||||
Editor {}
|
||||
}
|
||||
}
|
||||
@@ -1,101 +1,93 @@
|
||||
use crate as gpui2;
|
||||
use crate::{
|
||||
style::{Style, StyleHelpers, Styleable},
|
||||
Element,
|
||||
};
|
||||
use futures::FutureExt;
|
||||
use gpui::geometry::vector::Vector2F;
|
||||
use gpui::scene;
|
||||
use gpui2_macros::IntoElement;
|
||||
use crate::{Element, Layout, LayoutId, Result, Style, Styled};
|
||||
use refineable::RefinementCascade;
|
||||
use util::arc_cow::ArcCow;
|
||||
use util::ResultExt;
|
||||
use std::marker::PhantomData;
|
||||
use util::{arc_cow::ArcCow, ResultExt};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub struct Img {
|
||||
pub struct Img<S> {
|
||||
style: RefinementCascade<Style>,
|
||||
uri: Option<ArcCow<'static, str>>,
|
||||
state_type: PhantomData<S>,
|
||||
}
|
||||
|
||||
pub fn img() -> Img {
|
||||
pub fn img<S>() -> Img<S> {
|
||||
Img {
|
||||
style: RefinementCascade::default(),
|
||||
uri: None,
|
||||
state_type: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
impl Img {
|
||||
impl<S> Img<S> {
|
||||
pub fn uri(mut self, uri: impl Into<ArcCow<'static, str>>) -> Self {
|
||||
self.uri = Some(uri.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: 'static> Element<V> for Img {
|
||||
type PaintState = ();
|
||||
impl<S: 'static> Element for Img<S> {
|
||||
type State = S;
|
||||
type FrameState = ();
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
_: &mut V,
|
||||
cx: &mut crate::ViewContext<V>,
|
||||
) -> anyhow::Result<(gpui::LayoutId, Self::PaintState)>
|
||||
_: &mut Self::State,
|
||||
cx: &mut crate::ViewContext<Self::State>,
|
||||
) -> anyhow::Result<(LayoutId, Self::FrameState)>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let style = self.computed_style();
|
||||
let layout_id = cx.add_layout_node(style, [])?;
|
||||
let layout_id = cx.request_layout(style, [])?;
|
||||
Ok((layout_id, ()))
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
_: &mut V,
|
||||
parent_origin: Vector2F,
|
||||
layout: &gpui::Layout,
|
||||
_: &mut Self::PaintState,
|
||||
cx: &mut crate::ViewContext<V>,
|
||||
) where
|
||||
Self: Sized,
|
||||
{
|
||||
layout: Layout,
|
||||
_: &mut Self::State,
|
||||
_: &mut Self::FrameState,
|
||||
cx: &mut crate::ViewContext<Self::State>,
|
||||
) -> Result<()> {
|
||||
let style = self.computed_style();
|
||||
let bounds = layout.bounds + parent_origin;
|
||||
let bounds = layout.bounds;
|
||||
|
||||
style.paint_background(bounds, cx);
|
||||
|
||||
if let Some(uri) = &self.uri {
|
||||
let image_future = cx.image_cache.get(uri.clone());
|
||||
if let Some(data) = image_future
|
||||
.clone()
|
||||
.now_or_never()
|
||||
.and_then(ResultExt::log_err)
|
||||
{
|
||||
let rem_size = cx.rem_size();
|
||||
cx.scene().push_image(scene::Image {
|
||||
bounds,
|
||||
border: gpui::Border {
|
||||
color: style.border_color.unwrap_or_default().into(),
|
||||
top: style.border_widths.top.to_pixels(rem_size),
|
||||
right: style.border_widths.right.to_pixels(rem_size),
|
||||
bottom: style.border_widths.bottom.to_pixels(rem_size),
|
||||
left: style.border_widths.left.to_pixels(rem_size),
|
||||
},
|
||||
corner_radii: style.corner_radii.to_gpui(bounds.size(), rem_size),
|
||||
grayscale: false,
|
||||
data,
|
||||
})
|
||||
} else {
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
if image_future.await.log_err().is_some() {
|
||||
this.update(&mut cx, |_, cx| cx.notify()).ok();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
// if let Some(uri) = &self.uri {
|
||||
// let image_future = cx.image_cache.get(uri.clone());
|
||||
// if let Some(data) = image_future
|
||||
// .clone()
|
||||
// .now_or_never()
|
||||
// .and_then(ResultExt::log_err)
|
||||
// {
|
||||
// let rem_size = cx.rem_size();
|
||||
// cx.scene().push_image(scene::Image {
|
||||
// bounds,
|
||||
// border: gpui::Border {
|
||||
// color: style.border_color.unwrap_or_default().into(),
|
||||
// top: style.border_widths.top.to_pixels(rem_size),
|
||||
// right: style.border_widths.right.to_pixels(rem_size),
|
||||
// bottom: style.border_widths.bottom.to_pixels(rem_size),
|
||||
// left: style.border_widths.left.to_pixels(rem_size),
|
||||
// },
|
||||
// corner_radii: style.corner_radii.to_gpui(bounds.size(), rem_size),
|
||||
// grayscale: false,
|
||||
// data,
|
||||
// })
|
||||
// } else {
|
||||
// cx.spawn(|this, mut cx| async move {
|
||||
// if image_future.await.log_err().is_some() {
|
||||
// this.update(&mut cx, |_, cx| cx.notify()).ok();
|
||||
// }
|
||||
// })
|
||||
// .detach();
|
||||
// }
|
||||
// }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Styleable for Img {
|
||||
impl<S> Styled for Img<S> {
|
||||
type Style = Style;
|
||||
|
||||
fn style_cascade(&mut self) -> &mut RefinementCascade<Self::Style> {
|
||||
@@ -106,5 +98,3 @@ impl Styleable for Img {
|
||||
self.style.base()
|
||||
}
|
||||
}
|
||||
|
||||
impl StyleHelpers for Img {}
|
||||
|
||||
@@ -1,75 +1,72 @@
|
||||
use crate::{
|
||||
self as gpui2, scene,
|
||||
style::{Style, StyleHelpers, Styleable},
|
||||
Element, IntoElement, Layout, LayoutId, Rgba,
|
||||
};
|
||||
use gpui::geometry::vector::Vector2F;
|
||||
use crate::{Element, Layout, LayoutId, Result, Style, Styled};
|
||||
use refineable::RefinementCascade;
|
||||
use std::borrow::Cow;
|
||||
use util::ResultExt;
|
||||
use std::{borrow::Cow, marker::PhantomData};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub struct Svg {
|
||||
pub struct Svg<S> {
|
||||
path: Option<Cow<'static, str>>,
|
||||
style: RefinementCascade<Style>,
|
||||
state_type: PhantomData<S>,
|
||||
}
|
||||
|
||||
pub fn svg() -> Svg {
|
||||
pub fn svg<S>() -> Svg<S> {
|
||||
Svg {
|
||||
path: None,
|
||||
style: RefinementCascade::<Style>::default(),
|
||||
state_type: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
impl Svg {
|
||||
impl<S> Svg<S> {
|
||||
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 = ();
|
||||
impl<S: 'static> Element for Svg<S> {
|
||||
type State = S;
|
||||
type FrameState = ();
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
_: &mut V,
|
||||
cx: &mut crate::ViewContext<V>,
|
||||
) -> anyhow::Result<(LayoutId, Self::PaintState)>
|
||||
_: &mut S,
|
||||
cx: &mut crate::ViewContext<S>,
|
||||
) -> anyhow::Result<(LayoutId, Self::FrameState)>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let style = self.computed_style();
|
||||
Ok((cx.add_layout_node(style, [])?, ()))
|
||||
Ok((cx.request_layout(style, [])?, ()))
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
_: &mut V,
|
||||
parent_origin: Vector2F,
|
||||
layout: &Layout,
|
||||
_: &mut Self::PaintState,
|
||||
cx: &mut crate::ViewContext<V>,
|
||||
) where
|
||||
layout: Layout,
|
||||
_: &mut Self::State,
|
||||
_: &mut Self::FrameState,
|
||||
cx: &mut crate::ViewContext<S>,
|
||||
) -> Result<()>
|
||||
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 Some(svg_tree) = cx.asset_cache.svg(path).log_err() {
|
||||
let icon = scene::Icon {
|
||||
bounds: layout.bounds + parent_origin,
|
||||
svg: svg_tree,
|
||||
path: path.clone(),
|
||||
color: Rgba::from(fill_color).into(),
|
||||
};
|
||||
// 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 Some(svg_tree) = cx.asset_cache.svg(path).log_err() {
|
||||
// let icon = scene::Icon {
|
||||
// bounds: layout.bounds + parent_origin,
|
||||
// svg: svg_tree,
|
||||
// path: path.clone(),
|
||||
// color: Rgba::from(fill_color).into(),
|
||||
// };
|
||||
|
||||
cx.scene().push_icon(icon);
|
||||
}
|
||||
}
|
||||
// cx.scene().push_icon(icon);
|
||||
// }
|
||||
// }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Styleable for Svg {
|
||||
impl<S> Styled for Svg<S> {
|
||||
type Style = Style;
|
||||
|
||||
fn style_cascade(&mut self) -> &mut refineable::RefinementCascade<Self::Style> {
|
||||
@@ -80,5 +77,3 @@ impl Styleable for Svg {
|
||||
self.style.base()
|
||||
}
|
||||
}
|
||||
|
||||
impl StyleHelpers for Svg {}
|
||||
|
||||
@@ -1,69 +1,67 @@
|
||||
use crate::{
|
||||
element::{Element, IntoElement, Layout},
|
||||
AnyElement, Element, IntoAnyElement, Layout, LayoutId, Line, LineLayout, Pixels, Result, Size,
|
||||
ViewContext,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use gpui::{
|
||||
geometry::{vector::Vector2F, Size},
|
||||
text_layout::LineLayout,
|
||||
LayoutId,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use std::sync::Arc;
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
use util::arc_cow::ArcCow;
|
||||
|
||||
impl<V: 'static> IntoElement<V> for ArcCow<'static, str> {
|
||||
type Element = Text;
|
||||
|
||||
fn into_element(self) -> Self::Element {
|
||||
Text { text: self }
|
||||
impl<S: 'static> IntoAnyElement<S> for ArcCow<'static, str> {
|
||||
fn into_any(self) -> AnyElement<S> {
|
||||
Text {
|
||||
text: self,
|
||||
state_type: PhantomData,
|
||||
}
|
||||
.into_any()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: 'static> IntoElement<V> for &'static str {
|
||||
type Element = Text;
|
||||
|
||||
fn into_element(self) -> Self::Element {
|
||||
impl<V: 'static> IntoAnyElement<V> for &'static str {
|
||||
fn into_any(self) -> AnyElement<V> {
|
||||
Text {
|
||||
text: ArcCow::from(self),
|
||||
state_type: PhantomData,
|
||||
}
|
||||
.into_any()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Text {
|
||||
pub struct Text<S> {
|
||||
text: ArcCow<'static, str>,
|
||||
state_type: PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<V: 'static> Element<V> for Text {
|
||||
type PaintState = Arc<Mutex<Option<TextLayout>>>;
|
||||
impl<S: 'static> Element for Text<S> {
|
||||
type State = S;
|
||||
type FrameState = Arc<Mutex<Option<TextLayout>>>;
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
_view: &mut V,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> Result<(LayoutId, Self::PaintState)> {
|
||||
let fonts = cx.platform().fonts();
|
||||
_view: &mut S,
|
||||
cx: &mut ViewContext<S>,
|
||||
) -> Result<(LayoutId, Self::FrameState)> {
|
||||
let text_system = cx.text_system().clone();
|
||||
let text_style = cx.text_style();
|
||||
let line_height = cx.font_cache().line_height(text_style.font_size);
|
||||
let line_height = cx.text_system().line_height(text_style.font_size);
|
||||
let text = self.text.clone();
|
||||
let paint_state = Arc::new(Mutex::new(None));
|
||||
|
||||
let layout_id = cx.add_measured_layout_node(Default::default(), {
|
||||
let paint_state = paint_state.clone();
|
||||
move |_params| {
|
||||
let line_layout = fonts.layout_line(
|
||||
let layout_id = cx.request_measured_layout(Default::default(), cx.rem_size(), {
|
||||
let frame_state = paint_state.clone();
|
||||
move |_, _| {
|
||||
let line_layout = text_system.layout_str(
|
||||
text.as_ref(),
|
||||
text_style.font_size,
|
||||
&[(text.len(), text_style.to_run())],
|
||||
);
|
||||
|
||||
let size = Size {
|
||||
width: line_layout.width,
|
||||
width: line_layout.width(),
|
||||
height: line_height,
|
||||
};
|
||||
|
||||
paint_state.lock().replace(TextLayout {
|
||||
line_layout: Arc::new(line_layout),
|
||||
frame_state.lock().replace(TextLayout {
|
||||
line: Arc::new(line_layout),
|
||||
line_height,
|
||||
});
|
||||
|
||||
@@ -76,44 +74,33 @@ impl<V: 'static> Element<V> for Text {
|
||||
|
||||
fn paint<'a>(
|
||||
&mut self,
|
||||
_view: &mut V,
|
||||
parent_origin: Vector2F,
|
||||
layout: &Layout,
|
||||
paint_state: &mut Self::PaintState,
|
||||
cx: &mut ViewContext<V>,
|
||||
layout: Layout,
|
||||
_: &mut Self::State,
|
||||
paint_state: &mut Self::FrameState,
|
||||
cx: &mut ViewContext<S>,
|
||||
) {
|
||||
let bounds = layout.bounds + parent_origin;
|
||||
let bounds = layout.bounds;
|
||||
|
||||
let line_layout;
|
||||
let line;
|
||||
let line_height;
|
||||
{
|
||||
let paint_state = paint_state.lock();
|
||||
let paint_state = paint_state
|
||||
.as_ref()
|
||||
.expect("measurement has not been performed");
|
||||
line_layout = paint_state.line_layout.clone();
|
||||
line = paint_state.line.clone();
|
||||
line_height = paint_state.line_height;
|
||||
}
|
||||
|
||||
let text_style = cx.text_style();
|
||||
let line =
|
||||
gpui::text_layout::Line::new(line_layout, &[(self.text.len(), text_style.to_run())]);
|
||||
|
||||
// TODO: We haven't added visible bounds to the new element system yet, so this is a placeholder.
|
||||
// todo!("We haven't added visible bounds to the new element system yet, so this is a placeholder.");
|
||||
let visible_bounds = bounds;
|
||||
line.paint(bounds.origin(), visible_bounds, line_height, cx.legacy_cx);
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: 'static> IntoElement<V> for Text {
|
||||
type Element = Self;
|
||||
|
||||
fn into_element(self) -> Self::Element {
|
||||
self
|
||||
line.paint(bounds.origin, visible_bounds, line_height, cx.legacy_cx);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TextLayout {
|
||||
line_layout: Arc<LineLayout>,
|
||||
line_height: f32,
|
||||
line: Arc<Line>,
|
||||
line_height: Pixels,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user