1use egui::{Align2, FontId, Pos2, Rect, Vec2};
16
17use crate::canvas::{
18 Renderer,
19 palette::{PaletteStroke, Swatch},
20};
21use crate::document_ng::ImageData;
22
23fn fade_swatch(swatch: impl Into<Swatch>, factor: f32) -> Swatch {
26 let s = swatch.into();
27 Swatch {
28 base: s.base,
29 alpha: s.alpha * factor,
30 }
31}
32
33fn fade_stroke(stroke: impl Into<PaletteStroke>, factor: f32) -> PaletteStroke {
35 let s = stroke.into();
36 PaletteStroke {
37 width: s.width,
38 color: fade_swatch(s.color, factor),
39 }
40}
41
42pub struct OpacityWrapper<'a, R: Renderer> {
45 inner: &'a R,
46 factor: f32,
47}
48
49impl<'a, R: Renderer> OpacityWrapper<'a, R> {
50 pub fn new(inner: &'a R, factor: f32) -> Self {
51 Self { inner, factor }
52 }
53}
54
55impl<R: Renderer> Renderer for OpacityWrapper<'_, R> {
56 fn rect(
57 &self,
58 rect: Rect,
59 rounding: f32,
60 fill: impl Into<Swatch>,
61 stroke: impl Into<PaletteStroke>,
62 ) {
63 self.inner.rect(
64 rect,
65 rounding,
66 fade_swatch(fill, self.factor),
67 fade_stroke(stroke, self.factor),
68 );
69 }
70
71 fn line_segment(&self, points: [Pos2; 2], stroke: impl Into<PaletteStroke>) {
72 self.inner
73 .line_segment(points, fade_stroke(stroke, self.factor));
74 }
75
76 fn line(&self, points: Vec<Pos2>, stroke: impl Into<PaletteStroke>) {
77 self.inner.line(points, fade_stroke(stroke, self.factor));
78 }
79
80 fn circle(
81 &self,
82 center: Pos2,
83 radius: f32,
84 fill: impl Into<Swatch>,
85 stroke: impl Into<PaletteStroke>,
86 ) {
87 self.inner.circle(
88 center,
89 radius,
90 fade_swatch(fill, self.factor),
91 fade_stroke(stroke, self.factor),
92 );
93 }
94
95 fn add_convex_polygon(
96 &self,
97 points: Vec<Pos2>,
98 fill: impl Into<Swatch>,
99 stroke: impl Into<PaletteStroke>,
100 ) {
101 self.inner.add_convex_polygon(
102 points,
103 fade_swatch(fill, self.factor),
104 fade_stroke(stroke, self.factor),
105 );
106 }
107
108 fn text(
109 &self,
110 pos: Pos2,
111 anchor: Align2,
112 text: impl ToString,
113 font: &FontId,
114 color: impl Into<Swatch>,
115 ) -> Rect {
116 self.inner
117 .text(pos, anchor, text, font, fade_swatch(color, self.factor))
118 }
119
120 fn rotated_text(
121 &self,
122 pos: Pos2,
123 anchor: Align2,
124 text: impl ToString,
125 font: &FontId,
126 color: impl Into<Swatch>,
127 angle: f32,
128 ) {
129 self.inner.rotated_text(
130 pos,
131 anchor,
132 text,
133 font,
134 fade_swatch(color, self.factor),
135 angle,
136 );
137 }
138
139 fn text_wrapped(
140 &self,
141 pos: Pos2,
142 anchor: Align2,
143 text: impl ToString,
144 font: &FontId,
145 color: impl Into<Swatch>,
146 max_width: f32,
147 ) -> Rect {
148 self.inner.text_wrapped(
149 pos,
150 anchor,
151 text,
152 font,
153 fade_swatch(color, self.factor),
154 max_width,
155 )
156 }
157
158 fn text_size(&self, text: impl ToString, font: &FontId) -> Vec2 {
159 self.inner.text_size(text, font)
160 }
161
162 fn text_size_wrapped(&self, text: impl ToString, font: &FontId, max_width: f32) -> Vec2 {
163 self.inner.text_size_wrapped(text, font, max_width)
164 }
165
166 fn draw_image(&self, rect: Rect, image: &ImageData) {
167 self.inner.draw_image(rect, image);
168 }
169
170 fn image_intrinsic_size(&self, image: &ImageData) -> Option<Vec2> {
171 self.inner.image_intrinsic_size(image)
172 }
173
174 fn visible_world_bounds(&self) -> Option<Rect> {
175 self.inner.visible_world_bounds()
176 }
177}