diff --git a/src/app/core/controller.cc b/src/app/core/controller.cc index c56a2e47..e934ad86 100644 --- a/src/app/core/controller.cc +++ b/src/app/core/controller.cc @@ -8,6 +8,8 @@ #include +#include "absl/status/status.h" +#include "absl/strings/str_format.h" #include "app/editor/master_editor.h" #include "gui/icons.h" #include "gui/style.h" @@ -16,13 +18,9 @@ namespace yaze { namespace app { namespace core { -bool Controller::isActive() const { return active_; } +namespace { -void Controller::onEntry() { - CreateWindow(); - CreateRenderer(); - CreateGuiContext(); - master_editor_.SetupScreen(sdl_renderer_); +void InitializeKeymap() { ImGuiIO &io = ImGui::GetIO(); io.KeyMap[ImGuiKey_Backspace] = SDL_GetScancodeFromKey(SDLK_BACKSPACE); io.KeyMap[ImGuiKey_Enter] = SDL_GetScancodeFromKey(SDLK_RETURN); @@ -30,67 +28,46 @@ void Controller::onEntry() { io.KeyMap[ImGuiKey_DownArrow] = SDL_GetScancodeFromKey(SDLK_DOWN); io.KeyMap[ImGuiKey_Tab] = SDL_GetScancodeFromKey(SDLK_TAB); io.KeyMap[ImGuiKey_LeftCtrl] = SDL_GetScancodeFromKey(SDLK_LCTRL); - active_ = true; } -void Controller::onInput() { - int wheel = 0; +void HandleKeyDown(SDL_Event &event) { + ImGuiIO &io = ImGui::GetIO(); + switch (event.key.keysym.sym) { + case SDLK_UP: + case SDLK_DOWN: + case SDLK_RETURN: + case SDLK_BACKSPACE: + case SDLK_TAB: + io.KeysDown[event.key.keysym.scancode] = (event.type == SDL_KEYDOWN); + break; + default: + break; + } +} + +void HandleKeyUp(SDL_Event &event) { + ImGuiIO &io = ImGui::GetIO(); + int key = event.key.keysym.scancode; + IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown)); + io.KeysDown[key] = (event.type == SDL_KEYDOWN); + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); +} + +void ChangeWindowSizeEvent(SDL_Event &event) { + ImGuiIO &io = ImGui::GetIO(); + io.DisplaySize.x = static_cast(event.window.data1); + io.DisplaySize.y = static_cast(event.window.data2); +} + +void HandleMouseMovement(int &wheel) { + ImGuiIO &io = ImGui::GetIO(); int mouseX; int mouseY; - SDL_Event event; - ImGuiIO &io = ImGui::GetIO(); const int buttons = SDL_GetMouseState(&mouseX, &mouseY); - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_KEYDOWN: - switch (event.key.keysym.sym) { - case SDLK_UP: - case SDLK_DOWN: - case SDLK_RETURN: - case SDLK_BACKSPACE: - case SDLK_TAB: - io.KeysDown[event.key.keysym.scancode] = - (event.type == SDL_KEYDOWN); - break; - default: - break; - } - break; - - case SDL_KEYUP: { - int key = event.key.keysym.scancode; - IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown)); - io.KeysDown[key] = (event.type == SDL_KEYDOWN); - io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); - io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); - io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); - io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); - break; - } - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_WINDOWEVENT_CLOSE: - quit(); - break; - case SDL_WINDOWEVENT_SIZE_CHANGED: - io.DisplaySize.x = static_cast(event.window.data1); - io.DisplaySize.y = static_cast(event.window.data2); - break; - default: - break; - } - break; - case SDL_TEXTINPUT: - io.AddInputCharactersUTF8(event.text.text); - break; - case SDL_MOUSEWHEEL: - wheel = event.wheel.y; - break; - default: - break; - } - } io.DeltaTime = 1.0f / 60.0f; io.MousePos = ImVec2(static_cast(mouseX), static_cast(mouseY)); io.MouseDown[0] = buttons & SDL_BUTTON(SDL_BUTTON_LEFT); @@ -98,13 +75,66 @@ void Controller::onInput() { io.MouseWheel = static_cast(wheel); } +} // namespace + +bool Controller::isActive() const { return active_; } + +void Controller::onEntry() { + CreateWindow(); + CreateRenderer(); + CreateGuiContext(); + InitializeKeymap(); + master_editor_.SetupScreen(renderer_); + active_ = true; +} + +void Controller::onInput() { + int wheel = 0; + SDL_Event event; + ImGuiIO &io = ImGui::GetIO(); + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_KEYDOWN: + HandleKeyDown(event); + break; + case SDL_KEYUP: + HandleKeyUp(event); + break; + case SDL_TEXTINPUT: + io.AddInputCharactersUTF8(event.text.text); + break; + case SDL_MOUSEWHEEL: + wheel = event.wheel.y; + break; + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_CLOSE: + CloseWindow(); + break; + case SDL_WINDOWEVENT_SIZE_CHANGED: + ChangeWindowSizeEvent(event); + break; + default: + break; + } + break; + + default: + break; + } + } + + HandleMouseMovement(wheel); +} + void Controller::onLoad() { master_editor_.UpdateScreen(); } void Controller::doRender() const { - SDL_RenderClear(sdl_renderer_.get()); + SDL_RenderClear(renderer_.get()); ImGui::Render(); ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData()); - SDL_RenderPresent(sdl_renderer_.get()); + SDL_RenderPresent(renderer_.get()); } void Controller::onExit() const { @@ -118,7 +148,7 @@ void Controller::CreateWindow() { if (SDL_Init(SDL_INIT_EVERYTHING)) { SDL_Log("SDL_Init: %s\n", SDL_GetError()); } else { - sdl_window_ = std::unique_ptr( + window_ = std::unique_ptr( SDL_CreateWindow("Yet Another Zelda3 Editor", // window title SDL_WINDOWPOS_UNDEFINED, // initial x position SDL_WINDOWPOS_UNDEFINED, // initial y position @@ -130,21 +160,21 @@ void Controller::CreateWindow() { } void Controller::CreateRenderer() { - if (sdl_window_ == nullptr) { + if (window_ == nullptr) { SDL_Log("SDL_CreateWindow: %s\n", SDL_GetError()); SDL_Quit(); } else { - sdl_renderer_ = std::unique_ptr( + renderer_ = std::unique_ptr( SDL_CreateRenderer( - sdl_window_.get(), -1, + window_.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), sdl_deleter()); - if (sdl_renderer_ == nullptr) { + if (renderer_ == nullptr) { SDL_Log("SDL_CreateRenderer: %s\n", SDL_GetError()); SDL_Quit(); } else { - SDL_SetRenderDrawBlendMode(sdl_renderer_.get(), SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawColor(sdl_renderer_.get(), 0x00, 0x00, 0x00, 0x00); + SDL_SetRenderDrawBlendMode(renderer_.get(), SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer_.get(), 0x00, 0x00, 0x00, 0x00); } } } @@ -154,8 +184,8 @@ void Controller::CreateGuiContext() const { ImGui::CreateContext(); // Initialize ImGui for SDL - ImGui_ImplSDL2_InitForSDLRenderer(sdl_window_.get(), sdl_renderer_.get()); - ImGui_ImplSDLRenderer_Init(sdl_renderer_.get()); + ImGui_ImplSDL2_InitForSDLRenderer(window_.get(), renderer_.get()); + ImGui_ImplSDLRenderer_Init(renderer_.get()); // Load available fonts const ImGuiIO &io = ImGui::GetIO(); @@ -179,7 +209,79 @@ void Controller::CreateGuiContext() const { // Build a new ImGui frame ImGui_ImplSDLRenderer_NewFrame(); - ImGui_ImplSDL2_NewFrame(sdl_window_.get()); + ImGui_ImplSDL2_NewFrame(window_.get()); +} + +// V2 functions --------------------------------------------------------------- + +absl::Status Controller::CreateWindowV2() { + if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { + return absl::InternalError( + absl::StrFormat("SDL_Init: %s\n", SDL_GetError())); + } else { + window_ = std::unique_ptr( + SDL_CreateWindow("Yet Another Zelda3 Editor", // window title + SDL_WINDOWPOS_UNDEFINED, // initial x position + SDL_WINDOWPOS_UNDEFINED, // initial y position + 1200, // width, in pixels + 800, // height, in pixels + SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL), + sdl_deleter()); + if (window_ == nullptr) { + return absl::InternalError( + absl::StrFormat("SDL_CreateWindow: %s\n", SDL_GetError())); + } + } + return absl::OkStatus(); +} + +absl::Status Controller::CreateRendererV2() { + renderer_ = std::unique_ptr( + SDL_CreateRenderer(window_.get(), -1, + SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), + sdl_deleter()); + if (renderer_ == nullptr) { + return absl::InternalError( + absl::StrFormat("SDL_CreateRenderer: %s\n", SDL_GetError())); + } else { + SDL_SetRenderDrawBlendMode(renderer_.get(), SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer_.get(), 0x00, 0x00, 0x00, 0x00); + } + return absl::OkStatus(); +} + +absl::Status Controller::CreateGuiContextV2() { + ImGui::CreateContext(); + + // Initialize ImGui for SDL + ImGui_ImplSDL2_InitForSDLRenderer(window_.get(), renderer_.get()); + ImGui_ImplSDLRenderer_Init(renderer_.get()); + + // Load available fonts + const ImGuiIO &io = ImGui::GetIO(); + io.Fonts->AddFontFromFileTTF("assets/font/Karla-Regular.ttf", 14.0f); + + // merge in icons from Google Material Design + static const ImWchar icons_ranges[] = {ICON_MIN_MD, 0xf900, 0}; + ImFontConfig icons_config; + icons_config.MergeMode = true; + icons_config.GlyphOffset.y = 5.0f; + icons_config.GlyphMinAdvanceX = 13.0f; + icons_config.PixelSnapH = true; + io.Fonts->AddFontFromFileTTF(FONT_ICON_FILE_NAME_MD, 18.0f, &icons_config, + icons_ranges); + io.Fonts->AddFontFromFileTTF("assets/font/Roboto-Medium.ttf", 14.0f); + io.Fonts->AddFontFromFileTTF("assets/font/Cousine-Regular.ttf", 14.0f); + io.Fonts->AddFontFromFileTTF("assets/font/DroidSans.ttf", 16.0f); + + // Set the default style + gui::ColorsYaze(); + + // Build a new ImGui frame + ImGui_ImplSDLRenderer_NewFrame(); + ImGui_ImplSDL2_NewFrame(window_.get()); + + return absl::OkStatus(); } } // namespace core diff --git a/src/app/core/controller.h b/src/app/core/controller.h index a32b1485..ec0d181a 100644 --- a/src/app/core/controller.h +++ b/src/app/core/controller.h @@ -10,6 +10,7 @@ #include +#include "absl/status/status.h" #include "app/editor/master_editor.h" #include "gui/icons.h" #include "gui/style.h" @@ -22,8 +23,6 @@ namespace core { class Controller { public: - Controller() = default; - bool isActive() const; void onEntry(); void onInput(); @@ -32,22 +31,27 @@ class Controller { void onExit() const; private: - void CreateWindow(); - void CreateRenderer(); - void CreateGuiContext() const; - void quit() { active_ = false; } - friend int ::main(int argc, char **argv); - struct sdl_deleter { void operator()(SDL_Window *p) const { SDL_DestroyWindow(p); } void operator()(SDL_Renderer *p) const { SDL_DestroyRenderer(p); } void operator()(SDL_Texture *p) const { SDL_DestroyTexture(p); } }; + void CreateWindow(); + void CreateRenderer(); + void CreateGuiContext() const; + void CloseWindow() { active_ = false; } + + absl::Status CreateWindowV2(); + absl::Status CreateRendererV2(); + absl::Status CreateGuiContextV2(); + + friend int ::main(int argc, char **argv); + bool active_; editor::MasterEditor master_editor_; - std::shared_ptr sdl_window_; - std::shared_ptr sdl_renderer_; + std::shared_ptr window_; + std::shared_ptr renderer_; }; } // namespace core