Introduce layer clipping
This commit is contained in:
parent
63f9719c99
commit
61d4da9934
5 changed files with 47 additions and 17 deletions
|
@ -1,6 +1,7 @@
|
|||
use crate::{
|
||||
geometry::vector::Vector2F, AfterLayoutContext, Element, ElementBox, Event, EventContext,
|
||||
LayoutContext, PaintContext, SizeConstraint,
|
||||
geometry::{rect::RectF, vector::Vector2F},
|
||||
AfterLayoutContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext,
|
||||
SizeConstraint,
|
||||
};
|
||||
|
||||
pub struct Stack {
|
||||
|
@ -44,12 +45,12 @@ impl Element for Stack {
|
|||
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: pathfinder_geometry::rect::RectF,
|
||||
bounds: RectF,
|
||||
_: &mut Self::LayoutState,
|
||||
ctx: &mut PaintContext,
|
||||
) -> Self::PaintState {
|
||||
for child in &mut self.children {
|
||||
ctx.scene.push_layer();
|
||||
ctx.scene.push_layer(None);
|
||||
child.paint(bounds.origin(), ctx);
|
||||
ctx.scene.pop_layer();
|
||||
}
|
||||
|
@ -58,7 +59,7 @@ impl Element for Stack {
|
|||
fn dispatch_event(
|
||||
&mut self,
|
||||
event: &Event,
|
||||
_: pathfinder_geometry::rect::RectF,
|
||||
_: RectF,
|
||||
_: &mut Self::LayoutState,
|
||||
_: &mut Self::PaintState,
|
||||
ctx: &mut EventContext,
|
||||
|
|
|
@ -195,10 +195,7 @@ where
|
|||
layout: &mut Self::LayoutState,
|
||||
ctx: &mut PaintContext,
|
||||
) -> Self::PaintState {
|
||||
// ctx.canvas.save();
|
||||
// let mut clip_path = Path2D::new();
|
||||
// clip_path.rect(RectF::new(origin, self.size.unwrap()));
|
||||
// ctx.canvas.clip_path(clip_path, FillRule::Winding);
|
||||
ctx.scene.push_layer(Some(bounds));
|
||||
|
||||
let mut item_origin =
|
||||
bounds.origin() - vec2f(0.0, self.state.scroll_top() % layout.item_height);
|
||||
|
@ -207,7 +204,8 @@ where
|
|||
item.paint(item_origin, ctx);
|
||||
item_origin += vec2f(0.0, layout.item_height);
|
||||
}
|
||||
// ctx.canvas.restore();
|
||||
|
||||
ctx.scene.pop_layer();
|
||||
}
|
||||
|
||||
fn dispatch_event(
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
use super::{sprite_cache::SpriteCache, window::RenderContext};
|
||||
use crate::{
|
||||
color::ColorU,
|
||||
geometry::vector::{vec2i, Vector2I},
|
||||
geometry::{
|
||||
rect::RectF,
|
||||
vector::{vec2f, vec2i, Vector2I},
|
||||
},
|
||||
platform,
|
||||
scene::Layer,
|
||||
Scene,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use cocoa::foundation::NSUInteger;
|
||||
use metal::{MTLResourceOptions, NSRange};
|
||||
use shaders::{ToFloat2 as _, ToUchar4 as _};
|
||||
use std::{collections::HashMap, ffi::c_void, mem, sync::Arc};
|
||||
|
@ -96,12 +100,26 @@ impl Renderer {
|
|||
|
||||
let mut offset = 0;
|
||||
for layer in scene.layers() {
|
||||
self.clip(scene, layer, ctx);
|
||||
self.render_shadows(scene, layer, &mut offset, ctx);
|
||||
self.render_quads(scene, layer, &mut offset, ctx);
|
||||
self.render_sprites(scene, layer, &mut offset, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn clip(&mut self, scene: &Scene, layer: &Layer, ctx: &RenderContext) {
|
||||
let clip_bounds = layer.clip_bounds().unwrap_or(RectF::new(
|
||||
vec2f(0., 0.),
|
||||
ctx.drawable_size / scene.scale_factor(),
|
||||
)) * scene.scale_factor();
|
||||
ctx.command_encoder.set_scissor_rect(metal::MTLScissorRect {
|
||||
x: clip_bounds.origin_x() as NSUInteger,
|
||||
y: clip_bounds.origin_y() as NSUInteger,
|
||||
width: clip_bounds.width() as NSUInteger,
|
||||
height: clip_bounds.height() as NSUInteger,
|
||||
});
|
||||
}
|
||||
|
||||
fn render_shadows(
|
||||
&mut self,
|
||||
scene: &Scene,
|
||||
|
|
|
@ -57,7 +57,7 @@ impl Scene {
|
|||
pub fn new(scale_factor: f32) -> Self {
|
||||
Scene {
|
||||
scale_factor,
|
||||
layers: vec![Layer::default()],
|
||||
layers: vec![Layer::new(None)],
|
||||
active_layer_stack: vec![0],
|
||||
}
|
||||
}
|
||||
|
@ -70,9 +70,9 @@ impl Scene {
|
|||
self.layers.as_slice()
|
||||
}
|
||||
|
||||
pub fn push_layer(&mut self) {
|
||||
pub fn push_layer(&mut self, clip_bounds: Option<RectF>) {
|
||||
let ix = self.layers.len();
|
||||
self.layers.push(Layer::default());
|
||||
self.layers.push(Layer::new(clip_bounds));
|
||||
self.active_layer_stack.push(ix);
|
||||
}
|
||||
|
||||
|
@ -99,6 +99,19 @@ impl Scene {
|
|||
}
|
||||
|
||||
impl Layer {
|
||||
pub fn new(clip_bounds: Option<RectF>) -> Self {
|
||||
Self {
|
||||
clip_bounds,
|
||||
quads: Vec::new(),
|
||||
shadows: Vec::new(),
|
||||
glyphs: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clip_bounds(&self) -> Option<RectF> {
|
||||
self.clip_bounds
|
||||
}
|
||||
|
||||
fn push_quad(&mut self, quad: Quad) {
|
||||
self.quads.push(quad);
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ impl BufferElement {
|
|||
let line_height = view.line_height(ctx.font_cache);
|
||||
let scroll_top = view.scroll_position().y() * line_height;
|
||||
|
||||
ctx.scene.push_layer();
|
||||
ctx.scene.push_layer(Some(rect));
|
||||
ctx.scene.push_quad(Quad {
|
||||
bounds: rect,
|
||||
background: Some(ColorU::white()),
|
||||
|
@ -202,7 +202,7 @@ impl BufferElement {
|
|||
let max_glyph_width = view.em_width(ctx.font_cache);
|
||||
let scroll_left = view.scroll_position().x() * max_glyph_width;
|
||||
|
||||
ctx.scene.push_layer();
|
||||
ctx.scene.push_layer(Some(bounds));
|
||||
ctx.scene.push_quad(Quad {
|
||||
bounds,
|
||||
background: Some(ColorU::white()),
|
||||
|
@ -290,7 +290,7 @@ impl BufferElement {
|
|||
);
|
||||
}
|
||||
|
||||
ctx.scene.push_layer();
|
||||
ctx.scene.push_layer(Some(bounds));
|
||||
for cursor in cursors {
|
||||
cursor.paint(ctx);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue