1
0
mirror of synced 2025-01-18 00:56:49 +01:00

feat: Added tutorials view

This commit is contained in:
WerWolv 2023-12-13 13:04:59 +01:00
parent 3bc5295eae
commit 92043a3d23
7 changed files with 128 additions and 0 deletions

View File

@ -101,6 +101,9 @@ namespace hex {
Step& addStep();
const std::string& getUnlocalizedName() const { return this->m_unlocalizedName; }
const std::string& getUnlocalizedDescription() const { return this->m_unlocalizedDescription; }
private:
friend class TutorialManager;
@ -112,6 +115,17 @@ namespace hex {
decltype(m_steps)::iterator m_currentStep, m_latestStep;
};
/**
* @brief Gets a list of all tutorials
* @return List of all tutorials
*/
static const std::map<std::string, Tutorial>& getTutorials();
/**
* @brief Gets the currently running tutorial
* @return Iterator pointing to the current tutorial
*/
static std::map<std::string, Tutorial>::iterator getCurrentTutorial();
/**
* @brief Creates a new tutorial that can be started later

View File

@ -55,6 +55,16 @@ namespace hex {
}
const std::map<std::string, TutorialManager::Tutorial>& TutorialManager::getTutorials() {
return s_tutorials;
}
std::map<std::string, TutorialManager::Tutorial>::iterator TutorialManager::getCurrentTutorial() {
return s_currentTutorial;
}
TutorialManager::Tutorial& TutorialManager::createTutorial(const std::string& unlocalizedName, const std::string& unlocalizedDescription) {
return s_tutorials.try_emplace(unlocalizedName, Tutorial(unlocalizedName, unlocalizedDescription)).first->second;
}
@ -228,6 +238,8 @@ namespace hex {
if (m_parent->m_currentStep != m_parent->m_steps.end())
m_parent->m_currentStep->addHighlights();
else
s_currentTutorial = s_tutorials.end();
}

View File

@ -116,6 +116,7 @@ add_imhex_plugin(
source/content/views/view_logs.cpp
source/content/views/view_achievements.cpp
source/content/views/view_highlight_rules.cpp
source/content/views/view_tutorials.cpp
source/content/views/view_yara.cpp
source/content/helpers/notification.cpp

View File

@ -0,0 +1,35 @@
#pragma once
#include <hex/ui/view.hpp>
#include <hex/api/tutorial_manager.hpp>
namespace hex::plugin::builtin {
class ViewTutorials : public View::Floating {
public:
ViewTutorials();
~ViewTutorials() override = default;
void drawContent() override;
[[nodiscard]] bool shouldDraw() const override { return true; }
[[nodiscard]] bool hasViewMenuItemEntry() const override { return false; }
ImVec2 getMinSize() const override {
return scaled({ 400, 300 });
}
ImVec2 getMaxSize() const override {
return this->getMinSize();
}
ImGuiWindowFlags getWindowFlags() const override {
return Floating::getWindowFlags() | ImGuiWindowFlags_NoResize;
}
private:
const TutorialManager::Tutorial *m_selectedTutorial = nullptr;
};
}

View File

@ -1096,6 +1096,9 @@
"hex.builtin.view.theme_manager.save_theme": "Save Theme",
"hex.builtin.view.theme_manager.styles": "Styles",
"hex.builtin.view.tools.name": "Tools",
"hex.builtin.view.tutorials.name": "Interactive Tutorials",
"hex.builtin.view.tutorials.description": "Description",
"hex.builtin.view.tutorials.start": "Start Tutorial",
"hex.builtin.view.yara.error": "Yara Compiler error: {0}",
"hex.builtin.view.yara.header.matches": "Matches",
"hex.builtin.view.yara.header.rules": "Rules",

View File

@ -22,6 +22,7 @@
#include "content/views/view_logs.hpp"
#include "content/views/view_achievements.hpp"
#include "content/views/view_highlight_rules.hpp"
#include "content/views/view_tutorials.hpp"
namespace hex::plugin::builtin {
@ -50,6 +51,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Views::add<ViewLogs>();
ContentRegistry::Views::add<ViewAchievements>();
ContentRegistry::Views::add<ViewHighlightRules>();
ContentRegistry::Views::add<ViewTutorials>();
}
}

View File

@ -0,0 +1,61 @@
#include "content/views/view_tutorials.hpp"
#include <hex/api/content_registry.hpp>
#include <hex/api/tutorial_manager.hpp>
#include <ranges>
namespace hex::plugin::builtin {
ViewTutorials::ViewTutorials() : View::Floating("hex.builtin.view.tutorials.name") {
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.help", "hex.builtin.view.tutorials.name" }, 4000, Shortcut::None, [&, this] {
this->getWindowOpenState() = true;
});
}
void ViewTutorials::drawContent() {
const auto& tutorials = TutorialManager::getTutorials();
const auto& currTutorial = TutorialManager::getCurrentTutorial();
if (ImGui::BeginTable("TutorialLayout", 2, ImGuiTableFlags_SizingFixedFit)) {
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 0.3F);
ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthStretch, 0.7F);
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginTable("Tutorials", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImGui::GetContentRegionAvail())) {
for (const auto &tutorial : tutorials | std::views::values) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::Selectable(Lang(tutorial.getUnlocalizedName()), this->m_selectedTutorial == &tutorial, ImGuiSelectableFlags_SpanAllColumns)) {
this->m_selectedTutorial = &tutorial;
}
}
ImGui::EndTable();
}
ImGui::TableNextColumn();
if (this->m_selectedTutorial != nullptr) {
ImGuiExt::BeginSubWindow("hex.builtin.view.tutorials.description"_lang, ImGui::GetContentRegionAvail() - ImVec2(0, ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().ItemSpacing.y * 2));
{
ImGuiExt::TextFormattedWrapped(Lang(this->m_selectedTutorial->getUnlocalizedDescription()));
}
ImGuiExt::EndSubWindow();
ImGui::BeginDisabled(currTutorial != tutorials.end());
if (ImGuiExt::DimmedButton("hex.builtin.view.tutorials.start"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
TutorialManager::startTutorial(this->m_selectedTutorial->getUnlocalizedName());
}
ImGui::EndDisabled();
}
ImGui::EndTable();
}
}
}