zed/gpui/src/scene.rs

285 lines
5.9 KiB
Rust
Raw Normal View History

use serde::Deserialize;
use serde_json::json;
use std::borrow::Cow;
use crate::{
color::Color,
fonts::{FontId, GlyphId},
geometry::{rect::RectF, vector::Vector2F},
json::ToJson,
};
2021-03-19 22:31:25 +03:00
pub struct Scene {
scale_factor: f32,
layers: Vec<Layer>,
active_layer_stack: Vec<usize>,
}
2021-04-06 14:44:38 +03:00
#[derive(Default)]
pub struct Layer {
2021-03-19 22:31:25 +03:00
clip_bounds: Option<RectF>,
quads: Vec<Quad>,
shadows: Vec<Shadow>,
glyphs: Vec<Glyph>,
2021-04-06 14:44:38 +03:00
icons: Vec<Icon>,
paths: Vec<Path>,
2021-03-19 22:31:25 +03:00
}
#[derive(Default, Debug)]
2021-03-19 22:31:25 +03:00
pub struct Quad {
pub bounds: RectF,
pub background: Option<Color>,
2021-03-19 22:31:25 +03:00
pub border: Border,
pub corner_radius: f32,
2021-03-19 22:31:25 +03:00
}
#[derive(Debug)]
pub struct Shadow {
pub bounds: RectF,
pub corner_radius: f32,
pub sigma: f32,
pub color: Color,
}
#[derive(Debug)]
pub struct Glyph {
pub font_id: FontId,
pub font_size: f32,
pub id: GlyphId,
pub origin: Vector2F,
pub color: Color,
}
2021-04-06 14:44:38 +03:00
pub struct Icon {
pub bounds: RectF,
pub svg: usvg::Tree,
pub path: Cow<'static, str>,
pub color: Color,
2021-04-06 14:44:38 +03:00
}
#[derive(Clone, Copy, Default, Debug, Deserialize)]
2021-03-19 22:31:25 +03:00
pub struct Border {
pub width: f32,
pub color: Option<Color>,
2021-03-19 22:31:25 +03:00
pub top: bool,
pub right: bool,
pub bottom: bool,
pub left: bool,
}
#[derive(Debug)]
pub struct Path {
pub bounds: RectF,
pub color: Color,
pub vertices: Vec<PathVertex>,
}
#[derive(Debug)]
pub struct PathVertex {
pub xy_position: Vector2F,
pub st_position: Vector2F,
}
2021-03-19 22:31:25 +03:00
impl Scene {
pub fn new(scale_factor: f32) -> Self {
Scene {
scale_factor,
2021-03-26 12:28:05 +03:00
layers: vec![Layer::new(None)],
2021-03-19 22:31:25 +03:00
active_layer_stack: vec![0],
}
}
pub fn scale_factor(&self) -> f32 {
self.scale_factor
}
pub fn layers(&self) -> &[Layer] {
self.layers.as_slice()
2021-03-19 22:31:25 +03:00
}
2021-03-26 12:28:05 +03:00
pub fn push_layer(&mut self, clip_bounds: Option<RectF>) {
let ix = self.layers.len();
2021-03-26 12:28:05 +03:00
self.layers.push(Layer::new(clip_bounds));
self.active_layer_stack.push(ix);
}
pub fn pop_layer(&mut self) {
assert!(self.active_layer_stack.len() > 1);
self.active_layer_stack.pop();
}
2021-03-19 22:31:25 +03:00
pub fn push_quad(&mut self, quad: Quad) {
self.active_layer().push_quad(quad)
}
pub fn push_shadow(&mut self, shadow: Shadow) {
self.active_layer().push_shadow(shadow)
}
pub fn push_glyph(&mut self, glyph: Glyph) {
self.active_layer().push_glyph(glyph)
}
2021-04-06 14:44:38 +03:00
pub fn push_icon(&mut self, icon: Icon) {
self.active_layer().push_icon(icon)
}
pub fn push_path(&mut self, path: Path) {
self.active_layer().push_path(path);
}
2021-03-19 22:31:25 +03:00
fn active_layer(&mut self) -> &mut Layer {
&mut self.layers[*self.active_layer_stack.last().unwrap()]
}
}
impl Layer {
2021-03-26 12:28:05 +03:00
pub fn new(clip_bounds: Option<RectF>) -> Self {
Self {
clip_bounds,
quads: Vec::new(),
shadows: Vec::new(),
glyphs: Vec::new(),
2021-04-06 14:44:38 +03:00
icons: Vec::new(),
paths: Vec::new(),
2021-03-26 12:28:05 +03:00
}
}
pub fn clip_bounds(&self) -> Option<RectF> {
self.clip_bounds
}
2021-03-19 22:31:25 +03:00
fn push_quad(&mut self, quad: Quad) {
self.quads.push(quad);
}
pub fn quads(&self) -> &[Quad] {
self.quads.as_slice()
}
fn push_shadow(&mut self, shadow: Shadow) {
self.shadows.push(shadow);
}
pub fn shadows(&self) -> &[Shadow] {
self.shadows.as_slice()
}
fn push_glyph(&mut self, glyph: Glyph) {
self.glyphs.push(glyph);
}
pub fn glyphs(&self) -> &[Glyph] {
self.glyphs.as_slice()
}
2021-04-06 14:44:38 +03:00
pub fn push_icon(&mut self, icon: Icon) {
self.icons.push(icon);
}
pub fn icons(&self) -> &[Icon] {
self.icons.as_slice()
}
fn push_path(&mut self, path: Path) {
if !path.bounds.is_empty() {
self.paths.push(path);
}
}
pub fn paths(&self) -> &[Path] {
self.paths.as_slice()
}
2021-03-19 22:31:25 +03:00
}
impl Border {
pub fn new(width: f32, color: Color) -> Self {
2021-03-19 22:31:25 +03:00
Self {
width,
color: Some(color),
2021-03-19 22:31:25 +03:00
top: false,
left: false,
bottom: false,
right: false,
}
}
pub fn all(width: f32, color: Color) -> Self {
2021-03-19 22:31:25 +03:00
Self {
width,
color: Some(color),
2021-03-19 22:31:25 +03:00
top: true,
left: true,
bottom: true,
right: true,
}
}
pub fn top(width: f32, color: Color) -> Self {
2021-03-19 22:31:25 +03:00
let mut border = Self::new(width, color);
border.top = true;
border
}
pub fn left(width: f32, color: Color) -> Self {
2021-03-19 22:31:25 +03:00
let mut border = Self::new(width, color);
border.left = true;
border
}
pub fn bottom(width: f32, color: Color) -> Self {
2021-03-19 22:31:25 +03:00
let mut border = Self::new(width, color);
border.bottom = true;
border
}
pub fn right(width: f32, color: Color) -> Self {
2021-03-19 22:31:25 +03:00
let mut border = Self::new(width, color);
border.right = true;
border
}
pub fn with_sides(mut self, top: bool, left: bool, bottom: bool, right: bool) -> Self {
self.top = top;
self.left = left;
self.bottom = bottom;
self.right = right;
self
}
pub fn top_width(&self) -> f32 {
if self.top {
self.width
} else {
0.0
}
}
pub fn left_width(&self) -> f32 {
if self.left {
self.width
} else {
0.0
}
}
2021-03-19 22:31:25 +03:00
}
impl ToJson for Border {
fn to_json(&self) -> serde_json::Value {
let mut value = json!({});
if self.top {
value["top"] = json!(self.width);
}
if self.right {
value["right"] = json!(self.width);
}
if self.bottom {
value["bottom"] = json!(self.width);
}
if self.left {
value["left"] = json!(self.width);
}
value
}
}