diff --git a/lib/libimhex/include/hex/ui/view.hpp b/lib/libimhex/include/hex/ui/view.hpp index 0637ecaf9..0fb435d5a 100644 --- a/lib/libimhex/include/hex/ui/view.hpp +++ b/lib/libimhex/include/hex/ui/view.hpp @@ -14,6 +14,7 @@ #include #include +#include namespace hex { @@ -147,11 +148,17 @@ namespace hex { public: explicit Window(UnlocalizedString unlocalizedName, const char *icon) : View(std::move(unlocalizedName), icon) {} + /** + * @brief Draws help text for the view + */ + virtual void drawHelpText() = 0; + void draw() final { if (this->shouldDraw()) { ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize()); const auto title = fmt::format("{} {}", this->getIcon(), View::toWindowName(this->getUnlocalizedName())); if (ImGui::Begin(title.c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse | this->getWindowFlags())) { + TutorialManager::setLastItemInteractiveHelpPopup([this]{ this->drawHelpText(); }); this->drawContent(); } ImGui::End(); @@ -226,4 +233,4 @@ namespace hex { } }; -} \ No newline at end of file +} diff --git a/lib/libimhex/source/api/tutorial_manager.cpp b/lib/libimhex/source/api/tutorial_manager.cpp index a2244ae26..083875b6f 100644 --- a/lib/libimhex/source/api/tutorial_manager.cpp +++ b/lib/libimhex/source/api/tutorial_manager.cpp @@ -97,6 +97,9 @@ namespace hex { EventImGuiElementRendered::subscribe([](ImGuiID id, const std::array bb){ const auto boundingBox = ImRect(bb[0], bb[1], bb[2], bb[3]); + if (!ImGui::IsItemVisible()) + return; + { const auto element = hex::s_highlights->find(id); if (element != hex::s_highlights->end()) { diff --git a/plugins/builtin/include/content/views/view_achievements.hpp b/plugins/builtin/include/content/views/view_achievements.hpp index 0c7300bc4..31befb568 100644 --- a/plugins/builtin/include/content/views/view_achievements.hpp +++ b/plugins/builtin/include/content/views/view_achievements.hpp @@ -12,6 +12,7 @@ namespace hex::plugin::builtin { void drawContent() override; void drawAlwaysVisibleContent() override; + void drawHelpText() override; [[nodiscard]] bool shouldDraw() const override { return true; } [[nodiscard]] bool hasViewMenuItemEntry() const override { return false; } diff --git a/plugins/builtin/include/content/views/view_bookmarks.hpp b/plugins/builtin/include/content/views/view_bookmarks.hpp index bac57e129..96625cb0c 100644 --- a/plugins/builtin/include/content/views/view_bookmarks.hpp +++ b/plugins/builtin/include/content/views/view_bookmarks.hpp @@ -15,6 +15,7 @@ namespace hex::plugin::builtin { ~ViewBookmarks() override; void drawContent() override; + void drawHelpText() override; private: struct Bookmark { diff --git a/plugins/builtin/include/content/views/view_data_inspector.hpp b/plugins/builtin/include/content/views/view_data_inspector.hpp index 0a74031fc..d63d0ce95 100644 --- a/plugins/builtin/include/content/views/view_data_inspector.hpp +++ b/plugins/builtin/include/content/views/view_data_inspector.hpp @@ -23,6 +23,8 @@ namespace hex::plugin::builtin { return ContentRegistry::Views::getViewByName("hex.builtin.view.hex_editor.name"); } + void drawHelpText() override; + private: struct InspectorCacheEntry { UnlocalizedString unlocalizedName; diff --git a/plugins/builtin/include/content/views/view_data_processor.hpp b/plugins/builtin/include/content/views/view_data_processor.hpp index d0e5ff148..f47d6e6ab 100644 --- a/plugins/builtin/include/content/views/view_data_processor.hpp +++ b/plugins/builtin/include/content/views/view_data_processor.hpp @@ -42,6 +42,7 @@ namespace hex::plugin::builtin { ~ViewDataProcessor() override; void drawContent() override; + void drawHelpText() override; static nlohmann::json saveNode(const dp::Node *node); static nlohmann::json saveNodes(const Workspace &workspace); diff --git a/plugins/builtin/include/content/views/view_find.hpp b/plugins/builtin/include/content/views/view_find.hpp index bb056eb46..89cf68125 100644 --- a/plugins/builtin/include/content/views/view_find.hpp +++ b/plugins/builtin/include/content/views/view_find.hpp @@ -27,6 +27,8 @@ namespace hex::plugin::builtin { return ContentRegistry::Views::getViewByName("hex.builtin.view.hex_editor.name"); } + void drawHelpText() override; + private: using Occurrence = hex::ContentRegistry::DataFormatter::impl::FindOccurrence; diff --git a/plugins/builtin/include/content/views/view_hex_editor.hpp b/plugins/builtin/include/content/views/view_hex_editor.hpp index 5d4db0656..1776961f9 100644 --- a/plugins/builtin/include/content/views/view_hex_editor.hpp +++ b/plugins/builtin/include/content/views/view_hex_editor.hpp @@ -79,6 +79,8 @@ namespace hex::plugin::builtin { m_currPopup.reset(); } + void drawHelpText() override; + private: void drawPopup(); diff --git a/plugins/builtin/include/content/views/view_highlight_rules.hpp b/plugins/builtin/include/content/views/view_highlight_rules.hpp index 627e191f3..045fb9954 100644 --- a/plugins/builtin/include/content/views/view_highlight_rules.hpp +++ b/plugins/builtin/include/content/views/view_highlight_rules.hpp @@ -14,6 +14,7 @@ namespace hex::plugin::builtin { ~ViewHighlightRules() override = default; void drawContent() override; + void drawHelpText() override; [[nodiscard]] bool hasViewMenuItemEntry() const override { return false; } diff --git a/plugins/builtin/include/content/views/view_information.hpp b/plugins/builtin/include/content/views/view_information.hpp index 6dee65e8d..692794934 100644 --- a/plugins/builtin/include/content/views/view_information.hpp +++ b/plugins/builtin/include/content/views/view_information.hpp @@ -14,6 +14,8 @@ namespace hex::plugin::builtin { void drawContent() override; + void drawHelpText() override; + private: void analyze(); diff --git a/plugins/builtin/include/content/views/view_logs.hpp b/plugins/builtin/include/content/views/view_logs.hpp index 189536840..caaf3b0e9 100644 --- a/plugins/builtin/include/content/views/view_logs.hpp +++ b/plugins/builtin/include/content/views/view_logs.hpp @@ -10,6 +10,7 @@ namespace hex::plugin::builtin { ~ViewLogs() override = default; void drawContent() override; + void drawHelpText() override; [[nodiscard]] bool shouldDraw() const override { return true; } [[nodiscard]] bool hasViewMenuItemEntry() const override { return false; } diff --git a/plugins/builtin/include/content/views/view_patches.hpp b/plugins/builtin/include/content/views/view_patches.hpp index 1e58c6350..38b8201a1 100644 --- a/plugins/builtin/include/content/views/view_patches.hpp +++ b/plugins/builtin/include/content/views/view_patches.hpp @@ -13,6 +13,7 @@ namespace hex::plugin::builtin { void drawContent() override; void drawAlwaysVisibleContent() override; + void drawHelpText() override; private: u64 m_selectedPatch = 0x00; diff --git a/plugins/builtin/include/content/views/view_pattern_data.hpp b/plugins/builtin/include/content/views/view_pattern_data.hpp index 4dc4008ca..8bc00e000 100644 --- a/plugins/builtin/include/content/views/view_pattern_data.hpp +++ b/plugins/builtin/include/content/views/view_pattern_data.hpp @@ -24,6 +24,8 @@ namespace hex::plugin::builtin { return ContentRegistry::Views::getViewByName("hex.builtin.view.pattern_editor.name"); } + void drawHelpText() override; + private: bool m_rowColoring = false; u32 m_maxFilterItems = 128; diff --git a/plugins/builtin/include/content/views/view_pattern_editor.hpp b/plugins/builtin/include/content/views/view_pattern_editor.hpp index 044ebc6f4..06950a2a4 100644 --- a/plugins/builtin/include/content/views/view_pattern_editor.hpp +++ b/plugins/builtin/include/content/views/view_pattern_editor.hpp @@ -78,6 +78,8 @@ namespace hex::plugin::builtin { Deny }; + void drawHelpText() override; + private: class PopupAcceptPattern; diff --git a/plugins/builtin/include/content/views/view_store.hpp b/plugins/builtin/include/content/views/view_store.hpp index d56aa0e8b..e34f308cc 100644 --- a/plugins/builtin/include/content/views/view_store.hpp +++ b/plugins/builtin/include/content/views/view_store.hpp @@ -52,6 +52,7 @@ namespace hex::plugin::builtin { ~ViewStore() override = default; void drawContent() override; + void drawHelpText() override; [[nodiscard]] bool shouldDraw() const override { return true; } [[nodiscard]] bool hasViewMenuItemEntry() const override { return false; } diff --git a/plugins/builtin/include/content/views/view_theme_manager.hpp b/plugins/builtin/include/content/views/view_theme_manager.hpp index 14c9c12ea..6c85e7959 100644 --- a/plugins/builtin/include/content/views/view_theme_manager.hpp +++ b/plugins/builtin/include/content/views/view_theme_manager.hpp @@ -12,6 +12,7 @@ namespace hex::plugin::builtin { ~ViewThemeManager() override = default; void drawContent() override; + void drawHelpText() override; [[nodiscard]] bool shouldDraw() const override { return true; } [[nodiscard]] bool hasViewMenuItemEntry() const override { return false; } diff --git a/plugins/builtin/include/content/views/view_tools.hpp b/plugins/builtin/include/content/views/view_tools.hpp index 763d470b2..024c130f0 100644 --- a/plugins/builtin/include/content/views/view_tools.hpp +++ b/plugins/builtin/include/content/views/view_tools.hpp @@ -14,6 +14,7 @@ namespace hex::plugin::builtin { void drawContent() override; void drawAlwaysVisibleContent() override; + void drawHelpText() override; private: std::vector::const_iterator m_dragStartIterator; diff --git a/plugins/builtin/include/content/views/view_tutorials.hpp b/plugins/builtin/include/content/views/view_tutorials.hpp index 834f29186..76fc3e413 100644 --- a/plugins/builtin/include/content/views/view_tutorials.hpp +++ b/plugins/builtin/include/content/views/view_tutorials.hpp @@ -12,6 +12,7 @@ namespace hex::plugin::builtin { ~ViewTutorials() override = default; void drawContent() override; + void drawHelpText() override; [[nodiscard]] bool shouldDraw() const override { return true; } [[nodiscard]] bool hasViewMenuItemEntry() const override { return false; } diff --git a/plugins/builtin/source/content/ui_items.cpp b/plugins/builtin/source/content/ui_items.cpp index 7a7a33e87..9d77886f5 100644 --- a/plugins/builtin/source/content/ui_items.cpp +++ b/plugins/builtin/source/content/ui_items.cpp @@ -27,6 +27,7 @@ #include #include +#include namespace hex::plugin::builtin { @@ -45,6 +46,9 @@ namespace hex::plugin::builtin { hex::openWebpage("https://github.com/WerWolv/ImHex/discussions/categories/feedback"); }); + ContentRegistry::UserInterface::addTitleBarButton(ICON_TA_HELP, ImGuiCustomCol_ToolbarGray, "hex.builtin.title_bar_button.interactive_help", []{ + TutorialManager::startHelpHover(); + }); } static void drawGlobalPopups() { diff --git a/plugins/builtin/source/content/views/view_achievements.cpp b/plugins/builtin/source/content/views/view_achievements.cpp index f4a3d6f7b..282222136 100644 --- a/plugins/builtin/source/content/views/view_achievements.cpp +++ b/plugins/builtin/source/content/views/view_achievements.cpp @@ -468,4 +468,7 @@ namespace hex::plugin::builtin { } } -} \ No newline at end of file + void ViewAchievements::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This is the Achievements view. Before you ask yourself what achievements are doing in a hex editor: The Achievements are meant to be a fun way to learn about the various features of ImHex without having to read through the entire documentation. Read through the achievements, try to unlock them all, and have fun!"); + } +} diff --git a/plugins/builtin/source/content/views/view_bookmarks.cpp b/plugins/builtin/source/content/views/view_bookmarks.cpp index 73805a6a2..63affd2b0 100644 --- a/plugins/builtin/source/content/views/view_bookmarks.cpp +++ b/plugins/builtin/source/content/views/view_bookmarks.cpp @@ -639,4 +639,18 @@ namespace hex::plugin::builtin { }); } + void ViewBookmarks::drawHelpText() { + ImGuiExt::TextFormattedWrapped("All your created Bookmarks will be listed in here."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("Bookmarks provide an easy way to mark important regions in your binary and quickly navigate to them later. You can also name them, add further information through comments or change their color."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped( + "To create a Bookmark, select a byte region in the Hex Editor view and use the {} option in the {} menu or use the shortcut '{}'.", + "hex.builtin.menu.edit.bookmark.create"_lang, "hex.builtin.menu.edit"_lang, + ShortcutManager::getShortcutByName( + { "hex.builtin.menu.edit", "hex.builtin.menu.edit.bookmark.create" }, + ContentRegistry::Views::getViewByName("hex.builtin.view.hex_editor.name") + ).toString() + ); + } } \ No newline at end of file diff --git a/plugins/builtin/source/content/views/view_data_inspector.cpp b/plugins/builtin/source/content/views/view_data_inspector.cpp index bdb7cbef0..ec1211f5e 100644 --- a/plugins/builtin/source/content/views/view_data_inspector.cpp +++ b/plugins/builtin/source/content/views/view_data_inspector.cpp @@ -608,5 +608,13 @@ namespace hex::plugin::builtin { return displayFunction; } + void ViewDataInspector::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view decodes bytes, starting from the currently selected address in the Hex Editor View, as various different data types."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("The decoding here may or may not make sense depending on the actual data at the selected address but it can give a rough idea of what kind of data is present. If certain types make no sense, they can be hidden by entering the editing mode (pencil icon) and clicking the eye icon next to the corresponding row."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("By clicking on a row, the corresponding bytes will be selected in the Hex Editor View and you can use the navigation buttons at the top to move to the next or previous value, assuming you're dealing with a list of such values."); + ImGuiExt::TextFormattedWrapped("Double-clicking a row (if editable) will allow you to change the value and write it back to the underlying data. Some types may also have additional options available in the context menu (right-click on a row)."); + } } diff --git a/plugins/builtin/source/content/views/view_data_processor.cpp b/plugins/builtin/source/content/views/view_data_processor.cpp index afef4aab4..7b8af928f 100644 --- a/plugins/builtin/source/content/views/view_data_processor.cpp +++ b/plugins/builtin/source/content/views/view_data_processor.cpp @@ -1293,4 +1293,13 @@ namespace hex::plugin::builtin { } } + void ViewDataProcessor::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view lets you create and evaluate data processing pipelines using a node-based interface.\n\n"); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("Right click anywhere in the workspace to add nodes. Connect the nodes by dragging links between their input and output attributes. " + "Nodes that have no output attributes are considered end nodes and will produce the final output of the pipeline.\n\n" + "Click the green play button at the bottom to evaluate the current pipeline. If any errors occur during evaluation, " + "the affected node will be highlighted in red and an error message will be shown when hovering over it."); + } + } \ No newline at end of file diff --git a/plugins/builtin/source/content/views/view_find.cpp b/plugins/builtin/source/content/views/view_find.cpp index cc5a03bbf..e1fee685b 100644 --- a/plugins/builtin/source/content/views/view_find.cpp +++ b/plugins/builtin/source/content/views/view_find.cpp @@ -1149,4 +1149,16 @@ namespace hex::plugin::builtin { } } + void ViewFind::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view lets you search for all occurrences of a specific pattern in the opened data source."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped( + "- Strings: Search for all strings matching the specified criteria.\n" + "- Sequences: Search for a specific string character sequence in various encodings.\n" + "- Regex: Search for all strings matching the specified regular expression.\n" + "- Binary Pattern: Search for a specific byte pattern with wildcards.\n" + "- Numeric Value: Search for numeric values within a specified range in various formats." + ); + } + } diff --git a/plugins/builtin/source/content/views/view_hex_editor.cpp b/plugins/builtin/source/content/views/view_hex_editor.cpp index a2f9deb02..69ddef36f 100644 --- a/plugins/builtin/source/content/views/view_hex_editor.cpp +++ b/plugins/builtin/source/content/views/view_hex_editor.cpp @@ -1738,4 +1738,16 @@ namespace hex::plugin::builtin { this); } + void ViewHexEditor::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This is the main view you'll be working with. It shows the raw data of the currently opened data source together with any highlighting that may be generated by other parts of ImHex."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("You can edit cells by simply double clicking them. By default, this will overwrite the existing value of that cell. To insert new bytes instead, toggle the {} option in the {} menu.", + "hex.builtin.view.hex_editor.menu.edit.insert_mode"_lang, "hex.builtin.menu.edit"_lang + ); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("Many more options can be found by right clicking anywhere in this view, or by using the toggles and options in the footer bar. This includes options to change the number of bytes shown per row, the encoding used to display text, the minimap and the cell's data format.", + "hex.builtin.view.hex_editor.menu.edit.insert_mode"_lang, "hex.builtin.menu.edit"_lang + ); + } + } diff --git a/plugins/builtin/source/content/views/view_highlight_rules.cpp b/plugins/builtin/source/content/views/view_highlight_rules.cpp index 12301e97c..66bd689dc 100644 --- a/plugins/builtin/source/content/views/view_highlight_rules.cpp +++ b/plugins/builtin/source/content/views/view_highlight_rules.cpp @@ -327,4 +327,13 @@ namespace hex::plugin::builtin { } } + void ViewHighlightRules::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view allows you to create custom highlighting rules based on mathematical expressions. Each rule can contain multiple expressions, each defining a color and a mathematical condition. When the condition evaluates to true for a given byte or range of bytes, those bytes's text will be highlighted with the specified color in the hex editor.\n\n" + "You can use the following variables in your expressions:\n" + "- 'value': The byte value at the current offset.\n" + "- 'offset': The current byte offset within the data source.\n\n" + "Examples of expressions:\n" + "- 'value == 0x90' : Highlights all x86 NOP instructions (0x90).\n" + "- 'value >= 0x41 && value <= 0x5A' : Highlights all uppercase ASCII letters."); + } } diff --git a/plugins/builtin/source/content/views/view_information.cpp b/plugins/builtin/source/content/views/view_information.cpp index 19b4ad942..ed4c68c8d 100644 --- a/plugins/builtin/source/content/views/view_information.cpp +++ b/plugins/builtin/source/content/views/view_information.cpp @@ -240,4 +240,13 @@ namespace hex::plugin::builtin { ImGui::EndChild(); } + void ViewInformation::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view provides various analyses and information about the currently opened data source. " + "Use the settings panel to select which sections to analyze and the region to analyze. " + "Click the 'Analyze' button to start the analysis."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("The results of the analysis will be displayed in separate sections below the settings panel. " + "Each section can be enabled or disabled individually, and some sections may have additional settings available via the gear icon."); + } + } diff --git a/plugins/builtin/source/content/views/view_logs.cpp b/plugins/builtin/source/content/views/view_logs.cpp index 4f04ccfbf..8b4c960b8 100644 --- a/plugins/builtin/source/content/views/view_logs.cpp +++ b/plugins/builtin/source/content/views/view_logs.cpp @@ -71,4 +71,7 @@ namespace hex::plugin::builtin { } } -} \ No newline at end of file + void ViewLogs::drawHelpText() { + ImGuiExt::TextUnformattedCentered("This view displays all log messages generated by ImHex. In general it contains the same information as if you ran ImHex from the command line."); + } +} diff --git a/plugins/builtin/source/content/views/view_patches.cpp b/plugins/builtin/source/content/views/view_patches.cpp index 1e213013e..8641a1ea8 100644 --- a/plugins/builtin/source/content/views/view_patches.cpp +++ b/plugins/builtin/source/content/views/view_patches.cpp @@ -166,7 +166,7 @@ namespace hex::plugin::builtin { ImGui::BeginDisabled(size_t(i) < undoneOperationsCount); - if (ImGui::Selectable(fmt::format("{} {}", index == undoneOperationsCount ? ICON_VS_ARROW_SMALL_RIGHT : " ", index).c_str(), false, ImGuiSelectableFlags_SpanAllColumns)) { + if (ImGui::Selectable(fmt::format("{} {}", index == undoneOperationsCount ? ICON_VS_ARROW_SMALL_RIGHT : " ", index).c_str(), false, ImGuiSelectableFlags_SpanAllColumns)) { ImHexApi::HexEditor::setSelection(address, size); } if (ImGui::IsItemHovered()) { @@ -219,4 +219,11 @@ namespace hex::plugin::builtin { } } + void ViewPatches::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view shows a list of all patches (modifications, insertions, deletions) that were made to the current data source so far."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("The small arrow next to a patch indicates the current position in the undo/redo stack. When undoing operations, the arrow will move downwards and modifying any data will create new patches from the current position, discarding any patches above it."); + ImGuiExt::TextFormattedWrapped("Hovering over a patch will also show a tooltip with more detailed information about the patch and clicking on a patch will select the modified region in the hex editor."); + } + } \ No newline at end of file diff --git a/plugins/builtin/source/content/views/view_pattern_data.cpp b/plugins/builtin/source/content/views/view_pattern_data.cpp index 786df4f5f..46a6a8e03 100644 --- a/plugins/builtin/source/content/views/view_pattern_data.cpp +++ b/plugins/builtin/source/content/views/view_pattern_data.cpp @@ -379,4 +379,10 @@ namespace hex::plugin::builtin { } } + void ViewPatternData::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view displays the pattern tree generated by the previously executed pattern script. It only becomes active once a pattern has been successfully executed."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("Clicking on a pattern in the tree will select the corresponding bytes in the Hex Editor view and jump to its definition in the Pattern Editor view. Additionally you can edit the values of patterns by double clicking them which will automatically update the bytes in your loaded data source."); + } + } diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 55b4433eb..95b12b79f 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -404,7 +404,7 @@ namespace hex::plugin::builtin { } void ViewPatternEditor::drawPatternSettings() { - const auto size = scaled(500, 150); + const auto size = scaled(0, 150); if (ImGuiExt::BeginSubWindow("hex.builtin.view.pattern_editor.settings"_lang, nullptr, size)) { this->drawVariableSettings(*m_patternVariables); @@ -2624,6 +2624,13 @@ namespace hex::plugin::builtin { savePatternAsNewFile(trackFile); } - + void ViewPatternEditor::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This is the Pattern Editor view, where you can write and edit pattern matching code to analyze the loaded data. For more information on how to write pattern code, please refer to the official documentation and the check out the existing patterns included with ImHex."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("This view works in close conjunction with the Hex Editor view and the Pattern Data view. When you finished writing your code, click on the Play button at the bottom of the view or press {} to evaluate the pattern.", + ShortcutManager::getShortcutByName({ "hex.builtin.menu.edit","hex.builtin.view.pattern_editor.menu.edit.run_pattern" }).toString() + ); + ImGuiExt::TextFormattedWrapped("This will execute your code, output any log messages to the console window below and create a pattern tree that gets displayed in the Pattern Data view and highlights matching regions in the Hex Editor view."); + } } diff --git a/plugins/builtin/source/content/views/view_store.cpp b/plugins/builtin/source/content/views/view_store.cpp index 12dabbd4e..ac3f78f13 100644 --- a/plugins/builtin/source/content/views/view_store.cpp +++ b/plugins/builtin/source/content/views/view_store.cpp @@ -401,4 +401,8 @@ namespace hex::plugin::builtin { m_download = {}; } + void ViewStore::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view lets you download and update additional content for ImHex, such as pattern files, magic files, themes and more. All content is provided by the ImHex community and can be freely used within ImHex."); + } + } \ No newline at end of file diff --git a/plugins/builtin/source/content/views/view_theme_manager.cpp b/plugins/builtin/source/content/views/view_theme_manager.cpp index f481899a3..0b856fc71 100644 --- a/plugins/builtin/source/content/views/view_theme_manager.cpp +++ b/plugins/builtin/source/content/views/view_theme_manager.cpp @@ -127,4 +127,8 @@ namespace hex::plugin::builtin { } } + void ViewThemeManager::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view allows you to customize the colors and styles of the ImHex interface. You can modify individual colors and styles and save them as themes that you can load later or share with others."); + } + } \ No newline at end of file diff --git a/plugins/builtin/source/content/views/view_tools.cpp b/plugins/builtin/source/content/views/view_tools.cpp index 1917fb999..b28a1cdff 100644 --- a/plugins/builtin/source/content/views/view_tools.cpp +++ b/plugins/builtin/source/content/views/view_tools.cpp @@ -105,4 +105,11 @@ namespace hex::plugin::builtin { } } + void ViewTools::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view contains various standalone tools that didn't fit anywhere else but are useful nonetheless."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("Click on the arrow icon in the title bar of each tool to open or collapse it. When collapsed, you can drag the tool out of this window to create a separate floating window which can also be docked anywhere you like."); + + } + } \ No newline at end of file diff --git a/plugins/builtin/source/content/views/view_tutorials.cpp b/plugins/builtin/source/content/views/view_tutorials.cpp index d45c9629c..34c367dd2 100644 --- a/plugins/builtin/source/content/views/view_tutorials.cpp +++ b/plugins/builtin/source/content/views/view_tutorials.cpp @@ -73,4 +73,7 @@ namespace hex::plugin::builtin { } } -} \ No newline at end of file + void ViewTutorials::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view contains all available tutorials to help you get started with ImHex. Select a tutorial from the list and click the 'Start Tutorial' button to begin."); + } +} diff --git a/plugins/diffing/include/content/views/view_diff.hpp b/plugins/diffing/include/content/views/view_diff.hpp index 34b8f9526..afbf08fe8 100644 --- a/plugins/diffing/include/content/views/view_diff.hpp +++ b/plugins/diffing/include/content/views/view_diff.hpp @@ -20,6 +20,7 @@ namespace hex::plugin::diffing { void drawContent() override; void drawAlwaysVisibleContent() override; + void drawHelpText() override; ImGuiWindowFlags getWindowFlags() const override { return ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse; } public: diff --git a/plugins/diffing/source/content/views/view_diff.cpp b/plugins/diffing/source/content/views/view_diff.cpp index cd4697329..4d0d291c9 100644 --- a/plugins/diffing/source/content/views/view_diff.cpp +++ b/plugins/diffing/source/content/views/view_diff.cpp @@ -543,4 +543,15 @@ namespace hex::plugin::diffing { this ); } + + void ViewDiff::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view allows you to do binary comparisons between two data sources. Select the data sources you want to compare from the dropdown menus at the top. Once both data sources are selected, the differences will be calculated automatically."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("Differences are highlighted in the hex editors. Green indicates added bytes, red indicates removed bytes, and yellow indicates modified bytes. All differences are also listed in the table below the hex editors, where you can click on a difference to jump to it in both hex editors."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped( + "By default, a simple byte-by-byte comparison algorithm is used. This is quick but will only identify byte modifications but doesn't match insertions or deletions.\n" + "For a more sophisticated comparison, you can select a different diffing algorithm from the settings menu (gear icon)." + ); + } } diff --git a/plugins/disassembler/include/content/views/view_disassembler.hpp b/plugins/disassembler/include/content/views/view_disassembler.hpp index 60c0328d7..68b1e7f9c 100644 --- a/plugins/disassembler/include/content/views/view_disassembler.hpp +++ b/plugins/disassembler/include/content/views/view_disassembler.hpp @@ -19,6 +19,7 @@ namespace hex::plugin::disasm { ~ViewDisassembler() override; void drawContent() override; + void drawHelpText() override; private: TaskHolder m_disassemblerTask; diff --git a/plugins/disassembler/source/content/views/view_disassembler.cpp b/plugins/disassembler/source/content/views/view_disassembler.cpp index decda447f..589c17d4d 100644 --- a/plugins/disassembler/source/content/views/view_disassembler.cpp +++ b/plugins/disassembler/source/content/views/view_disassembler.cpp @@ -308,4 +308,9 @@ namespace hex::plugin::disasm { } } + void ViewDisassembler::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view lets you disassemble byte regions into assembly instructions of various different architectures."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("Select the desired Architecture from the tabs in the settings panel and configure its options as needed. Clicking the \"Disassemble\" button will disassemble the selected region (or the entire data if no region is selected) and display the resulting instructions in a table below."); + } } diff --git a/plugins/hashes/include/content/views/view_hashes.hpp b/plugins/hashes/include/content/views/view_hashes.hpp index bf9d29492..39083f59c 100644 --- a/plugins/hashes/include/content/views/view_hashes.hpp +++ b/plugins/hashes/include/content/views/view_hashes.hpp @@ -12,6 +12,7 @@ namespace hex::plugin::hashes { ~ViewHashes() override; void drawContent() override; + void drawHelpText() override; private: bool importHashes(prv::Provider *provider, const nlohmann::json &json); diff --git a/plugins/hashes/source/content/views/view_hashes.cpp b/plugins/hashes/source/content/views/view_hashes.cpp index 7fedcd6ac..62821ddba 100644 --- a/plugins/hashes/source/content/views/view_hashes.cpp +++ b/plugins/hashes/source/content/views/view_hashes.cpp @@ -342,4 +342,10 @@ namespace hex::plugin::hashes { return true; } + void ViewHashes::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view allows you to compute various hashes (MD5, SHA1, etc.) on selected data regions."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("Add a new hash function by double clicking on the last row in the Hashes table and configure it to your needs. You can add multiple hash functions and see their results in real-time as you select different regions of data in the hex editor. " + "Hold SHIFT while selecting data to see hash results in the tooltip."); + } } diff --git a/plugins/script_loader/support/c/source/script_api/v1/ui.cpp b/plugins/script_loader/support/c/source/script_api/v1/ui.cpp index 4cdcacce9..24fda4eb8 100644 --- a/plugins/script_loader/support/c/source/script_api/v1/ui.cpp +++ b/plugins/script_loader/support/c/source/script_api/v1/ui.cpp @@ -172,6 +172,7 @@ public: void drawContent() override { m_drawFunction(); } + void drawHelpText() override {} private: DrawFunction m_drawFunction; diff --git a/plugins/windows/include/views/view_tty_console.hpp b/plugins/windows/include/views/view_tty_console.hpp index 3461e3044..464c66e43 100644 --- a/plugins/windows/include/views/view_tty_console.hpp +++ b/plugins/windows/include/views/view_tty_console.hpp @@ -17,6 +17,7 @@ namespace hex::plugin::windows { ~ViewTTYConsole() override = default; void drawContent() override; + void drawHelpText() override; private: void drawSettings(); diff --git a/plugins/windows/source/views/view_tty_console.cpp b/plugins/windows/source/views/view_tty_console.cpp index 699d6eb2d..f9889af0a 100644 --- a/plugins/windows/source/views/view_tty_console.cpp +++ b/plugins/windows/source/views/view_tty_console.cpp @@ -459,4 +459,9 @@ namespace hex::plugin::windows { m_transmitting = false; } -} \ No newline at end of file + void ViewTTYConsole::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view can send and receive data over a Serial (TTY) port."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped("Connect your device to a Serial Port (or a USB port with a Serial adapter) and configure the connection settings on the left side. Once connected, you can send and receive data using the console below."); + } +} diff --git a/plugins/yara_rules/include/content/views/view_yara.hpp b/plugins/yara_rules/include/content/views/view_yara.hpp index 9e0a05a5a..e1bbb3b30 100644 --- a/plugins/yara_rules/include/content/views/view_yara.hpp +++ b/plugins/yara_rules/include/content/views/view_yara.hpp @@ -17,6 +17,7 @@ namespace hex::plugin::yara { ~ViewYara() override; void drawContent() override; + void drawHelpText() override; private: PerProvider>> m_rulePaths; diff --git a/plugins/yara_rules/source/content/views/view_yara.cpp b/plugins/yara_rules/source/content/views/view_yara.cpp index 630d75ca2..b392f6f97 100644 --- a/plugins/yara_rules/source/content/views/view_yara.cpp +++ b/plugins/yara_rules/source/content/views/view_yara.cpp @@ -337,4 +337,13 @@ namespace hex::plugin::yara { }); } -} \ No newline at end of file + void ViewYara::drawHelpText() { + ImGuiExt::TextFormattedWrapped("This view allows you to apply YARA rules to the currently opened file and highlights matched regions."); + ImGui::NewLine(); + ImGuiExt::TextFormattedWrapped( + "You can add YARA rules by clicking the + button in the top right corner of the view. " + "This will open a file chooser where you can select one or more YARA files to add." + "For further information on how to write YARA rules, please refer to its official documentation." + ); + } +}