1use crate::prelude::*;
2use theframework::prelude::*;
3
4#[derive(Clone, Debug)]
6pub enum ProjectUndoAtom {
7 MapEdit(ProjectContext, Box<Map>, Box<Map>),
8 AddRegion(Region),
9 RemoveRegion(usize, Region),
10 RenameRegion(Uuid, String, String),
11 AddRegionCharacterInstance(Uuid, Character),
12 RemoveRegionCharacterInstance(usize, Uuid, Character),
13 MoveRegionCharacterInstance(Uuid, Uuid, Vec3<f32>, Vec3<f32>), AddRegionItemInstance(Uuid, Item),
15 RemoveRegionItemInstance(usize, Uuid, Item),
16 MoveRegionItemInstance(Uuid, Uuid, Vec3<f32>, Vec3<f32>), AddCharacter(Character),
18 RemoveCharacter(usize, Character),
19 RenameCharacter(Uuid, String, String),
20 AddItem(Item),
21 RemoveItem(usize, Item),
22 RenameItem(Uuid, String, String),
23 AddTilemap(Tilemap),
24 RemoveTilemap(usize, Tilemap),
25 RenameTilemap(Uuid, String, String),
26 EditTilemapGridSize(Uuid, i32, i32),
27 AddScreen(Screen),
28 RemoveScreen(usize, Screen),
29 RenameScreen(Uuid, String, String),
30 AddAsset(Asset),
31 RemoveAsset(usize, Asset),
32 RenameAsset(Uuid, String, String),
33 AddAvatar(Avatar),
34 RemoveAvatar(usize, Avatar),
35 RenameAvatar(Uuid, String, String),
36 EditAvatarResolution(Uuid, u16, u16),
37 EditAvatarPerspectiveCount(Uuid, AvatarPerspectiveCount, AvatarPerspectiveCount),
38 AddAvatarAnimation(Uuid, AvatarAnimation),
39 RemoveAvatarAnimation(Uuid, usize, AvatarAnimation),
40 RenameAvatarAnimation(Uuid, Uuid, String, String),
41 EditAvatarAnimationFrameCount(Uuid, Uuid, usize, usize),
42 EditAvatarAnimationSpeed(Uuid, Uuid, f32, f32),
43 PaletteEdit(ThePalette, ThePalette),
44 TileEdit(rusterix::Tile, rusterix::Tile),
45}
46
47use ProjectUndoAtom::*;
48
49impl ProjectUndoAtom {
50 pub fn pc(&self) -> Option<ProjectContext> {
52 match self {
53 MapEdit(pc, _, _) => Some(*pc),
54 _ => None,
55 }
56 }
57
58 pub fn to_string(&self) -> String {
60 match self {
61 MapEdit(_, _, _) => "Map Edit".to_string(),
62 AddRegion(region) => format!("Add Region: {}", region.name),
63 RemoveRegion(_, region) => format!("Remove Region: {}", region.name),
64 RenameRegion(_, old, new) => format!("Rename Region: {} -> {}", old, new),
65 AddRegionCharacterInstance(_, character) => {
66 format!("Add Region Character Instance: {}", character.name)
67 }
68 RemoveRegionCharacterInstance(_, _, character) => {
69 format!("Remove Region Character Instance: {}", character.name)
70 }
71 MoveRegionCharacterInstance(_, _, _, _) => "Move Region Character Instance".into(),
72 AddRegionItemInstance(_, item) => {
73 format!("Add Region Item Instance: {}", item.name)
74 }
75 RemoveRegionItemInstance(_, _, item) => {
76 format!("Remove Region Item Instance: {}", item.name)
77 }
78 MoveRegionItemInstance(_, _, _, _) => "Move Region Item Instance".into(),
79 AddCharacter(character) => format!("Add Character: {}", character.name),
80 RemoveCharacter(_, character) => format!("Remove Character: {}", character.name),
81 RenameCharacter(_, old, new) => format!("Rename Character: {} -> {}", old, new),
82 AddItem(character) => format!("Add Item: {}", character.name),
83 RemoveItem(_, character) => format!("Remove Item: {}", character.name),
84 RenameItem(_, old, new) => format!("Rename Item: {} -> {}", old, new),
85 AddTilemap(tilemap) => format!("Add Tilemap: {}", tilemap.name),
86 RemoveTilemap(_, tilemap) => format!("Remove Tilemap: {}", tilemap.name),
87 RenameTilemap(_, old, new) => format!("Rename Tilemap: {} -> {}", old, new),
88 EditTilemapGridSize(_, old, new) => {
89 format!("Edit Tilemap Grid Size: {} -> {}", old, new)
90 }
91 AddScreen(screen) => format!("Add Screen: {}", screen.name),
92 RemoveScreen(_, screen) => format!("Remove Screen: {}", screen.name),
93 RenameScreen(_, old, new) => format!("Rename Screen: {} -> {}", old, new),
94 AddAsset(asset) => format!("Add Asset: {}", asset.name),
95 RemoveAsset(_, asset) => format!("Remove Asset: {}", asset.name),
96 RenameAsset(_, old, new) => format!("Rename Asset: {} -> {}", old, new),
97 AddAvatar(avatar) => format!("Add Avatar: {}", avatar.name),
98 RemoveAvatar(_, avatar) => format!("Remove Avatar: {}", avatar.name),
99 RenameAvatar(_, old, new) => format!("Rename Avatar: {} -> {}", old, new),
100 EditAvatarResolution(_, old, new) => {
101 format!("Edit Avatar Resolution: {} -> {}", old, new)
102 }
103 EditAvatarPerspectiveCount(_, old, new) => {
104 format!("Edit Avatar Perspectives: {:?} -> {:?}", old, new)
105 }
106 AddAvatarAnimation(_, anim) => format!("Add Animation: {}", anim.name),
107 RemoveAvatarAnimation(_, _, anim) => format!("Remove Animation: {}", anim.name),
108 RenameAvatarAnimation(_, _, old, new) => {
109 format!("Rename Animation: {} -> {}", old, new)
110 }
111 EditAvatarAnimationFrameCount(_, _, old, new) => {
112 format!("Edit Animation Frames: {} -> {}", old, new)
113 }
114 EditAvatarAnimationSpeed(_, _, old, new) => {
115 format!("Edit Animation Speed: {:.2} -> {:.2}", old, new)
116 }
117 PaletteEdit(_old, _new) => format!("Palette Changed"),
118 TileEdit(_old, _new) => format!("Tile Changed"),
119 }
120 }
121
122 pub fn undo(
123 &self,
124 project: &mut Project,
125 ui: &mut TheUI,
126 ctx: &mut TheContext,
127 server_ctx: &mut ServerContext,
128 ) {
129 match self {
130 MapEdit(pc, old, _new) => {
131 set_project_context(ctx, ui, project, server_ctx, *pc);
132 if let Some(map) = project.get_map_mut(server_ctx) {
133 *map = *old.clone();
134 map.clear_temp();
135 if pc.is_region() {
136 update_region(ctx);
137 map.update_surfaces();
138 }
139 }
140 }
141 AddRegion(region) => {
142 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
143 if let Some(region_node) =
144 tree_layout.get_node_by_id_mut(&server_ctx.tree_regions_id)
145 {
146 project.remove_region(®ion.id);
147 region_node.remove_child_by_uuid(®ion.id);
148 }
149 }
150 }
151 RemoveRegion(index, region) => {
152 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
153 let mut region = region.clone();
154 region.map.name = region.name.clone();
155
156 let mut node = gen_region_tree_node(®ion);
157 node.set_open(true);
158 if let Some(region_node) =
159 tree_layout.get_node_by_id_mut(&server_ctx.tree_regions_id)
160 {
161 region_node.add_child_at(*index, node);
162 }
163 let region_id: Uuid = region.id;
164 project.regions.insert(*index, region);
165
166 server_ctx.curr_region = region_id;
167 set_project_context(
168 ctx,
169 ui,
170 project,
171 server_ctx,
172 ProjectContext::Region(region_id),
173 );
174 update_region(ctx);
175 }
176 }
177 RenameRegion(id, old, _new) => {
178 if let Some(region) = project.get_region_mut(id) {
179 region.name = old.clone();
180 region.map.name = old.clone();
181 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
182 if let Some(region_node) = tree_layout.get_node_by_id_mut(®ion.id) {
183 region_node.widget.set_value(TheValue::Text(old.clone()));
184 if let Some(widget) = region_node.widgets[0].as_tree_item() {
185 if let Some(embedded) = widget.embedded_widget_mut() {
186 embedded.set_value(TheValue::Text(old.clone()));
187 }
188 }
189 }
190 }
191 }
192 }
193 AddRegionCharacterInstance(region_id, character) => {
194 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
195 if let Some(region_node) =
196 tree_layout.get_node_by_id_mut(&server_ctx.tree_regions_id)
197 {
198 region_node.remove_widget_by_uuid(&character.id);
199 }
200
201 if let Some(region) = project.get_region_mut(region_id) {
202 region.characters.shift_remove(&character.id);
203 region.map.entities.retain(|e| e.creator_id != character.id);
204 }
205
206 if let Some(region) = project.get_region(region_id) {
207 if let Some(region_node) = tree_layout.get_node_by_id_mut(®ion.id) {
208 region_node.set_open(true);
209 }
210 server_ctx.curr_region = region.id;
211 set_project_context(
212 ctx,
213 ui,
214 project,
215 server_ctx,
216 ProjectContext::Region(region.id),
217 );
218 update_region(ctx);
219 }
220 }
221 }
222 RemoveRegionCharacterInstance(index, region_id, character) => {
223 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
224 let character = character.clone();
225
226 if let Some(region) = project.get_region_mut(region_id) {
227 region
228 .characters
229 .insert_before(*index, character.id, character);
230
231 if let Some(region_node) = tree_layout.get_node_by_id_mut(®ion_id) {
232 gen_region_tree_items(region_node, region);
233 }
234 }
235 shared::rusterix_utils::insert_content_into_maps(project);
236 }
237 }
238 MoveRegionCharacterInstance(region_id, instance_id, from, _to) => {
239 move_region_character_pos(
240 project,
241 ui,
242 ctx,
243 server_ctx,
244 *region_id,
245 *instance_id,
246 *from,
247 );
248 }
249 AddRegionItemInstance(region_id, item) => {
250 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
251 if let Some(region_node) =
252 tree_layout.get_node_by_id_mut(&server_ctx.tree_regions_id)
253 {
254 region_node.remove_widget_by_uuid(&item.id);
255 }
256
257 if let Some(region) = project.get_region_mut(region_id) {
258 region.items.shift_remove(&item.id);
259 region.map.items.retain(|e| e.creator_id != item.id);
260 }
261
262 if let Some(region) = project.get_region(region_id) {
263 if let Some(region_node) = tree_layout.get_node_by_id_mut(®ion.id) {
264 region_node.set_open(true);
265 }
266 server_ctx.curr_region = region.id;
267 set_project_context(
268 ctx,
269 ui,
270 project,
271 server_ctx,
272 ProjectContext::Region(region.id),
273 );
274 update_region(ctx);
275 }
276 }
277 }
278 RemoveRegionItemInstance(index, region_id, item) => {
279 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
280 let item = item.clone();
281
282 if let Some(region) = project.get_region_mut(region_id) {
283 region.items.insert_before(*index, item.id, item);
284
285 if let Some(region_node) = tree_layout.get_node_by_id_mut(®ion_id) {
286 gen_region_tree_items(region_node, region);
287 }
288 }
289 shared::rusterix_utils::insert_content_into_maps(project);
290 }
291 }
292 MoveRegionItemInstance(region_id, instance_id, from, _to) => {
293 move_region_item_pos(
294 project,
295 ui,
296 ctx,
297 server_ctx,
298 *region_id,
299 *instance_id,
300 *from,
301 );
302 }
303 AddCharacter(character) => {
304 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
305 if let Some(region_node) =
306 tree_layout.get_node_by_id_mut(&server_ctx.tree_characters_id)
307 {
308 project.remove_character(&character.id);
309 region_node.remove_child_by_uuid(&character.id);
310 }
311 }
312 }
313 RemoveCharacter(index, character) => {
314 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
315 let character = character.clone();
316
317 let mut node = gen_character_tree_node(&character);
318 node.set_open(true);
319 if let Some(character_node) =
320 tree_layout.get_node_by_id_mut(&server_ctx.tree_characters_id)
321 {
322 character_node.add_child_at(*index, node);
323 }
324 let character_id: Uuid = character.id;
325 project
326 .characters
327 .insert_before(*index, character_id, character);
328
329 set_project_context(
330 ctx,
331 ui,
332 project,
333 server_ctx,
334 ProjectContext::Character(character_id),
335 );
336 update_region(ctx);
337 }
338 }
339 RenameCharacter(id, old, _new) => {
340 if let Some(character) = project.characters.get_mut(id) {
341 character.name = old.clone();
342 character.map.name = old.clone();
343 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
344 if let Some(region_node) = tree_layout.get_node_by_id_mut(&character.id) {
345 region_node.widget.set_value(TheValue::Text(old.clone()));
346 if let Some(widget) = region_node.widgets[0].as_tree_item() {
347 if let Some(embedded) = widget.embedded_widget_mut() {
348 embedded.set_value(TheValue::Text(old.clone()));
349 }
350 }
351 }
352 }
353 }
354 }
355 AddItem(item) => {
356 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
357 if let Some(region_node) =
358 tree_layout.get_node_by_id_mut(&server_ctx.tree_items_id)
359 {
360 project.remove_item(&item.id);
361 region_node.remove_child_by_uuid(&item.id);
362 }
363 }
364 }
365 RemoveItem(index, item) => {
366 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
367 let item = item.clone();
368
369 let mut node = gen_item_tree_node(&item);
370 node.set_open(true);
371 if let Some(item_node) =
372 tree_layout.get_node_by_id_mut(&server_ctx.tree_items_id)
373 {
374 item_node.add_child_at(*index, node);
375 }
376 let item_id: Uuid = item.id;
377 project.items.insert_before(*index, item_id, item);
378
379 set_project_context(
380 ctx,
381 ui,
382 project,
383 server_ctx,
384 ProjectContext::Item(item_id),
385 );
386 update_region(ctx);
387 }
388 }
389 RenameItem(id, old, _new) => {
390 if let Some(item) = project.items.get_mut(id) {
391 item.name = old.clone();
392 item.map.name = old.clone();
393 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
394 if let Some(region_node) = tree_layout.get_node_by_id_mut(&item.id) {
395 region_node.widget.set_value(TheValue::Text(old.clone()));
396 if let Some(widget) = region_node.widgets[0].as_tree_item() {
397 if let Some(embedded) = widget.embedded_widget_mut() {
398 embedded.set_value(TheValue::Text(old.clone()));
399 }
400 }
401 }
402 }
403 }
404 }
405 AddTilemap(tilemap) => {
406 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
407 if let Some(tilemap_node) =
408 tree_layout.get_node_by_id_mut(&server_ctx.tree_tilemaps_id)
409 {
410 if let Some(index) =
412 project.tilemaps.iter().position(|t| t.id == tilemap.id)
413 {
414 project.tilemaps.remove(index);
415 }
416 tilemap_node.remove_child_by_uuid(&tilemap.id);
417 }
418 }
419 }
420 RemoveTilemap(index, tilemap) => {
421 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
422 let tilemap = tilemap.clone();
423
424 let mut node = gen_tilemap_tree_node(&tilemap);
425 node.set_open(true);
426 if let Some(tilemap_node) =
427 tree_layout.get_node_by_id_mut(&server_ctx.tree_tilemaps_id)
428 {
429 tilemap_node.add_child_at(*index, node);
430 }
431 project.tilemaps.insert(*index, tilemap.clone());
432
433 set_project_context(
434 ctx,
435 ui,
436 project,
437 server_ctx,
438 ProjectContext::Tilemap(tilemap.id),
439 );
440 update_region(ctx);
441 }
442 }
443 RenameTilemap(id, old, _new) => {
444 if let Some(tilemap) = project.get_tilemap_mut(*id) {
445 tilemap.name = old.clone();
446 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
447 if let Some(tilemap_node) = tree_layout.get_node_by_id_mut(id) {
448 tilemap_node.widget.set_value(TheValue::Text(old.clone()));
449 if let Some(widget) = tilemap_node.widgets[0].as_tree_item() {
450 if let Some(embedded) = widget.embedded_widget_mut() {
451 embedded.set_value(TheValue::Text(old.clone()));
452 }
453 }
454 }
455 }
456 }
457 }
458 EditTilemapGridSize(id, old, _new) => {
459 if let Some(tilemap) = project.get_tilemap_mut(*id) {
460 tilemap.grid_size = *old;
461 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
463 if let Some(node) = tree_layout.get_node_by_id_mut(id) {
464 if let Some(widget) = node.widgets[1].as_tree_item() {
465 if let Some(embedded) = widget.embedded_widget_mut() {
466 embedded.set_value(TheValue::Int(*old));
467
468 ctx.ui.send(TheEvent::Custom(
469 TheId::named("Tilemap Grid Size Changed"),
470 TheValue::Int(*old),
471 ));
472 }
473 }
474 }
475 }
476 }
477 }
478 AddScreen(screen) => {
479 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
480 if let Some(screen_node) =
481 tree_layout.get_node_by_id_mut(&server_ctx.tree_screens_id)
482 {
483 project.remove_screen(&screen.id);
484 screen_node.remove_child_by_uuid(&screen.id);
485 }
486 }
487 }
488 RemoveScreen(index, screen) => {
489 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
490 let screen = screen.clone();
491
492 let mut node = gen_screen_tree_node(&screen);
493 node.set_open(true);
494 if let Some(screen_node) =
495 tree_layout.get_node_by_id_mut(&server_ctx.tree_screens_id)
496 {
497 screen_node.add_child_at(*index, node);
498 }
499 let screen_id: Uuid = screen.id;
500 project.screens.insert_before(*index, screen_id, screen);
501
502 set_project_context(
503 ctx,
504 ui,
505 project,
506 server_ctx,
507 ProjectContext::Screen(screen_id),
508 );
509 update_region(ctx);
510 }
511 }
512 RenameScreen(id, old, _new) => {
513 if let Some(screen) = project.screens.get_mut(id) {
514 screen.name = old.clone();
515 screen.map.name = old.clone();
516 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
517 if let Some(screen_node) = tree_layout.get_node_by_id_mut(&screen.id) {
518 screen_node.widget.set_value(TheValue::Text(old.clone()));
519 if let Some(widget) = screen_node.widgets[0].as_tree_item() {
520 if let Some(embedded) = widget.embedded_widget_mut() {
521 embedded.set_value(TheValue::Text(old.clone()));
522 }
523 }
524 }
525 }
526 }
527 }
528 AddAsset(asset) => {
529 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
530 let parent_id = match &asset.buffer {
531 AssetBuffer::Audio(_) => server_ctx.tree_assets_audio_id,
532 _ => server_ctx.tree_assets_fonts_id,
533 };
534 if let Some(asset_node) = tree_layout.get_node_by_id_mut(&parent_id) {
535 project.remove_asset(&asset.id);
536 asset_node.remove_child_by_uuid(&asset.id);
537 }
538 }
539 }
540 RemoveAsset(index, asset) => {
541 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
542 let asset = asset.clone();
543
544 let mut node = gen_asset_tree_node(&asset);
545 node.set_open(true);
546 let parent_id = match &asset.buffer {
547 AssetBuffer::Audio(_) => server_ctx.tree_assets_audio_id,
548 _ => server_ctx.tree_assets_fonts_id,
549 };
550 if let Some(asset_node) = tree_layout.get_node_by_id_mut(&parent_id) {
551 let insert_index = (*index).min(asset_node.childs.len());
552 asset_node.add_child_at(insert_index, node);
553 }
554 let asset_id: Uuid = asset.id;
555 project.assets.insert_before(*index, asset_id, asset);
556
557 set_project_context(
558 ctx,
559 ui,
560 project,
561 server_ctx,
562 ProjectContext::Asset(asset_id),
563 );
564 update_region(ctx);
565 }
566 }
567 RenameAsset(id, old, _new) => {
568 if let Some(asset) = project.assets.get_mut(id) {
569 asset.name = old.clone();
570 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
571 if let Some(asset_node) = tree_layout.get_node_by_id_mut(&asset.id) {
572 asset_node.widget.set_value(TheValue::Text(old.clone()));
573 if let Some(widget) = asset_node.widgets[0].as_tree_item() {
574 if let Some(embedded) = widget.embedded_widget_mut() {
575 embedded.set_value(TheValue::Text(old.clone()));
576 }
577 }
578 }
579 }
580 }
581 }
582 AddAvatar(avatar) => {
583 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
584 if let Some(avatar_node) =
585 tree_layout.get_node_by_id_mut(&server_ctx.tree_avatars_id)
586 {
587 project.remove_avatar(&avatar.id);
588 avatar_node.remove_child_by_uuid(&avatar.id);
589 }
590 }
591 }
592 RemoveAvatar(index, avatar) => {
593 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
594 let avatar = avatar.clone();
595
596 let mut node = gen_avatar_tree_node(&avatar);
597 node.set_open(true);
598 if let Some(avatar_node) =
599 tree_layout.get_node_by_id_mut(&server_ctx.tree_avatars_id)
600 {
601 avatar_node.add_child_at(*index, node);
602 }
603 let avatar_id: Uuid = avatar.id;
604 project.avatars.insert_before(*index, avatar_id, avatar);
605
606 set_project_context(
607 ctx,
608 ui,
609 project,
610 server_ctx,
611 ProjectContext::Avatar(avatar_id),
612 );
613 update_region(ctx);
614 }
615 }
616 RenameAvatar(id, old, _new) => {
617 if let Some(avatar) = project.avatars.get_mut(id) {
618 avatar.name = old.clone();
619 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
620 if let Some(avatar_node) = tree_layout.get_node_by_id_mut(&avatar.id) {
621 avatar_node.widget.set_value(TheValue::Text(old.clone()));
622 if let Some(widget) = avatar_node.widgets[0].as_tree_item() {
623 if let Some(embedded) = widget.embedded_widget_mut() {
624 embedded.set_value(TheValue::Text(old.clone()));
625 }
626 }
627 }
628 }
629 }
630 }
631 EditAvatarResolution(id, old, _new) => {
632 if let Some(avatar) = project.avatars.get_mut(id) {
633 avatar.set_resolution(*old);
634 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
635 if let Some(avatar_node) = tree_layout.get_node_by_id_mut(id) {
636 if let Some(widget) = avatar_node.widgets[1].as_tree_item() {
637 if let Some(embedded) = widget.embedded_widget_mut() {
638 embedded.set_value(TheValue::Int(*old as i32));
639 }
640 }
641 }
642 }
643 }
644 }
645 EditAvatarPerspectiveCount(id, old, _new) => {
646 if let Some(avatar) = project.avatars.get_mut(id) {
647 avatar.set_perspective_count(*old);
648 }
649 rebuild_avatar_tree_node(id, project, ui, server_ctx);
650 }
651 AddAvatarAnimation(avatar_id, anim) => {
652 if let Some(avatar) = project.avatars.get_mut(avatar_id) {
654 avatar.animations.retain(|a| a.id != anim.id);
655 rebuild_avatar_tree_node(avatar_id, project, ui, server_ctx);
656 }
657 }
658 RemoveAvatarAnimation(avatar_id, index, anim) => {
659 if let Some(avatar) = project.avatars.get_mut(avatar_id) {
661 let idx = (*index).min(avatar.animations.len());
662 avatar.animations.insert(idx, anim.clone());
663 rebuild_avatar_tree_node(avatar_id, project, ui, server_ctx);
664 }
665 }
666 RenameAvatarAnimation(_avatar_id, anim_id, old, _new) => {
667 if let Some(avatar) = project
668 .avatars
669 .values_mut()
670 .find(|a| a.animations.iter().any(|anim| anim.id == *anim_id))
671 {
672 if let Some(anim) = avatar.animations.iter_mut().find(|a| a.id == *anim_id) {
673 anim.name = old.clone();
674 }
675 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
676 if let Some(anim_node) = tree_layout.get_node_by_id_mut(anim_id) {
677 let label = format!("{} - Animation", old);
678 anim_node.widget.set_value(TheValue::Text(label));
679 if let Some(widget) = anim_node.widgets[0].as_tree_item() {
680 if let Some(embedded) = widget.embedded_widget_mut() {
681 embedded.set_value(TheValue::Text(old.clone()));
682 }
683 }
684 }
685 }
686 }
687 }
688 EditAvatarAnimationFrameCount(avatar_id, anim_id, old, _new) => {
689 if let Some(avatar) = project.avatars.get_mut(avatar_id) {
690 avatar.set_animation_frame_count(anim_id, *old);
691 }
692 rebuild_animation_tree_node(avatar_id, anim_id, project, ui, server_ctx);
693 }
694 EditAvatarAnimationSpeed(avatar_id, anim_id, old, _new) => {
695 if let Some(avatar) = project.avatars.get_mut(avatar_id) {
696 if let Some(anim) = avatar.animations.iter_mut().find(|a| a.id == *anim_id) {
697 anim.speed = *old;
698 }
699 }
700 rebuild_animation_tree_node(avatar_id, anim_id, project, ui, server_ctx);
701 }
702 PaletteEdit(old, _new) => {
703 let sel = project.palette.current_index;
704 project.palette = old.clone();
705 project.palette.current_index = sel;
706 apply_palette(ui, ctx, server_ctx, project);
707 }
708 TileEdit(old, _new) => {
709 project.tiles.insert(old.id, old.clone());
710 ctx.ui.send(TheEvent::Custom(
711 TheId::named("Update Tiles"),
712 TheValue::Empty,
713 ));
714 }
715 }
716 }
717
718 pub fn redo(
719 &self,
720 project: &mut Project,
721 ui: &mut TheUI,
722 ctx: &mut TheContext,
723 server_ctx: &mut ServerContext,
724 ) {
725 match self {
726 MapEdit(pc, _old, new) => {
727 set_project_context(ctx, ui, project, server_ctx, *pc);
728 if let Some(map) = project.get_map_mut(server_ctx) {
729 *map = *new.clone();
730 map.clear_temp();
731 if pc.is_region() {
732 update_region(ctx);
733 map.update_surfaces();
734 }
735 }
736 }
737 AddRegion(region) => {
738 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
740 let mut region = region.clone();
741 region.map.name = region.name.clone();
742
743 let mut node = gen_region_tree_node(®ion);
744 node.set_open(true);
745 if let Some(region_node) =
746 tree_layout.get_node_by_id_mut(&server_ctx.tree_regions_id)
747 {
748 region_node.add_child(node);
749 }
750 let region_id: Uuid = region.id;
751 project.regions.push(region);
752
753 server_ctx.curr_region = region_id;
754 set_project_context(
755 ctx,
756 ui,
757 project,
758 server_ctx,
759 ProjectContext::Region(region_id),
760 );
761 update_region(ctx);
762 }
763 }
764 RemoveRegion(_, region) => {
765 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
766 if let Some(region_node) =
767 tree_layout.get_node_by_id_mut(&server_ctx.tree_regions_id)
768 {
769 region_node.remove_child_by_uuid(®ion.id);
770 }
771 project.remove_region(®ion.id);
772
773 if let Some(region) = project.regions.first() {
774 if let Some(region_node) = tree_layout.get_node_by_id_mut(®ion.id) {
775 region_node.set_open(true);
776 }
777 server_ctx.curr_region = region.id;
778 set_project_context(
779 ctx,
780 ui,
781 project,
782 server_ctx,
783 ProjectContext::Region(region.id),
784 );
785 update_region(ctx);
786 }
787 }
788 }
789 RenameRegion(id, _old, new) => {
790 if let Some(region) = project.get_region_mut(id) {
791 region.name = new.clone();
792 region.map.name = new.clone();
793 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
794 if let Some(region_node) = tree_layout.get_node_by_id_mut(®ion.id) {
795 region_node.widget.set_value(TheValue::Text(new.clone()));
796 if let Some(widget) = region_node.widgets[0].as_tree_item() {
797 if let Some(embedded) = widget.embedded_widget_mut() {
798 embedded.set_value(TheValue::Text(new.clone()));
799 }
800 }
801 }
802 }
803 }
804 }
805 AddRegionCharacterInstance(region_id, character) => {
806 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
807 let character = character.clone();
808
809 if let Some(region) = project.get_region_mut(region_id) {
810 region.characters.insert(character.id, character);
811
812 if let Some(region_node) = tree_layout.get_node_by_id_mut(®ion_id) {
813 gen_region_tree_items(region_node, region);
814 }
815 }
816 shared::rusterix_utils::insert_content_into_maps(project);
817 }
818 }
819 MoveRegionCharacterInstance(region_id, instance_id, _from, to) => {
820 move_region_character_pos(
821 project,
822 ui,
823 ctx,
824 server_ctx,
825 *region_id,
826 *instance_id,
827 *to,
828 );
829 }
830 RemoveRegionCharacterInstance(_, region_id, character) => {
831 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
832 if let Some(region_node) =
833 tree_layout.get_node_by_id_mut(&server_ctx.tree_regions_id)
834 {
835 region_node.remove_widget_by_uuid(&character.id);
836 }
837
838 if let Some(region) = project.get_region_mut(region_id) {
839 region.characters.shift_remove(&character.id);
840 region.map.entities.retain(|e| e.creator_id != character.id);
841 }
842
843 if let Some(region) = project.get_region(region_id) {
844 if let Some(region_node) = tree_layout.get_node_by_id_mut(®ion.id) {
845 region_node.set_open(true);
846 }
847 server_ctx.curr_region = region.id;
848 set_project_context(
849 ctx,
850 ui,
851 project,
852 server_ctx,
853 ProjectContext::Region(region.id),
854 );
855 update_region(ctx);
856 }
857 }
858 }
859 AddRegionItemInstance(region_id, item) => {
860 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
861 let item = item.clone();
862
863 if let Some(region) = project.get_region_mut(region_id) {
864 region.items.insert(item.id, item);
865
866 if let Some(region_node) = tree_layout.get_node_by_id_mut(®ion_id) {
867 gen_region_tree_items(region_node, region);
868 }
869 }
870 shared::rusterix_utils::insert_content_into_maps(project);
871 }
872 }
873 MoveRegionItemInstance(region_id, instance_id, _from, to) => {
874 move_region_item_pos(project, ui, ctx, server_ctx, *region_id, *instance_id, *to);
875 }
876 RemoveRegionItemInstance(_, region_id, item) => {
877 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
878 if let Some(region_node) =
879 tree_layout.get_node_by_id_mut(&server_ctx.tree_regions_id)
880 {
881 region_node.remove_widget_by_uuid(&item.id);
882 }
883
884 if let Some(region) = project.get_region_mut(region_id) {
885 region.items.shift_remove(&item.id);
886 region.map.items.retain(|e| e.creator_id != item.id);
887 }
888
889 if let Some(region) = project.get_region(region_id) {
890 if let Some(region_node) = tree_layout.get_node_by_id_mut(®ion.id) {
891 region_node.set_open(true);
892 }
893 server_ctx.curr_region = region.id;
894 set_project_context(
895 ctx,
896 ui,
897 project,
898 server_ctx,
899 ProjectContext::Region(region.id),
900 );
901 update_region(ctx);
902 }
903 }
904 }
905 AddCharacter(character) => {
906 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
907 if let Some(node) =
908 tree_layout.get_node_by_id_mut(&server_ctx.tree_characters_id)
909 {
910 let mut character = character.clone();
911
912 if let Some(bytes) = crate::Embedded::get("eldrin/character.eldrin") {
913 if let Ok(source) = std::str::from_utf8(bytes.data.as_ref()) {
914 character.source = source.to_string();
915 }
916 }
917
918 if let Some(bytes) = crate::Embedded::get("toml/character.toml") {
919 if let Ok(source) = std::str::from_utf8(bytes.data.as_ref()) {
920 character.data = source.to_string();
921 }
922 }
923
924 character
925 .module
926 .set_module_type(codegridfx::ModuleType::CharacterTemplate);
927
928 let mut character_node = gen_character_tree_node(&character);
929 character_node.set_open(true);
930 node.add_child(character_node);
931
932 let character_id = character.id;
933 project.add_character(character);
934
935 set_project_context(
936 ctx,
937 ui,
938 project,
939 server_ctx,
940 ProjectContext::Character(character_id),
941 );
942 update_region(ctx);
943 }
944 }
945 }
946 RemoveCharacter(_, character) => {
947 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
948 if let Some(character_node) =
949 tree_layout.get_node_by_id_mut(&server_ctx.tree_characters_id)
950 {
951 character_node.remove_child_by_uuid(&character.id);
952 }
953 project.remove_character(&character.id);
954
955 if let Some(character) = project.characters.first() {
956 if let Some(character_node) = tree_layout.get_node_by_id_mut(character.0) {
957 character_node.set_open(true);
958 }
959 set_project_context(
960 ctx,
961 ui,
962 project,
963 server_ctx,
964 ProjectContext::Character(*character.0),
965 );
966 }
967 }
968 }
969 RenameCharacter(id, _old, new) => {
970 if let Some(character) = project.characters.get_mut(id) {
971 character.name = new.clone();
972 character.map.name = new.clone();
973 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
974 if let Some(region_node) = tree_layout.get_node_by_id_mut(&character.id) {
975 region_node.widget.set_value(TheValue::Text(new.clone()));
976 if let Some(widget) = region_node.widgets[0].as_tree_item() {
977 if let Some(embedded) = widget.embedded_widget_mut() {
978 embedded.set_value(TheValue::Text(new.clone()));
979 }
980 }
981 }
982 }
983 }
984 }
985 AddItem(item) => {
986 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
987 if let Some(node) = tree_layout.get_node_by_id_mut(&server_ctx.tree_items_id) {
988 let mut item = item.clone();
989
990 if let Some(bytes) = crate::Embedded::get("eldrin/item.eldrin") {
991 if let Ok(source) = std::str::from_utf8(bytes.data.as_ref()) {
992 item.source = source.to_string();
993 }
994 }
995
996 if let Some(bytes) = crate::Embedded::get("toml/item.toml") {
997 if let Ok(source) = std::str::from_utf8(bytes.data.as_ref()) {
998 item.data = source.to_string();
999 }
1000 }
1001
1002 item.module
1003 .set_module_type(codegridfx::ModuleType::ItemTemplate);
1004
1005 let mut item_node = gen_item_tree_node(&item);
1006 item_node.set_open(true);
1007 node.add_child(item_node);
1008
1009 let item_id = item.id;
1010 project.add_item(item);
1011
1012 set_project_context(
1013 ctx,
1014 ui,
1015 project,
1016 server_ctx,
1017 ProjectContext::Character(item_id),
1018 );
1019 update_region(ctx);
1020 }
1021 }
1022 }
1023 RemoveItem(_, item) => {
1024 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1025 if let Some(character_node) =
1026 tree_layout.get_node_by_id_mut(&server_ctx.tree_items_id)
1027 {
1028 character_node.remove_child_by_uuid(&item.id);
1029 }
1030 project.remove_character(&item.id);
1031
1032 if let Some(item) = project.items.first() {
1033 if let Some(item_node) = tree_layout.get_node_by_id_mut(item.0) {
1034 item_node.set_open(true);
1035 }
1036 set_project_context(
1037 ctx,
1038 ui,
1039 project,
1040 server_ctx,
1041 ProjectContext::Item(*item.0),
1042 );
1043 }
1044 }
1045 }
1046 RenameItem(id, _old, new) => {
1047 if let Some(item) = project.items.get_mut(id) {
1048 item.name = new.clone();
1049 item.map.name = new.clone();
1050 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1051 if let Some(item_node) = tree_layout.get_node_by_id_mut(&item.id) {
1052 item_node.widget.set_value(TheValue::Text(new.clone()));
1053 if let Some(widget) = item_node.widgets[0].as_tree_item() {
1054 if let Some(embedded) = widget.embedded_widget_mut() {
1055 embedded.set_value(TheValue::Text(new.clone()));
1056 }
1057 }
1058 }
1059 }
1060 }
1061 }
1062 AddTilemap(tilemap) => {
1063 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1064 if let Some(node) = tree_layout.get_node_by_id_mut(&server_ctx.tree_tilemaps_id)
1065 {
1066 let tilemap = tilemap.clone();
1067
1068 let mut tilemap_node = gen_tilemap_tree_node(&tilemap);
1069 tilemap_node.set_open(true);
1070 node.add_child(tilemap_node);
1071
1072 let tilemap_id = tilemap.id;
1073 project.add_tilemap(tilemap);
1074
1075 set_project_context(
1076 ctx,
1077 ui,
1078 project,
1079 server_ctx,
1080 ProjectContext::Tilemap(tilemap_id),
1081 );
1082 update_region(ctx);
1083 }
1084 }
1085 }
1086 RemoveTilemap(_, tilemap) => {
1087 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1088 if let Some(tilemap_node) =
1089 tree_layout.get_node_by_id_mut(&server_ctx.tree_tilemaps_id)
1090 {
1091 tilemap_node.remove_child_by_uuid(&tilemap.id);
1092 }
1093 if let Some(index) = project.tilemaps.iter().position(|t| t.id == tilemap.id) {
1095 project.tilemaps.remove(index);
1096 }
1097
1098 if let Some(first_tilemap) = project.tilemaps.first() {
1099 if let Some(tilemap_node) =
1100 tree_layout.get_node_by_id_mut(&first_tilemap.id)
1101 {
1102 tilemap_node.set_open(true);
1103 }
1104 set_project_context(
1105 ctx,
1106 ui,
1107 project,
1108 server_ctx,
1109 ProjectContext::Tilemap(first_tilemap.id),
1110 );
1111 }
1112 }
1113 }
1114 RenameTilemap(id, _old, new) => {
1115 if let Some(tilemap) = project.get_tilemap_mut(*id) {
1116 tilemap.name = new.clone();
1117 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1118 if let Some(tilemap_node) = tree_layout.get_node_by_id_mut(id) {
1119 tilemap_node.widget.set_value(TheValue::Text(new.clone()));
1120 if let Some(widget) = tilemap_node.widgets[0].as_tree_item() {
1121 if let Some(embedded) = widget.embedded_widget_mut() {
1122 embedded.set_value(TheValue::Text(new.clone()));
1123 }
1124 }
1125 }
1126 }
1127 }
1128 }
1129 EditTilemapGridSize(id, _old, new) => {
1130 if let Some(tilemap) = project.get_tilemap_mut(*id) {
1131 tilemap.grid_size = *new;
1132 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1134 if let Some(node) = tree_layout.get_node_by_id_mut(id) {
1135 if let Some(widget) = node.widgets[1].as_tree_item() {
1136 if let Some(embedded) = widget.embedded_widget_mut() {
1137 embedded.set_value(TheValue::Int(*new));
1138
1139 ctx.ui.send(TheEvent::Custom(
1140 TheId::named("Tilemap Grid Size Changed"),
1141 TheValue::Int(*new),
1142 ));
1143 }
1144 }
1145 }
1146 }
1147 }
1148 }
1149 AddScreen(screen) => {
1150 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1151 if let Some(node) = tree_layout.get_node_by_id_mut(&server_ctx.tree_screens_id)
1152 {
1153 let screen = screen.clone();
1154
1155 let mut screen_node = gen_screen_tree_node(&screen);
1156 screen_node.set_open(true);
1157 node.add_child(screen_node);
1158
1159 let screen_id = screen.id;
1160 project.add_screen(screen);
1161
1162 set_project_context(
1163 ctx,
1164 ui,
1165 project,
1166 server_ctx,
1167 ProjectContext::Screen(screen_id),
1168 );
1169 update_region(ctx);
1170 }
1171 }
1172 }
1173 RemoveScreen(_, screen) => {
1174 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1175 if let Some(screen_node) =
1176 tree_layout.get_node_by_id_mut(&server_ctx.tree_screens_id)
1177 {
1178 screen_node.remove_child_by_uuid(&screen.id);
1179 }
1180 project.remove_screen(&screen.id);
1181
1182 if let Some(first_screen) = project.screens.first() {
1183 if let Some(screen_node) = tree_layout.get_node_by_id_mut(first_screen.0) {
1184 screen_node.set_open(true);
1185 }
1186 set_project_context(
1187 ctx,
1188 ui,
1189 project,
1190 server_ctx,
1191 ProjectContext::Screen(*first_screen.0),
1192 );
1193 }
1194 }
1195 }
1196 RenameScreen(id, _old, new) => {
1197 if let Some(screen) = project.screens.get_mut(id) {
1198 screen.name = new.clone();
1199 screen.map.name = new.clone();
1200 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1201 if let Some(screen_node) = tree_layout.get_node_by_id_mut(id) {
1202 screen_node.widget.set_value(TheValue::Text(new.clone()));
1203 if let Some(widget) = screen_node.widgets[0].as_tree_item() {
1204 if let Some(embedded) = widget.embedded_widget_mut() {
1205 embedded.set_value(TheValue::Text(new.clone()));
1206 }
1207 }
1208 }
1209 }
1210 }
1211 }
1212 AddAsset(asset) => {
1213 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1214 let parent_id = match &asset.buffer {
1215 AssetBuffer::Audio(_) => server_ctx.tree_assets_audio_id,
1216 _ => server_ctx.tree_assets_fonts_id,
1217 };
1218 if let Some(node) = tree_layout.get_node_by_id_mut(&parent_id) {
1219 let asset = asset.clone();
1220
1221 let mut asset_node = gen_asset_tree_node(&asset);
1222 asset_node.set_open(true);
1223 node.add_child(asset_node);
1224
1225 let asset_id = asset.id;
1226 project.add_asset(asset);
1227
1228 set_project_context(
1229 ctx,
1230 ui,
1231 project,
1232 server_ctx,
1233 ProjectContext::Asset(asset_id),
1234 );
1235 update_region(ctx);
1236 }
1237 }
1238 }
1239 RemoveAsset(_, asset) => {
1240 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1241 if let Some(asset_node) =
1242 tree_layout.get_node_by_id_mut(&server_ctx.tree_assets_fonts_id)
1243 {
1244 asset_node.remove_child_by_uuid(&asset.id);
1245 }
1246 if let Some(asset_node) =
1247 tree_layout.get_node_by_id_mut(&server_ctx.tree_assets_audio_id)
1248 {
1249 asset_node.remove_child_by_uuid(&asset.id);
1250 }
1251 project.remove_asset(&asset.id);
1252
1253 if let Some(first_asset) = project.assets.first() {
1254 if let Some(asset_node) = tree_layout.get_node_by_id_mut(first_asset.0) {
1255 asset_node.set_open(true);
1256 }
1257 set_project_context(
1258 ctx,
1259 ui,
1260 project,
1261 server_ctx,
1262 ProjectContext::Asset(*first_asset.0),
1263 );
1264 }
1265 }
1266 }
1267 RenameAsset(id, _old, new) => {
1268 if let Some(asset) = project.assets.get_mut(id) {
1269 asset.name = new.clone();
1270 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1271 if let Some(asset_node) = tree_layout.get_node_by_id_mut(id) {
1272 asset_node.widget.set_value(TheValue::Text(new.clone()));
1273 if let Some(widget) = asset_node.widgets[0].as_tree_item() {
1274 if let Some(embedded) = widget.embedded_widget_mut() {
1275 embedded.set_value(TheValue::Text(new.clone()));
1276 }
1277 }
1278 }
1279 }
1280 }
1281 }
1282 AddAvatar(avatar) => {
1283 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1284 if let Some(node) = tree_layout.get_node_by_id_mut(&server_ctx.tree_avatars_id)
1285 {
1286 let avatar = avatar.clone();
1287
1288 let mut avatar_node = gen_avatar_tree_node(&avatar);
1289 avatar_node.set_open(true);
1290 node.add_child(avatar_node);
1291
1292 let avatar_id = avatar.id;
1293 project.add_avatar(avatar);
1294
1295 set_project_context(
1296 ctx,
1297 ui,
1298 project,
1299 server_ctx,
1300 ProjectContext::Avatar(avatar_id),
1301 );
1302 update_region(ctx);
1303 }
1304 }
1305 }
1306 RemoveAvatar(_, avatar) => {
1307 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1308 if let Some(avatar_node) =
1309 tree_layout.get_node_by_id_mut(&server_ctx.tree_avatars_id)
1310 {
1311 avatar_node.remove_child_by_uuid(&avatar.id);
1312 }
1313 project.remove_avatar(&avatar.id);
1314
1315 if let Some(first_avatar) = project.avatars.first() {
1316 if let Some(avatar_node) = tree_layout.get_node_by_id_mut(first_avatar.0) {
1317 avatar_node.set_open(true);
1318 }
1319 set_project_context(
1320 ctx,
1321 ui,
1322 project,
1323 server_ctx,
1324 ProjectContext::Avatar(*first_avatar.0),
1325 );
1326 }
1327 }
1328 }
1329 RenameAvatar(id, _old, new) => {
1330 if let Some(avatar) = project.avatars.get_mut(id) {
1331 avatar.name = new.clone();
1332 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1333 if let Some(avatar_node) = tree_layout.get_node_by_id_mut(id) {
1334 avatar_node.widget.set_value(TheValue::Text(new.clone()));
1335 if let Some(widget) = avatar_node.widgets[0].as_tree_item() {
1336 if let Some(embedded) = widget.embedded_widget_mut() {
1337 embedded.set_value(TheValue::Text(new.clone()));
1338 }
1339 }
1340 }
1341 }
1342 }
1343 }
1344 EditAvatarResolution(id, _old, new) => {
1345 if let Some(avatar) = project.avatars.get_mut(id) {
1346 avatar.set_resolution(*new);
1347 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1348 if let Some(avatar_node) = tree_layout.get_node_by_id_mut(id) {
1349 if let Some(widget) = avatar_node.widgets[1].as_tree_item() {
1350 if let Some(embedded) = widget.embedded_widget_mut() {
1351 embedded.set_value(TheValue::Int(*new as i32));
1352 }
1353 }
1354 }
1355 }
1356 }
1357 }
1358 EditAvatarPerspectiveCount(id, _old, new) => {
1359 if let Some(avatar) = project.avatars.get_mut(id) {
1360 avatar.set_perspective_count(*new);
1361 }
1362 rebuild_avatar_tree_node(id, project, ui, server_ctx);
1363 }
1364 AddAvatarAnimation(avatar_id, anim) => {
1365 if let Some(avatar) = project.avatars.get_mut(avatar_id) {
1367 avatar.animations.push(anim.clone());
1368 rebuild_avatar_tree_node(avatar_id, project, ui, server_ctx);
1369 }
1370 }
1371 RemoveAvatarAnimation(avatar_id, _, anim) => {
1372 if let Some(avatar) = project.avatars.get_mut(avatar_id) {
1374 avatar.animations.retain(|a| a.id != anim.id);
1375 rebuild_avatar_tree_node(avatar_id, project, ui, server_ctx);
1376 }
1377 }
1378 RenameAvatarAnimation(_avatar_id, anim_id, _old, new) => {
1379 if let Some(avatar) = project
1380 .avatars
1381 .values_mut()
1382 .find(|a| a.animations.iter().any(|anim| anim.id == *anim_id))
1383 {
1384 if let Some(anim) = avatar.animations.iter_mut().find(|a| a.id == *anim_id) {
1385 anim.name = new.clone();
1386 }
1387 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
1388 if let Some(anim_node) = tree_layout.get_node_by_id_mut(anim_id) {
1389 let label = format!("{} - Animation", new);
1390 anim_node.widget.set_value(TheValue::Text(label));
1391 if let Some(widget) = anim_node.widgets[0].as_tree_item() {
1392 if let Some(embedded) = widget.embedded_widget_mut() {
1393 embedded.set_value(TheValue::Text(new.clone()));
1394 }
1395 }
1396 }
1397 }
1398 }
1399 }
1400 EditAvatarAnimationFrameCount(avatar_id, anim_id, _old, new) => {
1401 if let Some(avatar) = project.avatars.get_mut(avatar_id) {
1402 avatar.set_animation_frame_count(anim_id, *new);
1403 }
1404 rebuild_animation_tree_node(avatar_id, anim_id, project, ui, server_ctx);
1405 }
1406 EditAvatarAnimationSpeed(avatar_id, anim_id, _old, new) => {
1407 if let Some(avatar) = project.avatars.get_mut(avatar_id) {
1408 if let Some(anim) = avatar.animations.iter_mut().find(|a| a.id == *anim_id) {
1409 anim.speed = *new;
1410 }
1411 }
1412 rebuild_animation_tree_node(avatar_id, anim_id, project, ui, server_ctx);
1413 }
1414 PaletteEdit(_old, new) => {
1415 let sel = project.palette.current_index;
1416 project.palette = new.clone();
1417 project.palette.current_index = sel;
1418 apply_palette(ui, ctx, server_ctx, project);
1419 }
1420 TileEdit(_old, new) => {
1421 project.tiles.insert(new.id, new.clone());
1422 ctx.ui.send(TheEvent::Custom(
1423 TheId::named("Update Tiles"),
1424 TheValue::Empty,
1425 ));
1426 }
1427 }
1428 }
1429}
1430
1431fn move_region_character_pos(
1432 project: &mut Project,
1433 ui: &mut TheUI,
1434 ctx: &mut TheContext,
1435 server_ctx: &mut ServerContext,
1436 region_id: Uuid,
1437 instance_id: Uuid,
1438 pos: Vec3<f32>,
1439) {
1440 set_project_context(
1441 ctx,
1442 ui,
1443 project,
1444 server_ctx,
1445 ProjectContext::Region(region_id),
1446 );
1447
1448 if let Some(region) = project.get_region_mut(®ion_id) {
1449 if let Some(instance) = region.characters.get_mut(&instance_id) {
1450 instance.position = pos;
1451 }
1452 for entity in region.map.entities.iter_mut() {
1453 if entity.creator_id == instance_id {
1454 entity.position = pos;
1455 }
1456 }
1457 }
1458
1459 if let Some(map) = project.get_map_mut(server_ctx) {
1460 for entity in map.entities.iter_mut() {
1461 if entity.creator_id == instance_id {
1462 entity.position = pos;
1463 }
1464 }
1465 }
1466}
1467
1468fn move_region_item_pos(
1469 project: &mut Project,
1470 ui: &mut TheUI,
1471 ctx: &mut TheContext,
1472 server_ctx: &mut ServerContext,
1473 region_id: Uuid,
1474 instance_id: Uuid,
1475 pos: Vec3<f32>,
1476) {
1477 set_project_context(
1478 ctx,
1479 ui,
1480 project,
1481 server_ctx,
1482 ProjectContext::Region(region_id),
1483 );
1484
1485 if let Some(region) = project.get_region_mut(®ion_id) {
1486 if let Some(instance) = region.items.get_mut(&instance_id) {
1487 instance.position = pos;
1488 }
1489 for item in region.map.items.iter_mut() {
1490 if item.creator_id == instance_id {
1491 item.position = pos;
1492 }
1493 }
1494 }
1495
1496 if let Some(map) = project.get_map_mut(server_ctx) {
1497 for item in map.items.iter_mut() {
1498 if item.creator_id == instance_id {
1499 item.position = pos;
1500 }
1501 }
1502 }
1503}