1use crate::color::Color;
36use crate::{Position, Rectangle, USize};
37use doryen_rs::{Console, TextAlign};
38use ilyvion_util::ownership::Borrowned;
39use std::borrow::{Borrow, BorrowMut};
40use std::ops::{Deref, DerefMut};
41
42#[allow(missing_debug_implementations)] pub struct ConsoleExtender<'b> {
50 console: Borrowned<'b, Console>,
51}
52
53impl<'b> ConsoleExtender<'b> {
54 pub fn extend(console: &'b mut Console) -> Self {
56 Self {
57 console: Borrowned::Borrowed(console),
58 }
59 }
60
61 pub fn new(size: USize) -> Self {
64 Self {
65 console: Borrowned::Owned(Console::new(size.width, size.height)),
66 }
67 }
68
69 pub fn wrap(console: Console) -> Self {
71 Self {
72 console: Borrowned::Owned(console),
73 }
74 }
75}
76
77impl ConsoleExtender<'_> {
79 pub fn resize(&mut self, size: USize) {
81 self.console.resize(size.width, size.height);
82 }
83
84 pub fn register_color<S: AsRef<str>>(&mut self, name: S, value: Color) {
86 self.console.register_color(name.as_ref(), value.into());
87 }
88
89 pub fn back(&self, position: Position) -> Option<Color> {
91 self.console
92 .get_back(position.x, position.y)
93 .map(Into::into)
94 }
95
96 pub fn fore(&self, position: Position) -> Option<Color> {
98 self.console
99 .get_fore(position.x, position.y)
100 .map(Into::into)
101 }
102
103 pub fn ascii(&self, position: Position) -> Option<u16> {
105 self.console.get_ascii(position.x, position.y)
106 }
107
108 pub fn back_unchecked(&self, position: Position) -> Color {
110 self.console.unsafe_get_back(position.x, position.y).into()
111 }
112
113 pub fn fore_unchecked(&self, position: Position) -> Color {
115 self.console.unsafe_get_fore(position.x, position.y).into()
116 }
117
118 pub fn ascii_unchecked(&self, position: Position) -> u16 {
120 self.console.unsafe_get_ascii(position.x, position.y)
121 }
122
123 pub fn set_ascii(&mut self, position: Position, ascii: u16) {
125 self.console.ascii(position.x, position.y, ascii);
126 }
127
128 pub fn set_fore(&mut self, position: Position, color: Color) {
130 self.console.fore(position.x, position.y, color.into());
131 }
132
133 pub fn set_back(&mut self, position: Position, color: Color) {
135 self.console.back(position.x, position.y, color.into());
136 }
137
138 pub fn set_ascii_unchecked(&mut self, position: Position, ascii: u16) {
140 self.console.unsafe_ascii(position.x, position.y, ascii);
141 }
142
143 pub fn set_fore_unchecked(&mut self, position: Position, color: Color) {
145 self.console
146 .unsafe_fore(position.x, position.y, color.into());
147 }
148
149 pub fn set_back_unchecked(&mut self, position: Position, color: Color) {
151 self.console
152 .unsafe_back(position.x, position.y, color.into());
153 }
154
155 pub fn clear(&mut self, fore: Option<Color>, back: Option<Color>, fill_char: Option<u16>) {
157 self.console
158 .clear(fore.map(Into::into), back.map(Into::into), fill_char);
159 }
160
161 pub fn print_color<S: AsRef<str>>(
163 &mut self,
164 position: Position,
165 text: S,
166 align: TextAlign,
167 back: Option<Color>,
168 ) {
169 self.console.print_color(
170 position.x,
171 position.y,
172 text.as_ref(),
173 align,
174 back.map(Into::into),
175 )
176 }
177
178 pub fn text_color_len<S: AsRef<str>>(text: S) -> usize {
180 Console::text_color_len(text.as_ref())
181 }
182
183 pub fn print<S: AsRef<str>>(
186 &mut self,
187 position: Position,
188 text: S,
189 align: TextAlign,
190 fore: Option<Color>,
191 back: Option<Color>,
192 ) {
193 self.console.print(
194 position.x,
195 position.y,
196 text.as_ref(),
197 align,
198 fore.map(Into::into),
199 back.map(Into::into),
200 );
201 }
202
203 pub fn rectangle(
205 &mut self,
206 rectangle: Rectangle,
207 fore: Option<Color>,
208 back: Option<Color>,
209 fill_char: Option<u16>,
210 ) {
211 self.console.rectangle(
212 rectangle.position.x,
213 rectangle.position.y,
214 rectangle.size.width,
215 rectangle.size.height,
216 fore.map(Into::into),
217 back.map(Into::into),
218 fill_char,
219 );
220 }
221
222 pub fn area(
224 &mut self,
225 rectangle: Rectangle,
226 fore: Option<Color>,
227 back: Option<Color>,
228 fill_char: Option<u16>,
229 ) {
230 self.console.area(
231 rectangle.position.x,
232 rectangle.position.y,
233 rectangle.size.width,
234 rectangle.size.height,
235 fore.map(Into::into),
236 back.map(Into::into),
237 fill_char,
238 );
239 }
240
241 pub fn cell(
243 &mut self,
244 position: Position,
245 ascii: Option<u16>,
246 fore: Option<Color>,
247 back: Option<Color>,
248 ) {
249 self.console.cell(
250 position.x,
251 position.y,
252 ascii,
253 fore.map(Into::into),
254 back.map(Into::into),
255 );
256 }
257
258 pub fn blit(
260 &self,
261 position: Position,
262 destination: &mut Console,
263 fore_alpha: f32,
264 back_alpha: f32,
265 key_color: Option<Color>,
266 ) {
267 self.console.blit(
268 position.x,
269 position.y,
270 destination,
271 fore_alpha,
272 back_alpha,
273 key_color.map(Into::into),
274 );
275 }
276
277 pub fn blit_ex(
279 &self,
280 source_rectangle: Rectangle,
281 destination: &mut Console,
282 destination_position: Position,
283 fore_alpha: f32,
284 back_alpha: f32,
285 key_color: Option<Color>,
286 ) {
287 self.console.blit_ex(
288 source_rectangle.position.x,
289 source_rectangle.position.y,
290 source_rectangle.size.width as i32,
291 source_rectangle.size.height as i32,
292 destination,
293 destination_position.x,
294 destination_position.y,
295 fore_alpha,
296 back_alpha,
297 key_color.map(Into::into),
298 );
299 }
300}
301
302impl ConsoleExtender<'_> {
304 pub fn get_size(&self) -> USize {
306 USize::new(self.console.get_width(), self.console.get_height())
307 }
308
309 pub fn print_frame<S: AsRef<str>>(
312 &mut self,
313 rectangle: Rectangle,
314 fore: Option<Color>,
315 back: Option<Color>,
316 fill: Option<u16>,
317 title: Option<S>,
318 ) {
319 self.rectangle(rectangle, fore, back, fill);
320
321 if let Some(title) = title {
322 let text = format!(" {} ", title.as_ref());
323 let Rectangle {
324 position: Position { x, y },
325 size: USize { width: w, .. },
326 } = rectangle;
327 self.print(
328 Position::new(x + (w / 2) as i32, y),
329 &text,
330 TextAlign::Center,
331 fore.map(Into::into),
332 back.map(Into::into),
333 );
334 }
335 }
336
337 pub fn print_char(
339 &mut self,
340 position: Position,
341 character: char,
342 fore: Option<Color>,
343 back: Option<Color>,
344 ) {
345 self.cell(position, Some(character as u16), fore, back);
346 }
347}
348
349impl Deref for ConsoleExtender<'_> {
350 type Target = Console;
351
352 fn deref(&self) -> &Self::Target {
353 self.console.deref()
354 }
355}
356
357impl DerefMut for ConsoleExtender<'_> {
358 fn deref_mut(&mut self) -> &mut Self::Target {
359 self.console.deref_mut()
360 }
361}
362
363impl Borrow<Console> for ConsoleExtender<'_> {
364 fn borrow(&self) -> &Console {
365 self.console.borrow()
366 }
367}
368
369impl BorrowMut<Console> for ConsoleExtender<'_> {
370 fn borrow_mut(&mut self) -> &mut Console {
371 self.console.borrow_mut()
372 }
373}
374
375impl AsRef<Console> for ConsoleExtender<'_> {
376 fn as_ref(&self) -> &Console {
377 self.console.as_ref()
378 }
379}
380
381impl AsMut<Console> for ConsoleExtender<'_> {
382 fn as_mut(&mut self) -> &mut Console {
383 self.console.as_mut()
384 }
385}