undo.rs - icy_draw - icy_draw is the successor to mystic draw. fork / mirror
(HTM) git clone https://git.drkhsh.at/icy_draw.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
undo.rs (9717B)
---
1 use i18n_embed_fl::fl;
2 use icy_engine::{BitFont, EngineResult, Glyph};
3
4 use crate::BitFontEditor;
5
6 pub trait UndoOperation: Send {
7 fn get_description(&self) -> String;
8
9 /// .
10 ///
11 /// # Errors
12 ///
13 /// This function will return an error if .
14 fn undo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()>;
15 /// .
16 ///
17 /// # Errors
18 ///
19 /// This function will return an error if .
20 fn redo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()>;
21 }
22
23 pub struct Paste {
24 ch: char,
25 glyph: Glyph,
26 old_data: Vec<u8>,
27 }
28
29 impl Paste {
30 pub(crate) fn new(ch: char, glyph: Glyph) -> Self {
31 Self {
32 ch,
33 glyph,
34 old_data: Vec::new(),
35 }
36 }
37 }
38
39 impl UndoOperation for Paste {
40 fn get_description(&self) -> String {
41 fl!(crate::LANGUAGE_LOADER, "undo-paste-glyph")
42 }
43
44 fn undo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
45 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
46 glyph.data = self.old_data.clone();
47 }
48 Ok(())
49 }
50
51 fn redo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
52 let len = edit_state.font.size.height as usize;
53 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
54 self.old_data = glyph.data.clone();
55 glyph.data = self.glyph.data.clone();
56 glyph.data.resize(len, 0);
57 }
58 Ok(())
59 }
60 }
61
62 pub struct FlipY {
63 ch: char,
64 }
65
66 impl FlipY {
67 pub(crate) fn new(ch: char) -> Self {
68 Self { ch }
69 }
70 }
71
72 impl UndoOperation for FlipY {
73 fn get_description(&self) -> String {
74 fl!(crate::LANGUAGE_LOADER, "undo-bitfont-flip-y")
75 }
76
77 fn undo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
78 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
79 glyph.data = glyph.data.iter().rev().copied().collect();
80 }
81 Ok(())
82 }
83
84 fn redo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
85 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
86 glyph.data = glyph.data.iter().rev().copied().collect();
87 }
88 Ok(())
89 }
90 }
91
92 pub struct FlipX {
93 ch: char,
94 }
95
96 impl FlipX {
97 pub(crate) fn new(ch: char) -> Self {
98 Self { ch }
99 }
100 }
101
102 impl UndoOperation for FlipX {
103 fn get_description(&self) -> String {
104 fl!(crate::LANGUAGE_LOADER, "undo-bitfont-flip-x")
105 }
106
107 fn undo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
108 let w = 8 - edit_state.font.size.width;
109 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
110 for i in 0..glyph.data.len() {
111 glyph.data[i] = glyph.data[i].reverse_bits() << w;
112 }
113 }
114 Ok(())
115 }
116
117 fn redo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
118 let w = 8 - edit_state.font.size.width;
119 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
120 for i in 0..glyph.data.len() {
121 glyph.data[i] = glyph.data[i].reverse_bits() << w;
122 }
123 }
124 Ok(())
125 }
126 }
127
128 pub struct DownGlyph {
129 ch: char,
130 old_data: Vec<u8>,
131 }
132
133 impl DownGlyph {
134 pub(crate) fn new(ch: char) -> Self {
135 Self { ch, old_data: Vec::new() }
136 }
137 }
138
139 impl UndoOperation for DownGlyph {
140 fn get_description(&self) -> String {
141 fl!(crate::LANGUAGE_LOADER, "undo-bitfont-move-down")
142 }
143
144 fn undo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
145 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
146 glyph.data = self.old_data.clone();
147 }
148 Ok(())
149 }
150
151 fn redo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
152 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
153 self.old_data = glyph.data.clone();
154 glyph.data.insert(0, 0);
155 glyph.data.pop();
156 }
157 Ok(())
158 }
159 }
160
161 pub struct UpGlyph {
162 ch: char,
163 old_data: Vec<u8>,
164 }
165
166 impl UpGlyph {
167 pub(crate) fn new(ch: char) -> Self {
168 Self { ch, old_data: Vec::new() }
169 }
170 }
171
172 impl UndoOperation for UpGlyph {
173 fn get_description(&self) -> String {
174 fl!(crate::LANGUAGE_LOADER, "undo-bitfont-move-up")
175 }
176
177 fn undo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
178 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
179 glyph.data = self.old_data.clone();
180 }
181 Ok(())
182 }
183
184 fn redo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
185 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
186 self.old_data = glyph.data.clone();
187 glyph.data.remove(0);
188 glyph.data.push(0);
189 }
190 Ok(())
191 }
192 }
193
194 pub struct RightGlyph {
195 ch: char,
196 old_data: Vec<u8>,
197 }
198
199 impl RightGlyph {
200 pub(crate) fn new(ch: char) -> Self {
201 Self { ch, old_data: Vec::new() }
202 }
203 }
204
205 impl UndoOperation for RightGlyph {
206 fn get_description(&self) -> String {
207 fl!(crate::LANGUAGE_LOADER, "undo-bitfont-move-right")
208 }
209
210 fn undo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
211 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
212 glyph.data = self.old_data.clone();
213 }
214 Ok(())
215 }
216
217 fn redo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
218 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
219 self.old_data = glyph.data.clone();
220 for i in 0..glyph.data.len() {
221 glyph.data[i] >>= 1;
222 }
223 }
224 Ok(())
225 }
226 }
227
228 pub struct LeftGlyph {
229 ch: char,
230 old_data: Vec<u8>,
231 }
232
233 impl LeftGlyph {
234 pub(crate) fn new(ch: char) -> Self {
235 Self { ch, old_data: Vec::new() }
236 }
237 }
238
239 impl UndoOperation for LeftGlyph {
240 fn get_description(&self) -> String {
241 fl!(crate::LANGUAGE_LOADER, "undo-bitfont-move-left")
242 }
243
244 fn undo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
245 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
246 glyph.data = self.old_data.clone();
247 }
248 Ok(())
249 }
250
251 fn redo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
252 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
253 self.old_data = glyph.data.clone();
254 for i in 0..glyph.data.len() {
255 glyph.data[i] <<= 1;
256 }
257 }
258 Ok(())
259 }
260 }
261
262 pub struct ClearGlyph {
263 ch: char,
264 old_data: Vec<u8>,
265 }
266
267 impl ClearGlyph {
268 pub(crate) fn new(ch: char) -> Self {
269 Self { ch, old_data: Vec::new() }
270 }
271 }
272
273 impl UndoOperation for ClearGlyph {
274 fn get_description(&self) -> String {
275 fl!(crate::LANGUAGE_LOADER, "undo-bitfont-clear")
276 }
277
278 fn undo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
279 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
280 glyph.data = self.old_data.clone();
281 }
282 Ok(())
283 }
284
285 fn redo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
286 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
287 self.old_data = glyph.data.clone();
288 glyph.data.fill(0);
289 }
290 Ok(())
291 }
292 }
293
294 pub struct InverseGlyph {
295 ch: char,
296 }
297
298 impl InverseGlyph {
299 pub(crate) fn new(ch: char) -> Self {
300 Self { ch }
301 }
302 }
303
304 impl UndoOperation for InverseGlyph {
305 fn get_description(&self) -> String {
306 fl!(crate::LANGUAGE_LOADER, "undo-bitfont-inverse")
307 }
308
309 fn undo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
310 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
311 for i in 0..glyph.data.len() {
312 glyph.data[i] ^= 0xFF;
313 }
314 }
315 Ok(())
316 }
317
318 fn redo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
319 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
320 for i in 0..glyph.data.len() {
321 glyph.data[i] ^= 0xFF;
322 }
323 }
324 Ok(())
325 }
326 }
327
328 pub struct Edit {
329 ch: char,
330 old_data: Vec<u8>,
331 data: Vec<u8>,
332 }
333
334 impl Edit {
335 pub(crate) fn new(ch: char, data: Vec<u8>, old_data: Vec<u8>) -> Self {
336 Self { ch, data, old_data }
337 }
338 }
339
340 impl UndoOperation for Edit {
341 fn get_description(&self) -> String {
342 fl!(crate::LANGUAGE_LOADER, "undo-bitfont-edit")
343 }
344
345 fn undo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
346 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
347 glyph.data = self.old_data.clone();
348 }
349 Ok(())
350 }
351
352 fn redo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
353 if let Some(glyph) = edit_state.font.get_glyph_mut(self.ch) {
354 glyph.data = self.data.clone();
355 }
356 Ok(())
357 }
358 }
359
360 pub struct ResizeFont {
361 old_font: BitFont,
362 new_font: BitFont,
363 }
364
365 impl ResizeFont {
366 pub(crate) fn new(old_font: BitFont, new_font: BitFont) -> Self {
367 Self { old_font, new_font }
368 }
369 }
370
371 impl UndoOperation for ResizeFont {
372 fn get_description(&self) -> String {
373 fl!(crate::LANGUAGE_LOADER, "undo-bitfont-resize")
374 }
375
376 fn undo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
377 edit_state.font = self.old_font.clone();
378 Ok(())
379 }
380
381 fn redo(&mut self, edit_state: &mut BitFontEditor) -> EngineResult<()> {
382 edit_state.font = self.new_font.clone();
383 Ok(())
384 }
385 }