#pragma once #include #include #include #include #include #include struct ImGuiTableSortSpecs; namespace hex::plugin::builtin::ui { class PatternDrawer : public pl::PatternVisitor { public: PatternDrawer() { this->m_formatters = pl::gen::fmt::createFormatters(); } void draw(const std::vector> &patterns, pl::PatternLanguage *runtime = nullptr, float height = 0.0F); enum class TreeStyle { Default = 0, AutoExpanded = 1, Flattened = 2 }; void setTreeStyle(TreeStyle style) { this->m_treeStyle = style; } void setSelectionCallback(std::function callback) { this->m_selectionCallback = std::move(callback); } void reset(); private: void draw(pl::ptrn::Pattern& pattern); public: void visit(pl::ptrn::PatternArrayDynamic& pattern) override; void visit(pl::ptrn::PatternArrayStatic& pattern) override; void visit(pl::ptrn::PatternBitfieldField& pattern) override; void visit(pl::ptrn::PatternBitfieldArray& pattern) override; void visit(pl::ptrn::PatternBitfield& pattern) override; void visit(pl::ptrn::PatternBoolean& pattern) override; void visit(pl::ptrn::PatternCharacter& pattern) override; void visit(pl::ptrn::PatternEnum& pattern) override; void visit(pl::ptrn::PatternFloat& pattern) override; void visit(pl::ptrn::PatternPadding& pattern) override; void visit(pl::ptrn::PatternPointer& pattern) override; void visit(pl::ptrn::PatternSigned& pattern) override; void visit(pl::ptrn::PatternString& pattern) override; void visit(pl::ptrn::PatternStruct& pattern) override; void visit(pl::ptrn::PatternUnion& pattern) override; void visit(pl::ptrn::PatternUnsigned& pattern) override; void visit(pl::ptrn::PatternWideCharacter& pattern) override; void visit(pl::ptrn::PatternWideString& pattern) override; private: constexpr static auto ChunkSize = 512; constexpr static auto DisplayEndStep = 64; void drawArray(pl::ptrn::Pattern& pattern, pl::ptrn::IIterable &iterable, bool isInlined); u64& getDisplayEnd(const pl::ptrn::Pattern& pattern); void makeSelectable(const pl::ptrn::Pattern &pattern); void drawValueColumn(pl::ptrn::Pattern& pattern); void drawVisualizer(const std::map &visualizers, const std::vector &arguments, pl::ptrn::Pattern &pattern, pl::ptrn::IIterable &iterable, bool reset); void drawFavoriteColumn(const pl::ptrn::Pattern& pattern); bool beginPatternTable(const std::vector> &patterns, std::vector &sortedPatterns, float height); bool createTreeNode(const pl::ptrn::Pattern& pattern, bool leaf = false); void createDefaultEntry(pl::ptrn::Pattern &pattern); void closeTreeNode(bool inlined); bool sortPatterns(const ImGuiTableSortSpecs* sortSpecs, const pl::ptrn::Pattern * left, const pl::ptrn::Pattern * right) const; bool isEditingPattern(const pl::ptrn::Pattern& pattern) const; void resetEditing(); bool matchesFilter(const std::vector &filterPath, const std::vector &patternPath, bool fullMatch); void traversePatternTree(pl::ptrn::Pattern &pattern, std::vector &patternPath, const std::function &callback); std::string getDisplayName(const pl::ptrn::Pattern& pattern) const; private: std::map m_displayEnd; std::vector m_sortedPatterns; const pl::ptrn::Pattern *m_editingPattern = nullptr; u64 m_editingPatternOffset = 0; TreeStyle m_treeStyle = TreeStyle::Default; pl::ptrn::Pattern *m_currVisualizedPattern = nullptr; std::set m_visualizedPatterns; std::string m_lastVisualizerError; std::string m_filterText; std::vector m_filter; std::vector m_currPatternPath; std::map, std::unique_ptr> m_favorites; bool m_showFavoriteStars = false; bool m_favoritesUpdated = false; bool m_showSpecName = false; TaskHolder m_favoritesUpdateTask; std::function m_selectionCallback = [](Region) { }; pl::gen::fmt::FormatterArray m_formatters; }; }