1use crate::editor::{DOCKMANAGER, RUSTERIX};
2use crate::prelude::*;
3use theframework::prelude::*;
4
5fn data_attr_bool(data: &str, key: &str) -> bool {
6 let Ok(value) = data.parse::<toml::Value>() else {
7 return false;
8 };
9
10 let attrs = value
11 .get("attributes")
12 .and_then(|v| v.as_table())
13 .or_else(|| value.as_table());
14
15 let Some(attrs) = attrs else {
16 return false;
17 };
18
19 match attrs.get(key) {
20 Some(toml::Value::Boolean(b)) => *b,
21 Some(toml::Value::Integer(i)) => *i != 0,
22 Some(toml::Value::String(s)) => {
23 let s = s.trim().to_ascii_lowercase();
24 s == "true" || s == "1" || s == "yes"
25 }
26 _ => false,
27 }
28}
29
30pub fn gen_region_tree_node(region: &Region) -> TheTreeNode {
32 let mut node: TheTreeNode = TheTreeNode::new(TheId::named_with_id(®ion.name, region.id));
33 node.set_root_mode(false);
34
35 gen_region_tree_items(&mut node, region);
36
37 node
38}
39
40pub fn gen_region_tree_items(node: &mut TheTreeNode, region: &Region) {
42 node.widgets = vec![];
43
44 let mut item = TheTreeItem::new(TheId::named_with_reference("Region Item", region.id));
46 item.set_text(fl!("name"));
47
48 let name = format!("Region Item Name Edit: {}", region.name);
49 let mut edit = TheTextLineEdit::new(TheId::named_with_id(&name, region.id));
50 edit.set_text(region.name.clone());
51 item.add_widget_column(200, Box::new(edit));
52 node.add_widget(Box::new(item));
53
54 let mut item = TheTreeItem::new(TheId::named_with_reference(
56 "Region Settings Item",
57 region.id,
58 ));
59 item.set_text(fl!("settings"));
60 node.add_widget(Box::new(item));
61
62 for (id, character) in ®ion.characters {
63 let mut item = TheTreeItem::new(TheId::named_with_id("Region Content List Item", *id));
64 item.add_value_column(200, TheValue::Text(fl!("character_instance")));
65 item.set_background_color(TheColor::from(ActionRole::Dock.to_color()));
66 item.set_text(character.name.clone());
67 node.add_widget(Box::new(item));
68 }
69
70 for (id, item_) in ®ion.items {
71 let mut item = TheTreeItem::new(TheId::named_with_id("Region Content List Item", *id));
72 item.add_value_column(200, TheValue::Text(fl!("item_instance")));
73 item.set_background_color(TheColor::from(ActionRole::Editor.to_color()));
74 item.set_text(item_.name.clone());
75 node.add_widget(Box::new(item));
76 }
77}
78
79pub fn gen_character_tree_node(character: &Character) -> TheTreeNode {
81 let mut node: TheTreeNode =
82 TheTreeNode::new(TheId::named_with_id(&character.name, character.id));
83 node.set_root_mode(false);
84 if data_attr_bool(&character.data, "player") {
85 node.set_background_color(ActionRole::Camera.to_color());
86 }
87
88 let mut item = TheTreeItem::new(TheId::named_with_reference("Character Item", character.id));
89 item.set_text(fl!("name"));
90
91 let mut edit = TheTextLineEdit::new(TheId::named_with_id(
92 "Character Item Name Edit",
93 character.id,
94 ));
95 edit.set_text(character.name.clone());
96 item.add_widget_column(200, Box::new(edit));
97
98 node.add_widget(Box::new(item));
99
100 let mut item = TheTreeItem::new(TheId::named_with_reference(
101 "Character Item Visual Code Edit",
102 character.id,
103 ));
104 item.set_background_color(TheColor::from(ActionRole::Dock.to_color()));
105 item.set_text(fl!("visual_script"));
106 node.add_widget(Box::new(item));
107
108 let mut item = TheTreeItem::new(TheId::named_with_reference(
109 "Character Item Code Edit",
110 character.id,
111 ));
112 item.set_background_color(TheColor::from(ActionRole::Dock.to_color()));
113 item.set_text(fl!("eldrin_scripting"));
114 node.add_widget(Box::new(item));
115
116 let mut item = TheTreeItem::new(TheId::named_with_reference(
117 "Character Item Data Edit",
118 character.id,
119 ));
120 item.set_background_color(TheColor::from(ActionRole::Dock.to_color()));
121 item.set_text(fl!("attributes"));
122 node.add_widget(Box::new(item));
123
124 let mut item = TheTreeItem::new(TheId::named_with_reference(
125 "Character Item Preview Rigging Edit",
126 character.id,
127 ));
128 item.set_background_color(TheColor::from(ActionRole::Dock.to_color()));
129 item.set_text(fl!("preview_rigging"));
130 node.add_widget(Box::new(item));
131
132 node
133}
134
135pub fn gen_item_tree_node(item_: &Item) -> TheTreeNode {
137 let mut node: TheTreeNode = TheTreeNode::new(TheId::named_with_id(&item_.name, item_.id));
138 node.set_root_mode(false);
139 if data_attr_bool(&item_.data, "is_spell") {
140 node.set_background_color(ActionRole::Editor.to_color());
141 }
142
143 let mut item = TheTreeItem::new(TheId::named_with_reference("Item Item", item_.id));
144 item.set_text(fl!("name"));
145
146 let mut edit = TheTextLineEdit::new(TheId::named_with_id("Item Item Name Edit", item_.id));
147 edit.set_text(item_.name.clone());
148 item.add_widget_column(200, Box::new(edit));
149
150 node.add_widget(Box::new(item));
151
152 let mut item = TheTreeItem::new(TheId::named_with_reference(
153 "Item Item Visual Code Edit",
154 item_.id,
155 ));
156 item.set_background_color(TheColor::from(ActionRole::Dock.to_color()));
157 item.set_text(fl!("visual_script"));
158 node.add_widget(Box::new(item));
159
160 let mut item = TheTreeItem::new(TheId::named_with_reference("Item Item Code Edit", item_.id));
161 item.set_background_color(TheColor::from(ActionRole::Dock.to_color()));
162 item.set_text(fl!("eldrin_scripting"));
163 node.add_widget(Box::new(item));
164
165 let mut item = TheTreeItem::new(TheId::named_with_reference("Item Item Data Edit", item_.id));
166 item.set_background_color(TheColor::from(ActionRole::Dock.to_color()));
167 item.set_text(fl!("attributes"));
168 node.add_widget(Box::new(item));
169
170 node
171}
172
173pub fn rebuild_avatar_tree_node(
175 avatar_id: &Uuid,
176 project: &Project,
177 ui: &mut TheUI,
178 server_ctx: &ServerContext,
179) {
180 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
181 if let Some(avatars_node) = tree_layout.get_node_by_id_mut(&server_ctx.tree_avatars_id) {
182 let index = avatars_node
183 .childs
184 .iter()
185 .position(|child| child.id.uuid == *avatar_id);
186 avatars_node.remove_child_by_uuid(avatar_id);
187
188 if let Some(avatar) = project.avatars.get(avatar_id) {
189 let mut node = gen_avatar_tree_node(avatar);
190 node.set_open(true);
191 if let Some(idx) = index {
192 avatars_node.add_child_at(idx, node);
193 } else {
194 avatars_node.add_child(node);
195 }
196 }
197 }
198 }
199}
200
201pub fn rebuild_animation_tree_node(
203 avatar_id: &Uuid,
204 anim_id: &Uuid,
205 project: &Project,
206 ui: &mut TheUI,
207 server_ctx: &ServerContext,
208) {
209 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
210 if let Some(avatars_node) = tree_layout.get_node_by_id_mut(&server_ctx.tree_avatars_id) {
211 if let Some(avatar_node) = avatars_node
212 .childs
213 .iter_mut()
214 .find(|c| c.id.uuid == *avatar_id)
215 {
216 let index = avatar_node
217 .childs
218 .iter()
219 .position(|child| child.id.uuid == *anim_id);
220 avatar_node.remove_child_by_uuid(anim_id);
221
222 if let Some(avatar) = project.avatars.get(avatar_id) {
223 if let Some(anim) = avatar.animations.iter().find(|a| a.id == *anim_id) {
224 let mut anim_node = gen_avatar_animation_node(anim);
225 anim_node.set_open(true);
226 if let Some(idx) = index {
227 avatar_node.add_child_at(idx, anim_node);
228 } else {
229 avatar_node.add_child(anim_node);
230 }
231 }
232 }
233 }
234 }
235 }
236}
237
238pub fn gen_avatar_tree_node(avatar: &Avatar) -> TheTreeNode {
240 let mut node: TheTreeNode = TheTreeNode::new(TheId::named_with_id(&avatar.name, avatar.id));
241 node.set_root_mode(false);
242
243 let mut item = TheTreeItem::new(TheId::named_with_reference("Avatar Item", avatar.id));
244 item.set_text(fl!("name"));
245
246 let mut edit = TheTextLineEdit::new(TheId::named_with_id("Avatar Item Name Edit", avatar.id));
247 edit.set_text(avatar.name.clone());
248 item.add_widget_column(200, Box::new(edit));
249
250 node.add_widget(Box::new(item));
251
252 let mut item = TheTreeItem::new(TheId::named_with_reference(
253 "Avatar Item Resolution",
254 avatar.id,
255 ));
256 item.set_text("Resolution".to_string());
257
258 let mut edit = TheTextLineEdit::new(TheId::named_with_reference(
259 "Avatar Item Resolution Edit",
260 avatar.id,
261 ));
262 edit.set_value(TheValue::Int(avatar.resolution as i32));
263 item.add_widget_column(200, Box::new(edit));
264
265 node.add_widget(Box::new(item));
266
267 let mut item = TheTreeItem::new(TheId::named_with_reference(
268 "Avatar Perspectives",
269 avatar.id,
270 ));
271 item.set_text("Perspectives".to_string());
272
273 let mut drop_down = TheDropdownMenu::new(TheId::named_with_reference(
274 "Avatar Perspective Count",
275 avatar.id,
276 ));
277 drop_down.add_option("1".to_string());
278 drop_down.add_option("4".to_string());
279 drop_down.set_selected_index(match avatar.perspective_count {
280 AvatarPerspectiveCount::One => 0,
281 AvatarPerspectiveCount::Four => 1,
282 });
283 item.add_widget_column(200, Box::new(drop_down));
284
285 node.add_widget(Box::new(item));
286
287 let mut item = TheTreeItem::new(TheId::named_with_reference("Avatar Animations", avatar.id));
288 item.set_text("Animations".to_string());
289
290 let mut add_button = TheTraybarButton::new(TheId::named_with_reference(
291 "Avatar Add Animation",
292 avatar.id,
293 ));
294 add_button.set_text("Add".to_string());
295 item.add_widget_column(200, Box::new(add_button));
296
297 node.add_widget(Box::new(item));
298
299 for animation in &avatar.animations {
301 let anim_node = gen_avatar_animation_node(animation);
302 node.add_child(anim_node);
303 }
304
305 node
306}
307
308pub fn gen_avatar_animation_node(animation: &AvatarAnimation) -> TheTreeNode {
310 let label = format!("{} - Animation", animation.name);
311 let mut node = TheTreeNode::new(TheId::named_with_id(&label, animation.id));
312 node.set_root_mode(false);
313
314 let mut item = TheTreeItem::new(TheId::named_with_reference(
316 "Avatar Animation Item",
317 animation.id,
318 ));
319 item.set_text(fl!("name"));
320
321 let mut edit = TheTextLineEdit::new(TheId::named_with_reference(
322 "Avatar Animation Name Edit",
323 animation.id,
324 ));
325 edit.set_text(animation.name.clone());
326 item.add_widget_column(200, Box::new(edit));
327 node.add_widget(Box::new(item));
328
329 let mut item = TheTreeItem::new(TheId::named_with_reference(
331 "Avatar Animation Frames",
332 animation.id,
333 ));
334 item.set_text("Frames".to_string());
335
336 let frame_count = if let Some(p) = animation.perspectives.first() {
337 p.frames.len() as i32
338 } else {
339 0
340 };
341 let mut edit = TheTextLineEdit::new(TheId::named_with_reference(
342 "Avatar Animation Frame Count Edit",
343 animation.id,
344 ));
345 edit.set_value(TheValue::Int(frame_count));
346 item.add_widget_column(200, Box::new(edit));
347 node.add_widget(Box::new(item));
348
349 let mut item = TheTreeItem::new(TheId::named_with_reference(
351 "Avatar Animation Speed",
352 animation.id,
353 ));
354 item.set_text("Speed".to_string());
355
356 let mut edit = TheTextLineEdit::new(TheId::named_with_reference(
357 "Avatar Animation Speed Edit",
358 animation.id,
359 ));
360 edit.set_value(TheValue::Float(animation.speed));
361 item.add_widget_column(200, Box::new(edit));
362 node.add_widget(Box::new(item));
363
364 for (persp_index, perspective) in animation.perspectives.iter().enumerate() {
366 let dir_name = match perspective.direction {
367 AvatarDirection::Front => "Front",
368 AvatarDirection::Back => "Back",
369 AvatarDirection::Left => "Left",
370 AvatarDirection::Right => "Right",
371 };
372
373 let mut persp_node = TheTreeNode::new(TheId::named(dir_name));
374 persp_node.set_root_mode(false);
375 persp_node.set_open(true);
376
377 let mut icons = TheTreeIcons::new(TheId::named_with_reference(
378 &format!("Avatar Perspective Icons {}", persp_index),
379 animation.id,
380 ));
381 icons.set_icon_size(24);
382 icons.set_icons_per_row(10);
383 icons.set_icon_count(perspective.frames.len());
384 for (i, frame) in perspective.frames.iter().enumerate() {
385 icons.set_icon(i, frame.texture.to_rgba());
386 }
387 icons.set_selected_index(None);
388 persp_node.add_widget(Box::new(icons));
389
390 node.add_child(persp_node);
391 }
392
393 node
394}
395
396pub fn gen_tilemap_tree_node(tilemap: &Tilemap) -> TheTreeNode {
398 let mut node: TheTreeNode = TheTreeNode::new(TheId::named_with_id(&tilemap.name, tilemap.id));
399 node.set_root_mode(false);
400
401 let mut item = TheTreeItem::new(TheId::named_with_reference("Tileset Item", tilemap.id));
402 item.set_text(fl!("name"));
403
404 let mut edit = TheTextLineEdit::new(TheId::named_with_id("Tilemap Item Name Edit", tilemap.id));
405 edit.set_text(tilemap.name.clone());
406 item.add_widget_column(200, Box::new(edit));
407
408 node.add_widget(Box::new(item));
409
410 let mut item = TheTreeItem::new(TheId::named_with_reference(
411 "Tilemap Item Code Edit",
412 tilemap.id,
413 ));
414 item.set_text(fl!("grid_size"));
415
416 let mut edit = TheTextLineEdit::new(TheId::named_with_reference(
417 "Tilemap Item Grid Edit",
418 tilemap.id,
419 ));
420 edit.set_value(TheValue::Int(tilemap.grid_size));
421 item.add_widget_column(200, Box::new(edit));
422
423 node.add_widget(Box::new(item));
424
425 node
426}
427
428pub fn gen_screen_tree_node(screen: &Screen) -> TheTreeNode {
430 let mut node: TheTreeNode = TheTreeNode::new(TheId::named_with_id(&screen.name, screen.id));
431 node.set_root_mode(false);
432
433 gen_screen_tree_items(&mut node, screen);
434
435 node
436}
437
438pub fn gen_screen_tree_items(node: &mut TheTreeNode, screen: &Screen) {
440 node.widgets = vec![];
441
442 let mut item = TheTreeItem::new(TheId::named_with_reference("Screen Item", screen.id));
443 item.set_text(fl!("name"));
444
445 let mut edit = TheTextLineEdit::new(TheId::named_with_id("Screen Item Name Edit", screen.id));
446 edit.set_text(screen.name.clone());
447 item.add_widget_column(200, Box::new(edit));
448
449 node.add_widget(Box::new(item));
450
451 for sector in &screen.map.sectors {
452 if !sector.name.is_empty() {
453 let mut item = TheTreeItem::new(TheId::named_with_id_and_reference(
454 "Screen Content List Item",
455 sector.creator_id,
456 screen.id,
457 ));
458 item.add_value_column(200, TheValue::Text("Widget".to_string()));
459 item.set_background_color(TheColor::from(ActionRole::Dock.to_color()));
460 item.set_text(sector.name.clone());
461 node.add_widget(Box::new(item));
462 }
463 }
464}
465
466pub fn gen_asset_tree_node(asset: &Asset) -> TheTreeNode {
468 let mut node: TheTreeNode = TheTreeNode::new(TheId::named_with_id(&asset.name, asset.id));
469 node.set_root_mode(false);
470
471 let mut item = TheTreeItem::new(TheId::named_with_reference("Asset Item", asset.id));
472 item.set_text(fl!("name"));
473
474 let mut edit = TheTextLineEdit::new(TheId::named_with_id("Asset Item Name Edit", asset.id));
475 edit.set_text(asset.name.clone());
476 item.add_widget_column(200, Box::new(edit));
477
478 node.add_widget(Box::new(item));
479
480 node
481}
482
483pub fn update_region(ctx: &mut TheContext) {
485 ctx.ui.send(TheEvent::Custom(
486 TheId::named("Update Minimap"),
487 TheValue::Empty,
488 ));
489
490 RUSTERIX.write().unwrap().set_dirty();
491
492 ctx.ui.send(TheEvent::Custom(
493 TheId::named("Render SceneManager Map"),
494 TheValue::Empty,
495 ));
496}
497
498pub fn apply_palette(
500 ui: &mut TheUI,
501 _ctx: &mut TheContext,
502 server_ctx: &mut ServerContext,
503 project: &mut Project,
504) {
505 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
506 if let Some(palette_node) = tree_layout.get_node_by_id_mut(&server_ctx.tree_palette_id) {
507 palette_node.widgets.clear();
508 palette_node.childs.clear();
509
510 let mut item = TheTreeIcons::new(TheId::named("Palette Item"));
511 item.set_icon_count(256);
512 item.set_icons_per_row(17);
513 item.set_palette(&project.palette);
514 item.set_selected_index(Some(project.palette.current_index as usize));
515
516 palette_node.add_widget(Box::new(item));
517 }
518 }
519}
520
521pub fn set_project_context(
523 ctx: &mut TheContext,
524 ui: &mut TheUI,
525 project: &Project,
526 server_ctx: &mut ServerContext,
527 pc: ProjectContext,
528) {
529 let mut old_project_id = None;
531 if let Some(old_id) = server_ctx.pc.id() {
532 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
533 if let Some(node) = tree_layout.get_node_by_id_mut(&old_id) {
534 if let Some(snapper) = node.widget.as_any().downcast_mut::<TheSnapperbar>() {
535 snapper.set_selected(false);
536 }
537 }
538 }
539 old_project_id = Some(old_id);
540 }
541
542 server_ctx.pc = pc;
543
544 let duplicate_allowed = matches!(
545 pc,
546 ProjectContext::Region(_)
547 | ProjectContext::RegionSettings(_)
548 | ProjectContext::RegionCharacterInstance(_, _)
549 | ProjectContext::RegionItemInstance(_, _)
550 | ProjectContext::Character(_)
551 | ProjectContext::CharacterVisualCode(_)
552 | ProjectContext::CharacterCode(_)
553 | ProjectContext::CharacterData(_)
554 | ProjectContext::CharacterPreviewRigging(_)
555 | ProjectContext::Item(_)
556 | ProjectContext::ItemVisualCode(_)
557 | ProjectContext::ItemCode(_)
558 | ProjectContext::ItemData(_)
559 | ProjectContext::Screen(_)
560 | ProjectContext::ScreenWidget(_, _)
561 | ProjectContext::Avatar(_)
562 | ProjectContext::AvatarAnimation(_, _, _)
563 );
564 ui.set_widget_disabled_state("Project Duplicate", ctx, !duplicate_allowed);
565
566 match pc {
567 ProjectContext::Region(id) => {
568 if let Some(region) = project.get_region(&id) {
569 server_ctx.curr_region = id;
570 ui.set_widget_value(
571 "Project Context",
572 ctx,
573 TheValue::Text(format!("{}: {}", fl!("region"), region.name)),
574 );
575 }
576 DOCKMANAGER
577 .write()
578 .unwrap()
579 .set_dock("Tiles".into(), ui, ctx, project, server_ctx);
580 }
581 ProjectContext::RegionSettings(id) => {
582 if let Some(region) = project.get_region(&id) {
583 server_ctx.curr_region = id;
584 ui.set_widget_value(
585 "Project Context",
586 ctx,
587 TheValue::Text(format!("Region Settings: {}", region.name)),
588 );
589 }
590 DOCKMANAGER
591 .write()
592 .unwrap()
593 .set_dock("Data".into(), ui, ctx, project, server_ctx);
594 }
595 ProjectContext::RegionCharacterInstance(id, _) => {
596 if let Some(region) = project.get_region(&id) {
597 server_ctx.curr_region = id;
598 ui.set_widget_value(
599 "Project Context",
600 ctx,
601 TheValue::Text(format!("Region ({}) Character", region.name)),
602 );
603 }
604 DOCKMANAGER.write().unwrap().set_dock(
605 "Visual Code".into(),
606 ui,
607 ctx,
608 project,
609 server_ctx,
610 );
611 }
612 ProjectContext::RegionItemInstance(id, _) => {
613 if let Some(region) = project.get_region(&id) {
614 server_ctx.curr_region = id;
615 ui.set_widget_value(
616 "Project Context",
617 ctx,
618 TheValue::Text(format!("Region ({}) Item", region.name)),
619 );
620 }
621 DOCKMANAGER
622 .write()
623 .unwrap()
624 .set_dock("Tiles".into(), ui, ctx, project, server_ctx);
625 }
626 ProjectContext::Character(id) => {
627 if let Some(region) = project.characters.get(&id) {
628 ui.set_widget_value(
629 "Project Context",
630 ctx,
631 TheValue::Text(format!("Character: {}", region.name)),
632 );
633 }
634 DOCKMANAGER
635 .write()
636 .unwrap()
637 .set_dock("Tiles".into(), ui, ctx, project, server_ctx);
638 }
639 ProjectContext::CharacterVisualCode(id) => {
640 if let Some(region) = project.characters.get(&id) {
641 ui.set_widget_value(
642 "Project Context",
643 ctx,
644 TheValue::Text(format!("Character: {}", region.name)),
645 );
646 }
647 DOCKMANAGER.write().unwrap().set_dock(
648 "Visual Code".into(),
649 ui,
650 ctx,
651 project,
652 server_ctx,
653 );
654 }
655 ProjectContext::CharacterCode(id) => {
656 if let Some(region) = project.characters.get(&id) {
657 ui.set_widget_value(
658 "Project Context",
659 ctx,
660 TheValue::Text(format!("Character: {}", region.name)),
661 );
662 }
663 DOCKMANAGER
664 .write()
665 .unwrap()
666 .set_dock("Code".into(), ui, ctx, project, server_ctx);
667 }
668 ProjectContext::CharacterData(id) => {
669 if let Some(region) = project.characters.get(&id) {
670 ui.set_widget_value(
671 "Project Context",
672 ctx,
673 TheValue::Text(format!("Character: {}", region.name)),
674 );
675 }
676 DOCKMANAGER
677 .write()
678 .unwrap()
679 .set_dock("Data".into(), ui, ctx, project, server_ctx);
680 }
681 ProjectContext::CharacterPreviewRigging(id) => {
682 if let Some(region) = project.characters.get(&id) {
683 ui.set_widget_value(
684 "Project Context",
685 ctx,
686 TheValue::Text(format!("Character Preview Rigging: {}", region.name)),
687 );
688 }
689 DOCKMANAGER
690 .write()
691 .unwrap()
692 .set_dock("Data".into(), ui, ctx, project, server_ctx);
693 }
694 ProjectContext::Item(id) => {
695 if let Some(item) = project.items.get(&id) {
696 ui.set_widget_value(
697 "Project Context",
698 ctx,
699 TheValue::Text(format!("Item: {}", item.name)),
700 );
701 }
702 DOCKMANAGER
703 .write()
704 .unwrap()
705 .set_dock("Tiles".into(), ui, ctx, project, server_ctx);
706 }
707 ProjectContext::ItemVisualCode(id) => {
708 if let Some(item) = project.items.get(&id) {
709 ui.set_widget_value(
710 "Project Context",
711 ctx,
712 TheValue::Text(format!("Item: {}", item.name)),
713 );
714 }
715 DOCKMANAGER.write().unwrap().set_dock(
716 "Visual Code".into(),
717 ui,
718 ctx,
719 project,
720 server_ctx,
721 );
722 }
723 ProjectContext::ItemCode(id) => {
724 if let Some(item) = project.items.get(&id) {
725 ui.set_widget_value(
726 "Project Context",
727 ctx,
728 TheValue::Text(format!("Item: {}", item.name)),
729 );
730 }
731 DOCKMANAGER
732 .write()
733 .unwrap()
734 .set_dock("Code".into(), ui, ctx, project, server_ctx);
735 }
736 ProjectContext::ItemData(id) => {
737 if let Some(item) = project.items.get(&id) {
738 ui.set_widget_value(
739 "Project Context",
740 ctx,
741 TheValue::Text(format!("Item: {}", item.name)),
742 );
743 }
744 DOCKMANAGER
745 .write()
746 .unwrap()
747 .set_dock("Data".into(), ui, ctx, project, server_ctx);
748 }
749 ProjectContext::Tilemap(id) => {
750 if let Some(tilemap) = project.get_tilemap(id) {
751 ui.set_widget_value(
752 "Project Context",
753 ctx,
754 TheValue::Text(format!("Tilemap: {}", tilemap.name)),
755 );
756 }
757 DOCKMANAGER
758 .write()
759 .unwrap()
760 .set_dock("Tilemap".into(), ui, ctx, project, server_ctx);
761 }
762 ProjectContext::Screen(id) => {
763 server_ctx.editor_view_mode = EditorViewMode::D2;
765 ui.set_widget_value("Editor View Switch", ctx, TheValue::Int(0));
766 if let Some(screen) = project.screens.get(&id) {
767 ui.set_widget_value(
768 "Project Context",
769 ctx,
770 TheValue::Text(format!("Screen: {}", screen.name)),
771 );
772 }
773 DOCKMANAGER
774 .write()
775 .unwrap()
776 .set_dock("Tiles".into(), ui, ctx, project, server_ctx);
777 }
778 ProjectContext::ScreenWidget(id, _widget_id) => {
779 server_ctx.editor_view_mode = EditorViewMode::D2;
781 ui.set_widget_value("Editor View Switch", ctx, TheValue::Int(0));
782 if let Some(screen) = project.screens.get(&id) {
783 ui.set_widget_value(
784 "Project Context",
785 ctx,
786 TheValue::Text(format!("Screen ({}) Widget", screen.name,)),
787 );
788 }
789 DOCKMANAGER
790 .write()
791 .unwrap()
792 .set_dock("Data".into(), ui, ctx, project, server_ctx);
793 }
794 ProjectContext::Asset(id) => {
795 if let Some(asset) = project.assets.get(&id) {
796 ui.set_widget_value(
797 "Project Context",
798 ctx,
799 TheValue::Text(format!("Asset: {}", asset.name)),
800 );
801 }
802 DOCKMANAGER
803 .write()
804 .unwrap()
805 .set_dock("Tiles".into(), ui, ctx, project, server_ctx);
806 }
807 ProjectContext::Avatar(id) => {
808 if let Some(avatar) = project.avatars.get(&id) {
809 ui.set_widget_value(
810 "Project Context",
811 ctx,
812 TheValue::Text(format!("Avatar: {}", avatar.name)),
813 );
814 }
815 DOCKMANAGER
816 .write()
817 .unwrap()
818 .set_dock("Tiles".into(), ui, ctx, project, server_ctx);
819 }
820 ProjectContext::AvatarAnimation(avatar_id, anim_id, frame) => {
821 if let Some(avatar) = project.avatars.get(&avatar_id) {
822 if let Some(anim) = avatar.animations.iter().find(|a| a.id == anim_id) {
823 ui.set_widget_value(
824 "Project Context",
825 ctx,
826 TheValue::Text(format!(
827 "{} - {} (Frame {})",
828 avatar.name, anim.name, frame
829 )),
830 );
831 }
832 }
833 DOCKMANAGER
834 .write()
835 .unwrap()
836 .set_dock("Tiles".into(), ui, ctx, project, server_ctx);
837 }
838 ProjectContext::ProjectSettings => {
839 ui.set_widget_value(
840 "Project Context",
841 ctx,
842 TheValue::Text("Project Settings".into()),
843 );
844 DOCKMANAGER
845 .write()
846 .unwrap()
847 .set_dock("Data".into(), ui, ctx, project, server_ctx);
848 }
849 ProjectContext::GameRules => {
850 ui.set_widget_value("Project Context", ctx, TheValue::Text("Game Rules".into()));
851 DOCKMANAGER
852 .write()
853 .unwrap()
854 .set_dock("Data".into(), ui, ctx, project, server_ctx);
855 }
856 ProjectContext::GameLocales => {
857 ui.set_widget_value(
858 "Project Context",
859 ctx,
860 TheValue::Text("Game Locales".into()),
861 );
862 DOCKMANAGER
863 .write()
864 .unwrap()
865 .set_dock("Data".into(), ui, ctx, project, server_ctx);
866 }
867 ProjectContext::GameAudioFx => {
868 ui.set_widget_value(
869 "Project Context",
870 ctx,
871 TheValue::Text("Game Audio FX".into()),
872 );
873 DOCKMANAGER
874 .write()
875 .unwrap()
876 .set_dock("Data".into(), ui, ctx, project, server_ctx);
877 }
878 ProjectContext::DebugLog => {
879 DOCKMANAGER
881 .write()
882 .unwrap()
883 .set_dock("Log".into(), ui, ctx, project, server_ctx);
884 }
885 ProjectContext::Console => {
886 ui.set_widget_value("Project Context", ctx, TheValue::Text("Console".into()));
887 DOCKMANAGER
888 .write()
889 .unwrap()
890 .set_dock("Console".into(), ui, ctx, project, server_ctx);
891 }
892 _ => {}
893 }
894
895 if pc.is_region() {
897 if old_project_id != pc.id() {
898 ctx.ui.send(TheEvent::Custom(
899 TheId::named("Update Minimap"),
900 TheValue::Empty,
901 ));
902
903 RUSTERIX.write().unwrap().set_dirty();
904
905 ctx.ui.send(TheEvent::Custom(
906 TheId::named("Render SceneManager Map"),
907 TheValue::Empty,
908 ));
909 }
910 }
911
912 if let Some(tree_layout) = ui.get_tree_layout("Project Tree") {
913 if let Some(new_id) = pc.id() {
914 if let Some(node) = tree_layout.get_node_by_id_mut(&new_id)
915 && let Some(snapper) = node.widget.as_any().downcast_mut::<TheSnapperbar>()
916 {
917 snapper.set_selected(true);
918 }
919 } else {
920 match pc {
921 ProjectContext::ProjectSettings => {
922 let target_id = {
923 let mut found: Option<TheId> = None;
924 for node in &mut tree_layout.get_root().childs {
925 if node.id.name == fl!("game") {
926 node.set_open(true);
927 for widget in &node.widgets {
928 if widget.id().name == "Project Settings" {
929 found = Some(widget.id().clone());
930 break;
931 }
932 }
933 break;
934 }
935 }
936 found
937 };
938 if let Some(id) = target_id {
939 tree_layout.new_item_selected(id);
940 }
941 }
942 ProjectContext::GameRules => {
943 let target_id = {
944 let mut found: Option<TheId> = None;
945 for node in &mut tree_layout.get_root().childs {
946 if node.id.name == fl!("game") {
947 node.set_open(true);
948 for widget in &node.widgets {
949 if widget.id().name == "Game Rules" {
950 found = Some(widget.id().clone());
951 break;
952 }
953 }
954 break;
955 }
956 }
957 found
958 };
959 if let Some(id) = target_id {
960 tree_layout.new_item_selected(id);
961 }
962 }
963 ProjectContext::GameLocales => {
964 let target_id = {
965 let mut found: Option<TheId> = None;
966 for node in &mut tree_layout.get_root().childs {
967 if node.id.name == fl!("game") {
968 node.set_open(true);
969 for widget in &node.widgets {
970 if widget.id().name == "Game Locales" {
971 found = Some(widget.id().clone());
972 break;
973 }
974 }
975 break;
976 }
977 }
978 found
979 };
980 if let Some(id) = target_id {
981 tree_layout.new_item_selected(id);
982 }
983 }
984 ProjectContext::GameAudioFx => {
985 let target_id = {
986 let mut found: Option<TheId> = None;
987 for node in &mut tree_layout.get_root().childs {
988 if node.id.name == fl!("game") {
989 node.set_open(true);
990 for widget in &node.widgets {
991 if widget.id().name == "Game Audio FX" {
992 found = Some(widget.id().clone());
993 break;
994 }
995 }
996 break;
997 }
998 }
999 found
1000 };
1001 if let Some(id) = target_id {
1002 tree_layout.new_item_selected(id);
1003 }
1004 }
1005 ProjectContext::DebugLog => {
1006 let target_id = {
1007 let mut found: Option<TheId> = None;
1008 for node in &mut tree_layout.get_root().childs {
1009 if node.id.name == fl!("game") {
1010 node.set_open(true);
1011 for widget in &node.widgets {
1012 if widget.id().name == "Debug Log" {
1013 found = Some(widget.id().clone());
1014 break;
1015 }
1016 }
1017 break;
1018 }
1019 }
1020 found
1021 };
1022 if let Some(id) = target_id {
1023 tree_layout.new_item_selected(id);
1024 }
1025 }
1026 ProjectContext::Console => {
1027 let target_id = {
1028 let mut found: Option<TheId> = None;
1029 for node in &mut tree_layout.get_root().childs {
1030 if node.id.name == fl!("game") {
1031 node.set_open(true);
1032 for widget in &node.widgets {
1033 if widget.id().name == "Console" {
1034 found = Some(widget.id().clone());
1035 break;
1036 }
1037 }
1038 break;
1039 }
1040 }
1041 found
1042 };
1043 if let Some(id) = target_id {
1044 tree_layout.new_item_selected(id);
1045 }
1046 }
1047 _ => {}
1048 }
1049 }
1050 }
1051
1052 ctx.ui.send(TheEvent::Custom(
1053 TheId::named("Update Action List"),
1054 TheValue::Empty,
1055 ));
1056
1057 ctx.ui.relayout = true;
1058}