3#include "absl/status/status.h"
4#include "absl/strings/match.h"
23#include "imgui/imgui.h"
24#include "imgui/misc/cpp/imgui_stdlib.h"
31using core::FileDialogWrapper;
36 ImGuiIO
const& io = GetIO();
37 ImVec2 pos(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f);
38 SetNextWindowPos(pos, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
39 ImGuiWindowFlags flags =
40 ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration |
41 ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings;
42 return Begin(name,
nullptr, flags);
46 return std::find(active_editors.begin(), active_editors.end(), editor) !=
53 if (!filename.empty()) {
81 return absl::OkStatus();
86 static bool show_add_editor =
false;
87 if (show_add_editor) OpenPopup(
"AddEditor");
89 if (BeginPopup(
"AddEditor", ImGuiWindowFlags_AlwaysAutoResize)) {
90 if (MenuItem(
"Overworld",
nullptr,
false,
95 if (MenuItem(
"Dungeon",
nullptr,
false,
100 if (MenuItem(
"Graphics",
nullptr,
false,
105 if (MenuItem(
"Music",
nullptr,
false,
110 if (MenuItem(
"Palette",
nullptr,
false,
115 if (MenuItem(
"Screen",
nullptr,
false,
120 if (MenuItem(
"Sprite",
nullptr,
false,
125 if (MenuItem(
"Code",
nullptr,
false,
130 if (MenuItem(
"Message",
nullptr,
false,
135 if (MenuItem(
"Settings",
nullptr,
false,
143 if (!IsPopupOpen(
"AddEditor")) {
144 show_add_editor =
false;
147 if (BeginTabBar(
"##TabBar", ImGuiTabBarFlags_Reorderable |
148 ImGuiTabBarFlags_AutoSelectNewTabs)) {
151 switch (editor->type()) {
154 if (BeginTabItem(
"Overworld", &open)) {
162 if (BeginTabItem(
"Dungeon", &open)) {
173 if (BeginTabItem(
"Graphics", &open)) {
180 if (BeginTabItem(
"Music", &open)) {
188 if (BeginTabItem(
"Palette", &open)) {
195 if (BeginTabItem(
"Screen", &open)) {
202 if (BeginTabItem(
"Sprite", &open)) {
209 if (BeginTabItem(
"Code", &open)) {
216 if (BeginTabItem(
"Settings", &open)) {
223 if (BeginTabItem(
"Message", &open)) {
239 if (TabItemButton(
ICON_MD_ADD, ImGuiTabItemFlags_Trailing)) {
240 show_add_editor =
true;
254 bool ctrl_or_super = (GetIO().KeyCtrl || GetIO().KeySuper);
259 if (IsKeyDown(ImGuiKey_R) && ctrl_or_super) {
268 if (IsKeyDown(ImGuiKey_F1)) {
273 if (IsKeyDown(ImGuiKey_Q) && ctrl_or_super) {
278 if (IsKeyDown(ImGuiKey_O) && ctrl_or_super) {
283 if (IsKeyDown(ImGuiKey_S) && ctrl_or_super) {
287 if (IsKeyDown(ImGuiKey_X) && ctrl_or_super) {
291 if (IsKeyDown(ImGuiKey_C) && ctrl_or_super) {
295 if (IsKeyDown(ImGuiKey_V) && ctrl_or_super) {
299 if (IsKeyDown(ImGuiKey_Z) && ctrl_or_super) {
303 if (IsKeyDown(ImGuiKey_Y) && ctrl_or_super) {
307 if (IsKeyDown(ImGuiKey_F) && ctrl_or_super) {
319 if (ImGui::BeginPopup(
"NewEditor")) {
320 ImGui::Text(
"New Editor");
322 if (ImGui::Button(
"Overworld")) {
324 ImGui::CloseCurrentPopup();
326 if (ImGui::Button(
"Dungeon")) {
328 ImGui::CloseCurrentPopup();
330 if (ImGui::Button(
"Graphics")) {
332 ImGui::CloseCurrentPopup();
334 if (ImGui::Button(
"Music")) {
336 ImGui::CloseCurrentPopup();
338 if (ImGui::Button(
"Palette")) {
340 ImGui::CloseCurrentPopup();
342 if (ImGui::Button(
"Screen")) {
344 ImGui::CloseCurrentPopup();
346 if (ImGui::Button(
"Sprite")) {
348 ImGui::CloseCurrentPopup();
350 if (ImGui::Button(
"Code")) {
352 ImGui::CloseCurrentPopup();
354 if (ImGui::Button(
"Settings")) {
356 ImGui::CloseCurrentPopup();
358 if (ImGui::Button(
"Message")) {
360 ImGui::CloseCurrentPopup();
366 "window management",
"");
368 "window",
"vsplit",
'/',
"vertical split",
369 "split windows vertically and place editor in new window", [
this]() {
370 ImGui::OpenPopup(
"NewEditor");
374 "window",
"hsplit",
'-',
"horizontal split",
375 "split windows horizontally and place editor in new window", [
this]() {
376 ImGui::OpenPopup(
"NewEditor");
380 "window",
"close",
'd',
"close",
"close the current editor", [
this]() {
388 static absl::Status prev_status;
396 Text(
"%s", prev_status.ToString().c_str());
409 SetClipboardText(prev_status.ToString().c_str());
416 if (
about_) OpenPopup(
"About");
417 if (BeginPopupModal(
"About",
nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
419 Text(
"Written by: scawful");
421 Text(
"Special Thanks: Zarby89, JaredBrian");
433 if (
rom_info_) OpenPopup(
"ROM Information");
434 if (BeginPopupModal(
"ROM Information",
nullptr,
435 ImGuiWindowFlags_AlwaysAutoResize)) {
436 Text(
"Title: %s",
rom()->title().c_str());
440 IsKeyPressed(ImGuiKey_Escape)) {
449 static bool show_display_settings =
false;
451 if (BeginMenuBar()) {
453 SameLine(GetWindowWidth() - GetStyle().ItemSpacing.x -
455 PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
457 show_display_settings = !show_display_settings;
464 if (show_display_settings) {
465 Begin(
"Display Settings", &show_display_settings, ImGuiWindowFlags_None);
472 static bool save_as_menu =
false;
473 static bool new_project_menu =
false;
475 if (BeginMenu(
"File")) {
476 if (MenuItem(
"Open",
"Ctrl+O")) {
480 if (BeginMenu(
"Open Recent")) {
484 MenuItem(
"No Recent Files",
nullptr,
false,
false);
487 if (MenuItem(filePath.c_str())) {
496 if (
rom()->is_loaded()) {
500 MENU_ITEM(
"Save As..") { save_as_menu =
true; }
502 if (
rom()->is_loaded()) {
511 if (BeginMenu(
"Project")) {
512 if (MenuItem(
"Create New Project")) {
514 new_project_menu =
true;
516 if (MenuItem(
"Open Project")) {
524 if (MenuItem(
"Save Project")) {
532 if (BeginMenu(
"Options")) {
536 if (BeginMenu(
"Experiment Flags")) {
546 if (MenuItem(
"Quit",
"Ctrl+Q")) {
554 static std::string save_as_filename =
"";
555 Begin(
"Save As..", &save_as_menu, ImGuiWindowFlags_AlwaysAutoResize);
556 InputText(
"Filename", &save_as_filename);
559 save_as_menu =
false;
563 save_as_menu =
false;
568 if (new_project_menu) {
569 Begin(
"New Project", &new_project_menu, ImGuiWindowFlags_AlwaysAutoResize);
570 static std::string save_as_filename =
"";
571 InputText(
"Project Name", &save_as_filename);
596 new_project_menu =
false;
604 new_project_menu =
false;
609 if (BeginMenu(
"Edit")) {
621 static bool show_imgui_metrics =
false;
622 static bool show_memory_editor =
false;
623 static bool show_asm_editor =
false;
624 static bool show_imgui_demo =
false;
625 static bool show_palette_editor =
false;
626 static bool show_emulator =
false;
628 if (show_imgui_demo) ShowDemoWindow();
629 if (show_imgui_metrics) ShowMetricsWindow(&show_imgui_metrics);
634 Begin(
"Emulator", &show_emulator, ImGuiWindowFlags_MenuBar);
639 if (show_palette_editor) {
640 Begin(
"Palette Editor", &show_palette_editor);
645 if (BeginMenu(
"View")) {
647 MenuItem(
"Emulator",
nullptr, &show_emulator);
649 MenuItem(
"Memory Editor",
nullptr, &show_memory_editor);
650 MenuItem(
"Assembly Editor",
nullptr, &show_asm_editor);
651 MenuItem(
"Palette Editor",
nullptr, &show_palette_editor);
655 MenuItem(
"ImGui Demo",
nullptr, &show_imgui_demo);
656 MenuItem(
"ImGui Metrics",
nullptr, &show_imgui_metrics);
660 static bool show_resource_label_manager =
false;
662 if (BeginMenu(
"Project")) {
668 MenuItem(
"Resource Labels",
nullptr, &show_resource_label_manager);
673 static bool open_rom_help =
false;
674 static bool open_supported_features =
false;
675 static bool open_manage_project =
false;
676 if (BeginMenu(
"Help")) {
677 if (MenuItem(
"How to open a ROM")) open_rom_help =
true;
678 if (MenuItem(
"Supported Features")) open_supported_features =
true;
679 if (MenuItem(
"How to manage a project")) open_manage_project =
true;
681 if (MenuItem(
"About",
"F1"))
about_ =
true;
685 if (open_supported_features) OpenPopup(
"Supported Features");
686 if (BeginPopupModal(
"Supported Features",
nullptr,
687 ImGuiWindowFlags_AlwaysAutoResize)) {
689 BulletText(
"LW/DW/SW Tilemap Editing");
690 BulletText(
"LW/DW/SW Map Properties");
691 BulletText(
"Create/Delete/Update Entrances");
692 BulletText(
"Create/Delete/Update Exits");
693 BulletText(
"Create/Delete/Update Sprites");
694 BulletText(
"Create/Delete/Update Items");
697 BulletText(
"View Room Header Properties");
698 BulletText(
"View Entrance Properties");
701 BulletText(
"View Decompressed Graphics Sheets");
702 BulletText(
"View/Update Graphics Groups");
705 BulletText(
"View Palette Groups");
708 BulletText(
"All Listed Overworld Features");
709 BulletText(
"Hex Editor Changes");
712 open_supported_features =
false;
718 if (open_rom_help) OpenPopup(
"Open a ROM");
719 if (BeginPopupModal(
"Open a ROM",
nullptr,
720 ImGuiWindowFlags_AlwaysAutoResize)) {
721 Text(
"File -> Open");
722 Text(
"Select a ROM file to open");
723 Text(
"Supported ROMs (headered or unheadered):");
724 Text(
"The Legend of Zelda: A Link to the Past");
725 Text(
"US Version 1.0");
726 Text(
"JP Version 1.0");
729 open_rom_help =
false;
735 if (open_manage_project) OpenPopup(
"Manage Project");
736 if (BeginPopupModal(
"Manage Project",
nullptr,
737 ImGuiWindowFlags_AlwaysAutoResize)) {
738 Text(
"Project Menu");
739 Text(
"Create a new project or open an existing one.");
740 Text(
"Save the project to save the current state of the project.");
742 "To save a project, you need to first open a ROM and initialize your "
743 "code path and labels file. Label resource manager can be found in "
744 "the View menu. Code path is set in the Code editor after opening a "
748 open_manage_project =
false;
754 if (show_resource_label_manager) {
755 rom()->resource_label()->DisplayLabels(&show_resource_label_manager);
765 auto load_rom =
rom()->LoadFromFile(file_name);
775 if (
flags()->kSaveDungeonMaps) {
787 if (absl::StrContains(filename,
".yaze")) {
801 return absl::InternalError(
802 "Could not load labels file, update your project file.");
815 return absl::OkStatus();
const std::vector< std::string > & GetRecentFiles() const
void AddFile(const std::string &file_path)
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath.
static std::string ShowOpenFolderDialog()
ShowOpenFolderDialog opens a file dialog and returns the selected folder path.
void OpenFolder(const std::string &folder_path)
void Update(bool &is_loaded)
void RegisterSubcommand(const std::string &group_name, const std::string &shortcut, const char mnemonic, const std::string &name, const std::string &desc, Command command)
void RegisterPrefix(const std::string &group_name, const char prefix, const std::string &name, const std::string &desc)
absl::Status Update() override
void ManageActiveEditors()
SpriteEditor sprite_editor_
AssemblyEditor assembly_editor_
GraphicsEditor graphics_editor_
SettingsEditor settings_editor_
void SetupScreen(std::string filename="")
PaletteEditor palette_editor_
ScreenEditor screen_editor_
EditorLayoutParams root_layout_
absl::Status DrawDynamicLayout()
MusicEditor music_editor_
void InitializeCommands()
void OpenRomOrProject(const std::string &filename)
absl::Status OpenProject()
void ManageKeyboardShortcuts()
MemoryEditorWithDiffChecker memory_editor_
OverworldEditor overworld_editor_
MessageEditor message_editor_
EditorContext editor_context_
DungeonEditor dungeon_editor_
std::vector< Editor * > active_editors_
Interface for editor classes.
virtual absl::Status Cut()=0
virtual absl::Status Undo()=0
virtual absl::Status Find()=0
virtual absl::Status Redo()=0
virtual absl::Status Copy()=0
virtual absl::Status Paste()=0
absl::Status Update() override
absl::Status Update() override
absl::Status Update() override
absl::Status Update() final
absl::Status LoadGraphics()
Load the Bitmap objects for each OverworldMap.
absl::Status Update() override
absl::Status Update() override
absl::Status SaveDungeonMaps()
absl::Status Update() override
absl::Status Update() override
Updates the sprite editor.
#define PRINT_IF_ERROR(expression)
#define RETURN_IF_ERROR(expression)
#define RETURN_VOID_IF_ERROR(expression)
#define ICON_MD_DISPLAY_SETTINGS
#define ICON_MD_CONTENT_COPY
std::string UppercaseHexLongLong(uint64_t qword)
constexpr std::string_view kYazeVersion
bool BeginCentered(const char *name)
bool IsEditorActive(Editor *editor, std::vector< Editor * > &active_editors)
absl::Status DrawEditor(EditorLayoutParams *params)
constexpr ImVec2 kDefaultModalSize
void DrawDisplaySettings(ImGuiStyle *ref)
absl::Status Open(const std::string &project_path)
std::string labels_filename_
absl::Status Create(const std::string &project_name)
std::string rom_filename_
static CommandManager command_manager
Dynamic Editor Layout Parameters.
void Update(bool &show_memory_editor)