Checkpoint
This commit is contained in:
parent
7f9e3bc787
commit
da211bef96
10 changed files with 215 additions and 81 deletions
|
@ -45,6 +45,7 @@ fn generate_shader_bindings() -> PathBuf {
|
||||||
"Pixels".into(),
|
"Pixels".into(),
|
||||||
"PointF".into(),
|
"PointF".into(),
|
||||||
"Hsla".into(),
|
"Hsla".into(),
|
||||||
|
"ScaledContentMask".into(),
|
||||||
"Uniforms".into(),
|
"Uniforms".into(),
|
||||||
"AtlasTile".into(),
|
"AtlasTile".into(),
|
||||||
"Quad".into(),
|
"Quad".into(),
|
||||||
|
@ -58,12 +59,14 @@ fn generate_shader_bindings() -> PathBuf {
|
||||||
.with_src(crate_dir.join("src/scene.rs"))
|
.with_src(crate_dir.join("src/scene.rs"))
|
||||||
.with_src(crate_dir.join("src/geometry.rs"))
|
.with_src(crate_dir.join("src/geometry.rs"))
|
||||||
.with_src(crate_dir.join("src/color.rs"))
|
.with_src(crate_dir.join("src/color.rs"))
|
||||||
|
.with_src(crate_dir.join("src/window.rs"))
|
||||||
.with_src(crate_dir.join("src/platform.rs"))
|
.with_src(crate_dir.join("src/platform.rs"))
|
||||||
.with_src(crate_dir.join("src/platform/mac/metal_renderer.rs"))
|
.with_src(crate_dir.join("src/platform/mac/metal_renderer.rs"))
|
||||||
.with_config(config)
|
.with_config(config)
|
||||||
.generate()
|
.generate()
|
||||||
.expect("Unable to generate bindings")
|
.expect("Unable to generate bindings")
|
||||||
.write_to_file(&output_path);
|
.write_to_file(&output_path);
|
||||||
|
|
||||||
output_path
|
output_path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyElement, Bounds, Element, Layout, LayoutId, Overflow, ParentElement, Pixels, Point,
|
AnyElement, Bounds, Element, Layout, LayoutId, Overflow, ParentElement, Pixels, Point,
|
||||||
Refineable, RefinementCascade, Result, StackContext, Style, StyleHelpers, Styled, ViewContext,
|
Refineable, RefinementCascade, Result, Style, StyleHelpers, Styled, ViewContext,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -33,16 +33,9 @@ impl<S: 'static + Send + Sync> Element for Div<S> {
|
||||||
cx: &mut ViewContext<S>,
|
cx: &mut ViewContext<S>,
|
||||||
) -> Result<(LayoutId, Self::FrameState)> {
|
) -> Result<(LayoutId, Self::FrameState)> {
|
||||||
let style = self.computed_style();
|
let style = self.computed_style();
|
||||||
let child_layout_ids = if let Some(text_style) = style.text_style(cx) {
|
let child_layout_ids = style.apply_text_style(cx, |cx| self.layout_children(view, cx))?;
|
||||||
cx.with_text_style(text_style.clone(), |cx| self.layout_children(view, cx))?
|
let layout_id = cx.request_layout(style.into(), child_layout_ids.clone())?;
|
||||||
} else {
|
Ok((layout_id, child_layout_ids))
|
||||||
self.layout_children(view, cx)?
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((
|
|
||||||
cx.request_layout(style.into(), child_layout_ids.clone())?,
|
|
||||||
child_layout_ids,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(
|
fn paint(
|
||||||
|
@ -56,20 +49,18 @@ impl<S: 'static + Send + Sync> Element for Div<S> {
|
||||||
|
|
||||||
let style = self.computed_style();
|
let style = self.computed_style();
|
||||||
style.paint(order, bounds, cx);
|
style.paint(order, bounds, cx);
|
||||||
let overflow = &style.overflow;
|
|
||||||
// // todo!("support only one dimension being hidden")
|
|
||||||
// if style.overflow.y != Overflow::Visible || style.overflow.x != Overflow::Visible {
|
|
||||||
// cx.scene().push_layer(Some(bounds));
|
|
||||||
// pop_layer = true;
|
|
||||||
// }
|
|
||||||
if let Some(text_style) = style.text_style(cx) {
|
|
||||||
cx.with_text_style(text_style.clone(), |cx| {
|
|
||||||
self.paint_children(overflow, state, cx)
|
|
||||||
})?;
|
|
||||||
} else {
|
|
||||||
self.paint_children(overflow, state, cx)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// // todo!("support only one dimension being hidden")
|
||||||
|
let overflow = &style.overflow;
|
||||||
|
// if style.overflow.y != Overflow::Visible || style.overflow.x != Overflow::Visible {
|
||||||
|
// cx.clip(layout.bounds, style.corner_radii, || )
|
||||||
|
// }
|
||||||
|
|
||||||
|
style.apply_text_style(cx, |cx| {
|
||||||
|
style.apply_overflow(layout.bounds, cx, |cx| {
|
||||||
|
self.paint_children(overflow, state, cx)
|
||||||
|
})
|
||||||
|
})?;
|
||||||
self.handle_scroll(order, bounds, style.overflow.clone(), child_layouts, cx);
|
self.handle_scroll(order, bounds, style.overflow.clone(), child_layouts, cx);
|
||||||
|
|
||||||
// todo!("enable inspector")
|
// todo!("enable inspector")
|
||||||
|
|
|
@ -225,6 +225,20 @@ pub struct Bounds<T: Clone + Debug> {
|
||||||
pub size: Size<T>,
|
pub size: Size<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Clone + Debug + Sub<Output = T>> Bounds<T> {
|
||||||
|
pub fn from_corners(upper_left: Point<T>, lower_right: Point<T>) -> Self {
|
||||||
|
let origin = Point {
|
||||||
|
x: upper_left.x.clone(),
|
||||||
|
y: upper_left.y.clone(),
|
||||||
|
};
|
||||||
|
let size = Size {
|
||||||
|
width: lower_right.x - upper_left.x,
|
||||||
|
height: lower_right.y - upper_left.y,
|
||||||
|
};
|
||||||
|
Bounds { origin, size }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, Rhs> Mul<Rhs> for Bounds<T>
|
impl<T, Rhs> Mul<Rhs> for Bounds<T>
|
||||||
where
|
where
|
||||||
T: Mul<Rhs, Output = Rhs> + Clone + Debug,
|
T: Mul<Rhs, Output = Rhs> + Clone + Debug,
|
||||||
|
@ -418,6 +432,28 @@ pub struct Corners<T: Clone + Debug> {
|
||||||
pub bottom_left: T,
|
pub bottom_left: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Corners<AbsoluteLength> {
|
||||||
|
pub fn to_pixels(&self, rem_size: Pixels) -> Corners<Pixels> {
|
||||||
|
Corners {
|
||||||
|
top_left: self.top_left.to_pixels(rem_size),
|
||||||
|
top_right: self.top_right.to_pixels(rem_size),
|
||||||
|
bottom_right: self.bottom_right.to_pixels(rem_size),
|
||||||
|
bottom_left: self.bottom_left.to_pixels(rem_size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Corners<Pixels> {
|
||||||
|
pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
|
||||||
|
Corners {
|
||||||
|
top_left: self.top_left.scale(factor),
|
||||||
|
top_right: self.top_right.scale(factor),
|
||||||
|
bottom_right: self.bottom_right.scale(factor),
|
||||||
|
bottom_left: self.bottom_left.scale(factor),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Clone + Debug> Corners<T> {
|
impl<T: Clone + Debug> Corners<T> {
|
||||||
pub fn map<U: Clone + Debug, F: Fn(&T) -> U>(&self, f: F) -> Corners<U> {
|
pub fn map<U: Clone + Debug, F: Fn(&T) -> U>(&self, f: F) -> Corners<U> {
|
||||||
Corners {
|
Corners {
|
||||||
|
|
|
@ -84,16 +84,16 @@ impl<T> DerefMut for MainThread<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait StackContext {
|
pub trait BorrowAppContext {
|
||||||
fn app(&mut self) -> &mut AppContext;
|
fn app_mut(&mut self) -> &mut AppContext;
|
||||||
|
|
||||||
fn with_text_style<F, R>(&mut self, style: TextStyleRefinement, f: F) -> R
|
fn with_text_style<F, R>(&mut self, style: TextStyleRefinement, f: F) -> R
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> R,
|
F: FnOnce(&mut Self) -> R,
|
||||||
{
|
{
|
||||||
self.app().push_text_style(style);
|
self.app_mut().push_text_style(style);
|
||||||
let result = f(self);
|
let result = f(self);
|
||||||
self.app().pop_text_style();
|
self.app_mut().pop_text_style();
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,9 +101,9 @@ pub trait StackContext {
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self) -> R,
|
F: FnOnce(&mut Self) -> R,
|
||||||
{
|
{
|
||||||
self.app().push_state(state);
|
self.app_mut().push_state(state);
|
||||||
let result = f(self);
|
let result = f(self);
|
||||||
self.app().pop_state::<T>();
|
self.app_mut().pop_state::<T>();
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
using namespace metal;
|
using namespace metal;
|
||||||
|
|
||||||
float4 hsla_to_rgba(Hsla hsla);
|
float4 hsla_to_rgba(Hsla hsla);
|
||||||
float4 to_device_position(float2 unit_vertex, Bounds_Pixels bounds,
|
float4 to_device_position(float2 unit_vertex, Bounds_ScaledPixels bounds,
|
||||||
Bounds_Pixels clip_bounds,
|
Bounds_ScaledPixels clip_bounds,
|
||||||
constant Size_DevicePixels *viewport_size);
|
constant Size_DevicePixels *viewport_size);
|
||||||
float quad_sdf(float2 point, Bounds_Pixels bounds, Corners_Pixels corner_radii);
|
float quad_sdf(float2 point, Bounds_ScaledPixels bounds, Corners_ScaledPixels corner_radii);
|
||||||
|
|
||||||
struct QuadVertexOutput {
|
struct QuadVertexOutput {
|
||||||
float4 position [[position]];
|
float4 position [[position]];
|
||||||
|
@ -131,7 +131,7 @@ vertex MonochromeSpriteVertexOutput monochrome_sprite_vertex(
|
||||||
float2 unit_vertex = unit_vertices[unit_vertex_id];
|
float2 unit_vertex = unit_vertices[unit_vertex_id];
|
||||||
MonochromeSprite sprite = sprites[sprite_id];
|
MonochromeSprite sprite = sprites[sprite_id];
|
||||||
float4 device_position = to_device_position(
|
float4 device_position = to_device_position(
|
||||||
unit_vertex, sprite.bounds, sprite.clip_bounds, viewport_size);
|
unit_vertex, sprite.bounds, sprite.content_mask.bounds, viewport_size);
|
||||||
|
|
||||||
float2 tile_origin =
|
float2 tile_origin =
|
||||||
float2(sprite.tile.bounds.origin.x, sprite.tile.bounds.origin.y);
|
float2(sprite.tile.bounds.origin.x, sprite.tile.bounds.origin.y);
|
||||||
|
@ -157,7 +157,7 @@ fragment float4 monochrome_sprite_fragment(
|
||||||
float4 sample =
|
float4 sample =
|
||||||
atlas_texture.sample(atlas_texture_sampler, input.tile_position);
|
atlas_texture.sample(atlas_texture_sampler, input.tile_position);
|
||||||
float clip_distance =
|
float clip_distance =
|
||||||
quad_sdf(input.position.xy, sprite.clip_bounds, sprite.clip_corner_radii);
|
quad_sdf(input.position.xy, sprite.content_mask.bounds, sprite.content_mask.corner_radii);
|
||||||
float4 color = input.color;
|
float4 color = input.color;
|
||||||
color.a *= sample.a * saturate(0.5 - clip_distance);
|
color.a *= sample.a * saturate(0.5 - clip_distance);
|
||||||
return color;
|
return color;
|
||||||
|
@ -211,8 +211,8 @@ float4 hsla_to_rgba(Hsla hsla) {
|
||||||
return rgba;
|
return rgba;
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 to_device_position(float2 unit_vertex, Bounds_Pixels bounds,
|
float4 to_device_position(float2 unit_vertex, Bounds_ScaledPixels bounds,
|
||||||
Bounds_Pixels clip_bounds,
|
Bounds_ScaledPixels clip_bounds,
|
||||||
constant Size_DevicePixels *input_viewport_size) {
|
constant Size_DevicePixels *input_viewport_size) {
|
||||||
float2 position =
|
float2 position =
|
||||||
unit_vertex * float2(bounds.size.width, bounds.size.height) +
|
unit_vertex * float2(bounds.size.width, bounds.size.height) +
|
||||||
|
@ -229,8 +229,8 @@ float4 to_device_position(float2 unit_vertex, Bounds_Pixels bounds,
|
||||||
return float4(device_position, 0., 1.);
|
return float4(device_position, 0., 1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
float quad_sdf(float2 point, Bounds_Pixels bounds,
|
float quad_sdf(float2 point, Bounds_ScaledPixels bounds,
|
||||||
Corners_Pixels corner_radii) {
|
Corners_ScaledPixels corner_radii) {
|
||||||
float2 half_size = float2(bounds.size.width, bounds.size.height) / 2.;
|
float2 half_size = float2(bounds.size.width, bounds.size.height) / 2.;
|
||||||
float2 center = float2(bounds.origin.x, bounds.origin.y) + half_size;
|
float2 center = float2(bounds.origin.x, bounds.origin.y) + half_size;
|
||||||
float2 center_to_point = point - center;
|
float2 center_to_point = point - center;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{iter::Peekable, mem};
|
use std::{iter::Peekable, mem};
|
||||||
|
|
||||||
use super::{Bounds, Hsla, Point};
|
use super::{Bounds, Hsla, Point};
|
||||||
use crate::{AtlasTextureId, AtlasTile, Corners, Edges, ScaledPixels};
|
use crate::{AtlasTextureId, AtlasTile, Corners, Edges, ScaledContentMask, ScaledPixels};
|
||||||
use collections::BTreeMap;
|
use collections::BTreeMap;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
|
@ -234,8 +234,7 @@ impl From<Quad> for Primitive {
|
||||||
pub struct MonochromeSprite {
|
pub struct MonochromeSprite {
|
||||||
pub order: u32,
|
pub order: u32,
|
||||||
pub bounds: Bounds<ScaledPixels>,
|
pub bounds: Bounds<ScaledPixels>,
|
||||||
pub clip_bounds: Bounds<ScaledPixels>,
|
pub content_mask: ScaledContentMask,
|
||||||
pub clip_corner_radii: Corners<ScaledPixels>,
|
|
||||||
pub color: Hsla,
|
pub color: Hsla,
|
||||||
pub tile: AtlasTile,
|
pub tile: AtlasTile,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
phi, rems, AbsoluteLength, Bounds, Corners, CornersRefinement, DefiniteLength, Edges,
|
phi, point, rems, AbsoluteLength, BorrowAppContext, BorrowWindow, Bounds, ContentMask, Corners,
|
||||||
EdgesRefinement, Font, FontFeatures, FontStyle, FontWeight, Hsla, Length, Pixels, Point,
|
CornersRefinement, DefiniteLength, Edges, EdgesRefinement, Font, FontFeatures, FontStyle,
|
||||||
PointRefinement, Quad, Rems, Result, RunStyle, SharedString, Size, SizeRefinement, ViewContext,
|
FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Quad, Rems, Result, RunStyle,
|
||||||
WindowContext,
|
SharedString, Size, SizeRefinement, ViewContext, WindowContext,
|
||||||
};
|
};
|
||||||
use refineable::Refineable;
|
use refineable::Refineable;
|
||||||
pub use taffy::style::{
|
pub use taffy::style::{
|
||||||
|
@ -179,6 +179,57 @@ impl Style {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn apply_text_style<C, F, R>(&self, cx: &mut C, f: F) -> R
|
||||||
|
where
|
||||||
|
C: BorrowAppContext,
|
||||||
|
F: FnOnce(&mut C) -> R,
|
||||||
|
{
|
||||||
|
if self.text.is_some() {
|
||||||
|
cx.with_text_style(self.text.clone(), f)
|
||||||
|
} else {
|
||||||
|
f(cx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply overflow to content mask
|
||||||
|
pub fn apply_overflow<C, F, R>(&self, bounds: Bounds<Pixels>, cx: &mut C, f: F) -> R
|
||||||
|
where
|
||||||
|
C: BorrowWindow,
|
||||||
|
F: FnOnce(&mut C) -> R,
|
||||||
|
{
|
||||||
|
let current_mask = cx.content_mask();
|
||||||
|
|
||||||
|
let min = current_mask.bounds.origin;
|
||||||
|
let max = current_mask.bounds.lower_right();
|
||||||
|
|
||||||
|
let mask_corner_radii = Corners::default();
|
||||||
|
let mask_bounds = match (
|
||||||
|
self.overflow.x == Overflow::Visible,
|
||||||
|
self.overflow.y == Overflow::Visible,
|
||||||
|
) {
|
||||||
|
// x and y both visible
|
||||||
|
(true, true) => return f(cx),
|
||||||
|
// x visible, y hidden
|
||||||
|
(true, false) => Bounds::from_corners(
|
||||||
|
point(min.x, bounds.origin.y),
|
||||||
|
point(max.x, bounds.lower_right().y),
|
||||||
|
),
|
||||||
|
// x hidden, y visible
|
||||||
|
(false, true) => Bounds::from_corners(
|
||||||
|
point(bounds.origin.x, min.y),
|
||||||
|
point(bounds.lower_right().x, max.y),
|
||||||
|
),
|
||||||
|
// both hidden
|
||||||
|
(false, false) => bounds,
|
||||||
|
};
|
||||||
|
let mask = ContentMask {
|
||||||
|
bounds: mask_bounds,
|
||||||
|
corner_radii: mask_corner_radii,
|
||||||
|
};
|
||||||
|
|
||||||
|
cx.with_content_mask(mask, f)
|
||||||
|
}
|
||||||
|
|
||||||
/// Paints the background of an element styled with this style.
|
/// Paints the background of an element styled with this style.
|
||||||
pub fn paint<V: 'static>(&self, order: u32, bounds: Bounds<Pixels>, cx: &mut ViewContext<V>) {
|
pub fn paint<V: 'static>(&self, order: u32, bounds: Bounds<Pixels>, cx: &mut ViewContext<V>) {
|
||||||
let rem_size = cx.rem_size();
|
let rem_size = cx.rem_size();
|
||||||
|
|
|
@ -2,12 +2,6 @@ use smol::future::FutureExt;
|
||||||
use std::{future::Future, time::Duration};
|
use std::{future::Future, time::Duration};
|
||||||
pub use util::*;
|
pub use util::*;
|
||||||
|
|
||||||
pub fn post_inc(value: &mut usize) -> usize {
|
|
||||||
let prev = *value;
|
|
||||||
*value += 1;
|
|
||||||
prev
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn timeout<F, T>(timeout: Duration, f: F) -> Result<T, ()>
|
pub async fn timeout<F, T>(timeout: Duration, f: F) -> Result<T, ()>
|
||||||
where
|
where
|
||||||
F: Future<Output = T>,
|
F: Future<Output = T>,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
px, AnyView, AppContext, AvailableSpace, Bounds, Context, Corners, Effect, Element, EntityId,
|
px, AnyView, AppContext, AvailableSpace, BorrowAppContext, Bounds, Context, Corners, Effect,
|
||||||
FontId, GlyphId, GlyphRasterParams, Handle, Hsla, IsZero, LayerId, LayoutId, MainThread,
|
Element, EntityId, FontId, GlyphId, GlyphRasterParams, Handle, Hsla, IsZero, LayerId, LayoutId,
|
||||||
MainThreadOnly, MonochromeSprite, Pixels, PlatformAtlas, PlatformWindow, Point, Reference,
|
MainThread, MainThreadOnly, MonochromeSprite, Pixels, PlatformAtlas, PlatformWindow, Point,
|
||||||
Scene, Size, StackContext, Style, TaffyLayoutEngine, WeakHandle, WindowOptions,
|
Reference, ScaledPixels, Scene, Size, Style, TaffyLayoutEngine, WeakHandle, WindowOptions,
|
||||||
SUBPIXEL_VARIANTS,
|
SUBPIXEL_VARIANTS,
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
@ -74,8 +74,24 @@ impl Window {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ContentMask {
|
pub struct ContentMask {
|
||||||
bounds: Bounds<Pixels>,
|
pub bounds: Bounds<Pixels>,
|
||||||
corner_radii: Corners<Pixels>,
|
pub corner_radii: Corners<Pixels>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ContentMask {
|
||||||
|
pub fn scale(&self, factor: f32) -> ScaledContentMask {
|
||||||
|
ScaledContentMask {
|
||||||
|
bounds: self.bounds.scale(factor),
|
||||||
|
corner_radii: self.corner_radii.scale(factor),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ScaledContentMask {
|
||||||
|
bounds: Bounds<ScaledPixels>,
|
||||||
|
corner_radii: Corners<ScaledPixels>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WindowContext<'a, 'w> {
|
pub struct WindowContext<'a, 'w> {
|
||||||
|
@ -174,20 +190,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
||||||
self.window.current_layer_id.clone()
|
self.window.current_layer_id.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_clipping_mask(&self) -> ContentMask {
|
|
||||||
self.window
|
|
||||||
.content_mask_stack
|
|
||||||
.last()
|
|
||||||
.cloned()
|
|
||||||
.unwrap_or_else(|| ContentMask {
|
|
||||||
bounds: Bounds {
|
|
||||||
origin: Point::default(),
|
|
||||||
size: self.window.content_size,
|
|
||||||
},
|
|
||||||
corner_radii: Default::default(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run_on_main<R>(
|
pub fn run_on_main<R>(
|
||||||
&self,
|
&self,
|
||||||
f: impl FnOnce(&mut MainThread<WindowContext>) -> R + Send + 'static,
|
f: impl FnOnce(&mut MainThread<WindowContext>) -> R + Send + 'static,
|
||||||
|
@ -239,14 +241,14 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
||||||
origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
|
origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
|
||||||
size: tile.bounds.size.map(Into::into),
|
size: tile.bounds.size.map(Into::into),
|
||||||
};
|
};
|
||||||
|
let content_mask = self.content_mask().scale(scale_factor);
|
||||||
|
|
||||||
self.window.scene.insert(
|
self.window.scene.insert(
|
||||||
layer_id,
|
layer_id,
|
||||||
MonochromeSprite {
|
MonochromeSprite {
|
||||||
order,
|
order,
|
||||||
bounds,
|
bounds,
|
||||||
clip_bounds: bounds,
|
content_mask,
|
||||||
clip_corner_radii: Default::default(),
|
|
||||||
color,
|
color,
|
||||||
tile,
|
tile,
|
||||||
},
|
},
|
||||||
|
@ -330,8 +332,60 @@ impl<'a, 'w> std::ops::DerefMut for WindowContext<'a, 'w> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> StackContext for ViewContext<'_, '_, S> {
|
impl BorrowAppContext for WindowContext<'_, '_> {
|
||||||
fn app(&mut self) -> &mut AppContext {
|
fn app_mut(&mut self) -> &mut AppContext {
|
||||||
|
&mut *self.app
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait BorrowWindow: BorrowAppContext {
|
||||||
|
fn window(&self) -> &Window;
|
||||||
|
fn window_mut(&mut self) -> &mut Window;
|
||||||
|
|
||||||
|
fn with_content_mask<R>(&mut self, mask: ContentMask, f: impl FnOnce(&mut Self) -> R) -> R {
|
||||||
|
self.window_mut().content_mask_stack.push(mask);
|
||||||
|
let result = f(self);
|
||||||
|
self.window_mut().content_mask_stack.pop();
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn content_mask(&self) -> ContentMask {
|
||||||
|
self.window()
|
||||||
|
.content_mask_stack
|
||||||
|
.last()
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_else(|| ContentMask {
|
||||||
|
bounds: Bounds {
|
||||||
|
origin: Point::default(),
|
||||||
|
size: self.window().content_size,
|
||||||
|
},
|
||||||
|
corner_radii: Default::default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rem_size(&self) -> Pixels {
|
||||||
|
self.window().rem_size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BorrowWindow for WindowContext<'_, '_> {
|
||||||
|
fn window(&self) -> &Window {
|
||||||
|
&*self.window
|
||||||
|
}
|
||||||
|
|
||||||
|
fn window_mut(&mut self) -> &mut Window {
|
||||||
|
&mut *self.window
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ViewContext<'a, 'w, S> {
|
||||||
|
window_cx: WindowContext<'a, 'w>,
|
||||||
|
entity_type: PhantomData<S>,
|
||||||
|
entity_id: EntityId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> BorrowAppContext for ViewContext<'_, '_, S> {
|
||||||
|
fn app_mut(&mut self) -> &mut AppContext {
|
||||||
&mut *self.window_cx.app
|
&mut *self.window_cx.app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,10 +410,14 @@ impl<S> StackContext for ViewContext<'_, '_, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ViewContext<'a, 'w, S> {
|
impl<S> BorrowWindow for ViewContext<'_, '_, S> {
|
||||||
window_cx: WindowContext<'a, 'w>,
|
fn window(&self) -> &Window {
|
||||||
entity_type: PhantomData<S>,
|
&self.window_cx.window
|
||||||
entity_id: EntityId,
|
}
|
||||||
|
|
||||||
|
fn window_mut(&mut self) -> &mut Window {
|
||||||
|
&mut *self.window_cx.window
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> {
|
impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use gpui3::{Element, Hsla, Layout, LayoutId, Result, StackContext, ViewContext, WindowContext};
|
use gpui3::{
|
||||||
|
BorrowAppContext, Element, Hsla, Layout, LayoutId, Result, ViewContext, WindowContext,
|
||||||
|
};
|
||||||
use serde::{de::Visitor, Deserialize, Deserializer};
|
use serde::{de::Visitor, Deserialize, Deserializer};
|
||||||
use std::{collections::HashMap, fmt};
|
use std::{collections::HashMap, fmt};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue