1use std::rc::Rc;
2
3use cranpose_core::NodeId;
4pub use cranpose_render_common::graph_scene::{ClickAction, HitRegion, Scene};
5use cranpose_ui::{TextLayoutOptions, TextStyle};
6use cranpose_ui_graphics::{
7 ArcGeometry, BlendMode, Brush, Color, ColorFilter, ImageBitmap, ImageSampling, Point, Rect,
8 RoundedCornerShape, Stroke,
9};
10
11#[derive(Clone)]
12pub(crate) struct DrawShape {
13 pub rect: Rect,
14 pub snap_anchor: Option<Point>,
15 pub snap_to_pixel_grid: bool,
16 pub brush: Brush,
17 pub shape: Option<RoundedCornerShape>,
18 pub stroke: Option<Stroke>,
21 pub arc: Option<ArcGeometry>,
23 pub z_index: usize,
24 pub clip: Option<Rect>,
25 pub blend_mode: BlendMode,
26}
27
28#[derive(Clone)]
29pub(crate) struct TextDraw {
30 pub node_id: NodeId,
31 pub rect: Rect,
32 pub snap_anchor: Option<Point>,
33 pub text: Rc<cranpose_ui::text::AnnotatedString>,
34 pub color: Color,
35 pub text_style: TextStyle,
36 pub font_size: f32,
37 pub scale: f32,
38 pub layout_options: TextLayoutOptions,
39 pub z_index: usize,
40 pub clip: Option<Rect>,
41}
42
43#[derive(Clone)]
44pub(crate) struct ImageDraw {
45 pub rect: Rect,
46 pub snap_anchor: Option<Point>,
47 pub image: ImageBitmap,
48 pub alpha: f32,
49 pub color_filter: Option<ColorFilter>,
50 pub sampling: ImageSampling,
51 pub z_index: usize,
52 pub clip: Option<Rect>,
53 pub blend_mode: BlendMode,
54 pub src_rect: Option<Rect>,
56}
57
58pub(crate) struct RasterScene {
59 pub shapes: Vec<DrawShape>,
60 pub images: Vec<ImageDraw>,
61 pub texts: Vec<TextDraw>,
62 pub next_z: usize,
63}
64
65impl RasterScene {
66 pub fn new() -> Self {
67 Self {
68 shapes: Vec::new(),
69 images: Vec::new(),
70 texts: Vec::new(),
71 next_z: 0,
72 }
73 }
74
75 pub fn push_shape(
76 &mut self,
77 rect: Rect,
78 brush: Brush,
79 shape: Option<RoundedCornerShape>,
80 clip: Option<Rect>,
81 blend_mode: BlendMode,
82 ) {
83 let z_index = self.next_z;
84 self.next_z += 1;
85 self.shapes.push(DrawShape {
86 rect,
87 snap_anchor: None,
88 snap_to_pixel_grid: false,
89 brush,
90 shape,
91 stroke: None,
92 arc: None,
93 z_index,
94 clip,
95 blend_mode,
96 });
97 }
98
99 pub fn push_pixel_snapped_shape(
100 &mut self,
101 rect: Rect,
102 brush: Brush,
103 shape: Option<RoundedCornerShape>,
104 clip: Option<Rect>,
105 blend_mode: BlendMode,
106 ) {
107 let z_index = self.next_z;
108 self.next_z += 1;
109 self.shapes.push(DrawShape {
110 rect,
111 snap_anchor: None,
112 snap_to_pixel_grid: true,
113 brush,
114 shape,
115 stroke: None,
116 arc: None,
117 z_index,
118 clip,
119 blend_mode,
120 });
121 }
122
123 #[allow(clippy::too_many_arguments)]
124 pub fn push_shape_with_stroke_and_arc(
125 &mut self,
126 rect: Rect,
127 brush: Brush,
128 shape: Option<RoundedCornerShape>,
129 stroke: Option<Stroke>,
130 arc: Option<ArcGeometry>,
131 clip: Option<Rect>,
132 blend_mode: BlendMode,
133 ) {
134 let z_index = self.next_z;
135 self.next_z += 1;
136 self.shapes.push(DrawShape {
137 rect,
138 snap_anchor: None,
139 snap_to_pixel_grid: false,
140 brush,
141 shape,
142 stroke,
143 arc,
144 z_index,
145 clip,
146 blend_mode,
147 });
148 }
149
150 #[allow(clippy::too_many_arguments)]
151 pub fn push_image_with_geometry(
152 &mut self,
153 rect: Rect,
154 _local_rect: Rect,
155 _quad: [[f32; 2]; 4],
156 image: ImageBitmap,
157 alpha: f32,
158 color_filter: Option<ColorFilter>,
159 sampling: ImageSampling,
160 clip: Option<Rect>,
161 src_rect: Option<Rect>,
162 blend_mode: BlendMode,
163 ) {
164 let z_index = self.next_z;
165 self.next_z += 1;
166 self.images.push(ImageDraw {
167 rect,
168 snap_anchor: None,
169 image,
170 alpha: alpha.clamp(0.0, 1.0),
171 color_filter,
172 sampling,
173 z_index,
174 clip,
175 blend_mode,
176 src_rect,
177 });
178 }
179
180 #[allow(clippy::too_many_arguments)]
181 pub fn push_text(
182 &mut self,
183 node_id: NodeId,
184 rect: Rect,
185 text: Rc<cranpose_ui::text::AnnotatedString>,
186 color: Color,
187 text_style: TextStyle,
188 font_size: f32,
189 scale: f32,
190 layout_options: TextLayoutOptions,
191 clip: Option<Rect>,
192 ) {
193 let z_index = self.next_z;
194 self.next_z += 1;
195 self.texts.push(TextDraw {
196 node_id,
197 rect,
198 snap_anchor: None,
199 text,
200 color,
201 text_style,
202 font_size,
203 scale,
204 layout_options,
205 z_index,
206 clip,
207 });
208 }
209}
210
211impl Default for RasterScene {
212 fn default() -> Self {
213 Self::new()
214 }
215}