1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use amethyst::ecs::prelude::*;
use amethyst_imgui::imgui;
use imgui::im_str;
#[derive(Default, Clone, Copy)]
pub struct InspectorHierarchy {
dragging: Option<Entity>,
hovering: Option<Entity>,
}
impl InspectorHierarchy {
fn render_boy(
&mut self,
entity: Entity,
hierarchy: &amethyst::core::ParentHierarchy,
names: &ReadStorage<'_, amethyst::core::Named>,
ui: &imgui::Ui<'_>,
inspector_state: &mut crate::InspectorState,
entities: &amethyst::ecs::world::EntitiesRes,
lazy: &LazyUpdate,
) {
let children = hierarchy.children(entity);
let label: String = if let Some(name) = names.get(entity) {
name.name.to_string()
} else {
format!("Entity {}/{}", entity.id(), entity.gen().id())
};
macro_rules! tree_node_buttons {
() => {
if ui.is_item_hovered_with_flags(imgui::ImGuiHoveredFlags::AllowWhenBlockedByActiveItem) {
self.hovering = Some(entity);
if ui.imgui().is_mouse_clicked(imgui::ImMouseButton::Left) && self.dragging.is_none() {
self.dragging = Some(entity);
}
}
ui.same_line(0.);
if ui.small_button(im_str!("inspect##selector{:?}", entity)) {
inspector_state.selected = Some(entity);
}
};
}
let mut opened = false;
ui.tree_node(im_str!("{:?}", entity))
.label(im_str!("{}", label))
.allow_item_overlap(true)
.selected(
inspector_state.selected == Some(entity) ||
self.dragging == Some(entity)
)
.leaf(children.is_empty())
.build(|| {
opened = true;
tree_node_buttons!();
for child in children {
self.render_boy(*child, hierarchy, names, ui, inspector_state, &entities, &lazy);
}
});
if !opened {
tree_node_buttons!();
}
}
}
impl<'s> System<'s> for InspectorHierarchy {
type SystemData = (
Write<'s, crate::InspectorState>,
ReadStorage<'s, amethyst::core::Named>,
ReadStorage<'s, amethyst::core::Parent>,
ReadExpect<'s, amethyst::core::ParentHierarchy>,
Entities<'s>,
Read<'s, LazyUpdate>,
);
fn run(&mut self, (mut inspector_state, names, parents, hierarchy, entities, lazy): Self::SystemData) {
amethyst_imgui::with(move |ui| {
ui.window(im_str!("Hierarchy"))
.size((300.0, 500.0), imgui::ImGuiCond::FirstUseEver)
.build(move || {
self.hovering = None;
if ui.small_button(im_str!("new entity##hierarchy")) {
lazy.create_entity(&entities).build();
}
ui.separator();
for (entity, _) in (&entities, !&parents).join() {
self.render_boy(entity, &hierarchy, &names, &ui, &mut inspector_state, &entities, &lazy);
}
let is_dragging = ui.imgui().is_mouse_dragging(imgui::ImMouseButton::Left);
let is_mouse_down = ui.imgui().is_mouse_down(imgui::ImMouseButton::Left);
if let Some(dragged) = self.dragging {
if !is_dragging && !is_mouse_down {
if let Some(hover) = self.hovering {
if dragged != hover {
lazy.insert(dragged, amethyst::core::Parent::new(hover));
}
} else {
}
self.dragging = None;
}
}
});
});
}
}