From 348a1bfb244288b1c78d8ce3c8d8a8cb5c1bdebc Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Tue, 24 Sep 2024 20:00:16 -0500 Subject: Start app rendering. --- CMakeLists.txt | 2 +- src/bookmouse.cpp | 211 ++++++++++++++++++++++++++++++-------------------- src/bookmouse.hpp | 49 ++++-------- src/bookmouse_old.cpp | 106 +++++++++++++++++++++++++ src/bookmouse_old.hpp | 51 ++++++++++++ src/demo.cpp | 28 +------ src/imgui_context.cpp | 26 ++++++- src/imgui_context.hpp | 8 +- src/main.cpp | 22 +----- 9 files changed, 336 insertions(+), 167 deletions(-) create mode 100644 src/bookmouse_old.cpp create mode 100644 src/bookmouse_old.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dcf8ee..c59a9a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ add_executable(bookmouse src/sdl_main_window.cpp src/imgui_context.cpp src/gl_context.cpp -# src/bookmouse.cpp + src/bookmouse.cpp ) include(warnings.cmake) diff --git a/src/bookmouse.cpp b/src/bookmouse.cpp index 9ba09c4..65184ef 100644 --- a/src/bookmouse.cpp +++ b/src/bookmouse.cpp @@ -1,106 +1,149 @@ #include "bookmouse.hpp" -#include "main_window.hpp" + +#include +#include namespace bookmouse { -Bookmouse::Bookmouse() +Bookmouse::Bookmouse() : + m_sdlContext{}, m_mainWindow{m_sdlContext}, m_glContext{m_mainWindow}, + m_imgui{m_glContext, m_sdlContext, m_mainWindow} { - m_layout = new QVBoxLayout(); - - m_layout->addWidget(&m_pageLeft); - m_layout->addWidget(&m_pageRight); - - setLayout(m_layout); + /* + * Load Fonts + * + * - If no fonts are loaded, dear imgui will use the default + * font. You can also load multiple fonts and use + * ImGui::PushFont()/PopFont() to select them. + * - AddFontFromFileTTF() will return the ImFont* so you can store + * it if you need to select the font among multiple. + * - If the file cannot be loaded, the function will return a + * nullptr. Please handle those errors in your application + * (e.g. use an assertion, or display an error and quit). + * - The fonts will be rasterized at a given size (w/ + * oversampling) and stored into a texture when calling + * ImFontAtlas::Build()/GetTexDataAsXXXX(), which + * ImGui_ImplXXXX_NewFrame below will call. + * - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to + * - use Freetype for higher quality font rendering. + * - Read 'docs/FONTS.md' for more instructions and details. + * - Remember that in C/C++ if you want to include a backslash \ + * in a string literal you need to write a double backslash \\ ! + * - Our Emscripten build process allows embedding fonts to be + * - accessible at runtime from the "fonts/" folder. See + * Makefile.emscripten for details. + * auto imguiIO = m_imgui.getIO(); + * imguiIO.Fonts->AddFontDefault(); + * imguiIO.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); + * imguiIO.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + * imguiIO.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + * imguiIO.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + * ImFont* font = imguiIO.Fonts->AddFontFromFileTTF( + * "c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, + * io.Fonts->GetGlyphRangesJapanese()); IM_ASSERT(font != nullptr); + */ } -void Bookmouse::setArchive(Archive* archive) { - if (archive == m_archive) { - return; +int Bookmouse::run() +{ + while (m_running) { + auto event = pollEvent(); + static_cast(event); + + constexpr uint32_t delayMillis = 10; + if (SDL_GetWindowFlags(m_mainWindow.window()) & SDL_WINDOW_MINIMIZED) { + SDL_Delay(delayMillis); + continue; + } + m_imgui.startFrame(); + updateState(); + renderFrame(); } - delete(m_archive); - m_archive = archive; - m_pageNumber = 0; - setPages(); + return 0; } -void Bookmouse::next() { - auto numPages = m_archive->numPages(); - size_t increment = 1; - if (m_pageLayout != PageLayout::Single) { - increment = 2; - } - if ((m_pageNumber + increment) >= numPages) - { - return; +SDL_Event Bookmouse::pollEvent() +{ + /* + * Poll and handle events (inputs, window resize, etc.) + * You can read the io.WantCaptureMouse, io.WantCaptureKeyboard + * flags to tell if dear imgui wants to use your inputs. + * - When io.WantCaptureMouse is true, do not dispatch mouse input + * data to your main application, or clear/overwrite your copy of + * the mouse data. + * - When io.WantCaptureKeyboard is true, do not dispatch keyboard + * input data to your main application, or clear/overwrite your + * copy of the keyboard data. + * Generally you may always pass all inputs to dear imgui, and + * hide them from your application based on those two flags. + */ + SDL_Event event{}; + while (SDL_PollEvent(&event)) { + static_cast(m_imgui.processEvent(event)); + if (event.type == SDL_QUIT) { + m_running = false; + } + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && + event.window.windowID == SDL_GetWindowID(m_mainWindow.window())) { + m_running = false; + } } - m_pageNumber += increment; - setPages(); + return event; } -void Bookmouse::back() { - auto numPages = m_archive->numPages(); - size_t decrement = 1; - if (m_pageLayout != PageLayout::Single) { - decrement = 2; - } - if (m_pageNumber < decrement) - { - m_pageNumber = 0; - decrement = 0; +void Bookmouse::updateState() +{ + bool my_tool_active{true}; + ImGui::Begin("My First Tool", &my_tool_active, ImGuiWindowFlags_MenuBar); + if (ImGui::BeginMenuBar()) { + if (ImGui::BeginMenu("File")) { + if (ImGui::MenuItem("Open..", "Ctrl+O")) { /* Do stuff */ + } + if (ImGui::MenuItem("Save", "Ctrl+S")) { /* Do stuff */ + } + if (ImGui::MenuItem("Close", "Ctrl+W")) { + my_tool_active = false; + } + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); } - m_pageNumber -= decrement; - setPages(); -} -void Bookmouse::setPages() { - m_pageLeft.setPixmap(QPixmap()); - m_pageRight.setPixmap(QPixmap()); + // Edit a color stored as 4 floats + fud::Array my_color{}; + ImGui::ColorEdit4("Color", my_color.data()); - switch (m_pageLayout) - { - case PageLayout::Dual: - return setPagesDual(); - case PageLayout::Manga: - return setPagesManga(); - case PageLayout::Single: - default: - return setPagesNormal(); + // Generate samples and plot them + float samples[100]; + for (int idx = 0; idx < 100; idx++) { + auto num = static_cast(idx); + auto time = static_cast(ImGui::GetTime()); + samples[idx] = sinf(num * 0.2f + time * 1.5f); } + ImGui::PlotLines("Samples", samples, 100); + + // Display contents in a scrolling region + ImGui::TextColored(ImVec4(1, 1, 0, 1), "Important Stuff"); + ImGui::BeginChild("Scrolling"); + for (int n = 0; n < 50; n++) + ImGui::Text("%04d: Some text", n); + ImGui::EndChild(); + ImGui::End(); } -void Bookmouse::setPagesNormal() { - auto page1 = m_archive->getPage(m_pageNumber); - auto& label1 = m_pageLeft; - - if (page1.isOkay()) { - label1.setPixmap(QPixmap::fromImage(page1.getOkay())); - } -} - -void Bookmouse::setPagesDual() { - auto& label1 = m_pageLeft; - auto& label2 = m_pageRight; - setPages(label1, label2); -} - -void Bookmouse::setPagesManga() { - auto& label1 = m_pageRight; - auto& label2 = m_pageLeft; - setPages(label1, label2); -} - -void Bookmouse::setPages(QLabel& label1, QLabel& label2) { - auto page1 = m_archive->getPage(m_pageNumber); - auto page2 = m_archive->getPage(m_pageNumber + 1); - - if (page1.isOkay()) { - label1.setPixmap(QPixmap::fromImage(page1.getOkay())); - } - - - if (page2.isOkay()) { - label2.setPixmap(QPixmap::fromImage(page1.getOkay())); - } +void Bookmouse::renderFrame() +{ + ImGui::Render(); + const auto& imguiIO = m_imgui.getIO(); + glViewport(0, 0, static_cast(imguiIO.DisplaySize.x), static_cast(imguiIO.DisplaySize.y)); + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + glClearColor( + clear_color.x * clear_color.w, + clear_color.y * clear_color.w, + clear_color.z * clear_color.w, + clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + m_imgui.render(); } } // namespace bookmouse diff --git a/src/bookmouse.hpp b/src/bookmouse.hpp index b2a3a5a..58872d8 100644 --- a/src/bookmouse.hpp +++ b/src/bookmouse.hpp @@ -1,49 +1,30 @@ #ifndef BOOKMOUSE_HPP #define BOOKMOUSE_HPP -#include "archive.hpp" - -#include -#include -#include +#include "gl_context.hpp" +#include "imgui_context.hpp" +#include "sdl_context.hpp" +#include "sdl_main_window.hpp" namespace bookmouse { -enum class PageLayout : uint8_t { - Single, - Dual, - Manga -}; - -class Bookmouse : public QWidget { - Q_OBJECT - +class Bookmouse { public: - friend class BookmouseApp; - Bookmouse(); + Bookmouse() noexcept(false); - public slots: - void setArchive(Archive* archive); - void next(); - void back(); + int run(); private: - void setPages(); - void setPagesNormal(); - void setPagesDual(); - void setPagesManga(); - void setPages(QLabel& label1, QLabel& label2); - - QLayout* m_layout{nullptr}; - - Archive* m_archive{nullptr}; - - PageLayout m_pageLayout{PageLayout::Single}; + SDL_Event pollEvent(); + void updateState(); + void renderFrame(); - QLabel m_pageLeft{}; - QLabel m_pageRight{}; + SdlContext m_sdlContext; + SdlMainWindow m_mainWindow; + GlContext m_glContext; + ImguiContext m_imgui; - size_t m_pageNumber{0}; + bool m_running{true}; }; } // namespace bookmouse diff --git a/src/bookmouse_old.cpp b/src/bookmouse_old.cpp new file mode 100644 index 0000000..9ba09c4 --- /dev/null +++ b/src/bookmouse_old.cpp @@ -0,0 +1,106 @@ +#include "bookmouse.hpp" +#include "main_window.hpp" + +namespace bookmouse { + +Bookmouse::Bookmouse() +{ + m_layout = new QVBoxLayout(); + + m_layout->addWidget(&m_pageLeft); + m_layout->addWidget(&m_pageRight); + + setLayout(m_layout); +} + +void Bookmouse::setArchive(Archive* archive) { + if (archive == m_archive) { + return; + } + delete(m_archive); + m_archive = archive; + m_pageNumber = 0; + setPages(); +} + +void Bookmouse::next() { + auto numPages = m_archive->numPages(); + size_t increment = 1; + if (m_pageLayout != PageLayout::Single) { + increment = 2; + } + if ((m_pageNumber + increment) >= numPages) + { + return; + } + m_pageNumber += increment; + setPages(); +} + +void Bookmouse::back() { + auto numPages = m_archive->numPages(); + size_t decrement = 1; + if (m_pageLayout != PageLayout::Single) { + decrement = 2; + } + if (m_pageNumber < decrement) + { + m_pageNumber = 0; + decrement = 0; + } + m_pageNumber -= decrement; + setPages(); +} + +void Bookmouse::setPages() { + m_pageLeft.setPixmap(QPixmap()); + m_pageRight.setPixmap(QPixmap()); + + switch (m_pageLayout) + { + case PageLayout::Dual: + return setPagesDual(); + case PageLayout::Manga: + return setPagesManga(); + case PageLayout::Single: + default: + return setPagesNormal(); + } +} + +void Bookmouse::setPagesNormal() { + auto page1 = m_archive->getPage(m_pageNumber); + auto& label1 = m_pageLeft; + + if (page1.isOkay()) { + label1.setPixmap(QPixmap::fromImage(page1.getOkay())); + } +} + +void Bookmouse::setPagesDual() { + auto& label1 = m_pageLeft; + auto& label2 = m_pageRight; + setPages(label1, label2); +} + +void Bookmouse::setPagesManga() { + auto& label1 = m_pageRight; + auto& label2 = m_pageLeft; + setPages(label1, label2); +} + +void Bookmouse::setPages(QLabel& label1, QLabel& label2) { + auto page1 = m_archive->getPage(m_pageNumber); + auto page2 = m_archive->getPage(m_pageNumber + 1); + + if (page1.isOkay()) { + label1.setPixmap(QPixmap::fromImage(page1.getOkay())); + } + + + if (page2.isOkay()) { + label2.setPixmap(QPixmap::fromImage(page1.getOkay())); + } +} + +} // namespace bookmouse diff --git a/src/bookmouse_old.hpp b/src/bookmouse_old.hpp new file mode 100644 index 0000000..b2a3a5a --- /dev/null +++ b/src/bookmouse_old.hpp @@ -0,0 +1,51 @@ +#ifndef BOOKMOUSE_HPP +#define BOOKMOUSE_HPP + +#include "archive.hpp" + +#include +#include +#include + +namespace bookmouse { + +enum class PageLayout : uint8_t { + Single, + Dual, + Manga +}; + +class Bookmouse : public QWidget { + Q_OBJECT + + public: + friend class BookmouseApp; + Bookmouse(); + + public slots: + void setArchive(Archive* archive); + void next(); + void back(); + + private: + void setPages(); + void setPagesNormal(); + void setPagesDual(); + void setPagesManga(); + void setPages(QLabel& label1, QLabel& label2); + + QLayout* m_layout{nullptr}; + + Archive* m_archive{nullptr}; + + PageLayout m_pageLayout{PageLayout::Single}; + + QLabel m_pageLeft{}; + QLabel m_pageRight{}; + + size_t m_pageNumber{0}; +}; + +} // namespace bookmouse + +#endif diff --git a/src/demo.cpp b/src/demo.cpp index 64d75a7..279e59d 100644 --- a/src/demo.cpp +++ b/src/demo.cpp @@ -112,28 +112,6 @@ int demo(const fud::String& m_filename) bool ret = LoadTextureFromFile(m_filename, &my_image_texture, &my_image_width, &my_image_height); IM_ASSERT(ret); - // Load Fonts - // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use - // ImGui::PushFont()/PopFont() to select them. - // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. - // - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your - // application (e.g. use an assertion, or display an error and quit). - // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling - // ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. - // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. - // - Read 'docs/FONTS.md' for more instructions and details. - // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double - // backslash \\ ! - // - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See - // Makefile.emscripten for details. - // io.Fonts->AddFontDefault(); - // io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); - // io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); - // io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); - // io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); - // ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, - // io.Fonts->GetGlyphRangesJapanese()); IM_ASSERT(font != nullptr); - // Our state bool show_demo_window = true; bool show_another_window = false; @@ -155,11 +133,13 @@ int demo(const fud::String& m_filename) SDL_Event event; while (SDL_PollEvent(&event)) { ImGui_ImplSDL2_ProcessEvent(&event); - if (event.type == SDL_QUIT) + if (event.type == SDL_QUIT) { done = true; + } if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && - event.window.windowID == SDL_GetWindowID(mainWindow.window())) + event.window.windowID == SDL_GetWindowID(mainWindow.window())) { done = true; + } } if (SDL_GetWindowFlags(mainWindow.window()) & SDL_WINDOW_MINIMIZED) { SDL_Delay(10); diff --git a/src/imgui_context.cpp b/src/imgui_context.cpp index 49b74ca..d0f9206 100644 --- a/src/imgui_context.cpp +++ b/src/imgui_context.cpp @@ -5,7 +5,8 @@ namespace bookmouse { -ImguiContext::ImguiContext(GlContext& glContext, SdlContext& sdlContext, SdlMainWindow& mainWindow) +ImguiContext::ImguiContext(GlContext& glContext, SdlContext& sdlContext, SdlMainWindow& mainWindow) : + m_mainWindow(mainWindow) { IMGUI_CHECKVERSION(); ImGui::CreateContext(); @@ -27,14 +28,33 @@ ImguiContext::~ImguiContext() ImGui::DestroyContext(); } -void ImguiContext::setIOFlag(ImGuiConfigFlags_ flag) +void ImguiContext::setIOFlag(ImGuiConfigFlags_ flag) const { ImGui::GetIO().ConfigFlags |= flag; } -const ImGuiIO& ImguiContext::getIO() +const ImGuiIO& ImguiContext::getIO() const { return ImGui::GetIO(); } +bool ImguiContext::processEvent(SDL_Event& event) const +{ + return ImGui_ImplSDL2_ProcessEvent(&event); +} + +void ImguiContext::startFrame() const +{ + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + ImGui::NewFrame(); +} + +void ImguiContext::render() const +{ + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + SDL_GL_SwapWindow(m_mainWindow.window()); +} + } // namespace bookmouse diff --git a/src/imgui_context.hpp b/src/imgui_context.hpp index 520a711..94bac3d 100644 --- a/src/imgui_context.hpp +++ b/src/imgui_context.hpp @@ -13,11 +13,15 @@ class ImguiContext { ImguiContext(GlContext& glContext, SdlContext& sdlContext, SdlMainWindow& mainWindow); ~ImguiContext(); - const ImGuiIO& getIO(); + const ImGuiIO& getIO() const; - void setIOFlag(ImGuiConfigFlags_ flag); + void setIOFlag(ImGuiConfigFlags_ flag) const; + bool processEvent(SDL_Event& event) const; + void startFrame() const; + void render() const; private: + SdlMainWindow& m_mainWindow; }; } // namespace bookmouse diff --git a/src/main.cpp b/src/main.cpp index 5b4413e..d172586 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,7 @@ #include #include -// #include "main_window.hpp" -#include "stb_image.h" -#include "demo.hpp" +#include "bookmouse.hpp" void setupLogging() { @@ -19,22 +17,8 @@ int main(int argc, char* argv[]) setupLogging(); - fud::String filename{"Excel Saga Vol. 01/000.jpg"}; - return bookmouse::demo(filename); - -#if 0 - bookmouse::BookmouseApp bookmouse{}; - - QCommandLineParser parser; - parser.setApplicationDescription(QApplication::translate("main", "A comic book and manga reader")); - parser.addHelpOption(); - parser.addVersionOption(); - - parser.process(app); - - return app.exec(); -#endif - return 0; + bookmouse::Bookmouse bookmouse{}; + return bookmouse.run(); } void load_levels_example() -- cgit v1.2.3