diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f69878..e235abf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.23) -project(pixelarium VERSION 0.0.6) +project(pixelarium VERSION 0.0.7) set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_CXX_STANDARD 23) diff --git a/doc/versions.md b/doc/versions.md index e14cc75..e83e130 100644 --- a/doc/versions.md +++ b/doc/versions.md @@ -2,6 +2,7 @@ | Version | Description | |:-------:|:------------------------------------------------------------------------------------------------------------| +| 0.0.7 | Refactors image gallery logic from `DefaultApp` into a separate module | | 0.0.6 | Added documentation-only option `PIXELARIUM_BUILD_DOCS_ONLY`, libCZI upgrade to main branch CI improvements | | 0.0.5 | Compile for C++23 and code style adaptions | | 0.0.4 | Fix MSVC build, some cosmetics, explicit initial window size for images | diff --git a/lib/app/AppGLFW.cpp b/lib/app/AppGLFW.cpp index 9a01a9f..ab85185 100644 --- a/lib/app/AppGLFW.cpp +++ b/lib/app/AppGLFW.cpp @@ -84,14 +84,10 @@ void pixelarium::application::AppGLFW::InitMainWindow() IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); - (void)io; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform - // Windows - // io.ConfigViewportsNoAutoMerge = true; - // io.ConfigViewportsNoTaskBarIcon = true; // Setup Dear ImGui style ImGui::StyleColorsDark(); diff --git a/lib/app/CMakeLists.txt b/lib/app/CMakeLists.txt index ef41481..f670e38 100644 --- a/lib/app/CMakeLists.txt +++ b/lib/app/CMakeLists.txt @@ -6,6 +6,8 @@ set(APPLIBSRC AppGLFW.cpp DefaultApp.hpp DefaultApp.cpp + PixelariumGallery.hpp + PixelariumGallery.cpp ${imgui_DIR}/imgui.cpp ${imgui_DIR}/imgui_demo.cpp ${imgui_DIR}/imgui_draw.cpp diff --git a/lib/app/DefaultApp.cpp b/lib/app/DefaultApp.cpp index e24042d..45ffb61 100644 --- a/lib/app/DefaultApp.cpp +++ b/lib/app/DefaultApp.cpp @@ -2,25 +2,24 @@ #include #include -#include #include "PixelariumImageFactory.hpp" #include "app_resources_default.h" #include "imgui.h" #include "portable-file-dialogs.h" -#include "rendering/RenderImageManager.hpp" #include "resources/resource.hpp" #include "utilities/ILog.hpp" using namespace pixelarium::imaging; +using namespace pixelarium::application; -void pixelarium::ui::DefaultApp::MenuBarOptionsColumn1() +void DefaultApp::MenuBarOptionsColumn1() { ImGui::MenuItem(SHOWIMGUIDEMOS, NULL, &this->demop_); ImGui::MenuItem(SHOWIMAGEGALLERY, NULL, &this->image_listp_); } -void pixelarium::ui::DefaultApp::MenuBarOptionsColumn2() +void DefaultApp::MenuBarOptionsColumn2() { if (ImGui::BeginMenu(FILEMENUNAME)) { @@ -33,93 +32,15 @@ void pixelarium::ui::DefaultApp::MenuBarOptionsColumn2() } } -void pixelarium::ui::DefaultApp::Run() +void DefaultApp::Run() { if (demop_) ImGui::ShowDemoWindow(&this->demop_); - if (image_listp_) this->ImageGalleryRender(); + if (image_listp_) this->gallery.RenderGallery(); - this->RenderImages(); + this->gallery.RenderImages(); } -void pixelarium::ui::DefaultApp::RenderImages() -{ - this->render_manager_->Enumerate( - [&](resources::ResourceKey key, render::RenderImageStateWrapper& render_state) - { - render_state.view->ShowImage(); - - if (!*render_state.view->GetStatus()) - { - this->render_manager_->MarkForDeletion(key); - } - }); -} - -void pixelarium::ui::DefaultApp::ImageGalleryRender() -{ - ImGui::SetNextWindowSize(ImVec2(300, 550)); - ImGui::Begin(SHOWIMAGEGALLERY, &this->image_listp_); - - // this updates the render collection - // essentially deleting render views that were - // marked for deletion - this->render_manager_->UpdateCollection(); - - static size_t selected_index{0}; - int highlight_index{-1}; - - if (ImGui::BeginListBox("Image List", ImVec2(200, 400))) - { - pool_.EnumerateResources( - [&](size_t id, size_t idx, const imaging::IPixelariumImage& img) -> void - { - const bool is_selected = selected_index == idx; - if (ImGui::Selectable(std::format("{}", img.Name()).c_str(), is_selected)) - { - selected_index = idx; - this->selected_image_ = id; - } - if (highlight_index && ImGui::IsItemHovered()) highlight_index = idx; - - if (is_selected) ImGui::SetItemDefaultFocus(); - }); - - ImGui::EndListBox(); - } - - ImGui::Checkbox(AUTOSHOWSELECTED, &this->auto_show_selectd_image_); - ImGui::SameLine(); // put the button next to the checkbox - // note that the button will only show when the checkbox is toggled off - // this is intended behavior as the selected image will render automatically - // when the checkbox is toggled on - if (this->auto_show_selectd_image_ || ImGui::Button(OPENIMAGE)) - { - // Try add the selected index to the manager - this->render_manager_->Add(this->selected_image_); - } - - if (ImGui::Button(LOADIMAGE)) - { - this->LoadImage(); - } - - if (ImGui::Button(REMOVEIMAGE)) - { - this->render_manager_->MarkForDeletion(this->selected_image_); - this->pool_.DeleteResource(this->selected_image_); - } - - ImGui::SameLine(); - if (ImGui::Button(CLEARALL)) - { - this->render_manager_->Clear(); - this->pool_.Clear(); - } - - ImGui::End(); // end gallery window -} - -void pixelarium::ui::DefaultApp::LoadImage() +void DefaultApp::LoadImage() { auto res{pfd::open_file("Load Inputs", pfd::path::home(), {"All Files", "*"}, pfd::opt::multiselect).result()}; for (auto& p : res) diff --git a/lib/app/DefaultApp.hpp b/lib/app/DefaultApp.hpp index 816037f..76a9873 100644 --- a/lib/app/DefaultApp.hpp +++ b/lib/app/DefaultApp.hpp @@ -1,27 +1,25 @@ #pragma once #include -#include #include "AppGLFW.hpp" +#include "app/PixelariumGallery.hpp" #include "imgui.h" -#include "rendering/RenderImageManager.hpp" #include "resources/resource.hpp" #include "utilities/ILog.hpp" -namespace pixelarium::ui +namespace pixelarium::application { /// @brief Default implementation of AppGLFW. /// This can either be used as is, as an example or as a base class /// providing some defaults for a more custom implementation. -class DefaultApp : public application::AppGLFW +class DefaultApp : public AppGLFW { public: DefaultApp(const utils::log::ILog& log, pixelarium::resources::ImageResourcePool& pool) - : application::AppGLFW(log), - pool_(pool), - render_manager_(std::make_unique(pool, log)) + : application::AppGLFW(log), pool_(pool), gallery(log, pool) { + gallery.SetLoadFunction([&]() -> void { this->LoadImage(); }); } protected: @@ -31,16 +29,12 @@ class DefaultApp : public application::AppGLFW private: void LoadImage(); - void ImageGalleryRender(); - void RenderImages(); private: resources::ImageResourcePool& pool_; - std::unique_ptr render_manager_; bool image_listp_{true}; - bool auto_show_selectd_image_{true}; bool demop_{false}; ImVec2 curr_dim_; - size_t selected_image_{0}; + application::PixelariumImageGallery gallery; }; -} // namespace pixelarium::ui +} // namespace pixelarium::application diff --git a/lib/app/PixelariumGallery.cpp b/lib/app/PixelariumGallery.cpp new file mode 100644 index 0000000..835d69d --- /dev/null +++ b/lib/app/PixelariumGallery.cpp @@ -0,0 +1,86 @@ +#include "PixelariumGallery.hpp" + +#include + +#include "app_resources_default.h" +#include "imgui.h" + +using namespace pixelarium::application; + +void PixelariumImageGallery::RenderGallery() +{ + ImGui::SetNextWindowSize(ImVec2(300, 550)); + ImGui::Begin(SHOWIMAGEGALLERY, &this->image_listp_); + + // this updates the render collection + // essentially deleting render views that were + // marked for deletion + this->render_manager_->UpdateCollection(); + + static size_t selected_index{0}; + int highlight_index{-1}; + + if (ImGui::BeginListBox("Image List", ImVec2(200, 400))) + { + pool_.EnumerateResources( + [&](size_t id, size_t idx, const imaging::IPixelariumImage& img) -> void + { + const bool is_selected = selected_index == idx; + if (ImGui::Selectable(std::format("{}", img.Name()).c_str(), is_selected)) + { + selected_index = idx; + this->selected_image_ = id; + } + if (highlight_index && ImGui::IsItemHovered()) highlight_index = idx; + + if (is_selected) ImGui::SetItemDefaultFocus(); + }); + + ImGui::EndListBox(); + } + + ImGui::Checkbox(AUTOSHOWSELECTED, &this->auto_show_selectd_image_); + ImGui::SameLine(); // put the button next to the checkbox + // note that the button will only show when the checkbox is toggled off + // this is intended behavior as the selected image will render automatically + // when the checkbox is toggled on + if (this->auto_show_selectd_image_ || ImGui::Button(OPENIMAGE)) + { + // Try add the selected index to the manager + this->render_manager_->Add(this->selected_image_); + } + + if (ImGui::Button(LOADIMAGE)) + { + this->load_image_(); + } + + if (ImGui::Button(REMOVEIMAGE)) + { + this->render_manager_->MarkForDeletion(this->selected_image_); + this->pool_.DeleteResource(this->selected_image_); + } + + ImGui::SameLine(); + if (ImGui::Button(CLEARALL)) + { + this->render_manager_->Clear(); + this->pool_.Clear(); + } + + ImGui::End(); // end gallery window +} + +void PixelariumImageGallery::RenderImages() +{ + this->render_manager_->Enumerate( + [&](resources::ResourceKey key, render::RenderImageStateWrapper& render_state) + { + render_state.view->ShowImage(); + + if (!*render_state.view->GetStatus()) + { + this->render_manager_->MarkForDeletion(key); + } + }); +} diff --git a/lib/app/PixelariumGallery.hpp b/lib/app/PixelariumGallery.hpp new file mode 100644 index 0000000..6c36d8c --- /dev/null +++ b/lib/app/PixelariumGallery.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "rendering/RenderImageManager.hpp" +#include "resources/resource.hpp" +#include "utilities/ILog.hpp" +namespace pixelarium::application +{ + +template +concept GalleryT = requires(P& r) { static_cast&>(r); }; + +template +class IPixelariumGallery +{ + public: + virtual ~IPixelariumGallery() = default; + virtual void RenderGallery() = 0; +}; + +class PixelariumImageGallery : IPixelariumGallery +{ + using Pool = resources::ImageResourcePool; + using Log = utils::log::ILog; + + public: + PixelariumImageGallery(const Log& log, resources::ImageResourcePool& pool) + : pool_{pool}, log_{log}, render_manager_(std::make_unique(pool, log)) + { + } + + void RenderGallery() override; + + void RenderImages(); + + void Add(resources::ResourceKey key) { this->render_manager_->Add(key); } + + void SetLoadFunction(const std::function& fun) { this->load_image_ = fun; }; + + private: + std::function load_image_{}; + Pool& pool_; + const Log& log_; + std::unique_ptr render_manager_; + bool image_listp_{true}; + bool auto_show_selectd_image_{true}; + size_t selected_image_{0}; +}; +} // namespace pixelarium::application diff --git a/src/main.cpp b/src/main.cpp index 5316fe1..9e81e19 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,7 +20,7 @@ int main(int argc, char** argv) logger->ChangeLevel(utils::log::LogLevel::kDebug); auto image_pool{std::make_unique()}; - pixelarium::ui::DefaultApp app = pixelarium::ui::DefaultApp(*logger, *image_pool); + application::DefaultApp app = application::DefaultApp(*logger, *image_pool); app.Start(); }