1use argui_core::{Affine2D, Color, Rect};
2
3use crate::{
4 BilinearGradient, ClipChain, ImageFit, ImageId, ImageSampling, LinearGradient, RadialGradient,
5};
6
7#[derive(Clone, Debug, PartialEq)]
8pub enum Fill {
9 Solid(Color),
10 Linear(LinearGradient),
11 Radial(RadialGradient),
12 Bilinear(BilinearGradient),
13}
14
15#[derive(Clone, Copy, Debug, Default, PartialEq)]
16pub struct CornerRadii {
17 pub top_left: f32,
18 pub top_right: f32,
19 pub bottom_right: f32,
20 pub bottom_left: f32,
21}
22
23impl CornerRadii {
24 #[must_use]
25 pub const fn all(radius: f32) -> Self {
26 Self {
27 top_left: radius,
28 top_right: radius,
29 bottom_right: radius,
30 bottom_left: radius,
31 }
32 }
33
34 #[must_use]
35 pub const fn as_array(self) -> [f32; 4] {
36 [
37 self.top_left,
38 self.top_right,
39 self.bottom_right,
40 self.bottom_left,
41 ]
42 }
43
44 #[must_use]
45 pub const fn scaled(self, factor: f32) -> Self {
46 Self {
47 top_left: self.top_left * factor,
48 top_right: self.top_right * factor,
49 bottom_right: self.bottom_right * factor,
50 bottom_left: self.bottom_left * factor,
51 }
52 }
53}
54
55#[derive(Clone, Copy, Debug, Default, PartialEq)]
56pub struct BorderWidths {
57 pub left: f32,
58 pub right: f32,
59 pub top: f32,
60 pub bottom: f32,
61}
62
63impl BorderWidths {
64 #[must_use]
65 pub const fn all(width: f32) -> Self {
66 Self {
67 left: width,
68 right: width,
69 top: width,
70 bottom: width,
71 }
72 }
73
74 #[must_use]
75 pub const fn as_array(self) -> [f32; 4] {
76 [self.left, self.right, self.top, self.bottom]
77 }
78}
79
80#[derive(Clone, Copy, Debug, PartialEq)]
81pub struct Border {
82 pub widths: BorderWidths,
83 pub color: Color,
84}
85
86impl Border {
87 #[must_use]
88 pub const fn all(width: f32, color: Color) -> Self {
89 Self {
90 widths: BorderWidths::all(width),
91 color,
92 }
93 }
94}
95
96#[derive(Clone, Debug, PartialEq)]
97pub struct QuadStyle {
98 pub background: Option<Fill>,
99 pub border: Option<Border>,
100 pub radii: CornerRadii,
101 pub opacity: f32,
102}
103
104impl Default for QuadStyle {
105 fn default() -> Self {
106 Self {
107 background: None,
108 border: None,
109 radii: CornerRadii::all(0.0),
110 opacity: 1.0,
111 }
112 }
113}
114
115impl QuadStyle {
116 #[must_use]
117 pub const fn solid(color: Color) -> Self {
118 Self {
119 background: Some(Fill::Solid(color)),
120 border: None,
121 radii: CornerRadii::all(0.0),
122 opacity: 1.0,
123 }
124 }
125
126 #[must_use]
127 pub const fn border(mut self, border: Border) -> Self {
128 self.border = Some(border);
129 self
130 }
131
132 #[must_use]
133 pub const fn radius(mut self, radii: CornerRadii) -> Self {
134 self.radii = radii;
135 self
136 }
137
138 #[must_use]
139 pub const fn opacity(mut self, opacity: f32) -> Self {
140 self.opacity = opacity;
141 self
142 }
143
144 #[must_use]
145 pub const fn is_visible(&self) -> bool {
146 self.background.is_some() || self.border.is_some()
147 }
148}
149
150#[derive(Clone, Debug, Default, PartialEq)]
151pub struct PaintStyle {
152 pub quad: QuadStyle,
153}
154
155impl PaintStyle {
156 #[must_use]
157 pub const fn new(quad: QuadStyle) -> Self {
158 Self { quad }
159 }
160
161 #[must_use]
162 pub const fn is_visible(&self) -> bool {
163 self.quad.is_visible()
164 }
165}
166
167#[derive(Clone, Debug, PartialEq)]
168pub struct Quad {
169 pub bounds: Rect,
170 pub background: Option<Fill>,
171 pub border: Border,
172 pub radii: CornerRadii,
173 pub opacity: f32,
174 pub transform: Affine2D,
175 pub clips: ClipChain,
176}
177
178#[derive(Clone, Debug, PartialEq)]
179pub struct ImagePrimitive {
180 pub bounds: Rect,
181 pub image: ImageId,
182 pub fit: ImageFit,
183 pub sampling: ImageSampling,
184 pub opacity: f32,
185 pub radii: CornerRadii,
186 pub transform: Affine2D,
187 pub clips: ClipChain,
188}