1use rvimage_domain::{RvResult, ShapeI};
2
3use crate::{
4 annotations_accessor_mut,
5 events::{Events, KeyCode},
6 history::{History, Record},
7 make_tool_transform,
8 result::trace_ok_err,
9 tools_data::{annotations::InstanceAnnotations, rot90_data::NRotations},
10 util::Visibility,
11 world::World,
12 world_annotations_accessor, InstanceAnnotate,
13};
14use std::mem;
15
16use super::{bbox, brush, Manipulate, BBOX_NAME, BRUSH_NAME};
17
18pub const ACTOR_NAME: &str = "Rot90";
19annotations_accessor_mut!(ACTOR_NAME, rot90_mut, "Rotation 90 didn't work", NRotations);
20world_annotations_accessor!(ACTOR_NAME, rot90, "Rotation 90 didn't work", NRotations);
21
22fn rot90_instannos_of_file<T>(
23 annos: Option<&mut InstanceAnnotations<T>>,
24 shape: ShapeI,
25) -> RvResult<()>
26where
27 T: InstanceAnnotate,
28{
29 if let Some(annos) = annos {
30 for elt in annos.elts_iter_mut() {
31 *elt = mem::take(elt).rot90_with_image_ntimes(shape, 1)?;
32 }
33 }
34 Ok(())
35}
36
37fn rot90_instannos_once(world: &mut World, shape: ShapeI) -> RvResult<()> {
38 macro_rules! rot {
39 ($name:expr, $module:ident) => {
40 let annos = $module::get_annos_mut(world);
41 rot90_instannos_of_file(annos, shape)?;
42 if let Some(d) = $module::get_options_mut(world) {
43 d.core.is_redraw_annos_triggered = true;
44 }
45 world.request_redraw_annotations($name, Visibility::None);
46 };
47 }
48 rot!(BRUSH_NAME, brush);
49 rot!(BBOX_NAME, bbox);
50 Ok(())
51}
52
53fn rot90(mut world: World, n_rotations: NRotations, skip_annos: bool) -> World {
55 let shape = world.data.shape();
56 match n_rotations {
57 NRotations::Zero => (),
58 NRotations::One => {
59 if !skip_annos {
60 trace_ok_err(rot90_instannos_once(&mut world, shape));
61 }
62 world.data.apply(|im| im.rotate270());
63 }
64 NRotations::Two => {
65 world.data.apply(|im| im.rotate180());
66 }
67 NRotations::Three => {
68 world.data.apply(|im| im.rotate90());
69 }
70 }
71 world.set_zoom_box(None);
72 world.request_redraw_image();
73 world
74}
75#[derive(Clone, Copy, Debug)]
76pub struct Rot90;
77
78impl Rot90 {
79 fn key_pressed(
80 &mut self,
81 _events: &Events,
82 mut world: World,
83 mut history: History,
84 ) -> (World, History) {
85 let skip_annos = false;
86 world = rot90(world, NRotations::One, skip_annos);
87 if let Some(anno) = get_annos_mut(&mut world) {
88 *anno = anno.increase();
89 }
90 history.push(Record::new(world.clone(), ACTOR_NAME));
91 (world, history)
92 }
93}
94
95impl Manipulate for Rot90 {
96 fn new() -> Self {
97 Self {}
98 }
99
100 fn on_filechange(&mut self, mut world: World, history: History) -> (World, History) {
101 if let Some(nrot) = get_annos_if_some(&world).copied() {
102 let skip_annos = true;
103 world = rot90(world, nrot, skip_annos);
104 }
105 (world, history)
106 }
107
108 fn events_tf(&mut self, world: World, history: History, event: &Events) -> (World, History) {
109 let (world, history) = make_tool_transform!(
110 self,
111 world,
112 history,
113 event,
114 [(pressed, KeyCode::R, key_pressed)]
115 );
116 (world, history)
117 }
118}