mirror of https://github.com/WerWolv/ImHex
impr: Allow tutorials to use markdown formatted text
This commit is contained in:
parent
021c7e5fdb
commit
6b16f39be4
|
|
@ -22,6 +22,8 @@ EXPORT_MODULE namespace hex {
|
|||
Right = 8
|
||||
};
|
||||
|
||||
using DrawFunction = std::function<void()>;
|
||||
|
||||
struct Tutorial {
|
||||
Tutorial() = delete;
|
||||
Tutorial(const UnlocalizedString &unlocalizedName, const UnlocalizedString &unlocalizedDescription) :
|
||||
|
|
@ -101,6 +103,7 @@ EXPORT_MODULE namespace hex {
|
|||
std::vector<Highlight> m_highlights;
|
||||
std::optional<Message> m_message;
|
||||
std::function<void()> m_onAppear, m_onComplete;
|
||||
DrawFunction m_drawFunction;
|
||||
};
|
||||
|
||||
Step& addStep();
|
||||
|
|
@ -166,6 +169,8 @@ EXPORT_MODULE namespace hex {
|
|||
*/
|
||||
static void reset();
|
||||
|
||||
static void setRenderer(std::function<DrawFunction(const std::string &)> renderer);
|
||||
|
||||
private:
|
||||
TutorialManager() = delete;
|
||||
|
||||
|
|
|
|||
|
|
@ -319,6 +319,7 @@ namespace ImGuiExt {
|
|||
bool DimmedButtonToggle(const char *icon, bool *v, ImVec2 size = ImVec2(0, 0), ImVec2 iconOffset = ImVec2(0, 0));
|
||||
bool DimmedIconToggle(const char *icon, bool *v);
|
||||
bool DimmedIconToggle(const char *iconOn, const char *iconOff, bool *v);
|
||||
bool DimmedArrowButton(const char *id, ImGuiDir dir, ImVec2 size = ImVec2(ImGui::GetFrameHeight(), ImGui::GetFrameHeight()));
|
||||
|
||||
void TextOverlay(const char *text, ImVec2 pos, float maxWidth = -1);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ namespace hex {
|
|||
ImGuiID s_activeHelpId;
|
||||
bool s_helpHoverActive = false;
|
||||
|
||||
AutoReset<std::function<std::function<void()>(const std::string &)>> s_renderer;
|
||||
|
||||
|
||||
class IDStack {
|
||||
public:
|
||||
|
|
@ -126,6 +128,17 @@ namespace hex {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (*s_renderer == nullptr) {
|
||||
*s_renderer = [](const std::string &message) {
|
||||
return [message] {
|
||||
ImGui::PushTextWrapPos(300_scaled);
|
||||
ImGui::TextUnformatted(message.c_str());
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::NewLine();
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const std::map<std::string, TutorialManager::Tutorial>& TutorialManager::getTutorials() {
|
||||
|
|
@ -333,30 +346,29 @@ namespace hex {
|
|||
|
||||
ImGui::SetNextWindowPos(position, ImGuiCond_Always, pivot);
|
||||
ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID);
|
||||
if (ImGui::Begin("##TutorialMessage", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing)) {
|
||||
ImGui::SetNextWindowSize(ImVec2(300_scaled, 0));
|
||||
if (ImGui::Begin(message->unlocalizedTitle.empty() ? "##TutorialMessage" : Lang(message->unlocalizedTitle), nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoFocusOnAppearing)) {
|
||||
ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindowRead());
|
||||
|
||||
if (!message->unlocalizedTitle.empty())
|
||||
ImGuiExt::Header(Lang(message->unlocalizedTitle), true);
|
||||
|
||||
auto &step = s_currentTutorial->second.m_currentStep;
|
||||
if (!message->unlocalizedMessage.empty()) {
|
||||
ImGui::PushTextWrapPos(300_scaled);
|
||||
ImGui::TextUnformatted(Lang(message->unlocalizedMessage));
|
||||
ImGui::PopTextWrapPos();
|
||||
step->m_drawFunction();
|
||||
ImGui::NewLine();
|
||||
ImGui::NewLine();
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(s_currentTutorial->second.m_currentStep == s_currentTutorial->second.m_steps.begin());
|
||||
if (ImGui::ArrowButton("Backwards", ImGuiDir_Left)) {
|
||||
ImGui::BeginDisabled(step == s_currentTutorial->second.m_steps.begin());
|
||||
if (ImGuiExt::DimmedArrowButton("Backwards", ImGuiDir_Left)) {
|
||||
s_currentTutorial->second.m_currentStep->advance(-1);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginDisabled(!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::SetCursorPosX(ImGui::GetWindowWidth() - ImGui::GetFrameHeight() - ImGui::GetStyle().WindowPadding.x);
|
||||
ImGui::BeginDisabled(!message->allowSkip && step == s_currentTutorial->second.m_latestStep);
|
||||
if (ImGuiExt::DimmedArrowButton("Forwards", ImGuiDir_Right)) {
|
||||
step->advance(1);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
|
@ -387,6 +399,10 @@ namespace hex {
|
|||
s_highlightDisplays->clear();
|
||||
}
|
||||
|
||||
void TutorialManager::setRenderer(std::function<DrawFunction(const std::string &)> renderer) {
|
||||
s_renderer = std::move(renderer);
|
||||
}
|
||||
|
||||
TutorialManager::Tutorial::Step& TutorialManager::Tutorial::addStep() {
|
||||
auto &newStep = m_steps.emplace_back(this);
|
||||
m_currentStep = m_steps.end();
|
||||
|
|
@ -402,6 +418,9 @@ namespace hex {
|
|||
return;
|
||||
|
||||
m_currentStep->addHighlights();
|
||||
|
||||
if (m_currentStep->m_message.has_value())
|
||||
m_currentStep->m_drawFunction = (*s_renderer)(Lang(m_currentStep->m_message->unlocalizedMessage));
|
||||
}
|
||||
|
||||
void TutorialManager::Tutorial::Step::addHighlights() const {
|
||||
|
|
@ -426,8 +445,12 @@ namespace hex {
|
|||
std::advance(m_parent->m_latestStep, steps);
|
||||
std::advance(m_parent->m_currentStep, steps);
|
||||
|
||||
if (m_parent->m_currentStep != m_parent->m_steps.end())
|
||||
if (m_parent->m_currentStep != m_parent->m_steps.end()) {
|
||||
m_parent->m_currentStep->addHighlights();
|
||||
|
||||
if (m_message.has_value())
|
||||
m_parent->m_currentStep->m_drawFunction = (*s_renderer)(Lang(m_parent->m_currentStep->m_message->unlocalizedMessage));
|
||||
}
|
||||
else
|
||||
s_currentTutorial = s_tutorials->end();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1218,6 +1218,21 @@ namespace ImGuiExt {
|
|||
return res;
|
||||
}
|
||||
|
||||
bool DimmedArrowButton(const char *id, ImGuiDir dir, ImVec2 size) {
|
||||
PushStyleColor(ImGuiCol_ButtonHovered, GetCustomColorU32(ImGuiCustomCol_DescButtonHovered));
|
||||
PushStyleColor(ImGuiCol_Button, GetCustomColorU32(ImGuiCustomCol_DescButton));
|
||||
PushStyleColor(ImGuiCol_Text, GetColorU32(ImGuiCol_ButtonActive));
|
||||
PushStyleColor(ImGuiCol_ButtonActive, GetCustomColorU32(ImGuiCustomCol_DescButtonActive));
|
||||
PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.5 * hex::ImHexApi::System::getGlobalScale());
|
||||
|
||||
bool res = ArrowButtonEx(id, dir, size);
|
||||
|
||||
PopStyleColor(4);
|
||||
PopStyleVar(1);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool DimmedButtonToggle(const char *icon, bool *v, ImVec2 size, ImVec2 iconOffset) {
|
||||
bool pushed = false;
|
||||
bool toggled = false;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,18 @@
|
|||
#include <hex/api/tutorial_manager.hpp>
|
||||
#include <ui/markdown.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
void registerIntroductionTutorial();
|
||||
|
||||
void registerTutorials() {
|
||||
TutorialManager::setRenderer([](const std::string &message) {
|
||||
return [markdown = std::make_shared<ui::Markdown>(message)] {
|
||||
markdown->draw();
|
||||
};
|
||||
});
|
||||
|
||||
registerIntroductionTutorial();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@ namespace hex::ui {
|
|||
public:
|
||||
Markdown() = default;
|
||||
Markdown(const std::string &text);
|
||||
Markdown(const Markdown &) = delete;
|
||||
Markdown(Markdown &&other) = default;
|
||||
|
||||
Markdown &operator=(const Markdown &) = delete;
|
||||
Markdown &operator=(Markdown &&other) = default;
|
||||
|
||||
void draw();
|
||||
void reset();
|
||||
|
|
|
|||
Loading…
Reference in New Issue