supercell-wx/scwx-qt/source/scwx/qt/model/imgui_context_model.cpp
2023-04-17 18:37:23 -05:00

158 lines
3.8 KiB
C++

#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_ {};
ImFontAtlas fontAtlas_ {};
};
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 >= static_cast<int>(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(&p->fontAtlas_);
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};
style.WindowPadding = {6.0f, 4.0f};
style.Colors[ImGuiCol_Text] = {1.00f, 1.00f, 1.00f, 0.80f};
style.Colors[ImGuiCol_WindowBg] = {0.06f, 0.06f, 0.06f, 0.75f};
// 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();
ImGuiContext* context = it->context_;
// Erase context from index
beginRemoveRows(QModelIndex(), position, position);
p->contexts_.erase(it);
endRemoveRows();
// Destroy context
ImGui::SetCurrentContext(context);
ImGui::DestroyContext();
}
}
std::vector<ImGuiContextInfo> ImGuiContextModel::contexts() const
{
return p->contexts_;
}
ImFontAtlas* ImGuiContextModel::font_atlas()
{
return &p->fontAtlas_;
}
ImGuiContextModel& ImGuiContextModel::Instance()
{
static ImGuiContextModel instance_ {};
return instance_;
}
bool ImGuiContextInfo::operator==(const ImGuiContextInfo& o) const = default;
} // namespace model
} // namespace qt
} // namespace scwx