ui: Display array patterns in pattern data view in chunks of 512 entries
This commit is contained in:
parent
814c595c12
commit
9893e7a965
2
lib/external/pattern_language
vendored
2
lib/external/pattern_language
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 955f88b8e9673dbc98c9873965a65d7691eea1dc
|
Subproject commit 71669fe5f986d0f206a48ef76c8b0168a7c8c0ce
|
@ -6,11 +6,6 @@
|
|||||||
|
|
||||||
namespace hex {
|
namespace hex {
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
concept ArrayPattern = requires(u64 displayEnd, T pattern, std::function<void(int, pl::ptrn::Pattern&)> fn) {
|
|
||||||
{ pattern.forEachArrayEntry(displayEnd, fn) } -> std::same_as<void>;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PatternDrawer : public pl::PatternVisitor {
|
class PatternDrawer : public pl::PatternVisitor {
|
||||||
public:
|
public:
|
||||||
PatternDrawer() = default;
|
PatternDrawer() = default;
|
||||||
@ -36,24 +31,10 @@ namespace hex {
|
|||||||
private:
|
private:
|
||||||
void draw(pl::ptrn::Pattern& pattern);
|
void draw(pl::ptrn::Pattern& pattern);
|
||||||
|
|
||||||
template<ArrayPattern T>
|
constexpr static auto ChunkSize = 512;
|
||||||
void drawArray(T& pattern) {
|
constexpr static auto DisplayEndStep = 64;
|
||||||
bool opened = this->drawArrayRoot(pattern, pattern.getEntryCount(), pattern.isInlined());
|
|
||||||
|
|
||||||
if (opened) {
|
|
||||||
auto& displayEnd = this->getDisplayEnd(pattern);
|
|
||||||
pattern.forEachArrayEntry(displayEnd, [&] (u64 idx, auto &entry){
|
|
||||||
this->drawArrayNode(idx, displayEnd, entry);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this->drawArrayEnd(pattern, opened, pattern.isInlined());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool drawArrayRoot(pl::ptrn::Pattern& pattern, size_t entryCount, bool isInlined);
|
|
||||||
void drawArrayNode(u64 idx, u64& displayEnd, pl::ptrn::Pattern& pattern);
|
|
||||||
void drawArrayEnd(pl::ptrn::Pattern& pattern, bool opened, bool inlined);
|
|
||||||
|
|
||||||
|
void drawArray(pl::ptrn::Pattern& pattern, pl::ptrn::Iteratable &iteratable, bool isInlined);
|
||||||
u64& getDisplayEnd(const pl::ptrn::Pattern& pattern);
|
u64& getDisplayEnd(const pl::ptrn::Pattern& pattern);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -119,12 +119,14 @@ namespace hex {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PatternDrawer::visit(pl::ptrn::PatternArrayDynamic& pattern) {
|
void PatternDrawer::visit(pl::ptrn::PatternArrayDynamic& pattern) {
|
||||||
this->drawArray(pattern);
|
drawArray(pattern, pattern, pattern.isInlined());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatternDrawer::visit(pl::ptrn::PatternArrayStatic& pattern) {
|
void PatternDrawer::visit(pl::ptrn::PatternArrayStatic& pattern) {
|
||||||
this->drawArray(pattern);
|
drawArray(pattern, pattern, pattern.isInlined());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatternDrawer::visit(pl::ptrn::PatternBitfieldField& pattern) {
|
void PatternDrawer::visit(pl::ptrn::PatternBitfieldField& pattern) {
|
||||||
@ -272,8 +274,8 @@ namespace hex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (open) {
|
if (open) {
|
||||||
pattern.forEachMember([&](auto &member){
|
pattern.forEachEntry(0, pattern.getMembers().size(), [&](u64, auto *member){
|
||||||
this->draw(member);
|
this->draw(*member);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!pattern.isInlined())
|
if (!pattern.isInlined())
|
||||||
@ -302,8 +304,8 @@ namespace hex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (open) {
|
if (open) {
|
||||||
pattern.forEachMember([&](auto &member) {
|
pattern.forEachEntry(0, pattern.getEntryCount(), [&](u64, auto *member) {
|
||||||
this->draw(member);
|
this->draw(*member);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!pattern.isInlined())
|
if (!pattern.isInlined())
|
||||||
@ -331,9 +333,9 @@ namespace hex {
|
|||||||
pattern.accept(*this);
|
pattern.accept(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PatternDrawer::drawArrayRoot(pl::ptrn::Pattern& pattern, size_t entryCount, bool isInlined) {
|
void PatternDrawer::drawArray(pl::ptrn::Pattern& pattern, pl::ptrn::Iteratable &iteratable, bool isInlined) {
|
||||||
if (entryCount == 0)
|
if (iteratable.getEntryCount() == 0)
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
bool open = true;
|
bool open = true;
|
||||||
if (!isInlined) {
|
if (!isInlined) {
|
||||||
@ -354,7 +356,7 @@ namespace hex {
|
|||||||
|
|
||||||
ImGui::TextUnformatted("[");
|
ImGui::TextUnformatted("[");
|
||||||
ImGui::SameLine(0, 0);
|
ImGui::SameLine(0, 0);
|
||||||
ImGui::TextFormattedColored(ImColor(0xFF00FF00), "{0}", entryCount);
|
ImGui::TextFormattedColored(ImColor(0xFF00FF00), "{0}", iteratable.getEntryCount());
|
||||||
ImGui::SameLine(0, 0);
|
ImGui::SameLine(0, 0);
|
||||||
ImGui::TextUnformatted("]");
|
ImGui::TextUnformatted("]");
|
||||||
|
|
||||||
@ -362,35 +364,50 @@ namespace hex {
|
|||||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
return open;
|
if (open) {
|
||||||
}
|
u64 chunkCount = 0;
|
||||||
|
for (u64 i = 0; i < iteratable.getEntryCount(); i += ChunkSize) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
void PatternDrawer::drawArrayNode(u64 idx, u64& displayEnd, pl::ptrn::Pattern& pattern) {
|
chunkCount++;
|
||||||
u64 lastVisible = displayEnd - 1;
|
|
||||||
|
|
||||||
ImGui::PushID(reinterpret_cast<void*>(pattern.getOffset()));
|
auto &displayEnd = this->getDisplayEnd(pattern);
|
||||||
|
if (chunkCount > displayEnd) {
|
||||||
|
ImGui::Selectable("... (Double-click to see more items)", false, ImGuiSelectableFlags_SpanAllColumns);
|
||||||
|
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||||
|
displayEnd += DisplayEndStep;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
auto endIndex = std::min(iteratable.getEntryCount(), i + ChunkSize);
|
||||||
|
|
||||||
if (idx < lastVisible) {
|
auto startOffset = iteratable.getEntry(i)->getOffset();
|
||||||
this->draw(pattern);
|
auto endOffset = iteratable.getEntry(endIndex - 1)->getOffset();
|
||||||
} else if (idx == lastVisible) {
|
auto endSize = iteratable.getEntry(endIndex - 1)->getSize();
|
||||||
ImGui::TableNextRow();
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
|
|
||||||
ImGui::Selectable("... (Double-click to see more items)", false, ImGuiSelectableFlags_SpanAllColumns);
|
size_t chunkSize = (endOffset - startOffset) + endSize;
|
||||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
|
||||||
displayEnd += DisplayEndStep;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::PopID();
|
auto chunkOpen = ImGui::TreeNode(hex::format("[{} ... {}]", i, endIndex - 1).c_str());
|
||||||
}
|
ImGui::TableNextColumn();
|
||||||
|
drawColorColumn(pattern);
|
||||||
|
ImGui::TextFormatted("0x{0:08X} : 0x{1:08X}", startOffset, startOffset + chunkSize - (pattern.getSize() == 0 ? 0 : 1));
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TextFormatted("0x{0:04X}", chunkSize);
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
void PatternDrawer::drawArrayEnd(pl::ptrn::Pattern& pattern, bool opened, bool inlined) {
|
if (chunkOpen) {
|
||||||
if (opened) {
|
iteratable.forEachEntry(i, endIndex, [&](u64, auto *entry){
|
||||||
if (!inlined)
|
this->draw(*entry);
|
||||||
|
});
|
||||||
|
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isInlined)
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
} else {
|
|
||||||
auto& displayEnd = this->getDisplayEnd(pattern);
|
|
||||||
displayEnd = DisplayEndDefault;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user