35 ImVec2
const& sizeHint,
36 std::function<
size_t()>
const& getNumInputs,
37 std::function<
size_t()>
const& getNumRecords,
38 std::function<RECORD(
size_t)>
const& getRecord,
39 std::function<
size_t(RECORD
const&)>
const& getNumItems,
40 std::function<ITEM
const*(RECORD
const&,
size_t)>
const& getItem,
41 std::function<
int(ITEM
const&)>
const& getValue,
42 std::function<ImU32(
int value)>
const& getColor,
43 std::function<
void(
int row,
int column)>
const& describeCell)
45 ImVec2
size = ImVec2(sizeHint.x, std::min(sizeHint.y, 16.f * getNumItems(0) + 2));
46 ImU32 BORDER_COLOR = ImColor(200, 200, 200, 255);
47 ImU32 BACKGROUND_COLOR = ImColor(20, 20, 20, 255);
48 constexpr float MAX_BOX_X_SIZE = 16.f;
49 constexpr float MAX_BOX_Y_SIZE = 16.f;
50 ImDrawList* drawList = ImGui::GetWindowDrawList();
51 ImVec2 winPos = ImGui::GetCursorScreenPos() + ImVec2{0, 7};
52 auto records = getNumRecords();
53 auto boxSizeX = std::min(
size.x / records, MAX_BOX_X_SIZE);
54 auto numInputs = getNumInputs();
56 ImGui::InvisibleButton(
"sensible area", ImVec2(
size.x,
size.y));
57 if (ImGui::IsItemHovered()) {
58 auto pos = ImGui::GetMousePos() - winPos;
59 auto slot = std::lround(std::trunc(
pos.x /
size.x * records));
60 auto row = std::lround(std::trunc(
pos.y /
size.y * numInputs));
61 describeCell(
row, slot);
64 drawList->AddRectFilled(
65 ImVec2(0., 0.) + winPos,
69 ImVec2(0. - 1, -1) + winPos,
70 ImVec2{
size.x + 1,
size.y - 1} + winPos,
74 size_t totalRects = 0;
75 for (
size_t ri = 0, re = getNumRecords(); ri < re; ri++) {
76 auto record = getRecord(ri);
77 totalRects += getNumItems(record);
80 drawList->PrimReserve(totalRects * 6, totalRects * 4);
81 for (
size_t ri = 0, re = getNumRecords(); ri < re; ri++) {
82 auto record = getRecord(ri);
83 ImVec2 xOffset{(ri * boxSizeX) +
padding, 0};
84 ImVec2 xSize{boxSizeX - 2 *
padding, 0};
85 auto boxSizeY = std::min(
size.y / getNumItems(record), MAX_BOX_Y_SIZE);
86 for (
size_t mi = 0, me = getNumItems(record); mi < me; mi++) {
87 ImVec2 yOffSet{0, (mi * boxSizeY) +
padding};
88 ImVec2 ySize{0, boxSizeY - 2 *
padding};
91 xOffset + yOffSet + winPos,
92 xOffset + xSize + yOffSet + ySize + winPos,
93 getColor(getValue(*getItem(record, mi))));
97 ImGui::SetCursorScreenPos(winPos +
size);