Ember
Loading...
Searching...
No Matches
SceneContainer.cpp
Go to the documentation of this file.
2#include <algorithm>
3#include <wx/sizer.h>
4
5namespace EmberForge {
6namespace ui {
7
8// Event table
11
12 SceneContainer::SceneContainer(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style)
13 : wxPanel(parent, id, pos, size, style), m_maxInactiveScenes(3), m_enableTransitions(true), m_sizer(nullptr) {
14 // Create main sizer
15 m_sizer = new wxBoxSizer(wxVERTICAL);
16 SetSizer(m_sizer);
17}
18
20
21bool SceneContainer::AddScene(std::unique_ptr<IScene> scene, const wxString &name, const wxString &description) {
22 if (!scene || name.IsEmpty() || HasScene(name)) {
23 return false;
24 }
25
26 // Get the scene panel
27 wxPanel *scenePanel = scene->GetPanel();
28 if (!scenePanel) {
29 return false;
30 }
31
32 // Hide initially
33 scenePanel->Hide();
34
35 // Add to sizer
36 m_sizer->Add(scenePanel, 1, wxEXPAND);
37
38 // Store scene info
39 SceneInfo sceneInfo(std::move(scene), name);
40 sceneInfo.description = description;
41 m_scenes.emplace(name, std::move(sceneInfo));
42
43 // Notify callback
45
46 return true;
47}
48
49bool SceneContainer::RemoveScene(const wxString &name) {
50 auto it = m_scenes.find(name);
51 if (it == m_scenes.end()) {
52 return false;
53 }
54
55 // If this is the active scene, deactivate it
56 if (m_activeSceneName == name) {
57 if (it->second.scene) {
58 it->second.scene->OnDeactivated();
59 }
60 m_activeSceneName.Clear();
61 }
62
63 // Notify callback before removal
65
66 // Remove from UI
67 wxPanel *scenePanel = it->second.scene->GetPanel();
68 if (scenePanel) {
69 m_sizer->Detach(scenePanel);
70 scenePanel->Destroy();
71 }
72
73 // Remove from container
74 m_scenes.erase(it);
75
76 Layout();
77 return true;
78}
79
81 // Copy scene names to avoid iterator invalidation
82 std::vector<wxString> sceneNames;
83 for (const auto &pair : m_scenes) {
84 sceneNames.push_back(pair.first);
85 }
86
87 // Remove all scenes
88 for (const auto &name : sceneNames) {
89 RemoveScene(name);
90 }
91}
92
93IScene *SceneContainer::GetScene(const wxString &name) const {
94 auto it = m_scenes.find(name);
95 if (it != m_scenes.end()) {
96 return it->second.scene.get();
97 }
98 return nullptr;
99}
100
102 if (!m_activeSceneName.IsEmpty()) {
104 }
105 return nullptr;
106}
107
109
110std::vector<wxString> SceneContainer::GetSceneNames() const {
111 std::vector<wxString> names;
112 for (const auto &pair : m_scenes) {
113 names.push_back(pair.first);
114 }
115 return names;
116}
117
118int SceneContainer::GetSceneCount() const { return static_cast<int>(m_scenes.size()); }
119
120void SceneContainer::SetSceneDescription(const wxString &name, const wxString &description) {
121 auto it = m_scenes.find(name);
122 if (it != m_scenes.end()) {
123 it->second.description = description;
124 }
125}
126
127wxString SceneContainer::GetSceneDescription(const wxString &name) const {
128 auto it = m_scenes.find(name);
129 if (it != m_scenes.end()) {
130 return it->second.description;
131 }
132 return wxEmptyString;
133}
134
135void SceneContainer::SetSceneState(const wxString &name, SceneState state) {
136 auto it = m_scenes.find(name);
137 if (it != m_scenes.end()) {
138 it->second.state = state;
139 }
140}
141
143 auto it = m_scenes.find(name);
144 if (it != m_scenes.end()) {
145 return it->second.state;
146 }
148}
149
150void SceneContainer::SetScenePersistent(const wxString &name, bool persistent) {
151 auto it = m_scenes.find(name);
152 if (it != m_scenes.end()) {
153 it->second.persistent = persistent;
154 }
155}
156
157bool SceneContainer::IsScenePersistent(const wxString &name) const {
158 auto it = m_scenes.find(name);
159 if (it != m_scenes.end()) {
160 return it->second.persistent;
161 }
162 return false;
163}
164
165bool SceneContainer::SwitchToScene(const wxString &name, TransitionType transition) {
166 if (!HasScene(name) || !CanSwitchScene(name)) {
167 return false;
168 }
169
170 wxString previousScene = m_activeSceneName;
171
172 // Deactivate current scene
173 if (!previousScene.IsEmpty()) {
174 IScene *currentScene = GetScene(previousScene);
175 if (currentScene) {
176 currentScene->OnDeactivated();
177 SetSceneState(previousScene, SceneState::Inactive);
178 HideScene(previousScene);
179 NotifySceneDeactivated(previousScene);
180 }
181 }
182
183 // Activate new scene
184 IScene *newScene = GetScene(name);
185 if (newScene) {
187 m_activeSceneName = name;
188 newScene->OnActivated();
189 ShowScene(name);
191
192 // Perform transition if enabled
193 if (m_enableTransitions && !previousScene.IsEmpty()) {
194 PerformTransition(previousScene, name, transition);
195 }
196
197 Layout();
198 return true;
199 }
200
201 return false;
202}
203
205 for (const auto &pair : m_scenes) {
206 if (pair.second.scene.get() == scene) {
207 return SwitchToScene(pair.first, transition);
208 }
209 }
210 return false;
211}
212
213bool SceneContainer::HasScene(const wxString &name) const { return m_scenes.find(name) != m_scenes.end(); }
214
215void SceneContainer::RefreshScene(const wxString &name) {
216 IScene *scene = GetScene(name);
217 if (scene) {
218 scene->Refresh();
219 }
220}
221
227
229 for (const auto &pair : m_scenes) {
230 if (pair.second.scene) {
231 pair.second.scene->Refresh();
232 }
233 }
234}
235
236bool SceneContainer::CanSwitchScene(const wxString &name) {
237 auto it = m_scenes.find(name);
238 if (it == m_scenes.end()) {
239 return false;
240 }
241
242 SceneState state = it->second.state;
243 return state != SceneState::Loading && state != SceneState::Error;
244}
245
247
251
253
255
256void SceneContainer::SetSceneUserData(const wxString &name, void *userData) {
257 auto it = m_scenes.find(name);
258 if (it != m_scenes.end()) {
259 it->second.userData = userData;
260 }
261}
262
263void *SceneContainer::GetSceneUserData(const wxString &name) const {
264 auto it = m_scenes.find(name);
265 if (it != m_scenes.end()) {
266 return it->second.userData;
267 }
268 return nullptr;
269}
270
271void SceneContainer::SetSceneSize(const wxString &name, const wxSize &size) {
272 IScene *scene = GetScene(name);
273 if (scene) {
274 wxPanel *scenePanel = scene->GetPanel();
275 if (scenePanel) {
276 scenePanel->SetSize(size);
277 }
278 }
279}
280
281wxSize SceneContainer::GetSceneSize(const wxString &name) const {
282 IScene *scene = GetScene(name);
283 if (scene) {
284 wxPanel *scenePanel = scene->GetPanel();
285 if (scenePanel) {
286 return scenePanel->GetSize();
287 }
288 }
289 return wxDefaultSize;
290}
291
292void SceneContainer::FitSceneToContainer(const wxString &name) {
293 IScene *scene = GetScene(name);
294 if (scene) {
295 wxPanel *scenePanel = scene->GetPanel();
296 if (scenePanel) {
297 scenePanel->SetSize(GetClientSize());
298 }
299 }
300}
301
307
308bool SceneContainer::SerializeState(wxString &data) const {
309 // Simple serialization - can be enhanced later
310 data = wxString::Format("scenes:%d,active:%s", GetSceneCount(), m_activeSceneName);
311 return true;
312}
313
314bool SceneContainer::DeserializeState(const wxString &data) {
315 // Simple deserialization - can be enhanced later
316 return true;
317}
318
320 for (auto &pair : m_scenes) {
321 if (pair.first != m_activeSceneName && pair.second.state != SceneState::Suspended) {
322 // Mark as suspended (no actual suspend method in interface)
323 pair.second.state = SceneState::Suspended;
324 }
325 }
326}
327
329 for (auto &pair : m_scenes) {
330 if (pair.second.state == SceneState::Suspended) {
331 // Mark as inactive (no actual resume method in interface)
332 pair.second.state = SceneState::Inactive;
333 }
334 }
335}
336
338
340
341// Event handlers
342void SceneContainer::OnSize(wxSizeEvent &event) {
344 event.Skip();
345}
346
347void SceneContainer::OnPaint(wxPaintEvent &event) {
348 wxPaintDC dc(this);
349 // Custom painting can be added here
350}
351
352// Helper methods
354 Layout();
355 Refresh();
356}
357
358void SceneContainer::ShowScene(const wxString &name) {
359 IScene *scene = GetScene(name);
360 if (scene) {
361 wxPanel *scenePanel = scene->GetPanel();
362 if (scenePanel) {
363 scenePanel->Show();
364 }
365 }
366}
367
368void SceneContainer::HideScene(const wxString &name) {
369 IScene *scene = GetScene(name);
370 if (scene) {
371 wxPanel *scenePanel = scene->GetPanel();
372 if (scenePanel) {
373 scenePanel->Hide();
374 }
375 }
376}
377
378bool SceneContainer::ValidateSceneName(const wxString &name) const {
379 return !name.IsEmpty() && name.Find('/') == wxNOT_FOUND;
380}
381
382void SceneContainer::NotifySceneActivated(const wxString &name) {
384 IScene *scene = GetScene(name);
385 if (scene) {
386 m_sceneActivatedCallback(scene, name);
387 }
388 }
389}
390
391void SceneContainer::NotifySceneDeactivated(const wxString &name) {
393 IScene *scene = GetScene(name);
394 if (scene) {
395 m_sceneDeactivatedCallback(scene, name);
396 }
397 }
398}
399
400void SceneContainer::NotifySceneCreated(const wxString &name) {
402 IScene *scene = GetScene(name);
403 if (scene) {
404 m_sceneCreatedCallback(scene, name);
405 }
406 }
407}
408
409void SceneContainer::NotifySceneDestroyed(const wxString &name) {
411 IScene *scene = GetScene(name);
412 if (scene) {
413 m_sceneDestroyedCallback(scene, name);
414 }
415 }
416}
417
418void SceneContainer::PerformTransition(const wxString &fromScene, const wxString &toScene, TransitionType transition) {
419 switch (transition) {
421 FadeTransition(fromScene, toScene);
422 break;
424 SlideTransition(fromScene, toScene);
425 break;
427 // Custom transition implementation
428 break;
430 default:
431 // No transition effect
432 break;
433 }
434}
435
436void SceneContainer::FadeTransition(const wxString &fromScene, const wxString &toScene) {
437 // Simple fade implementation - can be enhanced with proper animation
438 // This is a placeholder for future animation framework
439}
440
441void SceneContainer::SlideTransition(const wxString &fromScene, const wxString &toScene) {
442 // Simple slide implementation - can be enhanced with proper animation
443 // This is a placeholder for future animation framework
444}
445
446} // namespace ui
447} // namespace EmberForge
BehaviorTreeProjectDialog::OnProjectNameChanged BehaviorTreeProjectDialog::OnRemoveFiles wxEND_EVENT_TABLE() BehaviorTreeProjectDialog
Container for managing multiple scenes.
std::function< void(IScene *scene, const wxString &sceneName)> SceneCreatedCallback
void HideScene(const wxString &name)
void OnPaint(wxPaintEvent &event)
wxSize GetSceneSize(const wxString &name) const
void * GetSceneUserData(const wxString &name) const
SceneCreatedCallback m_sceneCreatedCallback
std::function< void(IScene *scene, const wxString &sceneName)> SceneDestroyedCallback
void SetSceneDeactivatedCallback(SceneDeactivatedCallback callback)
void NotifySceneDestroyed(const wxString &name)
void FitSceneToContainer(const wxString &name)
void SetSceneState(const wxString &name, SceneState state)
bool SerializeState(wxString &data) const
void SetMaxInactiveScenes(int maxScenes)
void SetSceneSize(const wxString &name, const wxSize &size)
SceneDeactivatedCallback m_sceneDeactivatedCallback
void OnSize(wxSizeEvent &event)
void NotifySceneCreated(const wxString &name)
void ShowScene(const wxString &name)
void SetSceneUserData(const wxString &name, void *userData)
SceneDestroyedCallback m_sceneDestroyedCallback
bool SwitchToScene(const wxString &name, TransitionType transition=TransitionType::Immediate)
void SetSceneActivatedCallback(SceneActivatedCallback callback)
bool DeserializeState(const wxString &data)
SceneState GetSceneState(const wxString &name) const
bool HasScene(const wxString &name) const
IScene * GetScene(const wxString &name) const
void SlideTransition(const wxString &fromScene, const wxString &toScene)
bool RemoveScene(const wxString &name)
void FadeTransition(const wxString &fromScene, const wxString &toScene)
wxString GetSceneDescription(const wxString &name) const
bool CanSwitchScene(const wxString &name)
std::unordered_map< wxString, SceneInfo > m_scenes
void NotifySceneDeactivated(const wxString &name)
std::function< void(IScene *scene, const wxString &sceneName)> SceneActivatedCallback
void SetSceneDestroyedCallback(SceneDestroyedCallback callback)
void SetSceneDescription(const wxString &name, const wxString &description)
SceneActivatedCallback m_sceneActivatedCallback
void PerformTransition(const wxString &fromScene, const wxString &toScene, TransitionType transition)
void RefreshScene(const wxString &name)
void SetScenePersistent(const wxString &name, bool persistent)
bool ValidateSceneName(const wxString &name) const
void SetSceneCreatedCallback(SceneCreatedCallback callback)
bool AddScene(std::unique_ptr< IScene > scene, const wxString &name, const wxString &description=wxEmptyString)
bool IsScenePersistent(const wxString &name) const
std::function< void(IScene *scene, const wxString &sceneName)> SceneDeactivatedCallback
std::vector< wxString > GetSceneNames() const
void NotifySceneActivated(const wxString &name)
Interface for scene-based UI components (e.g., views or screens).
Definition IScene.h:7
virtual void OnActivated()
Called when the scene becomes active.
Definition IScene.h:19
virtual void Refresh()
Refreshes the scene content.
Definition IScene.h:23
virtual wxPanel * GetPanel()=0
Returns the wxPanel used as the scene content.
virtual void OnDeactivated()
Called when the scene becomes inactive.
Definition IScene.h:21
wxBEGIN_EVENT_TABLE(SceneContainer, wxPanel) EVT_SIZE(SceneContainer
PerformancePanel::OnUpdateTimer EVT_PAINT(PerformancePanel::OnPaint) EVT_SIZE(PerformancePanel