mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-13 06:39:31 +03:00
Checkpoint
This commit is contained in:
parent
fe3ef08f39
commit
6f7c305308
@ -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)));
|
||||
}
|
||||
|
||||
impl SceneLayer {
|
||||
pub fn batches(&mut self) -> impl Iterator<Item = PrimitiveBatch> {
|
||||
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)),
|
||||
);
|
||||
}
|
||||
|
||||
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()
|
||||
|
Loading…
Reference in New Issue
Block a user