Merge branch 'feature/imgui-debug' into develop

This commit is contained in:
Dan Paulat 2022-11-28 09:29:40 -06:00
commit 65f63bbf85
17 changed files with 720 additions and 48 deletions

@ -1 +1 @@
Subproject commit 6944775887e61d4d8185568e0205af5b3b483801
Subproject commit a914f1811185f5959d50f2a199420dee4d15ae74

View file

@ -93,12 +93,14 @@ set(SRC_MAP source/scwx/qt/map/alert_layer.cpp
source/scwx/qt/map/radar_range_layer.cpp)
set(HDR_MODEL source/scwx/qt/model/alert_model.hpp
source/scwx/qt/model/alert_proxy_model.hpp
source/scwx/qt/model/imgui_context_model.hpp
source/scwx/qt/model/radar_product_model.hpp
source/scwx/qt/model/radar_site_model.hpp
source/scwx/qt/model/tree_item.hpp
source/scwx/qt/model/tree_model.hpp)
set(SRC_MODEL source/scwx/qt/model/alert_model.cpp
source/scwx/qt/model/alert_proxy_model.cpp
source/scwx/qt/model/imgui_context_model.cpp
source/scwx/qt/model/radar_product_model.cpp
source/scwx/qt/model/radar_site_model.cpp
source/scwx/qt/model/tree_item.cpp
@ -119,6 +121,8 @@ set(SRC_TYPES source/scwx/qt/types/radar_product_record.cpp
set(HDR_UI source/scwx/qt/ui/alert_dialog.hpp
source/scwx/qt/ui/alert_dock_widget.hpp
source/scwx/qt/ui/flow_layout.hpp
source/scwx/qt/ui/imgui_debug_dialog.hpp
source/scwx/qt/ui/imgui_debug_widget.hpp
source/scwx/qt/ui/level2_products_widget.hpp
source/scwx/qt/ui/level2_settings_widget.hpp
source/scwx/qt/ui/level3_products_widget.hpp
@ -126,12 +130,15 @@ set(HDR_UI source/scwx/qt/ui/alert_dialog.hpp
set(SRC_UI source/scwx/qt/ui/alert_dialog.cpp
source/scwx/qt/ui/alert_dock_widget.cpp
source/scwx/qt/ui/flow_layout.cpp
source/scwx/qt/ui/imgui_debug_dialog.cpp
source/scwx/qt/ui/imgui_debug_widget.cpp
source/scwx/qt/ui/level2_products_widget.cpp
source/scwx/qt/ui/level2_settings_widget.cpp
source/scwx/qt/ui/level3_products_widget.cpp
source/scwx/qt/ui/radar_site_dialog.cpp)
set(UI_UI source/scwx/qt/ui/alert_dialog.ui
source/scwx/qt/ui/alert_dock_widget.ui
source/scwx/qt/ui/imgui_debug_dialog.ui
source/scwx/qt/ui/radar_site_dialog.ui)
set(HDR_UTIL source/scwx/qt/util/font.hpp
source/scwx/qt/util/font_buffer.hpp

View file

@ -11,6 +11,7 @@
#include <scwx/qt/model/radar_product_model.hpp>
#include <scwx/qt/ui/alert_dock_widget.hpp>
#include <scwx/qt/ui/flow_layout.hpp>
#include <scwx/qt/ui/imgui_debug_dialog.hpp>
#include <scwx/qt/ui/level2_products_widget.hpp>
#include <scwx/qt/ui/level2_settings_widget.hpp>
#include <scwx/qt/ui/level3_products_widget.hpp>
@ -49,6 +50,7 @@ public:
level2SettingsWidget_ {nullptr},
level3ProductsWidget_ {nullptr},
alertDockWidget_ {nullptr},
imGuiDebugDialog_ {nullptr},
radarSiteDialog_ {nullptr},
radarProductModel_ {nullptr},
textEventManager_ {manager::TextEventManager::Instance()},
@ -109,8 +111,9 @@ public:
ui::Level3ProductsWidget* level3ProductsWidget_;
ui::AlertDockWidget* alertDockWidget_;
ui::RadarSiteDialog* radarSiteDialog_;
ui::AlertDockWidget* alertDockWidget_;
ui::ImGuiDebugDialog* imGuiDebugDialog_;
ui::RadarSiteDialog* radarSiteDialog_;
std::unique_ptr<model::RadarProductModel> radarProductModel_;
std::shared_ptr<manager::TextEventManager> textEventManager_;
@ -196,6 +199,9 @@ MainWindow::MainWindow(QWidget* parent) :
ui->settingsFrame->layout()->addWidget(p->level2SettingsWidget_);
p->level2SettingsWidget_->setVisible(false);
// ImGui Debug Dialog
p->imGuiDebugDialog_ = new ui::ImGuiDebugDialog(this);
auto mapSettings = manager::SettingsManager::map_settings();
for (size_t i = 0; i < p->maps_.size(); i++)
{
@ -323,6 +329,11 @@ void MainWindow::on_actionExit_triggered()
close();
}
void MainWindow::on_actionImGuiDebug_triggered()
{
p->imGuiDebugDialog_->show();
}
void MainWindow::on_radarSiteSelectButton_clicked()
{
p->radarSiteDialog_->show();

View file

@ -35,6 +35,7 @@ private slots:
void on_actionOpenNexrad_triggered();
void on_actionOpenTextEvent_triggered();
void on_actionExit_triggered();
void on_actionImGuiDebug_triggered();
void on_radarSiteSelectButton_clicked();
void on_resourceTreeCollapseAllButton_clicked();
void on_resourceTreeExpandAllButton_clicked();

View file

@ -35,7 +35,7 @@
<x>0</x>
<y>0</y>
<width>1024</width>
<height>22</height>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@ -67,8 +67,15 @@
<addaction name="actionResourceExplorer"/>
<addaction name="actionAlerts"/>
</widget>
<widget class="QMenu" name="menuDebug">
<property name="title">
<string>&amp;Debug</string>
</property>
<addaction name="actionImGuiDebug"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuView"/>
<addaction name="menuDebug"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
@ -342,6 +349,11 @@
<string>&amp;Alerts</string>
</property>
</action>
<action name="actionImGuiDebug">
<property name="text">
<string>&amp;ImGui Debug</string>
</property>
</action>
</widget>
<resources>
<include location="../../../../scwx-qt.qrc"/>

View file

@ -4,11 +4,6 @@
#include <scwx/qt/util/texture_atlas.hpp>
#include <scwx/util/logger.hpp>
#include <backends/imgui_impl_opengl3.h>
#include <imgui.h>
#include <QOffscreenSurface>
#include <QOpenGLContext>
namespace scwx
{
namespace qt
@ -17,45 +12,21 @@ namespace manager
{
namespace ResourceManager
{
static const std::string logPrefix_ = "scwx::qt::manager::ResourceManager";
static const std::string logPrefix_ = "scwx::qt::manager::resource_manager";
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
static void InitializeImGui();
static void LoadFonts();
static void LoadTextures();
static void ShutdownImGui();
static std::unique_ptr<QOffscreenSurface> surface_ {};
void Initialize()
{
config::CountyDatabase::Initialize();
InitializeImGui();
LoadFonts();
LoadTextures();
}
void Shutdown()
{
ShutdownImGui();
}
static void InitializeImGui()
{
// Create OpenGL Offscreen Surface
surface_ = std::make_unique<QOffscreenSurface>();
surface_->create();
if (!QOpenGLContext::globalShareContext()->makeCurrent(surface_.get()))
{
logger_->warn("Failed to initialize offscreen surface");
}
// Initialize ImGui
ImGui::CreateContext();
ImGui_ImplOpenGL3_Init();
QOpenGLContext::globalShareContext()->doneCurrent();
}
void Shutdown() {}
static void LoadFonts()
{
@ -73,14 +44,6 @@ static void LoadTextures()
textureAtlas.BuildAtlas(8, 8);
}
static void ShutdownImGui()
{
QOpenGLContext::globalShareContext()->makeCurrent(surface_.get());
ImGui_ImplOpenGL3_Shutdown();
ImGui::DestroyContext();
QOpenGLContext::globalShareContext()->doneCurrent();
}
} // namespace ResourceManager
} // namespace manager
} // namespace qt

View file

@ -8,12 +8,14 @@
#include <scwx/qt/map/overlay_layer.hpp>
#include <scwx/qt/map/radar_product_layer.hpp>
#include <scwx/qt/map/radar_range_layer.hpp>
#include <scwx/qt/model/imgui_context_model.hpp>
#include <scwx/qt/view/radar_product_view_factory.hpp>
#include <scwx/util/logger.hpp>
#include <scwx/util/threads.hpp>
#include <scwx/util/time.hpp>
#include <backends/imgui_impl_opengl3.h>
#include <backends/imgui_impl_qt.hpp>
#include <imgui.h>
#include <QApplication>
#include <QColor>
@ -60,6 +62,7 @@ public:
settings_(settings),
map_(),
layerList_ {},
imGuiRendererInitialized_ {false},
radarProductManager_ {nullptr},
radarProductLayer_ {nullptr},
alertLayer_ {std::make_shared<AlertLayer>(context_)},
@ -79,8 +82,33 @@ public:
{
SetRadarSite(scwx::qt::manager::SettingsManager::general_settings()
->default_radar_site());
// Create ImGui Context
static size_t currentMapId_ {0u};
imGuiContextName_ = std::format("Map {}", ++currentMapId_);
imGuiContext_ =
model::ImGuiContextModel::Instance().CreateContext(imGuiContextName_);
// Initialize ImGui Qt backend
ImGui_ImplQt_Init();
ImGui_ImplQt_RegisterWidget(widget_);
}
~MapWidgetImpl()
{
// Set ImGui Context
ImGui::SetCurrentContext(imGuiContext_);
// Shutdown ImGui Context
if (imGuiRendererInitialized_)
{
ImGui_ImplOpenGL3_Shutdown();
}
ImGui_ImplQt_Shutdown();
// Destroy ImGui Context
model::ImGuiContextModel::Instance().DestroyContext(imGuiContextName_);
}
~MapWidgetImpl() = default;
void AddLayer(const std::string& id,
std::shared_ptr<GenericLayer> layer,
@ -103,6 +131,10 @@ public:
std::shared_ptr<QMapLibreGL::Map> map_;
std::list<std::string> layerList_;
ImGuiContext* imGuiContext_;
std::string imGuiContextName_;
bool imGuiRendererInitialized_;
std::shared_ptr<manager::RadarProductManager> radarProductManager_;
std::shared_ptr<common::ColorTable> colorTable_;
@ -136,6 +168,8 @@ MapWidget::MapWidget(const QMapLibreGL::Settings& settings) :
p(std::make_unique<MapWidgetImpl>(this, settings))
{
setFocusPolicy(Qt::StrongFocus);
ImGui_ImplQt_RegisterWidget(this);
}
MapWidget::~MapWidget()
@ -644,6 +678,11 @@ void MapWidget::initializeGL()
makeCurrent();
p->context_->gl().initializeOpenGLFunctions();
// Initialize ImGui OpenGL3 backend
ImGui::SetCurrentContext(p->imGuiContext_);
ImGui_ImplOpenGL3_Init();
p->imGuiRendererInitialized_ = true;
p->map_.reset(
new QMapLibreGL::Map(nullptr, p->settings_, size(), pixelRatio()));
p->context_->set_map(p->map_);
@ -686,10 +725,10 @@ void MapWidget::paintGL()
p->frameDraws_++;
// Setup ImGui Frame
ImGui::GetIO().DisplaySize = {static_cast<float>(size().width()),
static_cast<float>(size().height())};
ImGui::SetCurrentContext(p->imGuiContext_);
// Start ImGui Frame
ImGui_ImplQt_NewFrame(this);
ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame();

View file

@ -0,0 +1,143 @@
#include <scwx/qt/model/imgui_context_model.hpp>
#include <scwx/qt/types/qt_types.hpp>
#include <scwx/util/logger.hpp>
#include <imgui.h>
namespace scwx
{
namespace qt
{
namespace model
{
static const std::string logPrefix_ = "scwx::qt::model::imgui_context_model";
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
class ImGuiContextModelImpl
{
public:
explicit ImGuiContextModelImpl() {}
~ImGuiContextModelImpl() = default;
std::vector<ImGuiContextInfo> contexts_ {};
};
ImGuiContextModel::ImGuiContextModel() :
QAbstractListModel(nullptr), p {std::make_unique<ImGuiContextModelImpl>()}
{
}
ImGuiContextModel::~ImGuiContextModel() {}
int ImGuiContextModel::rowCount(const QModelIndex& parent) const
{
return parent.isValid() ? 0 : static_cast<int>(p->contexts_.size());
}
QVariant ImGuiContextModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
{
return {};
}
const int row = index.row();
if (row >= p->contexts_.size() || row < 0)
{
return {};
}
switch (role)
{
case Qt::ItemDataRole::DisplayRole:
return QString("%1: %2")
.arg(p->contexts_[row].id_)
.arg(p->contexts_[row].name_.c_str());
case qt::types::ItemDataRole::RawDataRole:
QVariant variant {};
variant.setValue(p->contexts_[row]);
return variant;
}
return {};
}
QModelIndex ImGuiContextModel::IndexOf(const std::string& contextName) const
{
// Find context from registry
auto it =
std::find_if(p->contexts_.begin(),
p->contexts_.end(),
[&](auto& info) { return info.name_ == contextName; });
if (it != p->contexts_.end())
{
const int row = it - p->contexts_.begin();
return createIndex(row, 0, nullptr);
}
return {};
}
ImGuiContext* ImGuiContextModel::CreateContext(const std::string& name)
{
static size_t nextId_ {0};
ImGuiContext* context = ImGui::CreateContext();
ImGui::SetCurrentContext(context);
// ImGui Configuration
auto& io = ImGui::GetIO();
// Disable automatic configuration loading/saving
io.IniFilename = nullptr;
// Style
auto& style = ImGui::GetStyle();
style.WindowMinSize = {10.0f, 10.0f};
// Register context
const int nextPosition = static_cast<int>(p->contexts_.size());
beginInsertRows(QModelIndex(), nextPosition, nextPosition);
p->contexts_.emplace_back(ImGuiContextInfo {nextId_++, name, context});
endInsertRows();
return context;
}
void ImGuiContextModel::DestroyContext(const std::string& name)
{
// Find context from registry
auto it = std::find_if(p->contexts_.begin(),
p->contexts_.end(),
[&](auto& info) { return info.name_ == name; });
if (it != p->contexts_.end())
{
const int position = it - p->contexts_.begin();
// Destroy context
ImGui::SetCurrentContext(it->context_);
ImGui::DestroyContext();
// Erase context from index
beginRemoveRows(QModelIndex(), position, position);
p->contexts_.erase(it);
endRemoveRows();
}
}
ImGuiContextModel& ImGuiContextModel::Instance()
{
static ImGuiContextModel instance_ {};
return instance_;
}
bool ImGuiContextInfo::operator==(const ImGuiContextInfo& o) const = default;
} // namespace model
} // namespace qt
} // namespace scwx

View file

@ -0,0 +1,60 @@
#pragma once
#include <memory>
#include <string>
#include <QAbstractListModel>
struct ImGuiContext;
namespace scwx
{
namespace qt
{
namespace model
{
class ImGuiContextModelImpl;
struct ImGuiContextInfo
{
size_t id_ {};
std::string name_ {};
ImGuiContext* context_ {};
bool operator==(const ImGuiContextInfo& o) const;
};
class ImGuiContextModel : public QAbstractListModel
{
private:
Q_OBJECT
Q_DISABLE_COPY(ImGuiContextModel)
public:
explicit ImGuiContextModel();
~ImGuiContextModel();
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index,
int role = Qt::DisplayRole) const override;
QModelIndex IndexOf(const std::string& contextName) const;
ImGuiContext* CreateContext(const std::string& name);
void DestroyContext(const std::string& name);
static ImGuiContextModel& Instance();
signals:
void ContextsUpdated();
private:
friend class ImGuiContextModelImpl;
std::unique_ptr<ImGuiContextModelImpl> p;
};
} // namespace model
} // namespace qt
} // namespace scwx

View file

@ -12,7 +12,8 @@ namespace types
enum ItemDataRole
{
SortRole = Qt::UserRole,
TimePointRole
TimePointRole,
RawDataRole
};
} // namespace types

View file

@ -0,0 +1,69 @@
#include "imgui_debug_dialog.hpp"
#include "ui_imgui_debug_dialog.h"
#include <scwx/qt/model/imgui_context_model.hpp>
#include <scwx/qt/types/qt_types.hpp>
#include <scwx/qt/ui/imgui_debug_widget.hpp>
namespace scwx
{
namespace qt
{
namespace ui
{
static const std::string logPrefix_ = "scwx::qt::ui::imgui_debug_dialog";
class ImGuiDebugDialogImpl
{
public:
explicit ImGuiDebugDialogImpl() : imGuiDebugWidget_ {nullptr} {}
~ImGuiDebugDialogImpl() = default;
ImGuiDebugWidget* imGuiDebugWidget_;
};
ImGuiDebugDialog::ImGuiDebugDialog(QWidget* parent) :
QDialog(parent),
p {std::make_unique<ImGuiDebugDialogImpl>()},
ui(new Ui::ImGuiDebugDialog)
{
ui->setupUi(this);
// ImGui Debug Widget
p->imGuiDebugWidget_ = new ImGuiDebugWidget(this);
p->imGuiDebugWidget_->setSizePolicy(QSizePolicy::Policy::Expanding,
QSizePolicy::Policy::Expanding);
ui->verticalLayout->insertWidget(0, p->imGuiDebugWidget_);
// Context Combo Box
auto& contextModel = model::ImGuiContextModel::Instance();
auto index = contextModel.IndexOf(p->imGuiDebugWidget_->context_name());
ui->contextComboBox->setModel(&contextModel);
ui->contextComboBox->setCurrentIndex(index.row());
connect(
ui->contextComboBox,
&QComboBox::currentIndexChanged,
[=](int row)
{
auto& contextModel = model::ImGuiContextModel::Instance();
auto index = contextModel.index(row, 0);
if (index.isValid())
{
QVariant data = contextModel.data(index, qt::types::RawDataRole);
auto contextInfo = data.value<model::ImGuiContextInfo>();
p->imGuiDebugWidget_->set_current_context(contextInfo.context_);
}
});
}
ImGuiDebugDialog::~ImGuiDebugDialog()
{
delete ui;
}
} // namespace ui
} // namespace qt
} // namespace scwx

View file

@ -0,0 +1,36 @@
#pragma once
#include <QDialog>
namespace Ui
{
class ImGuiDebugDialog;
}
namespace scwx
{
namespace qt
{
namespace ui
{
class ImGuiDebugDialogImpl;
class ImGuiDebugDialog : public QDialog
{
private:
Q_DISABLE_COPY(ImGuiDebugDialog)
public:
explicit ImGuiDebugDialog(QWidget* parent = nullptr);
~ImGuiDebugDialog();
private:
friend class ImGuiDebugDialogImpl;
std::unique_ptr<ImGuiDebugDialogImpl> p;
Ui::ImGuiDebugDialog* ui;
};
} // namespace ui
} // namespace qt
} // namespace scwx

View file

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ImGuiDebugDialog</class>
<widget class="QDialog" name="ImGuiDebugDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>592</width>
<height>754</height>
</rect>
</property>
<property name="windowTitle">
<string>ImGui Debug</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="bottomFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="contextLabel">
<property name="text">
<string>Context</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="contextComboBox"/>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ImGuiDebugDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ImGuiDebugDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -0,0 +1,137 @@
#include <scwx/qt/ui/imgui_debug_widget.hpp>
#include <scwx/qt/model/imgui_context_model.hpp>
#include <set>
#include <imgui.h>
#include <backends/imgui_impl_opengl3.h>
#include <backends/imgui_impl_qt.hpp>
namespace scwx
{
namespace qt
{
namespace ui
{
static const std::string logPrefix_ = "scwx::qt::ui::imgui_debug_widget";
class ImGuiDebugWidgetImpl
{
public:
explicit ImGuiDebugWidgetImpl(ImGuiDebugWidget* self) : self_ {self}
{
// Create ImGui Context
static size_t currentIndex_ {0u};
contextName_ = std::format("ImGui Debug {}", ++currentIndex_);
context_ =
model::ImGuiContextModel::Instance().CreateContext(contextName_);
currentContext_ = context_;
// Initialize ImGui Qt backend
ImGui_ImplQt_Init();
ImGui_ImplQt_RegisterWidget(self_);
}
~ImGuiDebugWidgetImpl()
{
// Set ImGui Context
ImGui::SetCurrentContext(context_);
// Shutdown ImGui Context
if (imGuiRendererInitialized_)
{
ImGui_ImplOpenGL3_Shutdown();
}
ImGui_ImplQt_Shutdown();
// Destroy ImGui Context
model::ImGuiContextModel::Instance().DestroyContext(contextName_);
}
ImGuiDebugWidget* self_;
ImGuiContext* context_;
std::string contextName_;
ImGuiContext* currentContext_;
std::set<ImGuiContext*> renderedSet_ {};
bool imGuiRendererInitialized_ {false};
};
ImGuiDebugWidget::ImGuiDebugWidget(QWidget* parent) :
QOpenGLWidget(parent), p {std::make_unique<ImGuiDebugWidgetImpl>(this)}
{
// Accept focus for keyboard events
setFocusPolicy(Qt::StrongFocus);
}
ImGuiDebugWidget::~ImGuiDebugWidget() {}
std::string ImGuiDebugWidget::context_name() const
{
return p->contextName_;
}
void ImGuiDebugWidget::set_current_context(ImGuiContext* context)
{
if (context == p->currentContext_)
{
return;
}
// Unregister widget with current context
ImGui::SetCurrentContext(p->currentContext_);
ImGui_ImplQt_UnregisterWidget(this);
p->currentContext_ = context;
// Register widget with new context
ImGui::SetCurrentContext(context);
ImGui_ImplQt_RegisterWidget(this);
// Queue an update
update();
}
void ImGuiDebugWidget::initializeGL()
{
makeCurrent();
// Initialize ImGui OpenGL3 backend
ImGui::SetCurrentContext(p->context_);
ImGui_ImplOpenGL3_Init();
p->imGuiRendererInitialized_ = true;
}
void ImGuiDebugWidget::paintGL()
{
ImGui::SetCurrentContext(p->currentContext_);
ImGui_ImplQt_NewFrame(this);
ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame();
if (!p->renderedSet_.contains(p->currentContext_))
{
// Set initial position of demo window
ImGui::SetNextWindowPos(ImVec2 {width() / 2.0f, height() / 2.0f},
ImGuiCond_FirstUseEver,
ImVec2 {0.5f, 0.5f});
ImGui::Begin("Dear ImGui Demo");
ImGui::End();
p->renderedSet_.insert(p->currentContext_);
update();
}
ImGui::ShowDemoWindow();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
} // namespace ui
} // namespace qt
} // namespace scwx

View file

@ -0,0 +1,44 @@
#pragma once
#include <QOpenGLWidget>
struct ImGuiContext;
namespace Ui
{
class ImGuiDebugWidget;
}
namespace scwx
{
namespace qt
{
namespace ui
{
class ImGuiDebugWidgetImpl;
class ImGuiDebugWidget : public QOpenGLWidget
{
private:
Q_DISABLE_COPY(ImGuiDebugWidget)
public:
explicit ImGuiDebugWidget(QWidget* parent = nullptr);
~ImGuiDebugWidget();
std::string context_name() const;
void set_current_context(ImGuiContext* context);
void initializeGL() override;
void paintGL() override;
private:
friend class ImGuiDebugWidgetImpl;
std::unique_ptr<ImGuiDebugWidgetImpl> p;
};
} // namespace ui
} // namespace qt
} // namespace scwx

View file

@ -0,0 +1,44 @@
#include <scwx/qt/manager/imgui_manager.hpp>
#include <gtest/gtest.h>
namespace scwx
{
namespace qt
{
namespace manager
{
TEST(ImGuiManagerTest, State)
{
auto& ImGuiManager = ImGuiManager::Instance();
ImGuiManager.CreateContext("Context One");
ImGuiManager.CreateContext("Context Two");
ImGuiManager.CreateContext("Context Three");
auto contexts = ImGuiManager.contexts();
ASSERT_EQ(contexts.size(), 3u);
EXPECT_EQ(contexts.at(0).id_, 0u);
EXPECT_EQ(contexts.at(1).id_, 1u);
EXPECT_EQ(contexts.at(2).id_, 2u);
EXPECT_EQ(contexts.at(0).name_, "Context One");
EXPECT_EQ(contexts.at(1).name_, "Context Two");
EXPECT_EQ(contexts.at(2).name_, "Context Three");
EXPECT_NE(contexts.at(0).context_, nullptr);
EXPECT_NE(contexts.at(1).context_, nullptr);
EXPECT_NE(contexts.at(2).context_, nullptr);
ImGuiManager.DestroyContext("Context Two");
auto contexts2 = ImGuiManager.contexts();
ASSERT_EQ(contexts2.size(), 2u);
EXPECT_EQ(contexts2.at(0), contexts.at(0));
EXPECT_EQ(contexts2.at(1), contexts.at(2));
}
} // namespace manager
} // namespace qt
} // namespace scwx

View file

@ -21,7 +21,8 @@ set(SRC_PROVIDER_TESTS source/scwx/provider/aws_level2_data_provider.test.cpp
source/scwx/provider/warnings_provider.test.cpp)
set(SRC_QT_CONFIG_TESTS source/scwx/qt/config/county_database.test.cpp
source/scwx/qt/config/radar_site.test.cpp)
set(SRC_QT_MANAGER_TESTS source/scwx/qt/manager/settings_manager.test.cpp)
set(SRC_QT_MANAGER_TESTS source/scwx/qt/manager/imgui_manager.test.cpp
source/scwx/qt/manager/settings_manager.test.cpp)
set(SRC_UTIL_TESTS source/scwx/util/float.test.cpp
source/scwx/util/rangebuf.test.cpp
source/scwx/util/streams.test.cpp