omage/components/mod.rs
1#![allow(non_snake_case)]
2
3use crate::config::Config;
4use crate::error::CustomError;
5use circle::Circle;
6use image::{ImageBuffer, Rgba};
7use line::Line;
8use rectangle::Rectangle;
9use std::error::Error;
10use text::Text;
11
12mod circle;
13mod line;
14mod rectangle;
15mod text;
16
17/// A trait for drawing components on an image buffer.
18pub trait ComponentTrait {
19 /// Draws the component on the image buffer using the specified configuration.
20 ///
21 /// # Arguments
22 ///
23 /// * `config` - Configuration for the drawing canvas.
24 /// * `buffer` - Image buffer to draw the component on.
25 ///
26 /// # Errors
27 ///
28 /// Returns an error if there is an issue drawing the component.
29 fn draw(
30 &self,
31 config: Config,
32 buffer: &mut ImageBuffer<Rgba<u8>, Vec<u8>>,
33 ) -> Result<(), Box<dyn Error>>;
34}
35
36/// Enum representing different types of drawing components.
37pub enum Component {
38 /// Represents a circle component.
39 Circle {
40 /// X-coordinate of the circle's center.
41 cx: u32,
42 /// Y-coordinate of the circle's center.
43 cy: u32,
44 /// Radius of the circle.
45 r: u32,
46 /// Color of the circle in Rgba format.
47 color: Rgba<u8>,
48 },
49 /// Represents a rectangle component.
50 Rectangle {
51 /// Height of the rectangle.
52 h: u32,
53 /// Width of the rectangle.
54 w: u32,
55 /// X-coordinate of the top-left corner of the rectangle.
56 x: u32,
57 /// Y-coordinate of the top-left corner of the rectangle.
58 y: u32,
59 /// Color of the rectangle in Rgba format.
60 color: Rgba<u8>,
61 },
62 /// Represents a line component.
63 Line {
64 /// X-coordinate of the starting point of the line.
65 x1: u32,
66 /// Y-coordinate of the starting point of the line.
67 y1: u32,
68 /// X-coordinate of the ending point of the line.
69 x2: u32,
70 /// Y-coordinate of the ending point of the line.
71 y2: u32,
72 /// Color of the line in Rgba format.
73 color: Rgba<u8>,
74 },
75 /// Represents a text component.
76 Text {
77 /// X-coordinate of the top-left corner of the text.
78 x: u32,
79 /// Y-coordinate of the top-left corner of the text.
80 y: u32,
81 /// Size of the text.
82 size: u32,
83 /// Text field of the text.
84 text: &'static str,
85 /// Color of the rectangle in Rgba format.
86 color: Rgba<u8>,
87 /// Border.
88 border: Option<(Rgba<u8>, u32)>,
89 },
90}
91
92/// A struct providing convenience methods for creating different types of components.
93///
94/// The `Components` struct serves as a utility for easily generating instances of various graphical
95/// components in a 2D space. It offers methods for creating circles, rectangles, lines, and text
96/// components with specified attributes.
97///
98/// # Examples
99///
100/// ```
101/// use omage::{Components, Rgba};
102///
103/// // Create a new circle component
104/// let circle = Components::Circle(50, 50, 30, Rgba([255, 0, 0, 255]));
105///
106/// // Create a new rectangle component
107/// let rectangle = Components::Rectangle(40, 60, 10, 20, Rgba([0, 255, 0, 255]));
108///
109/// // Create a new line component
110/// let line = Components::Line(10, 10, 80, 80, Rgba([0, 0, 255, 255]));
111///
112/// // Create a new text component
113/// let text = Components::Text(30, 40, 16, "Hello, Rust!", Rgba([255, 255, 255, 255]), Some((Rgba([0, 0, 0, 255]), 2)));
114/// ```
115///
116/// # Methods
117///
118/// The `Components` struct provides the following methods:
119///
120/// - `Circle`: Creates a new circle component with specified attributes.
121/// - `Rectangle`: Creates a new rectangle component with specified attributes.
122/// - `Line`: Creates a new line component with specified attributes.
123/// - `Text`: Creates a new text component with specified attributes, including an optional border.
124///
125/// # Note
126///
127/// The `Components` struct is designed to simplify the process of creating graphical components
128/// for use in a 2D drawing context. It encapsulates the logic for constructing different types
129/// of components with ease.
130/// ```
131pub struct Components;
132
133impl Components {
134 /// Creates a new circle component.
135 ///
136 /// # Parameters
137 ///
138 /// - `cx`: X-coordinate of the center of the circle.
139 /// - `cy`: Y-coordinate of the center of the circle.
140 /// - `r`: Radius of the circle.
141 /// - `color`: RGBA color of the circle.
142 ///
143 /// # Returns
144 ///
145 /// A `Component::Circle` instance.
146 pub fn Circle(cx: u32, cy: u32, r: u32, color: Rgba<u8>) -> Component {
147 Component::Circle { cx, cy, r, color }
148 }
149
150 /// Creates a new rectangle component.
151 ///
152 /// # Parameters
153 ///
154 /// - `h`: Height of the rectangle.
155 /// - `w`: Width of the rectangle.
156 /// - `x`: X-coordinate of the top-left corner of the rectangle.
157 /// - `y`: Y-coordinate of the top-left corner of the rectangle.
158 /// - `color`: RGBA color of the rectangle.
159 ///
160 /// # Returns
161 ///
162 /// A `Component::Rectangle` instance.
163 pub fn Rectangle(h: u32, w: u32, x: u32, y: u32, color: Rgba<u8>) -> Component {
164 Component::Rectangle { h, w, x, y, color }
165 }
166
167 /// Creates a new line component.
168 ///
169 /// # Parameters
170 ///
171 /// - `x1`: X-coordinate of the starting point of the line.
172 /// - `y1`: Y-coordinate of the starting point of the line.
173 /// - `x2`: X-coordinate of the ending point of the line.
174 /// - `y2`: Y-coordinate of the ending point of the line.
175 /// - `color`: RGBA color of the line.
176 ///
177 /// # Returns
178 ///
179 /// A `Component::Line` instance.
180 pub fn Line(x1: u32, y1: u32, x2: u32, y2: u32, color: Rgba<u8>) -> Component {
181 Component::Line {
182 x1,
183 y1,
184 x2,
185 y2,
186 color,
187 }
188 }
189
190 /// Creates a new text component.
191 ///
192 /// # Parameters
193 ///
194 /// - `x`: X-coordinate of the text.
195 /// - `y`: Y-coordinate of the text.
196 /// - `size`: Font size of the text.
197 /// - `text`: The actual text content.
198 /// - `color`: RGBA color of the text.
199 /// - `border`: Optional border color and thickness as a tuple.
200 ///
201 /// # Returns
202 ///
203 /// A `Component::Text` instance.
204 pub fn Text(
205 x: u32,
206 y: u32,
207 size: u32,
208 text: &'static str,
209 color: Rgba<u8>,
210 border: Option<(Rgba<u8>, u32)>,
211 ) -> Component {
212 Component::Text {
213 x,
214 y,
215 size,
216 text,
217 color,
218 border,
219 }
220 }
221}
222
223impl ComponentTrait for Component {
224 fn draw(
225 &self,
226 config: Config,
227 buffer: &mut ImageBuffer<Rgba<u8>, Vec<u8>>,
228 ) -> Result<(), Box<dyn Error>> {
229 match *self {
230 Component::Circle { cx, cy, r, color } => {
231 let circle = Circle::new(cx, cy, r, color);
232 circle.draw(config, buffer)
233 }
234 Component::Rectangle { h, w, x, y, color } => {
235 let rectangle = Rectangle::new(h, w, x, y, color);
236 rectangle.draw(config, buffer)
237 }
238 Component::Line {
239 x1,
240 y1,
241 x2,
242 y2,
243 color,
244 } => {
245 let line = Line::new(x1, y1, x2, y2, color);
246 line.draw(config, buffer)
247 }
248 Component::Text {
249 x,
250 y,
251 size,
252 text,
253 color,
254 border,
255 } => {
256 let text = Text::new(x, y, size, text, color, border);
257 text.draw(config, buffer)
258 }
259 }
260 }
261}