Detailed changes
@@ -7,7 +7,7 @@ description = "The next version of Zed's GPU-accelerated UI framework"
publish = false
[features]
-test = ["backtrace", "dhat", "env_logger", "collections/test-support"]
+test = ["backtrace", "dhat", "env_logger", "collections/test-support", "util/test-support"]
[lib]
path = "src/gpui3.rs"
@@ -66,6 +66,7 @@ dhat = "0.3"
env_logger.workspace = true
png = "0.16"
simplelog = "0.9"
+util = { path = "../util", features = ["test-support"] }
[build-dependencies]
bindgen = "0.65.1"
@@ -48,17 +48,14 @@ impl<S: 'static + Send + Sync> Element for Div<S> {
let Layout { order, bounds } = layout;
let style = self.computed_style();
- style.paint(order, bounds, cx);
+ cx.stack(0, |cx| style.paint(order, bounds, 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)
+ cx.stack(1, |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);
@@ -73,7 +73,9 @@ impl<S: Send + Sync + 'static> Element for Img<S> {
.and_then(ResultExt::log_err)
{
let corner_radii = style.corner_radii.to_pixels(bounds.size, cx.rem_size());
- cx.paint_image(bounds, corner_radii, order, data, self.grayscale)?;
+ cx.stack(1, |cx| {
+ cx.paint_image(bounds, corner_radii, order, data, self.grayscale)
+ })?;
} else {
cx.spawn(|_, mut cx| async move {
if image_future.await.log_err().is_some() {
@@ -2,7 +2,7 @@ use core::fmt::Debug;
use derive_more::{Add, AddAssign, Div, Mul, Sub, SubAssign};
use refineable::Refineable;
use std::{
- cmp,
+ cmp, fmt,
ops::{Add, AddAssign, Div, Mul, MulAssign, Sub, SubAssign},
};
@@ -128,7 +128,7 @@ impl<T: Clone + Debug> Clone for Point<T> {
}
}
-#[derive(Refineable, Default, Clone, Copy, Debug, PartialEq, Div, Hash)]
+#[derive(Refineable, Default, Clone, Copy, PartialEq, Div, Hash)]
#[refineable(debug)]
#[repr(C)]
pub struct Size<T: Clone + Debug> {
@@ -199,14 +199,11 @@ impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Size<T> {
impl<T: Eq + Debug + Clone> Eq for Size<T> {}
-// impl From<Size<Option<Pixels>>> for Size<Option<f32>> {
-// fn from(size: Size<Option<Pixels>>) -> Self {
-// Size {
-// width: size.width.map(|p| p.0 as f32),
-// height: size.height.map(|p| p.0 as f32),
-// }
-// }
-// }
+impl<T: Clone + Debug> Debug for Size<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "Size {{ {:?} Γ {:?} }}", self.width, self.height)
+ }
+}
impl From<Size<Pixels>> for Size<GlobalPixels> {
fn from(size: Size<Pixels>) -> Self {
@@ -345,6 +342,13 @@ impl<T: Clone + Debug + Add<T, Output = T>> Bounds<T> {
y: self.origin.y.clone() + self.size.height.clone(),
}
}
+
+ pub fn lower_left(&self) -> Point<T> {
+ Point {
+ x: self.origin.x.clone(),
+ y: self.origin.y.clone() + self.size.height.clone(),
+ }
+ }
}
impl<T: Clone + Debug + PartialOrd + Add<T, Output = T>> Bounds<T> {
@@ -627,7 +631,7 @@ impl From<f32> for Pixels {
}
impl Debug for Pixels {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} px", self.0)
}
}
@@ -662,8 +666,8 @@ impl DevicePixels {
}
}
-impl std::fmt::Debug for DevicePixels {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+impl fmt::Debug for DevicePixels {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} px (device)", self.0)
}
}
@@ -721,7 +725,7 @@ impl ScaledPixels {
impl Eq for ScaledPixels {}
impl Debug for ScaledPixels {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} px (scaled)", self.0)
}
}
@@ -738,12 +742,18 @@ impl From<DevicePixels> for ScaledPixels {
}
}
+impl From<ScaledPixels> for f64 {
+ fn from(scaled_pixels: ScaledPixels) -> Self {
+ scaled_pixels.0 as f64
+ }
+}
+
#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct GlobalPixels(pub(crate) f32);
impl Debug for GlobalPixels {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} px (global coordinate space)", self.0)
}
}
@@ -772,7 +782,7 @@ impl Mul<Pixels> for Rems {
}
impl Debug for Rems {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} rem", self.0)
}
}
@@ -840,7 +850,7 @@ impl DefiniteLength {
}
impl Debug for DefiniteLength {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DefiniteLength::Absolute(length) => Debug::fmt(length, f),
DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
@@ -880,7 +890,7 @@ pub enum Length {
}
impl Debug for Length {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
Length::Auto => write!(f, "auto"),
@@ -182,49 +182,42 @@ impl MetalRenderer {
});
let mut instance_offset = 0;
- for layer in scene.layers() {
- for batch in layer.batches() {
- match batch {
- crate::PrimitiveBatch::Quads(quads) => {
- self.draw_quads(
- quads,
- &mut instance_offset,
- viewport_size,
- command_encoder,
- );
- }
- crate::PrimitiveBatch::Shadows(shadows) => {
- self.draw_shadows(
- shadows,
- &mut instance_offset,
- viewport_size,
- command_encoder,
- );
- }
- crate::PrimitiveBatch::MonochromeSprites {
+ for batch in scene.batches() {
+ match batch {
+ crate::PrimitiveBatch::Quads(quads) => {
+ self.draw_quads(quads, &mut instance_offset, viewport_size, command_encoder);
+ }
+ crate::PrimitiveBatch::Shadows(shadows) => {
+ self.draw_shadows(
+ shadows,
+ &mut instance_offset,
+ viewport_size,
+ command_encoder,
+ );
+ }
+ crate::PrimitiveBatch::MonochromeSprites {
+ texture_id,
+ sprites,
+ } => {
+ self.draw_monochrome_sprites(
texture_id,
sprites,
- } => {
- self.draw_monochrome_sprites(
- texture_id,
- sprites,
- &mut instance_offset,
- viewport_size,
- command_encoder,
- );
- }
- crate::PrimitiveBatch::PolychromeSprites {
+ &mut instance_offset,
+ viewport_size,
+ command_encoder,
+ );
+ }
+ crate::PrimitiveBatch::PolychromeSprites {
+ texture_id,
+ sprites,
+ } => {
+ self.draw_polychrome_sprites(
texture_id,
sprites,
- } => {
- self.draw_polychrome_sprites(
- texture_id,
- sprites,
- &mut instance_offset,
- viewport_size,
- command_encoder,
- );
- }
+ &mut instance_offset,
+ viewport_size,
+ command_encoder,
+ );
}
}
}
@@ -1,18 +1,26 @@
-use std::{iter::Peekable, mem, slice};
-
-use super::{Bounds, Hsla, Point};
-use crate::{AtlasTextureId, AtlasTile, Corners, Edges, ScaledContentMask, ScaledPixels};
+use crate::{
+ AtlasTextureId, AtlasTile, Bounds, Corners, Edges, Hsla, Point, ScaledContentMask, ScaledPixels,
+};
use collections::BTreeMap;
+use etagere::euclid::{Point3D, Vector3D};
+use plane_split::{BspSplitter, Polygon as BspPolygon};
use smallvec::SmallVec;
+use std::{iter::Peekable, mem, slice};
// Exported to metal
pub type PointF = Point<f32>;
-pub type LayerId = SmallVec<[u32; 16]>;
+pub type StackingOrder = SmallVec<[u32; 16]>;
+pub type LayerId = u32;
+pub type DrawOrder = u32;
#[derive(Debug)]
pub struct Scene {
pub(crate) scale_factor: f32,
- pub(crate) layers: BTreeMap<LayerId, SceneLayer>,
+ pub(crate) layers: BTreeMap<StackingOrder, LayerId>,
+ pub quads: Vec<Quad>,
+ pub shadows: Vec<Shadow>,
+ pub monochrome_sprites: Vec<MonochromeSprite>,
+ pub polychrome_sprites: Vec<PolychromeSprite>,
}
impl Scene {
@@ -20,6 +28,10 @@ impl Scene {
Scene {
scale_factor,
layers: BTreeMap::new(),
+ quads: Vec::new(),
+ shadows: Vec::new(),
+ monochrome_sprites: Vec::new(),
+ polychrome_sprites: Vec::new(),
}
}
@@ -27,47 +39,95 @@ impl Scene {
Scene {
scale_factor: self.scale_factor,
layers: mem::take(&mut self.layers),
+ quads: mem::take(&mut self.quads),
+ shadows: mem::take(&mut self.shadows),
+ monochrome_sprites: mem::take(&mut self.monochrome_sprites),
+ polychrome_sprites: mem::take(&mut self.polychrome_sprites),
}
}
- pub fn insert(&mut self, stacking_order: LayerId, primitive: impl Into<Primitive>) {
- let layer = self.layers.entry(stacking_order).or_default();
-
+ pub fn insert(&mut self, layer_id: StackingOrder, primitive: impl Into<Primitive>) {
+ let next_id = self.layers.len() as LayerId;
+ let layer_id = *self.layers.entry(layer_id).or_insert(next_id);
let primitive = primitive.into();
match primitive {
- Primitive::Quad(quad) => {
- layer.quads.push(quad);
+ Primitive::Quad(mut quad) => {
+ quad.order = layer_id;
+ self.quads.push(quad);
}
- Primitive::Shadow(shadow) => {
- layer.shadows.push(shadow);
+ Primitive::Shadow(mut shadow) => {
+ shadow.order = layer_id;
+ self.shadows.push(shadow);
}
- Primitive::MonochromeSprite(sprite) => {
- layer.monochrome_sprites.push(sprite);
+ Primitive::MonochromeSprite(mut sprite) => {
+ sprite.order = layer_id;
+ self.monochrome_sprites.push(sprite);
}
- Primitive::PolychromeSprite(sprite) => {
- layer.polychrome_sprites.push(sprite);
+ Primitive::PolychromeSprite(mut sprite) => {
+ sprite.order = layer_id;
+ self.polychrome_sprites.push(sprite);
}
}
}
- pub(crate) fn layers(&mut self) -> impl Iterator<Item = &mut SceneLayer> {
- self.layers.values_mut()
- }
-}
+ pub(crate) fn batches(&mut self) -> impl Iterator<Item = PrimitiveBatch> {
+ // Map each layer id to a float between 0. and 1., with 1. closer to the viewer.
+ let mut layer_z_values = vec![0.; self.layers.len()];
+ for (ix, layer_id) in self.layers.values().enumerate() {
+ layer_z_values[*layer_id as usize] = ix as f32 / self.layers.len() as f32;
+ }
-#[derive(Debug, Default)]
-pub(crate) struct SceneLayer {
- pub quads: Vec<Quad>,
- pub shadows: Vec<Shadow>,
- pub monochrome_sprites: Vec<MonochromeSprite>,
- pub polychrome_sprites: Vec<PolychromeSprite>,
-}
+ // Add all primitives to the BSP splitter to determine draw order
+ let mut splitter = BspSplitter::new();
+ for (ix, quad) in self.quads.iter().enumerate() {
+ let z = layer_z_values[quad.order as LayerId as usize];
+ splitter.add(quad.bounds.to_bsp_polygon(z, (PrimitiveKind::Quad, ix)));
+ }
+
+ for (ix, shadow) in self.shadows.iter().enumerate() {
+ let z = layer_z_values[shadow.order as LayerId as usize];
+ splitter.add(shadow.bounds.to_bsp_polygon(z, (PrimitiveKind::Shadow, ix)));
+ }
+
+ for (ix, monochrome_sprite) in self.monochrome_sprites.iter().enumerate() {
+ let z = layer_z_values[monochrome_sprite.order as LayerId as usize];
+ splitter.add(
+ monochrome_sprite
+ .bounds
+ .to_bsp_polygon(z, (PrimitiveKind::MonochromeSprite, ix)),
+ );
+ }
-impl SceneLayer {
- pub fn batches(&mut self) -> impl Iterator<Item = PrimitiveBatch> {
+ for (ix, polychrome_sprite) in self.polychrome_sprites.iter().enumerate() {
+ let z = layer_z_values[polychrome_sprite.order as LayerId as usize];
+ splitter.add(
+ polychrome_sprite
+ .bounds
+ .to_bsp_polygon(z, (PrimitiveKind::PolychromeSprite, ix)),
+ );
+ }
+
+ // Sort all polygons, then reassign the order field of each primitive to `draw_order`
+ // We need primitives to be repr(C), hence the weird reuse of the order field for two different types.
+ for (draw_order, polygon) in splitter.sort(Vector3D::new(0., 0., 1.)).iter().enumerate() {
+ match polygon.anchor {
+ (PrimitiveKind::Quad, ix) => self.quads[ix].order = draw_order as DrawOrder,
+ (PrimitiveKind::Shadow, ix) => self.shadows[ix].order = draw_order as DrawOrder,
+ (PrimitiveKind::MonochromeSprite, ix) => {
+ self.monochrome_sprites[ix].order = draw_order as DrawOrder
+ }
+ (PrimitiveKind::PolychromeSprite, ix) => {
+ self.polychrome_sprites[ix].order = draw_order as DrawOrder
+ }
+ }
+ }
+
+ // Sort the primitives
self.quads.sort_unstable();
+ self.shadows.sort_unstable();
self.monochrome_sprites.sort_unstable();
self.polychrome_sprites.sort_unstable();
+
BatchIterator {
quads: &self.quads,
quads_start: 0,
@@ -104,27 +164,27 @@ impl<'a> Iterator for BatchIterator<'a> {
type Item = PrimitiveBatch<'a>;
fn next(&mut self) -> Option<Self::Item> {
- let mut kinds_and_orders = [
- (PrimitiveKind::Quad, self.quads_iter.peek().map(|q| q.order)),
+ let mut orders_and_kinds = [
+ (self.quads_iter.peek().map(|q| q.order), PrimitiveKind::Quad),
(
- PrimitiveKind::Shadow,
self.shadows_iter.peek().map(|s| s.order),
+ PrimitiveKind::Shadow,
),
(
- PrimitiveKind::MonochromeSprite,
self.monochrome_sprites_iter.peek().map(|s| s.order),
+ PrimitiveKind::MonochromeSprite,
),
(
- PrimitiveKind::PolychromeSprite,
self.polychrome_sprites_iter.peek().map(|s| s.order),
+ PrimitiveKind::PolychromeSprite,
),
];
- kinds_and_orders.sort_by_key(|(_, order)| order.unwrap_or(u32::MAX));
+ orders_and_kinds.sort_by_key(|(order, kind)| (order.unwrap_or(u32::MAX), *kind));
- let first = kinds_and_orders[0];
- let second = kinds_and_orders[1];
- let (batch_kind, max_order) = if first.1.is_some() {
- (first.0, second.1.unwrap_or(u32::MAX))
+ let first = orders_and_kinds[0];
+ let second = orders_and_kinds[1];
+ let (batch_kind, max_order) = if first.0.is_some() {
+ (first.1, second.0.unwrap_or(u32::MAX))
} else {
return None;
};
@@ -132,23 +192,27 @@ impl<'a> Iterator for BatchIterator<'a> {
match batch_kind {
PrimitiveKind::Quad => {
let quads_start = self.quads_start;
- let quads_end = quads_start
- + self
- .quads_iter
- .by_ref()
- .take_while(|quad| quad.order <= max_order)
- .count();
+ let mut quads_end = quads_start;
+ while self
+ .quads_iter
+ .next_if(|quad| quad.order <= max_order)
+ .is_some()
+ {
+ quads_end += 1;
+ }
self.quads_start = quads_end;
Some(PrimitiveBatch::Quads(&self.quads[quads_start..quads_end]))
}
PrimitiveKind::Shadow => {
let shadows_start = self.shadows_start;
- let shadows_end = shadows_start
- + self
- .shadows_iter
- .by_ref()
- .take_while(|shadow| shadow.order <= max_order)
- .count();
+ let mut shadows_end = shadows_start;
+ while self
+ .shadows_iter
+ .next_if(|shadow| shadow.order <= max_order)
+ .is_some()
+ {
+ shadows_end += 1;
+ }
self.shadows_start = shadows_end;
Some(PrimitiveBatch::Shadows(
&self.shadows[shadows_start..shadows_end],
@@ -157,14 +221,16 @@ impl<'a> Iterator for BatchIterator<'a> {
PrimitiveKind::MonochromeSprite => {
let texture_id = self.monochrome_sprites_iter.peek().unwrap().tile.texture_id;
let sprites_start = self.monochrome_sprites_start;
- let sprites_end = sprites_start
- + self
- .monochrome_sprites_iter
- .by_ref()
- .take_while(|sprite| {
- sprite.order <= max_order && sprite.tile.texture_id == texture_id
- })
- .count();
+ let mut sprites_end = sprites_start;
+ while self
+ .monochrome_sprites_iter
+ .next_if(|sprite| {
+ sprite.order <= max_order && sprite.tile.texture_id == texture_id
+ })
+ .is_some()
+ {
+ sprites_end += 1;
+ }
self.monochrome_sprites_start = sprites_end;
Some(PrimitiveBatch::MonochromeSprites {
texture_id,
@@ -174,14 +240,16 @@ impl<'a> Iterator for BatchIterator<'a> {
PrimitiveKind::PolychromeSprite => {
let texture_id = self.polychrome_sprites_iter.peek().unwrap().tile.texture_id;
let sprites_start = self.polychrome_sprites_start;
- let sprites_end = sprites_start
- + self
- .polychrome_sprites_iter
- .by_ref()
- .take_while(|sprite| {
- sprite.order <= max_order && sprite.tile.texture_id == texture_id
- })
- .count();
+ let mut sprites_end = self.polychrome_sprites_start;
+ while self
+ .polychrome_sprites_iter
+ .next_if(|sprite| {
+ sprite.order <= max_order && sprite.tile.texture_id == texture_id
+ })
+ .is_some()
+ {
+ sprites_end += 1;
+ }
self.polychrome_sprites_start = sprites_end;
Some(PrimitiveBatch::PolychromeSprites {
texture_id,
@@ -192,10 +260,11 @@ impl<'a> Iterator for BatchIterator<'a> {
}
}
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Default)]
pub enum PrimitiveKind {
- Quad,
Shadow,
+ #[default]
+ Quad,
MonochromeSprite,
PolychromeSprite,
}
@@ -222,10 +291,10 @@ pub(crate) enum PrimitiveBatch<'a> {
},
}
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Default, Debug, Clone, Eq, PartialEq)]
#[repr(C)]
pub struct Quad {
- pub order: u32,
+ pub order: u32, // Initially a LayerId, then a DrawOrder.
pub bounds: Bounds<ScaledPixels>,
pub content_mask: ScaledContentMask,
pub background: Hsla,
@@ -346,3 +415,76 @@ impl From<PolychromeSprite> for Primitive {
#[derive(Copy, Clone, Debug)]
pub struct AtlasId(pub(crate) usize);
+
+impl Bounds<ScaledPixels> {
+ fn to_bsp_polygon<A: Copy>(&self, z: f32, anchor: A) -> BspPolygon<A> {
+ let upper_left = self.origin;
+ let upper_right = self.upper_right();
+ let lower_right = self.lower_right();
+ let lower_left = self.lower_left();
+
+ BspPolygon::from_points(
+ [
+ Point3D::new(upper_left.x.into(), upper_left.y.into(), z as f64),
+ Point3D::new(upper_right.x.into(), upper_right.y.into(), z as f64),
+ Point3D::new(lower_right.x.into(), lower_right.y.into(), z as f64),
+ Point3D::new(lower_left.x.into(), lower_left.y.into(), z as f64),
+ ],
+ anchor,
+ )
+ .expect("Polygon should not be empty")
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::{point, size};
+
+ use super::*;
+ use smallvec::smallvec;
+
+ #[test]
+ fn test_scene() {
+ let mut scene = Scene::new(1.0);
+ assert_eq!(scene.layers.len(), 0);
+
+ scene.insert(smallvec![1], quad());
+ scene.insert(smallvec![2], shadow());
+ scene.insert(smallvec![3], quad());
+
+ let mut batches_count = 0;
+ for _ in scene.batches() {
+ batches_count += 1;
+ }
+ assert_eq!(batches_count, 3);
+ }
+
+ fn quad() -> Quad {
+ Quad {
+ order: 0,
+ bounds: Bounds {
+ origin: point(ScaledPixels(0.), ScaledPixels(0.)),
+ size: size(ScaledPixels(100.), ScaledPixels(100.)),
+ },
+ content_mask: Default::default(),
+ background: Default::default(),
+ border_color: Default::default(),
+ corner_radii: Default::default(),
+ border_widths: Default::default(),
+ }
+ }
+
+ fn shadow() -> Shadow {
+ Shadow {
+ order: Default::default(),
+ bounds: Bounds {
+ origin: point(ScaledPixels(0.), ScaledPixels(0.)),
+ size: size(ScaledPixels(100.), ScaledPixels(100.)),
+ },
+ corner_radii: Default::default(),
+ content_mask: Default::default(),
+ color: Default::default(),
+ blur_radius: Default::default(),
+ }
+ }
+}
@@ -246,46 +246,50 @@ impl Style {
let scale = cx.scale_factor();
for shadow in &self.box_shadow {
- let layer_id = cx.current_layer_id();
let content_mask = cx.content_mask();
let mut shadow_bounds = bounds;
shadow_bounds.origin += shadow.offset;
shadow_bounds.dilate(shadow.spread_radius);
- cx.scene().insert(
- layer_id,
- Shadow {
- order,
- bounds: shadow_bounds.scale(scale),
- content_mask: content_mask.scale(scale),
- corner_radii: self
- .corner_radii
- .to_pixels(shadow_bounds.size, rem_size)
- .scale(scale),
- color: shadow.color,
- blur_radius: shadow.blur_radius.scale(scale),
- },
- );
+ cx.stack(0, |cx| {
+ let layer_id = cx.current_stacking_order();
+ cx.scene().insert(
+ layer_id,
+ Shadow {
+ order: 0,
+ bounds: shadow_bounds.scale(scale),
+ content_mask: content_mask.scale(scale),
+ corner_radii: self
+ .corner_radii
+ .to_pixels(shadow_bounds.size, rem_size)
+ .scale(scale),
+ color: shadow.color,
+ blur_radius: shadow.blur_radius.scale(scale),
+ },
+ );
+ })
}
let background_color = self.fill.as_ref().and_then(Fill::color);
if background_color.is_some() || self.is_border_visible() {
- let layer_id = cx.current_layer_id();
let content_mask = cx.content_mask();
- cx.scene().insert(
- layer_id,
- Quad {
+ cx.stack(1, |cx| {
+ let order = cx.current_stacking_order();
+ cx.scene().insert(
order,
- bounds: bounds.scale(scale),
- content_mask: content_mask.scale(scale),
- background: background_color.unwrap_or_default(),
- border_color: self.border_color.unwrap_or_default(),
- corner_radii: self
- .corner_radii
- .to_pixels(bounds.size, rem_size)
- .scale(scale),
- border_widths: self.border_widths.to_pixels(rem_size).scale(scale),
- },
- );
+ Quad {
+ order: 0,
+ bounds: bounds.scale(scale),
+ content_mask: content_mask.scale(scale),
+ background: background_color.unwrap_or_default(),
+ border_color: self.border_color.unwrap_or_default(),
+ corner_radii: self
+ .corner_radii
+ .to_pixels(bounds.size, rem_size)
+ .scale(scale),
+ border_widths: self.border_widths.to_pixels(rem_size).scale(scale),
+ },
+ );
+ });
}
}
@@ -263,7 +263,7 @@ pub trait StyleHelpers: Styled<Style = Style> {
{
self.declared_style().box_shadow = Some(smallvec![
BoxShadow {
- color: hsla(0., 0., 0., 0.1),
+ color: hsla(0.5, 0., 0., 1.0),
offset: point(px(0.), px(4.)),
blur_radius: px(6.),
spread_radius: px(-1.),
@@ -1,11 +1,10 @@
use crate::{
image_cache::RenderImageParams, px, AnyView, AppContext, AsyncWindowContext, AvailableSpace,
BorrowAppContext, Bounds, Context, Corners, DevicePixels, DisplayId, Effect, Element, EntityId,
- FontId, GlyphId, Handle, Hsla, ImageData, IsZero, LayerId, LayoutId, MainThread,
- MainThreadOnly, MonochromeSprite, Pixels, PlatformAtlas, PlatformWindow, Point,
- PolychromeSprite, Reference, RenderGlyphParams, RenderSvgParams, ScaledPixels, Scene,
- SharedString, Size, Style, TaffyLayoutEngine, Task, WeakHandle, WindowOptions,
- SUBPIXEL_VARIANTS,
+ FontId, GlyphId, Handle, Hsla, ImageData, IsZero, LayoutId, MainThread, MainThreadOnly,
+ MonochromeSprite, Pixels, PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Reference,
+ RenderGlyphParams, RenderSvgParams, ScaledPixels, Scene, SharedString, Size, StackingOrder,
+ Style, TaffyLayoutEngine, Task, WeakHandle, WindowOptions, SUBPIXEL_VARIANTS,
};
use anyhow::Result;
use smallvec::SmallVec;
@@ -24,7 +23,7 @@ pub struct Window {
layout_engine: TaffyLayoutEngine,
pub(crate) root_view: Option<AnyView<()>>,
mouse_position: Point<Pixels>,
- current_layer_id: LayerId,
+ current_stacking_order: StackingOrder,
content_mask_stack: Vec<ContentMask>,
pub(crate) scene: Scene,
pub(crate) dirty: bool,
@@ -73,7 +72,7 @@ impl Window {
layout_engine: TaffyLayoutEngine::new(),
root_view: None,
mouse_position,
- current_layer_id: SmallVec::new(),
+ current_stacking_order: SmallVec::new(),
content_mask_stack: Vec::new(),
scene: Scene::new(scale_factor),
dirty: true,
@@ -99,7 +98,7 @@ impl ContentMask {
}
}
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Default, Clone, Debug, PartialEq, Eq)]
#[repr(C)]
pub struct ScaledContentMask {
bounds: Bounds<ScaledPixels>,
@@ -250,14 +249,14 @@ impl<'a, 'w> WindowContext<'a, 'w> {
}
pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
- self.window.current_layer_id.push(order);
+ self.window.current_stacking_order.push(order);
let result = f(self);
- self.window.current_layer_id.pop();
+ self.window.current_stacking_order.pop();
result
}
- pub fn current_layer_id(&self) -> LayerId {
- self.window.current_layer_id.clone()
+ pub fn current_stacking_order(&self) -> StackingOrder {
+ self.window.current_stacking_order.clone()
}
pub fn paint_glyph(
@@ -286,7 +285,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
let raster_bounds = self.text_system().raster_bounds(¶ms)?;
if !raster_bounds.is_zero() {
- let layer_id = self.current_layer_id();
+ let layer_id = self.current_stacking_order();
let tile =
self.window
.sprite_atlas
@@ -336,7 +335,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
let raster_bounds = self.text_system().raster_bounds(¶ms)?;
if !raster_bounds.is_zero() {
- let layer_id = self.current_layer_id();
+ let layer_id = self.current_stacking_order();
let tile =
self.window
.sprite_atlas
@@ -382,7 +381,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
.map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
};
- let layer_id = self.current_layer_id();
+ let layer_id = self.current_stacking_order();
let tile =
self.window
.sprite_atlas
@@ -418,7 +417,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
let bounds = bounds.scale(scale_factor);
let params = RenderImageParams { image_id: data.id };
- let layer_id = self.current_layer_id();
+ let order = self.current_stacking_order();
let tile = self
.window
.sprite_atlas
@@ -429,9 +428,9 @@ impl<'a, 'w> WindowContext<'a, 'w> {
let corner_radii = corner_radii.scale(scale_factor);
self.window.scene.insert(
- layer_id,
+ order,
PolychromeSprite {
- order,
+ order: 0, // Used in in Scene::batches. 0 has no meaning.
bounds,
content_mask,
corner_radii,
@@ -620,6 +619,13 @@ impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> {
self.entities.weak_handle(self.entity_id)
}
+ pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
+ self.window.current_stacking_order.push(order);
+ let result = f(self);
+ self.window.current_stacking_order.pop();
+ result
+ }
+
pub fn on_next_frame(&mut self, f: impl FnOnce(&mut S, &mut ViewContext<S>) + Send + 'static) {
let entity = self.handle();
self.window_cx.on_next_frame(move |cx| {
@@ -92,7 +92,7 @@ impl CollabPanel {
),
]
})
- .take(10)
+ .take(5)
.flatten(),
),
),
@@ -168,7 +168,7 @@ impl CollabPanel {
.uri(avatar_uri)
.size_3p5()
.rounded_full()
- // .fill(theme.middle.positive.default.foreground)
+ .fill(theme.middle.positive.default.foreground)
.shadow_md(),
)
.child(label),
@@ -1,3 +1,3 @@
-mod rose_pine_dawn;
+mod rose_pine;
-pub use rose_pine_dawn::*;
+pub use rose_pine::*;
@@ -1,7 +1,7 @@
use crate::theme::Theme;
use gpui3::serde_json::{self, json};
-pub fn rose_pine_dawn() -> Theme {
+pub fn rose_pine() -> Theme {
serde_json::from_value(json! {
{
"name": "RosΓ© Pine",
@@ -843,3 +843,844 @@ pub fn rose_pine_dawn() -> Theme {
})
.unwrap()
}
+
+pub fn rose_pine_dawn() -> Theme {
+ serde_json::from_value(json!({
+ "name": "RosΓ© Pine Dawn",
+ "is_light": true,
+ "ramps": {},
+ "lowest": {
+ "base": {
+ "default": {
+ "background": "#dcd8d8",
+ "border": "#dcd6d5",
+ "foreground": "#575279"
+ },
+ "hovered": {
+ "background": "#dcd6d5",
+ "border": "#dcd6d5",
+ "foreground": "#575279"
+ },
+ "pressed": {
+ "background": "#efe6df",
+ "border": "#dcd6d5",
+ "foreground": "#575279"
+ },
+ "active": {
+ "background": "#c1bac1",
+ "border": "#a9a3b0",
+ "foreground": "#575279"
+ },
+ "disabled": {
+ "background": "#dcd8d8",
+ "border": "#d0cccf",
+ "foreground": "#938fa3"
+ },
+ "inverted": {
+ "background": "#575279",
+ "border": "#faf4ed",
+ "foreground": "#c7c0c5"
+ }
+ },
+ "variant": {
+ "default": {
+ "background": "#dcd8d8",
+ "border": "#dcd6d5",
+ "foreground": "#706c8c"
+ },
+ "hovered": {
+ "background": "#dcd6d5",
+ "border": "#dcd6d5",
+ "foreground": "#706c8c"
+ },
+ "pressed": {
+ "background": "#efe6df",
+ "border": "#dcd6d5",
+ "foreground": "#706c8c"
+ },
+ "active": {
+ "background": "#c1bac1",
+ "border": "#a9a3b0",
+ "foreground": "#575279"
+ },
+ "disabled": {
+ "background": "#dcd8d8",
+ "border": "#d0cccf",
+ "foreground": "#938fa3"
+ },
+ "inverted": {
+ "background": "#575279",
+ "border": "#faf4ed",
+ "foreground": "#c7c0c5"
+ }
+ },
+ "on": {
+ "default": {
+ "background": "#fef9f2",
+ "border": "#e5e0df",
+ "foreground": "#575279"
+ },
+ "hovered": {
+ "background": "#e5e0df",
+ "border": "#e5e0df",
+ "foreground": "#575279"
+ },
+ "pressed": {
+ "background": "#d4d0d2",
+ "border": "#e5e0df",
+ "foreground": "#575279"
+ },
+ "active": {
+ "background": "#dbd5d4",
+ "border": "#dbd3d1",
+ "foreground": "#575279"
+ },
+ "disabled": {
+ "background": "#fef9f2",
+ "border": "#f6f1eb",
+ "foreground": "#b1abb5"
+ },
+ "inverted": {
+ "background": "#575279",
+ "border": "#faf4ed",
+ "foreground": "#d6d1d1"
+ }
+ },
+ "accent": {
+ "default": {
+ "background": "#dde9eb",
+ "border": "#c3d7db",
+ "foreground": "#57949f"
+ },
+ "hovered": {
+ "background": "#c3d7db",
+ "border": "#c3d7db",
+ "foreground": "#57949f"
+ },
+ "pressed": {
+ "background": "#b6cfd3",
+ "border": "#c3d7db",
+ "foreground": "#57949f"
+ },
+ "active": {
+ "background": "#a3c3c9",
+ "border": "#8db6bd",
+ "foreground": "#06090a"
+ },
+ "disabled": {
+ "background": "#dde9eb",
+ "border": "#d0e0e3",
+ "foreground": "#72a5ae"
+ },
+ "inverted": {
+ "background": "#06090a",
+ "border": "#ffffff",
+ "foreground": "#a8c7cd"
+ }
+ },
+ "positive": {
+ "default": {
+ "background": "#dbeee7",
+ "border": "#bee0d5",
+ "foreground": "#3eaa8e"
+ },
+ "hovered": {
+ "background": "#bee0d5",
+ "border": "#bee0d5",
+ "foreground": "#3eaa8e"
+ },
+ "pressed": {
+ "background": "#b0dacb",
+ "border": "#bee0d5",
+ "foreground": "#3eaa8e"
+ },
+ "active": {
+ "background": "#9bd0bf",
+ "border": "#82c6b1",
+ "foreground": "#060a09"
+ },
+ "disabled": {
+ "background": "#dbeee7",
+ "border": "#cde7de",
+ "foreground": "#63b89f"
+ },
+ "inverted": {
+ "background": "#060a09",
+ "border": "#ffffff",
+ "foreground": "#a1d4c3"
+ }
+ },
+ "warning": {
+ "default": {
+ "background": "#ffebd6",
+ "border": "#ffdab7",
+ "foreground": "#e99d35"
+ },
+ "hovered": {
+ "background": "#ffdab7",
+ "border": "#ffdab7",
+ "foreground": "#e99d35"
+ },
+ "pressed": {
+ "background": "#fed2a6",
+ "border": "#ffdab7",
+ "foreground": "#e99d35"
+ },
+ "active": {
+ "background": "#fbc891",
+ "border": "#f7bc77",
+ "foreground": "#330704"
+ },
+ "disabled": {
+ "background": "#ffebd6",
+ "border": "#ffe2c7",
+ "foreground": "#f1ac57"
+ },
+ "inverted": {
+ "background": "#330704",
+ "border": "#ffffff",
+ "foreground": "#fccb97"
+ }
+ },
+ "negative": {
+ "default": {
+ "background": "#f1dfe3",
+ "border": "#e6c6cd",
+ "foreground": "#b4647a"
+ },
+ "hovered": {
+ "background": "#e6c6cd",
+ "border": "#e6c6cd",
+ "foreground": "#b4647a"
+ },
+ "pressed": {
+ "background": "#e0bac2",
+ "border": "#e6c6cd",
+ "foreground": "#b4647a"
+ },
+ "active": {
+ "background": "#d8a8b3",
+ "border": "#ce94a3",
+ "foreground": "#0b0708"
+ },
+ "disabled": {
+ "background": "#f1dfe3",
+ "border": "#ecd2d8",
+ "foreground": "#c17b8e"
+ },
+ "inverted": {
+ "background": "#0b0708",
+ "border": "#ffffff",
+ "foreground": "#dbadb8"
+ }
+ }
+ },
+ "middle": {
+ "base": {
+ "default": {
+ "background": "#fef9f2",
+ "border": "#e5e0df",
+ "foreground": "#575279"
+ },
+ "hovered": {
+ "background": "#e5e0df",
+ "border": "#e5e0df",
+ "foreground": "#575279"
+ },
+ "pressed": {
+ "background": "#d4d0d2",
+ "border": "#e5e0df",
+ "foreground": "#575279"
+ },
+ "active": {
+ "background": "#dbd5d4",
+ "border": "#dbd3d1",
+ "foreground": "#575279"
+ },
+ "disabled": {
+ "background": "#fef9f2",
+ "border": "#f6f1eb",
+ "foreground": "#b1abb5"
+ },
+ "inverted": {
+ "background": "#575279",
+ "border": "#faf4ed",
+ "foreground": "#d6d1d1"
+ }
+ },
+ "variant": {
+ "default": {
+ "background": "#fef9f2",
+ "border": "#e5e0df",
+ "foreground": "#706c8c"
+ },
+ "hovered": {
+ "background": "#e5e0df",
+ "border": "#e5e0df",
+ "foreground": "#706c8c"
+ },
+ "pressed": {
+ "background": "#d4d0d2",
+ "border": "#e5e0df",
+ "foreground": "#706c8c"
+ },
+ "active": {
+ "background": "#dbd5d4",
+ "border": "#dbd3d1",
+ "foreground": "#575279"
+ },
+ "disabled": {
+ "background": "#fef9f2",
+ "border": "#f6f1eb",
+ "foreground": "#b1abb5"
+ },
+ "inverted": {
+ "background": "#575279",
+ "border": "#faf4ed",
+ "foreground": "#d6d1d1"
+ }
+ },
+ "on": {
+ "default": {
+ "background": "#faf4ed",
+ "border": "#fdf8f1",
+ "foreground": "#575279"
+ },
+ "hovered": {
+ "background": "#fdf8f1",
+ "border": "#fdf8f1",
+ "foreground": "#575279"
+ },
+ "pressed": {
+ "background": "#fdf8f2",
+ "border": "#fdf8f1",
+ "foreground": "#575279"
+ },
+ "active": {
+ "background": "#e6e1e0",
+ "border": "#d0cccf",
+ "foreground": "#575279"
+ },
+ "disabled": {
+ "background": "#faf4ed",
+ "border": "#fcf6ef",
+ "foreground": "#efe6df"
+ },
+ "inverted": {
+ "background": "#575279",
+ "border": "#faf4ed",
+ "foreground": "#ede9e5"
+ }
+ },
+ "accent": {
+ "default": {
+ "background": "#dde9eb",
+ "border": "#c3d7db",
+ "foreground": "#57949f"
+ },
+ "hovered": {
+ "background": "#c3d7db",
+ "border": "#c3d7db",
+ "foreground": "#57949f"
+ },
+ "pressed": {
+ "background": "#b6cfd3",
+ "border": "#c3d7db",
+ "foreground": "#57949f"
+ },
+ "active": {
+ "background": "#a3c3c9",
+ "border": "#8db6bd",
+ "foreground": "#06090a"
+ },
+ "disabled": {
+ "background": "#dde9eb",
+ "border": "#d0e0e3",
+ "foreground": "#72a5ae"
+ },
+ "inverted": {
+ "background": "#06090a",
+ "border": "#ffffff",
+ "foreground": "#a8c7cd"
+ }
+ },
+ "positive": {
+ "default": {
+ "background": "#dbeee7",
+ "border": "#bee0d5",
+ "foreground": "#3eaa8e"
+ },
+ "hovered": {
+ "background": "#bee0d5",
+ "border": "#bee0d5",
+ "foreground": "#3eaa8e"
+ },
+ "pressed": {
+ "background": "#b0dacb",
+ "border": "#bee0d5",
+ "foreground": "#3eaa8e"
+ },
+ "active": {
+ "background": "#9bd0bf",
+ "border": "#82c6b1",
+ "foreground": "#060a09"
+ },
+ "disabled": {
+ "background": "#dbeee7",
+ "border": "#cde7de",
+ "foreground": "#63b89f"
+ },
+ "inverted": {
+ "background": "#060a09",
+ "border": "#ffffff",
+ "foreground": "#a1d4c3"
+ }
+ },
+ "warning": {
+ "default": {
+ "background": "#ffebd6",
+ "border": "#ffdab7",
+ "foreground": "#e99d35"
+ },
+ "hovered": {
+ "background": "#ffdab7",
+ "border": "#ffdab7",
+ "foreground": "#e99d35"
+ },
+ "pressed": {
+ "background": "#fed2a6",
+ "border": "#ffdab7",
+ "foreground": "#e99d35"
+ },
+ "active": {
+ "background": "#fbc891",
+ "border": "#f7bc77",
+ "foreground": "#330704"
+ },
+ "disabled": {
+ "background": "#ffebd6",
+ "border": "#ffe2c7",
+ "foreground": "#f1ac57"
+ },
+ "inverted": {
+ "background": "#330704",
+ "border": "#ffffff",
+ "foreground": "#fccb97"
+ }
+ },
+ "negative": {
+ "default": {
+ "background": "#f1dfe3",
+ "border": "#e6c6cd",
+ "foreground": "#b4647a"
+ },
+ "hovered": {
+ "background": "#e6c6cd",
+ "border": "#e6c6cd",
+ "foreground": "#b4647a"
+ },
+ "pressed": {
+ "background": "#e0bac2",
+ "border": "#e6c6cd",
+ "foreground": "#b4647a"
+ },
+ "active": {
+ "background": "#d8a8b3",
+ "border": "#ce94a3",
+ "foreground": "#0b0708"
+ },
+ "disabled": {
+ "background": "#f1dfe3",
+ "border": "#ecd2d8",
+ "foreground": "#c17b8e"
+ },
+ "inverted": {
+ "background": "#0b0708",
+ "border": "#ffffff",
+ "foreground": "#dbadb8"
+ }
+ }
+ },
+ "highest": {
+ "base": {
+ "default": {
+ "background": "#faf4ed",
+ "border": "#fdf8f1",
+ "foreground": "#575279"
+ },
+ "hovered": {
+ "background": "#fdf8f1",
+ "border": "#fdf8f1",
+ "foreground": "#575279"
+ },
+ "pressed": {
+ "background": "#fdf8f2",
+ "border": "#fdf8f1",
+ "foreground": "#575279"
+ },
+ "active": {
+ "background": "#e6e1e0",
+ "border": "#d0cccf",
+ "foreground": "#575279"
+ },
+ "disabled": {
+ "background": "#faf4ed",
+ "border": "#fcf6ef",
+ "foreground": "#efe6df"
+ },
+ "inverted": {
+ "background": "#575279",
+ "border": "#faf4ed",
+ "foreground": "#ede9e5"
+ }
+ },
+ "variant": {
+ "default": {
+ "background": "#faf4ed",
+ "border": "#fdf8f1",
+ "foreground": "#706c8c"
+ },
+ "hovered": {
+ "background": "#fdf8f1",
+ "border": "#fdf8f1",
+ "foreground": "#706c8c"
+ },
+ "pressed": {
+ "background": "#fdf8f2",
+ "border": "#fdf8f1",
+ "foreground": "#706c8c"
+ },
+ "active": {
+ "background": "#e6e1e0",
+ "border": "#d0cccf",
+ "foreground": "#575279"
+ },
+ "disabled": {
+ "background": "#faf4ed",
+ "border": "#fcf6ef",
+ "foreground": "#efe6df"
+ },
+ "inverted": {
+ "background": "#575279",
+ "border": "#faf4ed",
+ "foreground": "#ede9e5"
+ }
+ },
+ "on": {
+ "default": {
+ "background": "#fef9f2",
+ "border": "#e5e0df",
+ "foreground": "#575279"
+ },
+ "hovered": {
+ "background": "#e5e0df",
+ "border": "#e5e0df",
+ "foreground": "#575279"
+ },
+ "pressed": {
+ "background": "#d4d0d2",
+ "border": "#e5e0df",
+ "foreground": "#575279"
+ },
+ "active": {
+ "background": "#dbd5d4",
+ "border": "#dbd3d1",
+ "foreground": "#575279"
+ },
+ "disabled": {
+ "background": "#fef9f2",
+ "border": "#f6f1eb",
+ "foreground": "#b1abb5"
+ },
+ "inverted": {
+ "background": "#575279",
+ "border": "#faf4ed",
+ "foreground": "#d6d1d1"
+ }
+ },
+ "accent": {
+ "default": {
+ "background": "#dde9eb",
+ "border": "#c3d7db",
+ "foreground": "#57949f"
+ },
+ "hovered": {
+ "background": "#c3d7db",
+ "border": "#c3d7db",
+ "foreground": "#57949f"
+ },
+ "pressed": {
+ "background": "#b6cfd3",
+ "border": "#c3d7db",
+ "foreground": "#57949f"
+ },
+ "active": {
+ "background": "#a3c3c9",
+ "border": "#8db6bd",
+ "foreground": "#06090a"
+ },
+ "disabled": {
+ "background": "#dde9eb",
+ "border": "#d0e0e3",
+ "foreground": "#72a5ae"
+ },
+ "inverted": {
+ "background": "#06090a",
+ "border": "#ffffff",
+ "foreground": "#a8c7cd"
+ }
+ },
+ "positive": {
+ "default": {
+ "background": "#dbeee7",
+ "border": "#bee0d5",
+ "foreground": "#3eaa8e"
+ },
+ "hovered": {
+ "background": "#bee0d5",
+ "border": "#bee0d5",
+ "foreground": "#3eaa8e"
+ },
+ "pressed": {
+ "background": "#b0dacb",
+ "border": "#bee0d5",
+ "foreground": "#3eaa8e"
+ },
+ "active": {
+ "background": "#9bd0bf",
+ "border": "#82c6b1",
+ "foreground": "#060a09"
+ },
+ "disabled": {
+ "background": "#dbeee7",
+ "border": "#cde7de",
+ "foreground": "#63b89f"
+ },
+ "inverted": {
+ "background": "#060a09",
+ "border": "#ffffff",
+ "foreground": "#a1d4c3"
+ }
+ },
+ "warning": {
+ "default": {
+ "background": "#ffebd6",
+ "border": "#ffdab7",
+ "foreground": "#e99d35"
+ },
+ "hovered": {
+ "background": "#ffdab7",
+ "border": "#ffdab7",
+ "foreground": "#e99d35"
+ },
+ "pressed": {
+ "background": "#fed2a6",
+ "border": "#ffdab7",
+ "foreground": "#e99d35"
+ },
+ "active": {
+ "background": "#fbc891",
+ "border": "#f7bc77",
+ "foreground": "#330704"
+ },
+ "disabled": {
+ "background": "#ffebd6",
+ "border": "#ffe2c7",
+ "foreground": "#f1ac57"
+ },
+ "inverted": {
+ "background": "#330704",
+ "border": "#ffffff",
+ "foreground": "#fccb97"
+ }
+ },
+ "negative": {
+ "default": {
+ "background": "#f1dfe3",
+ "border": "#e6c6cd",
+ "foreground": "#b4647a"
+ },
+ "hovered": {
+ "background": "#e6c6cd",
+ "border": "#e6c6cd",
+ "foreground": "#b4647a"
+ },
+ "pressed": {
+ "background": "#e0bac2",
+ "border": "#e6c6cd",
+ "foreground": "#b4647a"
+ },
+ "active": {
+ "background": "#d8a8b3",
+ "border": "#ce94a3",
+ "foreground": "#0b0708"
+ },
+ "disabled": {
+ "background": "#f1dfe3",
+ "border": "#ecd2d8",
+ "foreground": "#c17b8e"
+ },
+ "inverted": {
+ "background": "#0b0708",
+ "border": "#ffffff",
+ "foreground": "#dbadb8"
+ }
+ }
+ },
+ "popover_shadow": {
+ "blur": 4,
+ "color": "#2c2a4d33",
+ "offset": [
+ 1,
+ 2
+ ]
+ },
+ "modal_shadow": {
+ "blur": 16,
+ "color": "#2c2a4d33",
+ "offset": [
+ 0,
+ 2
+ ]
+ },
+ "players": {
+ "0": {
+ "selection": "#57949f3d",
+ "cursor": "#57949f"
+ },
+ "1": {
+ "selection": "#3eaa8e3d",
+ "cursor": "#3eaa8e"
+ },
+ "2": {
+ "selection": "#7c697f3d",
+ "cursor": "#7c697f"
+ },
+ "3": {
+ "selection": "#907aa93d",
+ "cursor": "#907aa9"
+ },
+ "4": {
+ "selection": "#907aa93d",
+ "cursor": "#907aa9"
+ },
+ "5": {
+ "selection": "#2a69833d",
+ "cursor": "#2a6983"
+ },
+ "6": {
+ "selection": "#b4647a3d",
+ "cursor": "#b4647a"
+ },
+ "7": {
+ "selection": "#e99d353d",
+ "cursor": "#e99d35"
+ }
+ },
+ "syntax": {
+ "comment": {
+ "color": "#9893a5"
+ },
+ "operator": {
+ "color": "#286983"
+ },
+ "punctuation": {
+ "color": "#797593"
+ },
+ "variable": {
+ "color": "#575279"
+ },
+ "string": {
+ "color": "#ea9d34"
+ },
+ "type": {
+ "color": "#56949f"
+ },
+ "type.builtin": {
+ "color": "#56949f"
+ },
+ "boolean": {
+ "color": "#d7827e"
+ },
+ "function": {
+ "color": "#d7827e"
+ },
+ "keyword": {
+ "color": "#286983"
+ },
+ "tag": {
+ "color": "#56949f"
+ },
+ "function.method": {
+ "color": "#d7827e"
+ },
+ "title": {
+ "color": "#ea9d34"
+ },
+ "link_text": {
+ "color": "#56949f",
+ "italic": false
+ },
+ "link_uri": {
+ "color": "#d7827e"
+ }
+ },
+ "color_family": {
+ "neutral": {
+ "low": 39.80392156862745,
+ "high": 95.49019607843137,
+ "range": 55.686274509803916,
+ "scaling_value": 1.7957746478873242
+ },
+ "red": {
+ "low": 0,
+ "high": 100,
+ "range": 100,
+ "scaling_value": 1
+ },
+ "orange": {
+ "low": 0,
+ "high": 100,
+ "range": 100,
+ "scaling_value": 1
+ },
+ "yellow": {
+ "low": 8.823529411764707,
+ "high": 100,
+ "range": 91.17647058823529,
+ "scaling_value": 1.0967741935483872
+ },
+ "green": {
+ "low": 0,
+ "high": 100,
+ "range": 100,
+ "scaling_value": 1
+ },
+ "cyan": {
+ "low": 0,
+ "high": 100,
+ "range": 100,
+ "scaling_value": 1
+ },
+ "blue": {
+ "low": 0,
+ "high": 100,
+ "range": 100,
+ "scaling_value": 1
+ },
+ "violet": {
+ "low": 0,
+ "high": 100,
+ "range": 100,
+ "scaling_value": 1
+ },
+ "magenta": {
+ "low": 0,
+ "high": 100,
+ "range": 100,
+ "scaling_value": 1
+ }
+ }
+ }))
+ .unwrap()
+}
@@ -26,8 +26,8 @@ impl Workspace {
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element<State = Self> {
- let theme = rose_pine_dawn();
themed(rose_pine_dawn(), cx, |cx| {
+ let theme = theme(cx);
div()
.size_full()
.flex()