feat: Added tutorial system
This commit is contained in:
parent
1a8a9e53e1
commit
5bcfe37b4e
@ -17,6 +17,7 @@ set(LIBIMHEX_SOURCES
|
||||
source/api/workspace_manager.cpp
|
||||
source/api/achievement_manager.cpp
|
||||
source/api/localization_manager.cpp
|
||||
source/api/tutorial_manager.cpp
|
||||
|
||||
source/data_processor/attribute.cpp
|
||||
source/data_processor/link.cpp
|
||||
|
169
lib/libimhex/include/hex/api/tutorial_manager.hpp
Normal file
169
lib/libimhex/include/hex/api/tutorial_manager.hpp
Normal file
@ -0,0 +1,169 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <variant>
|
||||
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class TutorialManager {
|
||||
private:
|
||||
class IDStack {
|
||||
public:
|
||||
IDStack();
|
||||
|
||||
void add(const void *pointer);
|
||||
void add(const std::string &string);
|
||||
void add(int value);
|
||||
|
||||
ImGuiID get();
|
||||
private:
|
||||
ImVector<ImGuiID> idStack;
|
||||
};
|
||||
|
||||
public:
|
||||
enum class Position : u8 {
|
||||
None = 0,
|
||||
Top = 1,
|
||||
Bottom = 2,
|
||||
Left = 4,
|
||||
Right = 8
|
||||
};
|
||||
|
||||
struct Tutorial {
|
||||
Tutorial() = delete;
|
||||
Tutorial(const std::string &unlocalizedName, const std::string &unlocalizedDescription) :
|
||||
m_unlocalizedName(unlocalizedName),
|
||||
m_unlocalizedDescription(unlocalizedDescription) { }
|
||||
|
||||
struct Step {
|
||||
explicit Step(Tutorial *parent) : m_parent(parent) { }
|
||||
|
||||
/**
|
||||
* @brief Adds a highlighting with text to a specific element
|
||||
* @param unlocalizedText Unlocalized text to display next to the highlighting
|
||||
* @param ids ID of the element to highlight
|
||||
* @return Current step
|
||||
*/
|
||||
Step& addHighlight(const std::string &unlocalizedText, std::initializer_list<std::variant<std::string, int>> &&ids);
|
||||
|
||||
/**
|
||||
* @brief Adds a highlighting to a specific element
|
||||
* @param ids ID of the element to highlight
|
||||
* @return Current step
|
||||
*/
|
||||
Step& addHighlight(std::initializer_list<std::variant<std::string, int>> &&ids);
|
||||
|
||||
/**
|
||||
* @brief Sets the text that will be displayed in the tutorial message box
|
||||
* @param unlocalizedTitle Title of the message box
|
||||
* @param unlocalizedMessage Main message of the message box
|
||||
* @param position Position of the message box
|
||||
* @return Current step
|
||||
*/
|
||||
Step& setMessage(const std::string &unlocalizedTitle, const std::string &unlocalizedMessage, Position position = Position::None);
|
||||
|
||||
/**
|
||||
* @brief Allows this step to be skipped by clicking on the advance button
|
||||
* @return Current step
|
||||
*/
|
||||
Step& allowSkip();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Checks if this step is the current step
|
||||
* @return True if this step is the current step
|
||||
*/
|
||||
bool isCurrent() const;
|
||||
|
||||
/**
|
||||
* @brief Completes this step if it is the current step
|
||||
*/
|
||||
void complete() const;
|
||||
|
||||
private:
|
||||
struct Highlight {
|
||||
std::string unlocalizedText;
|
||||
ImGuiID highlightId;
|
||||
};
|
||||
|
||||
struct Message {
|
||||
Position position;
|
||||
std::string unlocalizedTitle;
|
||||
std::string unlocalizedMessage;
|
||||
bool allowSkip;
|
||||
};
|
||||
|
||||
private:
|
||||
void addHighlights() const;
|
||||
void removeHighlights() const;
|
||||
|
||||
void advance(i32 steps = 1) const;
|
||||
|
||||
friend class TutorialManager;
|
||||
|
||||
Tutorial *m_parent;
|
||||
std::vector<Highlight> m_highlights;
|
||||
std::optional<Message> m_message;
|
||||
};
|
||||
|
||||
Step& addStep();
|
||||
|
||||
private:
|
||||
friend class TutorialManager;
|
||||
|
||||
void start();
|
||||
|
||||
std::string m_unlocalizedName;
|
||||
std::string m_unlocalizedDescription;
|
||||
std::list<Step> m_steps;
|
||||
decltype(m_steps)::iterator m_currentStep, m_latestStep;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Creates a new tutorial that can be started later
|
||||
* @param unlocalizedName Name of the tutorial
|
||||
* @param unlocalizedDescription
|
||||
* @return Reference to created tutorial
|
||||
*/
|
||||
static Tutorial& createTutorial(const std::string &unlocalizedName, const std::string &unlocalizedDescription);
|
||||
|
||||
/**
|
||||
* @brief Starts the tutorial with the given name
|
||||
* @param unlocalizedName Name of tutorial to start
|
||||
*/
|
||||
static void startTutorial(const std::string &unlocalizedName);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Draws the tutorial
|
||||
* @note This function should only be called by the main GUI
|
||||
*/
|
||||
static void drawTutorial();
|
||||
|
||||
/**
|
||||
* @brief Resets the tutorial manager
|
||||
*/
|
||||
static void reset();
|
||||
|
||||
private:
|
||||
TutorialManager() = delete;
|
||||
|
||||
static void drawHighlights();
|
||||
static void drawMessageBox(std::optional<Tutorial::Step::Message> message);
|
||||
};
|
||||
|
||||
inline TutorialManager::Position operator|(TutorialManager::Position a, TutorialManager::Position b) {
|
||||
return static_cast<TutorialManager::Position>(static_cast<u8>(a) | static_cast<u8>(b));
|
||||
}
|
||||
|
||||
inline TutorialManager::Position operator&(TutorialManager::Position a, TutorialManager::Position b) {
|
||||
return static_cast<TutorialManager::Position>(static_cast<u8>(a) & static_cast<u8>(b));
|
||||
}
|
||||
|
||||
}
|
307
lib/libimhex/source/api/tutorial_manager.cpp
Normal file
307
lib/libimhex/source/api/tutorial_manager.cpp
Normal file
@ -0,0 +1,307 @@
|
||||
#include <hex/api/tutorial_manager.hpp>
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#include <imgui_internal.h>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace {
|
||||
|
||||
std::map<std::string, TutorialManager::Tutorial> s_tutorials;
|
||||
decltype(s_tutorials)::iterator s_currentTutorial = s_tutorials.end();
|
||||
|
||||
std::map<ImGuiID, std::string> s_highlights;
|
||||
std::vector<std::pair<ImRect, std::string>> s_highlightDisplays;
|
||||
|
||||
|
||||
}
|
||||
|
||||
TutorialManager::Tutorial& TutorialManager::createTutorial(const std::string& unlocalizedName, const std::string& unlocalizedDescription) {
|
||||
return s_tutorials.try_emplace(unlocalizedName, Tutorial(unlocalizedName, unlocalizedDescription)).first->second;
|
||||
}
|
||||
|
||||
void TutorialManager::startTutorial(const std::string& unlocalizedName) {
|
||||
s_currentTutorial = s_tutorials.find(unlocalizedName);
|
||||
if (s_currentTutorial == s_tutorials.end())
|
||||
return;
|
||||
|
||||
s_currentTutorial->second.start();
|
||||
}
|
||||
|
||||
void TutorialManager::drawHighlights() {
|
||||
for (const auto &[rect, unlocalizedText] : s_highlightDisplays) {
|
||||
const auto drawList = ImGui::GetForegroundDrawList();
|
||||
|
||||
drawList->PushClipRectFullScreen();
|
||||
{
|
||||
auto highlightColor = ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_Highlight);
|
||||
highlightColor.w *= ImSin(ImGui::GetTime() * 6.0F) / 4.0F + 0.75F;
|
||||
|
||||
drawList->AddRect(rect.Min - ImVec2(5, 5), rect.Max + ImVec2(5, 5), ImColor(highlightColor), 5.0F, ImDrawFlags_None, 2.0F);
|
||||
}
|
||||
|
||||
{
|
||||
if (!unlocalizedText.empty()) {
|
||||
const auto margin = ImGui::GetStyle().WindowPadding;
|
||||
|
||||
const ImVec2 windowPos = { rect.Min.x + 20_scaled, rect.Max.y + 10_scaled };
|
||||
ImVec2 windowSize = { std::max<float>(rect.Max.x - rect.Min.x - 40_scaled, 300_scaled), 0 };
|
||||
|
||||
const char* text = Lang(unlocalizedText);
|
||||
const auto textSize = ImGui::CalcTextSize(text, nullptr, false, windowSize.x - margin.x * 2);
|
||||
windowSize.y = textSize.y + margin.y * 2;
|
||||
|
||||
drawList->AddRectFilled(windowPos, windowPos + windowSize, ImGui::GetColorU32(ImGuiCol_WindowBg) | 0xFF000000);
|
||||
drawList->AddRect(windowPos, windowPos + windowSize, ImGui::GetColorU32(ImGuiCol_Border));
|
||||
drawList->AddText(nullptr, 0.0F, windowPos + margin, ImGui::GetColorU32(ImGuiCol_Text), text, nullptr, windowSize.x - margin.x * 2);
|
||||
}
|
||||
}
|
||||
drawList->PopClipRect();
|
||||
|
||||
}
|
||||
s_highlightDisplays.clear();
|
||||
}
|
||||
|
||||
void TutorialManager::drawMessageBox(std::optional<Tutorial::Step::Message> message) {
|
||||
const auto windowStart = ImHexApi::System::getMainWindowPosition() + scaled({ 10, 10 });
|
||||
const auto windowEnd = ImHexApi::System::getMainWindowPosition() + ImHexApi::System::getMainWindowSize() - scaled({ 10, 10 });
|
||||
|
||||
ImVec2 position = ImHexApi::System::getMainWindowPosition() + ImHexApi::System::getMainWindowSize() / 2.0F;
|
||||
ImVec2 pivot = { 0.5F, 0.5F };
|
||||
|
||||
if (!message.has_value()) {
|
||||
message = Tutorial::Step::Message {
|
||||
Position::None,
|
||||
"",
|
||||
"",
|
||||
false
|
||||
};
|
||||
}
|
||||
|
||||
if (message->position == Position::None) {
|
||||
message->position = Position::Bottom | Position::Right;
|
||||
}
|
||||
|
||||
if ((message->position & Position::Top) == Position::Top) {
|
||||
position.y = windowStart.y;
|
||||
pivot.y = 0.0F;
|
||||
}
|
||||
if ((message->position & Position::Bottom) == Position::Bottom) {
|
||||
position.y = windowEnd.y;
|
||||
pivot.y = 1.0F;
|
||||
}
|
||||
if ((message->position & Position::Left) == Position::Left) {
|
||||
position.x = windowStart.x;
|
||||
pivot.x = 0.0F;
|
||||
}
|
||||
if ((message->position & Position::Right) == Position::Right) {
|
||||
position.x = windowEnd.x;
|
||||
pivot.x = 1.0F;
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowPos(position, ImGuiCond_Always, pivot);
|
||||
if (ImGui::Begin("##TutorialMessage", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing)) {
|
||||
ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow());
|
||||
|
||||
if (!message->unlocalizedTitle.empty())
|
||||
ImGuiExt::Header(Lang(message->unlocalizedTitle), true);
|
||||
|
||||
if (!message->unlocalizedMessage.empty()) {
|
||||
ImGui::PushTextWrapPos(300_scaled);
|
||||
ImGui::TextUnformatted(Lang(message->unlocalizedMessage));
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::NewLine();
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(s_currentTutorial->second.m_currentStep == s_currentTutorial->second.m_steps.begin());
|
||||
if (ImGui::ArrowButton("Backwards", ImGuiDir_Left)) {
|
||||
s_currentTutorial->second.m_currentStep->advance(-1);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginDisabled(s_currentTutorial->second.m_currentStep == s_currentTutorial->second.m_steps.end() || (!message->allowSkip && s_currentTutorial->second.m_currentStep == s_currentTutorial->second.m_latestStep));
|
||||
if (ImGui::ArrowButton("Forwards", ImGuiDir_Right)) {
|
||||
s_currentTutorial->second.m_currentStep->advance(1);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void TutorialManager::drawTutorial() {
|
||||
drawHighlights();
|
||||
|
||||
if (s_currentTutorial == s_tutorials.end())
|
||||
return;
|
||||
|
||||
const auto ¤tStep = s_currentTutorial->second.m_currentStep;
|
||||
if (currentStep == s_currentTutorial->second.m_steps.end())
|
||||
return;
|
||||
|
||||
const auto &message = currentStep->m_message;
|
||||
drawMessageBox(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TutorialManager::reset() {
|
||||
s_tutorials.clear();
|
||||
s_currentTutorial = s_tutorials.end();
|
||||
|
||||
s_highlights.clear();
|
||||
s_highlightDisplays.clear();
|
||||
}
|
||||
|
||||
TutorialManager::IDStack::IDStack() {
|
||||
idStack.push_back(0);
|
||||
}
|
||||
|
||||
TutorialManager::Tutorial::Step& TutorialManager::Tutorial::addStep() {
|
||||
auto &newStep = this->m_steps.emplace_back(this);
|
||||
this->m_currentStep = this->m_steps.begin();
|
||||
this->m_latestStep = this->m_currentStep;
|
||||
|
||||
return newStep;
|
||||
}
|
||||
|
||||
void TutorialManager::Tutorial::start() {
|
||||
this->m_currentStep = m_steps.begin();
|
||||
this->m_latestStep = this->m_currentStep;
|
||||
if (m_currentStep == m_steps.end())
|
||||
return;
|
||||
|
||||
m_currentStep->addHighlights();
|
||||
}
|
||||
|
||||
void TutorialManager::Tutorial::Step::addHighlights() const {
|
||||
for (const auto &[text, id] : this->m_highlights) {
|
||||
s_highlights.emplace(id, text.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void TutorialManager::Tutorial::Step::removeHighlights() const {
|
||||
for (const auto &[text, id] : this->m_highlights) {
|
||||
s_highlights.erase(id);
|
||||
}
|
||||
}
|
||||
|
||||
void TutorialManager::Tutorial::Step::advance(i32 steps) const {
|
||||
m_parent->m_currentStep->removeHighlights();
|
||||
std::advance(s_currentTutorial->second.m_currentStep, steps);
|
||||
|
||||
if (m_parent->m_currentStep != m_parent->m_steps.end())
|
||||
m_parent->m_currentStep->addHighlights();
|
||||
}
|
||||
|
||||
|
||||
TutorialManager::Tutorial::Step& TutorialManager::Tutorial::Step::addHighlight(const std::string& unlocalizedText, std::initializer_list<std::variant<std::string, int>>&& ids) {
|
||||
IDStack idStack;
|
||||
|
||||
for (const auto &id : ids) {
|
||||
std::visit([&idStack](const auto &id) {
|
||||
idStack.add(id);
|
||||
}, id);
|
||||
}
|
||||
|
||||
this->m_highlights.emplace_back(
|
||||
unlocalizedText,
|
||||
idStack.get()
|
||||
);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
TutorialManager::Tutorial::Step& TutorialManager::Tutorial::Step::addHighlight(std::initializer_list<std::variant<std::string, int>>&& ids) {
|
||||
return this->addHighlight("", std::move(ids));
|
||||
}
|
||||
|
||||
|
||||
|
||||
TutorialManager::Tutorial::Step& TutorialManager::Tutorial::Step::setMessage(const std::string& unlocalizedTitle, const std::string& unlocalizedMessage, Position position) {
|
||||
this->m_message = Message {
|
||||
position,
|
||||
unlocalizedTitle,
|
||||
unlocalizedMessage,
|
||||
false
|
||||
};
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
TutorialManager::Tutorial::Step& TutorialManager::Tutorial::Step::allowSkip() {
|
||||
if (this->m_message.has_value()) {
|
||||
this->m_message->allowSkip = true;
|
||||
} else {
|
||||
this->m_message = Message {
|
||||
Position::Bottom | Position::Right,
|
||||
"",
|
||||
"",
|
||||
true
|
||||
};
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool TutorialManager::Tutorial::Step::isCurrent() const {
|
||||
const auto ¤tStep = this->m_parent->m_currentStep;
|
||||
|
||||
if (currentStep == this->m_parent->m_steps.end())
|
||||
return false;
|
||||
|
||||
return &*currentStep == this;
|
||||
}
|
||||
|
||||
void TutorialManager::Tutorial::Step::complete() const {
|
||||
if (this->isCurrent()) {
|
||||
this->advance();
|
||||
this->m_parent->m_latestStep = this->m_parent->m_currentStep;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TutorialManager::IDStack::add(const std::string &string) {
|
||||
const ImGuiID seed = idStack.back();
|
||||
const ImGuiID id = ImHashStr(string.c_str(), string.length(), seed);
|
||||
|
||||
idStack.push_back(id);
|
||||
}
|
||||
|
||||
void TutorialManager::IDStack::add(const void *pointer) {
|
||||
const ImGuiID seed = idStack.back();
|
||||
const ImGuiID id = ImHashData(&pointer, sizeof(pointer), seed);
|
||||
|
||||
idStack.push_back(id);
|
||||
}
|
||||
|
||||
void TutorialManager::IDStack::add(int value) {
|
||||
const ImGuiID seed = idStack.back();
|
||||
const ImGuiID id = ImHashData(&value, sizeof(value), seed);
|
||||
|
||||
idStack.push_back(id);
|
||||
}
|
||||
|
||||
ImGuiID TutorialManager::IDStack::get() {
|
||||
return idStack.back();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ImGuiTestEngineHook_ItemAdd(ImGuiContext*, ImGuiID id, const ImRect& bb, const ImGuiLastItemData*) {
|
||||
const auto element = hex::s_highlights.find(id);
|
||||
if (element != hex::s_highlights.end()) {
|
||||
hex::s_highlightDisplays.emplace_back(bb, element->second);
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiTestEngineHook_ItemInfo(ImGuiContext*, ImGuiID, const char*, ImGuiItemStatusFlags) {}
|
||||
void ImGuiTestEngineHook_Log(ImGuiContext*, const char*, ...) {}
|
||||
const char* ImGuiTestEngine_FindItemDebugLabel(ImGuiContext*, ImGuiID) { return nullptr; }
|
@ -11,12 +11,15 @@
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
|
||||
#include <fonts/codicons_font.h>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/api/theme_manager.hpp>
|
||||
|
||||
|
||||
namespace ImGuiExt {
|
||||
@ -172,7 +175,7 @@ namespace ImGuiExt {
|
||||
GetWindowDrawList()->AddLine(ImVec2(pos.x, pos.y + size.y), pos + size, ImU32(col));
|
||||
PopStyleColor();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -204,7 +207,7 @@ namespace ImGuiExt {
|
||||
GetWindowDrawList()->AddLine(ImVec2(pos.x, pos.y + size.y), pos + size, ImU32(col));
|
||||
PopStyleColor();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -239,7 +242,7 @@ namespace ImGuiExt {
|
||||
GetWindowDrawList()->AddLine(bb.Min + ImVec2(g.FontSize * 0.5 + style.FramePadding.x, size.y), pos + size - ImVec2(g.FontSize * 0.5 + style.FramePadding.x, 0), ImU32(col));
|
||||
PopStyleColor();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -290,7 +293,7 @@ namespace ImGuiExt {
|
||||
// if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
|
||||
// CloseCurrentPopup();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -345,7 +348,7 @@ namespace ImGuiExt {
|
||||
// if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
|
||||
// CloseCurrentPopup();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -570,7 +573,7 @@ namespace ImGuiExt {
|
||||
// if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
|
||||
// CloseCurrentPopup();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -613,7 +616,7 @@ namespace ImGuiExt {
|
||||
// if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
|
||||
// CloseCurrentPopup();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, symbol, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -656,7 +659,7 @@ namespace ImGuiExt {
|
||||
// if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
|
||||
// CloseCurrentPopup();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, symbol, g.LastItemData.StatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
|
@ -127,6 +127,8 @@ namespace ImGui
|
||||
}
|
||||
*/
|
||||
|
||||
#define IMGUI_ENABLE_TEST_ENGINE
|
||||
|
||||
|
||||
// IMPLOT CONFIG
|
||||
#define IMPLOT_CUSTOM_NUMERIC_TYPES (ImS8)(ImU8)(ImS16)(ImU16)(ImS32)(ImU32)(ImS64)(ImU64)(float)(double)(long double)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <hex/api/plugin_manager.hpp>
|
||||
#include <hex/api/layout_manager.hpp>
|
||||
#include <hex/api/achievement_manager.hpp>
|
||||
#include <hex/api/tutorial_manager.hpp>
|
||||
#include <hex/api/workspace_manager.hpp>
|
||||
|
||||
#include <hex/ui/view.hpp>
|
||||
@ -137,6 +138,7 @@ namespace hex::init {
|
||||
ThemeManager::reset();
|
||||
|
||||
AchievementManager::getAchievements().clear();
|
||||
TutorialManager::reset();
|
||||
|
||||
ProjectFile::getHandlers().clear();
|
||||
ProjectFile::getProviderHandlers().clear();
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <hex/api/shortcut_manager.hpp>
|
||||
#include <hex/api/workspace_manager.hpp>
|
||||
#include <hex/api/project_file_manager.hpp>
|
||||
#include <hex/api/tutorial_manager.hpp>
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/fs.hpp>
|
||||
@ -828,6 +829,8 @@ namespace hex {
|
||||
void Window::frameEnd() {
|
||||
EventFrameEnd::post();
|
||||
|
||||
TutorialManager::drawTutorial();
|
||||
|
||||
// Clean up all tasks that are done
|
||||
TaskManager::collectGarbage();
|
||||
|
||||
@ -1194,7 +1197,10 @@ namespace hex {
|
||||
};
|
||||
|
||||
handler.UserData = this;
|
||||
ImGui::GetCurrentContext()->SettingsHandlers.push_back(handler);
|
||||
|
||||
auto context = ImGui::GetCurrentContext();
|
||||
context->SettingsHandlers.push_back(handler);
|
||||
context->TestEngineHookItems = true;
|
||||
|
||||
io.IniFilename = nullptr;
|
||||
}
|
||||
|
@ -160,8 +160,6 @@ namespace hex::plugin::builtin {
|
||||
ImGui::SetCursorPosX(50_scaled);
|
||||
if (ImGuiExt::DimmedButton("hex.builtin.view.information.analyze"_lang, ImVec2(ImGui::GetContentRegionAvail().x - 50_scaled, 0)))
|
||||
this->analyze();
|
||||
|
||||
|
||||
}
|
||||
ImGuiExt::EndSubWindow();
|
||||
ImGui::EndDisabled();
|
||||
|
Loading…
Reference in New Issue
Block a user