Skip to content

Commit

Permalink
imview: added popup support
Browse files Browse the repository at this point in the history
  • Loading branch information
rxdu committed Dec 18, 2024
1 parent d78503e commit cbedd76
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/imview/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ add_library(imview
# ui components
src/window.cpp
src/viewer.cpp
src/popup.cpp
src/fonts.cpp
src/scene_object.cpp
src/panel.cpp
Expand All @@ -31,6 +32,7 @@ add_library(imview
src/widget/rt_line_plot_widget.cpp
src/widget/gl_widget.cpp
# components
src/component/popup_manager.cpp
src/component/image_utils.cpp
src/component/cairo_context.cpp
src/component/cairo_draw.cpp
Expand Down
57 changes: 57 additions & 0 deletions src/imview/include/imview/component/popup_manager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* @file popup_manager.hpp
* @date 12/18/24
* @brief
*
* @copyright Copyright (c) 2024 Ruixiang Du (rdu)
*/

#ifndef POPUP_MANAGER_HPP
#define POPUP_MANAGER_HPP

#include <mutex>

#include "imview/popup.hpp"

namespace quickviz {
class PopupManager {
struct PopupDescriptor {
PopupType type;
std::string title;
std::string msg;
float width;
float height;
OnConfirmationCallback callback;
};

struct PopupState {
bool triggered;
PopupDescriptor descriptor;
};

public:
static PopupManager& GetInstance() {
static PopupManager instance;
return instance;
}

void RegisterNotificationPopup(std::string title, std::string msg,
float width = 300, float height = 150);
void RegisterConfirmationPopup(std::string title, std::string msg,
OnConfirmationCallback callback = nullptr,
float width = 300, float height = 150);

void TriggerPopup(std::string title);
void CancelPopup(std::string title);
void UpdatePopups();

private:
PopupManager() = default;
~PopupManager() = default;

std::mutex popup_mtx_;
std::unordered_map<std::string, PopupState> popups_;
};
} // namespace quickviz

#endif // POPUP_MANAGER_HPP
16 changes: 12 additions & 4 deletions src/imview/include/imview/popup.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* popup.hpp
*
* Created on 4/5/22 11:08 PM
Expand All @@ -12,10 +12,18 @@

#include <string>
#include <cstdint>
#include <functional>

namespace quickviz {
bool ShowPopupNotification(std::string msg, std::string title,
enum class PopupType { kNotification, kConfirmation };

void ShowNotificationPopup(std::string title, std::string msg,
float width = 300, float height = 150);

using OnConfirmationCallback = std::function<void(bool)>;
void ShowConfirmationPopup(std::string title, std::string msg,
OnConfirmationCallback callback = nullptr,
float width = 300, float height = 150);
}
} // namespace quickviz

#endif //ROBOSW_SRC_VISUALIZATION_IMVIEW_INCLUDE_IMVIEW_POPUP_HPP
#endif // ROBOSW_SRC_VISUALIZATION_IMVIEW_INCLUDE_IMVIEW_POPUP_HPP
75 changes: 75 additions & 0 deletions src/imview/src/component/popup_manager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* @file popup_manager.cpp
* @date 12/18/24
* @brief
*
* @copyright Copyright (c) 2024 Ruixiang Du (rdu)
*/

#include "imview/component/popup_manager.hpp"

#include "imgui.h"

namespace quickviz {
void PopupManager::RegisterNotificationPopup(std::string title, std::string msg,
float width, float height) {
std::lock_guard<std::mutex> lock(popup_mtx_);
popups_[title].triggered = false;
popups_[title].descriptor = PopupDescriptor{
PopupType::kNotification, title, msg, width, height, nullptr};
}

void PopupManager::RegisterConfirmationPopup(std::string title, std::string msg,
OnConfirmationCallback callback,
float width, float height) {
std::lock_guard<std::mutex> lock(popup_mtx_);
popups_[title].triggered = false;
popups_[title].descriptor = PopupDescriptor{
PopupType::kConfirmation, title, msg, width, height, callback};
}

void PopupManager::TriggerPopup(std::string title) {
std::lock_guard<std::mutex> lock(popup_mtx_);
if (popups_.find(title) != popups_.end()) {
popups_[title].triggered = true;
}
}

void PopupManager::CancelPopup(std::string title) {
std::lock_guard<std::mutex> lock(popup_mtx_);
if (popups_.find(title) != popups_.end()) {
popups_[title].triggered = false;
}
}

void PopupManager::UpdatePopups() {
std::unordered_map<std::string, PopupState> popups;

// update popup date
{
std::lock_guard<std::mutex> lock(popup_mtx_);
popups = popups_;
for (auto& [title, state] : popups_) {
if (state.triggered) {
ImGui::OpenPopup(title.c_str());
state.triggered = false;
}
}
}

// show popups if triggered
for (auto& [title, state] : popups) {
switch (state.descriptor.type) {
case PopupType::kNotification:
ShowNotificationPopup(state.descriptor.title, state.descriptor.msg,
state.descriptor.width, state.descriptor.height);
break;
case PopupType::kConfirmation:
ShowConfirmationPopup(state.descriptor.title, state.descriptor.msg,
state.descriptor.callback, state.descriptor.width,
state.descriptor.height);
break;
}
}
}
} // namespace quickviz
42 changes: 32 additions & 10 deletions src/imview/src/popup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,14 @@
#include "imgui.h"

namespace quickviz {
bool ShowPopupNotification(std::string msg, std::string title, float width,
void ShowNotificationPopup(std::string title, std::string msg, float width,
float height) {
bool show_popup = true;

ImGui::OpenPopup(title.c_str());

// Always center this window when appearing
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
ImGui::SetNextWindowSize(ImVec2(width, height));
ImGui::SetNextWindowBgAlpha(0.75f);

ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));

if (ImGui::BeginPopupModal(
title.c_str(), NULL,
ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoResize)) {
Expand All @@ -38,13 +32,41 @@ bool ShowPopupNotification(std::string msg, std::string title, float width,
ImGui::SetCursorPos(ImVec2((width - 120) / 2.0f, 100));
if (ImGui::Button("OK", ImVec2(120, 0))) {
ImGui::CloseCurrentPopup();
show_popup = false;
}
ImGui::SetItemDefaultFocus();
ImGui::EndPopup();
}
}

ImGui::PopStyleVar(1);
void ShowConfirmationPopup(std::string title, std::string msg,
OnConfirmationCallback callback, float width,
float height) {
// Always center this window when appearing
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
ImGui::SetNextWindowSize(ImVec2(width, height));
ImGui::SetNextWindowBgAlpha(0.75f);

if (ImGui::BeginPopupModal(
title.c_str(), NULL,
ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoResize)) {
ImGui::SetCursorPos(ImVec2(15, 40));
ImGui::Text("%s", msg.c_str());
ImGui::Text("\n");
// ImGui::Separator();

return show_popup;
ImGui::SetItemDefaultFocus();
ImGui::SetCursorPos(ImVec2((width - 170) / 2.0f, 100));
if (ImGui::Button("Yes", ImVec2(80, 0))) {
callback(true);
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button("No", ImVec2(80, 0))) {
callback(false);
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
} // namespace quickviz
3 changes: 3 additions & 0 deletions src/imview/test/feature/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ target_link_libraries(test_implot_widget PRIVATE imview)

add_executable(test_gl_widget test_gl_widget.cpp)
target_link_libraries(test_gl_widget PRIVATE imview)

add_executable(test_popup test_popup.cpp)
target_link_libraries(test_popup PRIVATE imview)
71 changes: 71 additions & 0 deletions src/imview/test/feature/test_popup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* test_viewer.cpp
*
* Created on: Jul 27, 2021 09:07
* Description:
*
* Copyright (c) 2021 Ruixiang Du (rdu)
*/

#include <iostream>

#include "imview/viewer.hpp"
#include "imview/box.hpp"

#include "imview/panel.hpp"
#include "imview/popup.hpp"

#include "imview/component/popup_manager.hpp"

using namespace quickviz;

class MyPanel : public Panel {
public:
MyPanel(std::string name = "MyPanel") : Panel(name) {
this->SetAutoLayout(false);

PopupManager::GetInstance().RegisterNotificationPopup(
"Notification", "This is a popup test");
PopupManager::GetInstance().RegisterConfirmationPopup(
"Confirmation", "This is a confirmation test", [](bool confirm) {
if (confirm) {
std::cout << "Confirmed" << std::endl;
} else {
std::cout << "Not Confirmed" << std::endl;
}
});
}

void Draw() override {
Begin();
{
static bool show_popup = false;
if (ImGui::Button("Show Notification")) {
PopupManager::GetInstance().TriggerPopup("Notification");
}
if (ImGui::Button("Show Confirmation")) {
PopupManager::GetInstance().TriggerPopup("Confirmation");
}

PopupManager::GetInstance().UpdatePopups();

ImGui::PushFont(Fonts::GetFont(FontSize::kFont18));
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(0, 153, 153, 200));
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::PopStyleColor();
ImGui::PopFont();
}
End();
}
};

int main(int argc, char* argv[]) {
Viewer viewer;

auto obj1 = std::make_shared<MyPanel>("Panel1");
viewer.AddSceneObject(obj1);

viewer.Show();
return 0;
}

0 comments on commit cbedd76

Please sign in to comment.