yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
session_coordinator.cc
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cstdio>
5
6#include "absl/strings/str_format.h"
10#include "imgui/imgui.h"
11
12namespace yaze {
13namespace editor {
14
16 EditorCardRegistry* card_registry,
17 ToastManager* toast_manager,
18 UserSettings* user_settings)
19 : sessions_ptr_(sessions_ptr),
20 card_registry_(card_registry),
21 toast_manager_(toast_manager),
22 user_settings_(user_settings) {
23 auto* sessions = static_cast<std::deque<RomSession>*>(sessions_ptr_);
24 if (sessions && !sessions->empty()) {
26 session_count_ = sessions->size();
27 }
28}
29
30// Helper macro to get sessions pointer
31#define GET_SESSIONS() static_cast<std::deque<RomSession>*>(sessions_ptr_)
32
34 auto* sessions = GET_SESSIONS();
35 if (!sessions)
36 return;
37
40 return;
41 }
42
43 // Create new empty session
44 sessions->emplace_back();
46
47 // Set as active session
48 active_session_index_ = sessions->size() - 1;
49
50 LOG_INFO("SessionCoordinator", "Created new session %zu (total: %zu)",
52
53 ShowSessionOperationResult("Create Session", true);
54}
55
57 auto* sessions = GET_SESSIONS();
58 if (!sessions || sessions->empty())
59 return;
60
63 return;
64 }
65
66 // Create new empty session (cannot actually duplicate due to non-movable editors)
67 // TODO: Implement proper duplication when editors become movable
68 sessions->emplace_back();
70
71 // Set as active session
72 active_session_index_ = sessions->size() - 1;
73
74 LOG_INFO("SessionCoordinator", "Duplicated session %zu (total: %zu)",
76
77 ShowSessionOperationResult("Duplicate Session", true);
78}
79
83
85 auto* sessions = GET_SESSIONS();
86 if (!sessions || !IsValidSessionIndex(index))
87 return;
88
90 // Don't allow closing the last session
91 if (toast_manager_) {
92 toast_manager_->Show("Cannot close the last session",
94 }
95 return;
96 }
97
98 // Unregister cards for this session
99 if (card_registry_) {
101 }
102
103 // Mark session as closed (don't erase due to non-movable editors)
104 // TODO: Implement proper session removal when editors become movable
105 sessions->at(index).custom_name = "[CLOSED SESSION]";
106
107 // Note: We don't actually remove from the deque because EditorSet is not movable
108 // This is a temporary solution until we refactor to use unique_ptr<EditorSet>
110
111 // Adjust active session index
112 if (active_session_index_ >= index && active_session_index_ > 0) {
114 }
115
116 LOG_INFO("SessionCoordinator", "Closed session %zu (total: %zu)", index,
118
119 ShowSessionOperationResult("Close Session", true);
120}
121
123 CloseSession(index);
124}
125
127 if (!IsValidSessionIndex(index))
128 return;
129
130 active_session_index_ = index;
131
132 if (card_registry_) {
134 }
135}
136
138 SwitchToSession(index);
139}
140
144
146 auto* sessions = GET_SESSIONS();
147 if (!sessions || !IsValidSessionIndex(active_session_index_)) {
148 return nullptr;
149 }
150 return &sessions->at(active_session_index_);
151}
152
156
158 auto* session = GetActiveRomSession();
159 return session ? &session->rom : nullptr;
160}
161
163 auto* session = GetActiveRomSession();
164 return session ? &session->editors : nullptr;
165}
166
167void* SessionCoordinator::GetSession(size_t index) const {
168 auto* sessions = GET_SESSIONS();
169 if (!sessions || !IsValidSessionIndex(index)) {
170 return nullptr;
171 }
172 return &sessions->at(index);
173}
174
176 return session_count_ > 1;
177}
178
182
184 const std::string& filepath) const {
185 auto* sessions = GET_SESSIONS();
186 if (!sessions || filepath.empty())
187 return false;
188
189 for (const auto& session : *sessions) {
190 if (session.filepath == filepath) {
191 return true;
192 }
193 }
194 return false;
195}
196
198 auto* sessions = GET_SESSIONS();
199 if (!sessions || sessions->empty())
200 return;
201
203 return;
204
205 ImGui::SetNextWindowSize(ImVec2(400, 300), ImGuiCond_FirstUseEver);
206 ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
207 ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
208
209 if (!ImGui::Begin("Session Switcher", &show_session_switcher_)) {
210 ImGui::End();
211 return;
212 }
213
214 ImGui::Text("%s Active Sessions (%zu)", ICON_MD_TAB, session_count_);
215 ImGui::Separator();
216
217 for (size_t i = 0; i < sessions->size(); ++i) {
218 const auto& session = sessions->at(i);
219 bool is_active = (i == active_session_index_);
220
221 ImGui::PushID(static_cast<int>(i));
222
223 // Session tab
224 if (ImGui::Selectable(GetSessionDisplayName(i).c_str(), is_active)) {
226 }
227
228 // Right-click context menu
229 if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
230 ImGui::OpenPopup("SessionContextMenu");
231 }
232
233 if (ImGui::BeginPopup("SessionContextMenu")) {
235 ImGui::EndPopup();
236 }
237
238 ImGui::PopID();
239 }
240
241 ImGui::Separator();
242
243 // Action buttons
244 if (ImGui::Button(absl::StrFormat("%s New Session", ICON_MD_ADD).c_str())) {
246 }
247
248 ImGui::SameLine();
249 if (ImGui::Button(
250 absl::StrFormat("%s Duplicate", ICON_MD_CONTENT_COPY).c_str())) {
252 }
253
254 ImGui::SameLine();
255 if (HasMultipleSessions() &&
256 ImGui::Button(absl::StrFormat("%s Close", ICON_MD_CLOSE).c_str())) {
258 }
259
260 ImGui::End();
261}
262
264 auto* sessions = GET_SESSIONS();
265 if (!sessions || sessions->empty())
266 return;
267
269 return;
270
271 ImGui::SetNextWindowSize(ImVec2(600, 400), ImGuiCond_FirstUseEver);
272 ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
273 ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
274
275 if (!ImGui::Begin("Session Manager", &show_session_manager_)) {
276 ImGui::End();
277 return;
278 }
279
280 // Session statistics
281 ImGui::Text("%s Session Statistics", ICON_MD_ANALYTICS);
282 ImGui::Separator();
283
284 ImGui::Text("Total Sessions: %zu", GetTotalSessionCount());
285 ImGui::Text("Loaded Sessions: %zu", GetLoadedSessionCount());
286 ImGui::Text("Empty Sessions: %zu", GetEmptySessionCount());
287
288 ImGui::Spacing();
289
290 // Session list
291 if (ImGui::BeginTable("SessionTable", 4,
292 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg |
293 ImGuiTableFlags_Resizable)) {
294
295 ImGui::TableSetupColumn("Session", ImGuiTableColumnFlags_WidthStretch,
296 0.3f);
297 ImGui::TableSetupColumn("ROM File", ImGuiTableColumnFlags_WidthStretch,
298 0.4f);
299 ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthStretch, 0.2f);
300 ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthFixed,
301 120.0f);
302 ImGui::TableHeadersRow();
303
304 for (size_t i = 0; i < sessions->size(); ++i) {
305 const auto& session = sessions->at(i);
306 bool is_active = (i == active_session_index_);
307
308 ImGui::PushID(static_cast<int>(i));
309
310 ImGui::TableNextRow();
311
312 // Session name
313 ImGui::TableNextColumn();
314 if (is_active) {
315 ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "%s %s",
317 GetSessionDisplayName(i).c_str());
318 } else {
319 ImGui::Text("%s %s", ICON_MD_RADIO_BUTTON_UNCHECKED,
320 GetSessionDisplayName(i).c_str());
321 }
322
323 // ROM file
324 ImGui::TableNextColumn();
325 if (session.rom.is_loaded()) {
326 ImGui::Text("%s", session.filepath.c_str());
327 } else {
328 ImGui::TextDisabled("(No ROM loaded)");
329 }
330
331 // Status
332 ImGui::TableNextColumn();
333 if (session.rom.is_loaded()) {
334 ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "Loaded");
335 } else {
336 ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Empty");
337 }
338
339 // Actions
340 ImGui::TableNextColumn();
341 if (!is_active && ImGui::SmallButton("Switch")) {
343 }
344
345 ImGui::SameLine();
346 if (HasMultipleSessions() && ImGui::SmallButton("Close")) {
347 CloseSession(i);
348 }
349
350 ImGui::PopID();
351 }
352
353 ImGui::EndTable();
354 }
355
356 ImGui::End();
357}
358
361 return;
362
363 ImGui::SetNextWindowSize(ImVec2(300, 150), ImGuiCond_Always);
364 ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
365 ImGuiCond_Always, ImVec2(0.5f, 0.5f));
366
367 if (!ImGui::Begin("Rename Session", &show_session_rename_dialog_)) {
368 ImGui::End();
369 return;
370 }
371
372 ImGui::Text("Rename session %zu:", session_to_rename_);
373 ImGui::InputText("Name", session_rename_buffer_,
374 sizeof(session_rename_buffer_));
375
376 ImGui::Spacing();
377
378 if (ImGui::Button("OK")) {
381 session_rename_buffer_[0] = '\0';
382 }
383
384 ImGui::SameLine();
385 if (ImGui::Button("Cancel")) {
387 session_rename_buffer_[0] = '\0';
388 }
389
390 ImGui::End();
391}
392
394 auto* sessions = GET_SESSIONS();
395 if (!sessions || sessions->empty())
396 return;
397
398 if (ImGui::BeginTabBar("SessionTabs")) {
399 for (size_t i = 0; i < sessions->size(); ++i) {
400 bool is_active = (i == active_session_index_);
401 const auto& session = sessions->at(i);
402
403 std::string tab_name = GetSessionDisplayName(i);
404 if (session.rom.is_loaded()) {
405 tab_name += " ";
406 tab_name += ICON_MD_CHECK_CIRCLE;
407 }
408
409 if (ImGui::BeginTabItem(tab_name.c_str())) {
410 if (!is_active) {
412 }
413 ImGui::EndTabItem();
414 }
415
416 // Right-click context menu
417 if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
418 ImGui::OpenPopup(absl::StrFormat("SessionTabContext_%zu", i).c_str());
419 }
420
421 if (ImGui::BeginPopup(
422 absl::StrFormat("SessionTabContext_%zu", i).c_str())) {
424 ImGui::EndPopup();
425 }
426 }
427 ImGui::EndTabBar();
428 }
429}
430
432 if (!HasMultipleSessions())
433 return;
434
435 const auto& theme = gui::ThemeManager::Get().GetCurrentTheme();
436 ImVec4 accent_color = ConvertColorToImVec4(theme.accent);
437
438 ImGui::PushStyleColor(ImGuiCol_Text, accent_color);
439 ImGui::Text("%s Session %zu", ICON_MD_TAB, active_session_index_);
440 ImGui::PopStyleColor();
441
442 if (ImGui::IsItemHovered()) {
443 ImGui::SetTooltip("Active Session: %s\nClick to open session switcher",
445 }
446
447 if (ImGui::IsItemClicked()) {
449 }
450}
451
452std::string SessionCoordinator::GetSessionDisplayName(size_t index) const {
453 auto* sessions = GET_SESSIONS();
454 if (!sessions || !IsValidSessionIndex(index)) {
455 return "Invalid Session";
456 }
457
458 const auto& session = sessions->at(index);
459
460 if (!session.custom_name.empty()) {
461 return session.custom_name;
462 }
463
464 if (session.rom.is_loaded()) {
465 return absl::StrFormat(
466 "Session %zu (%s)", index,
467 std::filesystem::path(session.filepath).stem().string());
468 }
469
470 return absl::StrFormat("Session %zu (Empty)", index);
471}
472
476
478 const std::string& new_name) {
479 auto* sessions = GET_SESSIONS();
480 if (!sessions || !IsValidSessionIndex(index) || new_name.empty())
481 return;
482
483 sessions->at(index).custom_name = new_name;
484 LOG_INFO("SessionCoordinator", "Renamed session %zu to '%s'", index,
485 new_name.c_str());
486}
487
489 const std::string& editor_name, size_t session_index) const {
490 auto* sessions = GET_SESSIONS();
491
492 if (!sessions || sessions->size() <= 1) {
493 // Single session - use simple name
494 return editor_name;
495 }
496
497 if (session_index >= sessions->size()) {
498 return editor_name;
499 }
500
501 // Multi-session - include session identifier
502 const auto& session = sessions->at(session_index);
503 std::string session_name =
504 session.custom_name.empty() ? session.rom.title() : session.custom_name;
505
506 // Truncate long session names
507 if (session_name.length() > 20) {
508 session_name = session_name.substr(0, 17) + "...";
509 }
510
511 return absl::StrFormat("%s - %s##session_%zu", editor_name, session_name,
512 session_index);
513}
514
516 SwitchToSession(index);
517}
518
520 auto* sessions = GET_SESSIONS();
521 if (sessions) {
522 session_count_ = sessions->size();
523 } else {
524 session_count_ = 0;
525 }
526}
527
533
539
540void SessionCoordinator::ShowCardsInCategory(const std::string& category) {
541 if (card_registry_) {
543 }
544}
545
546void SessionCoordinator::HideCardsInCategory(const std::string& category) {
547 if (card_registry_) {
549 }
550}
551
553 auto* sessions = GET_SESSIONS();
554 return sessions && index < sessions->size();
555}
556
557bool SessionCoordinator::IsSessionActive(size_t index) const {
558 return index == active_session_index_;
559}
560
561bool SessionCoordinator::IsSessionLoaded(size_t index) const {
562 auto* sessions = GET_SESSIONS();
563 return IsValidSessionIndex(index) && sessions &&
564 sessions->at(index).rom.is_loaded();
565}
566
570
572 auto* sessions = GET_SESSIONS();
573 if (!sessions)
574 return 0;
575
576 size_t count = 0;
577 for (const auto& session : *sessions) {
578 if (session.rom.is_loaded()) {
579 count++;
580 }
581 }
582 return count;
583}
584
588
589absl::Status SessionCoordinator::LoadRomIntoSession(const std::string& filename,
590 size_t session_index) {
591 auto* sessions = GET_SESSIONS();
592 if (!sessions || filename.empty()) {
593 return absl::InvalidArgumentError("Invalid parameters");
594 }
595
596 size_t target_index =
597 (session_index == SIZE_MAX) ? active_session_index_ : session_index;
598 if (!IsValidSessionIndex(target_index)) {
599 return absl::InvalidArgumentError("Invalid session index");
600 }
601
602 // TODO: Implement actual ROM loading
603 LOG_INFO("SessionCoordinator", "LoadRomIntoSession: %s -> session %zu",
604 filename.c_str(), target_index);
605
606 return absl::OkStatus();
607}
608
610 const std::string& filename) {
611 auto* sessions = GET_SESSIONS();
612 if (!sessions || !IsValidSessionIndex(active_session_index_)) {
613 return absl::FailedPreconditionError("No active session");
614 }
615
616 // TODO: Implement actual ROM saving
617 LOG_INFO("SessionCoordinator", "SaveActiveSession: session %zu",
619
620 return absl::OkStatus();
621}
622
623absl::Status SessionCoordinator::SaveSessionAs(size_t session_index,
624 const std::string& filename) {
625 auto* sessions = GET_SESSIONS();
626 if (!sessions || !IsValidSessionIndex(session_index) || filename.empty()) {
627 return absl::InvalidArgumentError("Invalid parameters");
628 }
629
630 // TODO: Implement actual ROM saving
631 LOG_INFO("SessionCoordinator", "SaveSessionAs: session %zu -> %s",
632 session_index, filename.c_str());
633
634 return absl::OkStatus();
635}
636
638 Rom&& rom, const std::string& filepath) {
639 auto* sessions = GET_SESSIONS();
640 if (!sessions)
641 return absl::InternalError("Sessions not initialized");
642
643 size_t new_session_id = sessions->size();
644 sessions->emplace_back(std::move(rom), user_settings_, new_session_id);
645 RomSession& session = sessions->back();
646 session.filepath = filepath;
647
649 SwitchToSession(new_session_id);
650
651 return &session;
652}
653
655 auto* sessions = GET_SESSIONS();
656 if (!sessions)
657 return;
658
659 // Mark empty sessions as closed (except keep at least one)
660 // TODO: Actually remove when editors become movable
661 size_t loaded_count = 0;
662 for (auto& session : *sessions) {
663 if (session.rom.is_loaded()) {
664 loaded_count++;
665 }
666 }
667
668 if (loaded_count > 0) {
669 for (auto& session : *sessions) {
670 if (!session.rom.is_loaded() && sessions->size() > 1) {
671 session.custom_name = "[CLOSED SESSION]";
672 }
673 }
674 }
675
677 LOG_INFO("SessionCoordinator", "Cleaned up closed sessions (remaining: %zu)",
679}
680
682 auto* sessions = GET_SESSIONS();
683 if (!sessions)
684 return;
685
686 // Unregister all session cards
687 if (card_registry_) {
688 for (size_t i = 0; i < sessions->size(); ++i) {
690 }
691 }
692
693 // Mark all sessions as closed instead of clearing
694 // TODO: Actually clear when editors become movable
695 for (auto& session : *sessions) {
696 session.custom_name = "[CLOSED SESSION]";
697 }
698
701
702 LOG_INFO("SessionCoordinator", "Cleared all sessions");
703}
704
706 auto* sessions = GET_SESSIONS();
707 if (!sessions || sessions->empty())
708 return;
709
710 size_t next_index = (active_session_index_ + 1) % sessions->size();
711 SwitchToSession(next_index);
712}
713
715 auto* sessions = GET_SESSIONS();
716 if (!sessions || sessions->empty())
717 return;
718
719 size_t prev_index = (active_session_index_ == 0) ? sessions->size() - 1
721 SwitchToSession(prev_index);
722}
723
725 auto* sessions = GET_SESSIONS();
726 if (!sessions || sessions->empty())
727 return;
729}
730
732 auto* sessions = GET_SESSIONS();
733 if (!sessions || sessions->empty())
734 return;
735 SwitchToSession(sessions->size() - 1);
736}
737
739 auto* sessions = GET_SESSIONS();
740 if (sessions && !sessions->empty() &&
741 active_session_index_ >= sessions->size()) {
742 active_session_index_ = sessions->size() - 1;
743 }
744}
745
747 if (!IsValidSessionIndex(index)) {
748 throw std::out_of_range(
749 absl::StrFormat("Invalid session index: %zu", index));
750 }
751}
752
754 const std::string& base_name) const {
755 auto* sessions = GET_SESSIONS();
756 if (!sessions)
757 return base_name;
758
759 std::string name = base_name;
760 int counter = 1;
761
762 while (true) {
763 bool found = false;
764 for (const auto& session : *sessions) {
765 if (session.custom_name == name) {
766 found = true;
767 break;
768 }
769 }
770
771 if (!found)
772 break;
773
774 name = absl::StrFormat("%s %d", base_name, counter++);
775 }
776
777 return name;
778}
779
781 if (toast_manager_) {
783 absl::StrFormat("Maximum %zu sessions allowed", kMaxSessions),
785 }
786}
787
789 const std::string& operation, bool success) {
790 if (toast_manager_) {
791 std::string message =
792 absl::StrFormat("%s %s", operation, success ? "succeeded" : "failed");
794 toast_manager_->Show(message, type);
795 }
796}
797
798void SessionCoordinator::DrawSessionTab(size_t index, bool is_active) {
799 auto* sessions = GET_SESSIONS();
800 if (!sessions || index >= sessions->size())
801 return;
802
803 const auto& session = sessions->at(index);
804
805 ImVec4 color = GetSessionColor(index);
806 ImGui::PushStyleColor(ImGuiCol_Text, color);
807
808 std::string tab_name = GetSessionDisplayName(index);
809 if (session.rom.is_loaded()) {
810 tab_name += " ";
811 tab_name += ICON_MD_CHECK_CIRCLE;
812 }
813
814 if (ImGui::BeginTabItem(tab_name.c_str())) {
815 if (!is_active) {
816 SwitchToSession(index);
817 }
818 ImGui::EndTabItem();
819 }
820
821 ImGui::PopStyleColor();
822}
823
825 if (ImGui::MenuItem(
826 absl::StrFormat("%s Switch to Session", ICON_MD_TAB).c_str())) {
827 SwitchToSession(index);
828 }
829
830 if (ImGui::MenuItem(absl::StrFormat("%s Rename", ICON_MD_EDIT).c_str())) {
831 session_to_rename_ = index;
832 strncpy(session_rename_buffer_, GetSessionDisplayName(index).c_str(),
833 sizeof(session_rename_buffer_) - 1);
836 }
837
838 if (ImGui::MenuItem(
839 absl::StrFormat("%s Duplicate", ICON_MD_CONTENT_COPY).c_str())) {
840 // TODO: Implement session duplication
841 }
842
843 ImGui::Separator();
844
845 if (HasMultipleSessions() &&
846 ImGui::MenuItem(
847 absl::StrFormat("%s Close Session", ICON_MD_CLOSE).c_str())) {
848 CloseSession(index);
849 }
850}
851
853 auto* sessions = GET_SESSIONS();
854 if (!sessions || index >= sessions->size())
855 return;
856
857 const auto& session = sessions->at(index);
858 ImVec4 color = GetSessionColor(index);
859
860 ImGui::PushStyleColor(ImGuiCol_Text, color);
861
862 if (session.rom.is_loaded()) {
863 ImGui::Text("%s", ICON_MD_CHECK_CIRCLE);
864 } else {
865 ImGui::Text("%s", ICON_MD_RADIO_BUTTON_UNCHECKED);
866 }
867
868 ImGui::PopStyleColor();
869}
870
871ImVec4 SessionCoordinator::GetSessionColor(size_t index) const {
872 // Generate consistent colors for sessions
873 static const ImVec4 colors[] = {
874 ImVec4(0.0f, 1.0f, 0.0f, 1.0f), // Green
875 ImVec4(0.0f, 0.5f, 1.0f, 1.0f), // Blue
876 ImVec4(1.0f, 0.5f, 0.0f, 1.0f), // Orange
877 ImVec4(1.0f, 0.0f, 1.0f, 1.0f), // Magenta
878 ImVec4(1.0f, 1.0f, 0.0f, 1.0f), // Yellow
879 ImVec4(0.0f, 1.0f, 1.0f, 1.0f), // Cyan
880 ImVec4(1.0f, 0.0f, 0.0f, 1.0f), // Red
881 ImVec4(0.5f, 0.5f, 0.5f, 1.0f), // Gray
882 };
883
884 return colors[index % (sizeof(colors) / sizeof(colors[0]))];
885}
886
887std::string SessionCoordinator::GetSessionIcon(size_t index) const {
888 auto* sessions = GET_SESSIONS();
889 if (!sessions || index >= sessions->size())
891
892 const auto& session = sessions->at(index);
893
894 if (session.rom.is_loaded()) {
896 } else {
898 }
899}
900
901bool SessionCoordinator::IsSessionEmpty(size_t index) const {
902 auto* sessions = GET_SESSIONS();
903 return IsValidSessionIndex(index) && sessions &&
904 !sessions->at(index).rom.is_loaded();
905}
906
907bool SessionCoordinator::IsSessionClosed(size_t index) const {
908 return !IsValidSessionIndex(index);
909}
910
912 // TODO: Implement modification tracking
913 return false;
914}
915
916} // namespace editor
917} // namespace yaze
The Rom class is used to load, save, and modify Rom data.
Definition rom.h:74
Central registry for all editor cards with session awareness and dependency injection.
void HideAllCardsInSession(size_t session_id)
Hide all cards in a specific session.
void UnregisterSession(size_t session_id)
Unregister a session and all its cards.
void SetActiveSession(size_t session_id)
Set the currently active session.
void ShowAllCardsInCategory(size_t session_id, const std::string &category)
Show all cards in a category for a session.
void ShowAllCardsInSession(size_t session_id)
Show all cards in a specific session.
void HideAllCardsInCategory(size_t session_id, const std::string &category)
Hide all cards in a category for a session.
Contains a complete set of editors for a single ROM instance.
void * GetSession(size_t index) const
std::string GenerateUniqueEditorTitle(const std::string &editor_name, size_t session_index) const
absl::StatusOr< RomSession * > CreateSessionFromRom(Rom &&rom, const std::string &filepath)
absl::Status SaveSessionAs(size_t session_index, const std::string &filename)
absl::Status SaveActiveSession(const std::string &filename="")
ImVec4 GetSessionColor(size_t index) const
absl::Status LoadRomIntoSession(const std::string &filename, size_t session_index=SIZE_MAX)
std::string GetSessionDisplayName(size_t index) const
void RenameSession(size_t index, const std::string &new_name)
bool IsSessionModified(size_t index) const
bool HasDuplicateSession(const std::string &filepath) const
bool IsSessionClosed(size_t index) const
std::string GetSessionIcon(size_t index) const
SessionCoordinator(void *sessions_ptr, EditorCardRegistry *card_registry, ToastManager *toast_manager, UserSettings *user_settings)
void ShowCardsInCategory(const std::string &category)
std::string GetActiveSessionDisplayName() const
void ShowSessionOperationResult(const std::string &operation, bool success)
bool IsValidSessionIndex(size_t index) const
bool IsSessionEmpty(size_t index) const
void DrawSessionTab(size_t index, bool is_active)
bool IsSessionActive(size_t index) const
void HideCardsInCategory(const std::string &category)
void ValidateSessionIndex(size_t index) const
bool IsSessionLoaded(size_t index) const
std::string GenerateUniqueSessionName(const std::string &base_name) const
void Show(const std::string &message, ToastType type=ToastType::kInfo, float ttl_seconds=3.0f)
Manages user preferences and settings persistence.
static ThemeManager & Get()
const EnhancedTheme & GetCurrentTheme() const
#define ICON_MD_EDIT
Definition icons.h:643
#define ICON_MD_ADD
Definition icons.h:84
#define ICON_MD_CHECK_CIRCLE
Definition icons.h:398
#define ICON_MD_RADIO_BUTTON_CHECKED
Definition icons.h:1546
#define ICON_MD_TAB
Definition icons.h:1928
#define ICON_MD_CONTENT_COPY
Definition icons.h:463
#define ICON_MD_RADIO_BUTTON_UNCHECKED
Definition icons.h:1549
#define ICON_MD_CLOSE
Definition icons.h:416
#define ICON_MD_ANALYTICS
Definition icons.h:152
#define LOG_INFO(category, format,...)
Definition log.h:106
ImVec4 ConvertColorToImVec4(const Color &color)
Definition color.h:21
Main namespace for the application.
Definition controller.cc:20
#define GET_SESSIONS()
Represents a single session, containing a ROM and its associated editors.