Skip to content

Commit 4370e8e

Browse files
Simplify shapes, complete undo stack for various actions
1 parent d89da05 commit 4370e8e

File tree

3 files changed

+164
-172
lines changed

3 files changed

+164
-172
lines changed

src/renderer/app_state.rs

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
gpu_state::GpuResourceAllocator,
77
mouse_state::MouseState,
88
shader::{Shader, TextureResource},
9-
shape::{compute_distance, Circle, EditorState, Shape},
9+
shape::{compute_distance, Circle, EditorState},
1010
shape_uniform::{CircleData, ShapeUniform, MAX_CIRCLES},
1111
},
1212
};
@@ -145,6 +145,7 @@ impl<'a> AppState<'a> {
145145
let (start_x, start_y) = self.mouse_state.position();
146146
self.mouse_state.set_start_drag(Some((start_x, start_y)));
147147
draw_uniform.set_circle_center(start_x, start_y);
148+
self.mouse_state.set_selected_shape(None);
148149
}
149150
(true, false) => {
150151
let initial_drag_position = self.mouse_state.start_drag();
@@ -162,7 +163,9 @@ impl<'a> AppState<'a> {
162163
(self.size.width as f32, self.size.height as f32),
163164
);
164165

165-
self.editor_state.push_shape(Shape::Circle(circle));
166+
let element_id = self.editor_state.create_shape(circle);
167+
168+
self.mouse_state.set_selected_shape(Some(element_id));
166169

167170
// Clear state
168171
self.mouse_state.set_start_drag(None);
@@ -177,40 +180,38 @@ impl<'a> AppState<'a> {
177180
// Mouse press - check if we clicked on a circle
178181
let mouse_coordinate = self.mouse_state.position();
179182

180-
if let Some(circle_index) =
181-
self.editor_state.shape_stack.find_shape_at_point(
182-
mouse_coordinate,
183-
self.size.width,
184-
self.size.height,
185-
)
186-
{
187-
// Found a circle - select it and start dragging
188-
self.mouse_state.set_selected_shape(Some(circle_index));
189-
self.mouse_state.set_dragging_shape(true);
190-
191-
// Calculate offset from circle center to mouse position
192-
let Shape::Circle(circle) =
193-
self.editor_state.shape_stack.get_unchecked(circle_index);
194-
195-
let (x, y) = circle.center();
196-
197-
let normalized_mouse_coord = {
198-
let (x_in_pixel_coords, y_in_pixel_coords) =
199-
mouse_coordinate;
200-
201-
(
202-
x_in_pixel_coords / self.size.width as f32,
203-
y_in_pixel_coords / self.size.height as f32,
204-
)
205-
};
206-
207-
let offset_x = normalized_mouse_coord.0 - x;
208-
let offset_y = normalized_mouse_coord.1 - y;
209-
210-
self.mouse_state.set_drag_offset((offset_x, offset_y));
211-
} else {
212-
// Clicked on empty space - deselect any selected circle
213-
self.mouse_state.set_selected_shape(None);
183+
let res = self.editor_state.get_element_by_point(
184+
mouse_coordinate,
185+
(self.size.width as f32, self.size.height as f32),
186+
);
187+
188+
match res {
189+
Some(element) => {
190+
let id = element.id();
191+
let orig_pos = element.inner().center();
192+
193+
self.editor_state.start_shape_translate(id);
194+
195+
// Found a circle - select it and start dragging
196+
self.mouse_state.set_selected_shape(Some(id));
197+
self.mouse_state.set_dragging_shape(true);
198+
199+
let normalized_mouse_coord = {
200+
let (x_in_pixel_coords, y_in_pixel_coords) =
201+
mouse_coordinate;
202+
203+
(
204+
x_in_pixel_coords / self.size.width as f32,
205+
y_in_pixel_coords / self.size.height as f32,
206+
)
207+
};
208+
209+
let offset_x = normalized_mouse_coord.0 - orig_pos.0;
210+
let offset_y = normalized_mouse_coord.1 - orig_pos.1;
211+
212+
self.mouse_state.set_drag_offset((offset_x, offset_y));
213+
}
214+
None => self.mouse_state.set_selected_shape(None),
214215
}
215216
}
216217
(true, false) => {
@@ -234,7 +235,7 @@ impl<'a> AppState<'a> {
234235
} else {
235236
// Selection mode: Handle circle dragging
236237
if self.mouse_state.dragging_shape() {
237-
if let Some(selected_index) = self.mouse_state.selected_shape() {
238+
if let Some(selected_element_id) = self.mouse_state.selected_shape() {
238239
let normalized_x = x / self.size.width as f32;
239240
let normalized_y = y / self.size.height as f32;
240241

@@ -245,8 +246,7 @@ impl<'a> AppState<'a> {
245246

246247
// Move the circle to the new position
247248
self.editor_state
248-
.shape_stack
249-
.move_shape(selected_index, new_x, new_y);
249+
.translate_shape(selected_element_id, (new_x, new_y));
250250
}
251251
}
252252
}
@@ -319,8 +319,8 @@ impl<'a> AppState<'a> {
319319
(KeyCode::Delete, ElementState::Pressed)
320320
| (KeyCode::Backspace, ElementState::Pressed) => {
321321
// Delete the selected circle
322-
if let Some(selected_index) = self.mouse_state.selected_shape() {
323-
self.editor_state.shape_stack.remove_shape(selected_index);
322+
if let Some(selected_element_id) = self.mouse_state.selected_shape() {
323+
self.editor_state.remove_shape_by_id(selected_element_id);
324324
self.mouse_state.set_selected_shape(None);
325325
self.mouse_state.set_dragging_shape(false);
326326
}
@@ -357,29 +357,28 @@ impl<'a> AppState<'a> {
357357
}
358358

359359
fn update_shape_data(&mut self) {
360-
let num_circles = self.editor_state.shape_stack.len().min(MAX_CIRCLES);
360+
let num_circles = self.editor_state.num_elements();
361361

362362
self.shape_uniform.set_num_circles(num_circles as u32);
363-
self.shape_uniform
364-
.set_selected_circle(self.mouse_state.selected_shape());
363+
364+
// Convert element ID to array index for the shader
365+
let selected_index = self.mouse_state.selected_shape()
366+
.and_then(|element_id| self.editor_state.get_element_index_by_id(element_id));
367+
368+
self.shape_uniform.set_selected_circle(selected_index);
365369

366370
// Update shape uniform
367371
let shape_uniform_resources = &self.shape_shader.uniform_resources;
368372
self.gpu_allocator
369373
.write_uniform_buffer(&shape_uniform_resources[0].resource, self.shape_uniform);
370374

371375
// Update circle storage buffer
372-
let mut circle_data = vec![CircleData::default(); MAX_CIRCLES];
373-
for (i, (_, shape)) in self
376+
let circle_data = self
374377
.editor_state
375-
.shape_stack
376-
.shapes()
377-
.into_iter()
378-
.take(MAX_CIRCLES)
379-
.enumerate()
380-
{
381-
circle_data[i] = CircleData::from(shape);
382-
}
378+
.elements()
379+
.iter()
380+
.map(|e| CircleData::from(e.inner()))
381+
.collect::<Vec<_>>();
383382

384383
self.gpu_allocator
385384
.write_storage_buffer(&self.circle_storage_buffer, &circle_data);

0 commit comments

Comments
 (0)