@@ -58,11 +58,16 @@ impl EditorState {
5858 }
5959
6060 pub fn create_shape ( & mut self , circle : Circle ) -> usize {
61+ let element_id = self . create_element ( circle) ;
62+ self . revision_stack . push ( ElementAction :: Draw { element_id } ) ;
63+
64+ element_id
65+ }
66+
67+ fn create_element ( & mut self , circle : Circle ) -> usize {
6168 let _id = self . next_id ( ) ;
6269
6370 self . element_stack . push ( Element { _id, inner : circle } ) ;
64- self . revision_stack
65- . push ( ElementAction :: Draw { element_id : _id } ) ;
6671
6772 _id
6873 }
@@ -77,13 +82,15 @@ impl EditorState {
7782 element_id,
7883 original_pos,
7984 } ) ;
85+
86+ println ! ( "{:#?}" , self . revision_stack) ;
8087 }
8188 }
8289
8390 pub fn translate_shape ( & mut self , element_id : usize , new_coord : Coordinate ) {
8491 if let Some ( i) = self . get_element_index_by_id ( element_id) {
8592 let element = unsafe { self . element_stack . get_unchecked_mut ( i) } ;
86- element. inner . translate ( new_coord) ;
93+ element. inner . set_center ( new_coord) ;
8794 }
8895 }
8996
@@ -94,53 +101,72 @@ impl EditorState {
94101 . find_map ( |( i, & Element { _id, .. } ) | if _id == element_id { Some ( i) } else { None } )
95102 }
96103
104+ pub fn get_element_by_id ( & self , element_id : usize ) -> Option < & Element > {
105+ self . get_element_index_by_id ( element_id)
106+ . map ( |i| & self . element_stack [ i] )
107+ }
108+
97109 pub fn get_element_by_point (
98110 & self ,
99111 point : Coordinate ,
100112 window_dimension : ( f32 , f32 ) ,
101113 ) -> Option < & Element > {
102114 self . element_stack . iter ( ) . rev ( ) . find ( |e| {
103115 let circle = e. inner ( ) ;
104- let circle_in_pixel_coords = circle. convert_pixel_coordinate ( window_dimension) ;
116+ let circle_in_pixel_coords = circle. convert_into_pixel_coordinate ( window_dimension) ;
105117
106118 compute_distance ( circle_in_pixel_coords. center ( ) , point)
107119 <= circle_in_pixel_coords. radius ( )
108120 } )
109121 }
110122
111123 pub fn remove_shape_by_id ( & mut self , element_id : usize ) {
112- if let Some ( i) = self . get_element_index_by_id ( element_id) {
113- self . remove_shape_by_index ( i) ;
114- }
115- }
116-
117- fn remove_shape_by_index ( & mut self , index : usize ) {
118- let Element { _id, inner } = self . element_stack . remove ( index) ;
124+ let Element { _id, inner } = self . remove_element ( element_id) ;
119125 self . revision_stack
120126 . push ( ElementAction :: Delete { element_id : _id } ) ;
127+
121128 self . deleted_shapes . insert ( _id, inner) ;
122129 }
123130
131+ fn remove_element ( & mut self , element_id : usize ) -> Element {
132+ if let Some ( i) = self . get_element_index_by_id ( element_id) {
133+ return self . element_stack . remove ( i) ;
134+ }
135+
136+ panic ! ( "expected a valid element id" ) ;
137+ }
138+
124139 fn find_deleted_shape ( & mut self , element_id : usize ) -> Option < Circle > {
125140 self . deleted_shapes . remove ( & element_id)
126141 }
127142
128143 pub fn undo ( & mut self ) {
129- if let Some ( last_action) = self . revision_stack . last ( ) {
144+ if let Some ( last_action) = self . revision_stack . pop ( ) {
130145 match last_action {
131146 ElementAction :: Move {
132147 element_id,
133148 original_pos,
134- } => self . translate_shape ( * element_id, * original_pos) ,
135- ElementAction :: Draw { element_id } => self . remove_shape_by_id ( * element_id) ,
149+ } => self . translate_shape ( element_id, original_pos) ,
150+ ElementAction :: Draw { element_id } => {
151+ let _ = self . remove_element ( element_id) ;
152+ }
136153 ElementAction :: Delete { element_id } => {
137- if let Some ( circle) = self . find_deleted_shape ( * element_id) {
138- self . create_shape ( circle) ;
154+ if let Some ( circle) = self . find_deleted_shape ( element_id) {
155+ self . create_element ( circle) ;
139156 }
140157 }
141158 }
142159 }
143160 }
161+
162+ pub fn copy_shape ( & mut self , circle : Circle , window_dimensions : ( f32 , f32 ) ) -> usize {
163+ let circle = circle
164+ . convert_into_pixel_coordinate ( window_dimensions)
165+ . translate ( ( 40.0 , 40.0 ) )
166+ . convert_into_normalized_coordinate ( window_dimensions) ;
167+
168+ self . create_shape ( circle)
169+ }
144170}
145171
146172pub fn compute_distance ( from : Coordinate , to : Coordinate ) -> f32 {
@@ -150,7 +176,7 @@ pub fn compute_distance(from: Coordinate, to: Coordinate) -> f32 {
150176// Stored as (x, y)
151177pub type Coordinate = ( f32 , f32 ) ;
152178
153- #[ derive( Debug ) ]
179+ #[ derive( Debug , Clone ) ]
154180pub struct Circle {
155181 center : Coordinate ,
156182 radius : f32 ,
@@ -171,7 +197,17 @@ impl Circle {
171197 }
172198 }
173199
174- pub fn convert_pixel_coordinate ( & self , window_dimensions : ( f32 , f32 ) ) -> Self {
200+ pub fn convert_into_normalized_coordinate ( & self , window_dimensions : ( f32 , f32 ) ) -> Self {
201+ let ( w, h) = window_dimensions;
202+ let ( cx, cy) = self . center ;
203+
204+ Self {
205+ center : ( cx / w, cy / h) ,
206+ radius : self . radius / w. min ( h) ,
207+ }
208+ }
209+
210+ pub fn convert_into_pixel_coordinate ( & self , window_dimensions : ( f32 , f32 ) ) -> Self {
175211 let ( w, h) = window_dimensions;
176212 let ( cx, cy) = self . center ;
177213
@@ -189,7 +225,18 @@ impl Circle {
189225 self . radius
190226 }
191227
192- pub const fn translate ( & mut self , new_center : Coordinate ) {
228+ pub const fn set_center ( & mut self , new_center : Coordinate ) {
193229 self . center = new_center;
194230 }
231+
232+ // note the offsets are in pixel coordinates!
233+ pub const fn translate ( & self , offset : Coordinate ) -> Self {
234+ let ( dx, dy) = offset;
235+ let ( x, y) = self . center ;
236+
237+ Self {
238+ center : ( x + dx, y + dy) ,
239+ radius : self . radius ,
240+ }
241+ }
195242}
0 commit comments