galaxy 1.0.0
Real-Time C++23 Game Programming Framework. Built on data-driven design principles and agile software engineering.
Loading...
Searching...
No Matches
ScenePanel.cpp
Go to the documentation of this file.
1
7
8#include <entt/locator/locator.hpp>
9
13
14#include "ScenePanel.hpp"
15
16namespace galaxy
17{
19 : m_new {"ScenePanelNewScene"}
20 , m_clear {"ScenePanelClearScenes"}
21 {
22 }
23
25 {
26 }
27
29 {
30 if (ImGui::Begin(ICON_MDI_LIST_BOX_OUTLINE " Scenes"))
31 {
32 auto& sm = entt::locator<SceneManager>::value();
33
34 m_new.draw_button("New");
35 ImGui::SameLine();
36 m_clear.draw_button("Clear");
37 ImGui::SameLine();
38 if (ImGui::Button("Pop"))
39 {
40 sm.pop();
41 }
42 ImGui::SameLine();
43 if (ImGui::Button("Pop all"))
44 {
45 sm.pop_all();
46 }
47
48 m_new.draw([&]() {
49 static std::string s_buff;
50 ImGui::TextUnformatted("Create a new Scene");
51 ImGui::Separator();
52
53 if (ImGui::InputText("Name", &s_buff, ImGuiInputTextFlags_EnterReturnsTrue))
54 {
55 if (!s_buff.empty())
56 {
57 sm.add(s_buff);
58 s_buff = "";
59
60 ImGui::CloseCurrentPopup();
61 }
62 else
63 {
64 ui::imgui_notify_error("Scene name cannot be empty.");
65 }
66 }
67 });
68
69 m_clear.draw([&]() {
70 ui::imgui_confirm("Are you sure you want to delete all scenes?", [&]() {
71 sm.clear();
72 });
73 });
74
75 static std::string top;
76 for (auto&& [id, scene] : sm.storage())
77 {
78 ImGui::PushID(static_cast<int>(id));
79
80 ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_OpenOnDoubleClick;
81
82 std::string tree_id = scene->name();
83 if (sm.top())
84 {
85 if (sm.top()->name() == scene->name())
86 {
87 flags |= ImGuiTreeNodeFlags_Selected;
88 tree_id += " (top)";
89 }
90 }
91
92 if (ImGui::TreeNodeEx(tree_id.c_str(), flags))
93 {
94 if (ImGui::Button("Push"))
95 {
96 sm.push(scene->name());
97 }
98
99 // draw_camera(scene_ptr);
100 // draw_physics(scene_ptr);
101 // draw_mapping(tasks, scene_ptr, selected);
102 // draw_registry(selected, scene_ptr, scene_ptr->m_registry, m_entity_filter);
103
104 ImGui::TreePop();
105 }
106
107 ImGui::PopID();
108 }
109 }
110
111 ImGui::End();
112 }
113} // namespace galaxy
114
115/*
116ScenePanel::ScenePanel()
117 {
118 for (const auto& key : core::ServiceLocator<resource::Prefabs>::ref().keys())
119 {
120 m_prefab_data.items.push_back(key);
121 }
122 }
123
124 void ScenePanel::draw_camera(scene::Scene* scene)
125 {
126 if (ImGui::CollapsingHeader("Camera"))
127 {
128 if (ImGui::Button("Reset"))
129 {
130 scene->m_camera.reset();
131 }
132
133 ImGui::Text("Pos: %.2f, %.2f", scene->m_camera.get_pos().x, scene->m_camera.get_pos().y);
134 ImGui::Text("Rotation: %.1f", scene->m_camera.get_rotation());
135 ImGui::Text("Zoom: %.1f", scene->m_camera.get_scale().x);
136 ImGui::Text("Origin: %.2f, %.2f", scene->m_camera.get_origin().x, scene->m_camera.get_origin().y);
137
138 ImGui::Checkbox("Allow Rotation", &scene->m_camera.m_allow_rotation);
139 ImGui::InputFloat("Move Speed", &scene->m_camera.m_translation_speed, 0.1f, 1.0f, "%.1f");
140 ImGui::InputFloat("Rotation Speed", &scene->m_camera.m_rotation_speed, 0.1f, 1.0f, "%.1f");
141 }
142 }
143
144 void ScenePanel::draw_physics(scene::Scene* scene)
145 {
146 if (ImGui::CollapsingHeader("Physics"))
147 {
148 float gravity[2] = {scene->m_b2world.GetGravity().x, scene->m_b2world.GetGravity().y};
149 if (ImGui::InputFloat2("Gravity", &gravity[0], "%.2f", ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_EnterReturnsTrue))
150 {
151 scene->m_b2world.SetGravity({gravity[0], gravity[1]});
152 }
153
154 auto allow_sleeping = scene->m_b2world.GetAllowSleeping();
155 if (ImGui::Checkbox("Allow Sleeping", &allow_sleeping))
156 {
157 scene->m_b2world.SetAllowSleeping(allow_sleeping);
158 }
159
160 ImGui::SameLine();
161
162 auto allow_autoclear = scene->m_b2world.GetAutoClearForces();
163 if (ImGui::Checkbox("Auto Clear Forces", &allow_autoclear))
164 {
165 scene->m_b2world.SetAutoClearForces(allow_autoclear);
166 }
167
168 ImGui::SliderInt("Position Iterations", &scene->m_velocity_iterations, 1, 14);
169 ImGui::SliderInt("Velocity Iterations", &scene->m_position_iterations, 1, 14);
170 }
171 }
172
173 void ScenePanel::draw_mapping(meta::vector<std::move_only_function<void(void)>>& tasks, scene::Scene* scene, Selected& selected)
174 {
175 if (ImGui::CollapsingHeader("Mapping"))
176 {
177 if (ImGui::Button("Load World"))
178 {
179 auto& fs = core::ServiceLocator<fs::VirtualFileSystem>::ref();
180 auto file = fs.open_file_dialog({".ldtk"});
181 if (!file.empty())
182 {
183 tasks.push_back([&]() {
184 if (scene->load_world(file))
185 {
186 m_map_data.items.clear();
187
188 for (const auto& [key, value] : scene->m_world.maps())
189 {
190 m_map_data.items.push_back(key);
191 }
192 }
193 });
194 }
195 }
196
197 ImGui::SameLine();
198
199 if (ImGui::Button("Clear"))
200 {
201 scene->m_world.clear();
202 }
203
204 ImGui::Spacing();
205
206 if (scene->m_world.loaded())
207 {
208 const auto name = scene->m_world.name().c_str();
209
210 ImGui::PushID(name);
211 ImGui::Text("Name: %s", name);
212
213 if (ImGui::ComboAutoSelect("Map", m_map_data))
214 {
215 scene->m_world.set_active(m_map_data.input);
216 }
217
218 auto* active = scene->m_world.get_active();
219 if (active)
220 {
221 ImGui::Text("Name: %s", active->name().c_str());
222 draw_registry(selected, scene, active->m_registry, m_map_entity_filter);
223 }
224
225 ImGui::PopID();
226 }
227 }
228 }
229
230 void ScenePanel::draw_registry(Selected& selected, scene::Scene* scene, core::Registry& registry, ImGuiTextFilter& filter)
231 {
232 if (ImGui::CollapsingHeader("Registry"))
233 {
234 if (ImGui::Button("New Entity"))
235 {
236 selected.entity = registry.create();
237 selected.scene = scene;
238 }
239
240 if (ImGui::CollapsingHeader("Prefabs"))
241 {
242 ImGui::ComboAutoSelect("List", m_prefab_data);
243 if (ImGui::Button("Load"))
244 {
245 auto selected = std::string {m_prefab_data.input};
246 if (!selected.empty())
247 {
248 registry.create_from_prefab(selected);
249 }
250 else
251 {
252 ui::imgui_notify_warning("Please select a prefab.");
253 }
254 }
255
256 ImGui::SameLine();
257
258 if (ImGui::Button("Save"))
259 {
260 if (selected.entity != entt::null && selected.scene != nullptr)
261 {
262 core::Prefab prefab;
263 prefab.from_entity(selected.entity, selected.scene->m_registry.m_entt);
264
265 const auto base64 = math::encode_base64(prefab.to_json().dump(4));
266 const auto zlib = math::encode_zlib(base64);
267
268 auto& fs = core::ServiceLocator<fs::VirtualFileSystem>::ref();
269 auto dest = fs.open_save_dialog("untitled.galaxyprefab", {"*.galaxyprefab"});
270
271 if (!fs.write(zlib, dest))
272 {
273 GALAXY_LOG(GALAXY_ERROR, "Failed to save prefab.");
274 ui::imgui_notify_error("Failed to save prefab.");
275 }
276 }
277 }
278 }
279
280 filter.DrawWithHint("###EntitySearch", ICON_MDI_MAGNIFY "Search by tag...", ImGui::GetContentRegionAvail().x);
281
282 const auto entity_listbox_item = [&](entt::entity entity, components::Tag* tag) {
283 const auto is_selected = (selected.entity == entity);
284 auto id = std::to_string(static_cast<std::uint32_t>(entity));
285 if (tag)
286 {
287 id = tag->m_tag + "##" + id;
288 }
289
290 if (ImGui::Selectable(id.c_str(), is_selected))
291 {
292 selected.entity = entity;
293 selected.scene = scene;
294 }
295
296 if (is_selected)
297 {
298 ImGui::SetItemDefaultFocus();
299
300 auto deleted = false;
301 if (ImGui::BeginPopupContextItem())
302 {
303 if (ImGui::MenuItem("Delete Entity"))
304 {
305 deleted = true;
306 }
307
308 ImGui::EndPopup();
309 }
310
311 if (deleted)
312 {
313 registry.m_entt.destroy(entity);
314 if (selected.entity == entity)
315 {
316 selected.entity = entt::null;
317 selected.scene = scene;
318 }
319 }
320 }
321 };
322
323 ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
324 if (ImGui::BeginListBox("##EntityList"))
325 {
326 for (const auto& [entity] : registry.m_entt.storage<entt::entity>().each())
327 {
328 auto tag = registry.m_entt.try_get<components::Tag>(entity);
329 if (tag)
330 {
331 if (filter.PassFilter(tag->m_tag.c_str()))
332 {
333 entity_listbox_item(entity, tag);
334 }
335 }
336 else
337 {
338 entity_listbox_item(entity, tag);
339 }
340 }
341
342 ImGui::EndListBox();
343 }
344 }
345 }
346*/
void draw_button(const char *text) noexcept
Draw the button to show the popup.
Definition Popup.cpp:24
void draw(std::move_only_function< void(void)> &&func)
Show popup.
Definition Popup.cpp:34
virtual ~ScenePanel() noexcept
Destructor.
Popup m_clear
For removing all scenes.
ScenePanel() noexcept
Constructor.
Popup m_new
For creating a new scene.
void draw() override
Draw scene panel.
#define ICON_MDI_LIST_BOX_OUTLINE
void imgui_notify_error(const char *msg)
ImGui error notification.
void imgui_confirm(const char *msg, std::move_only_function< void(void)> &&yes, std::move_only_function< void(void)> &&no)
Handles a popup for a yes/no situation.
Application.hpp galaxy.