32 static void draw(
const char* ,
34 ImVec2
const& sizeHint,
35 std::function<
size_t()>
const& getNumInputs,
36 std::function<
size_t()>
const& getNumRecords,
37 std::function<RECORD(
size_t)>
const& getRecord,
38 std::function<
size_t(RECORD
const&)>
const& getNumItems,
39 std::function<ITEM
const*(RECORD
const&,
size_t)>
const& getItem,
40 std::function<
int(ITEM
const&)>
const&
getValue,
41 std::function<ImU32(
int value)>
const& getColor,
42 std::function<
void(
int row,
int column)>
const& describeCell)
46 size_t nw = getNumRecords() / WND;
47 ImGui::PushItemWidth(sizeHint.x);
48 ImGui::SliderInt(
"##window", &
v, 1, nw,
"wnd: %d", ImGuiSliderFlags_AlwaysClamp);
49 ImVec2 sliderMin = ImGui::GetItemRectMin();
51 constexpr float MAX_BOX_X_SIZE = 16.f;
52 constexpr float MAX_BOX_Y_SIZE = 16.f;
54 ImVec2
size = ImVec2(sizeHint.x, std::min(sizeHint.y, MAX_BOX_Y_SIZE * getNumItems(0) + 2));
55 ImU32 BORDER_COLOR = ImColor(200, 200, 200, 255);
56 ImU32 BACKGROUND_COLOR = ImColor(20, 20, 20, 255);
57 ImU32 BORDER_COLOR_A = ImColor(200, 200, 200, 0);
58 ImU32 BACKGROUND_COLOR_A = ImColor(0, 0, 0, 0);
60 ImDrawList* drawList = ImGui::GetWindowDrawList();
61 ImVec2 winPos = sliderMin;
64 auto xsz =
size.x / nw;
65 drawList->AddRectFilled(
66 ImVec2{0., 0.} + winPos,
70 ImVec2{0. - 1, -1} + winPos,
71 ImVec2{
size.x + 1,
size.y - 1} + winPos,
74 const static auto colorA = ImColor(ImVec4{0.945, 0.096, 0.278, 0.5});
75 const static auto colorE = ImColor(ImVec4{0, 0, 0, 0});
77 drawList->PrimReserve(nw * 6, nw * 4);
78 for (
size_t iw = 0; iw < nw; ++iw) {
79 ImVec2 xOffset{iw * xsz + 2 *
padding, 0};
80 ImVec2 xSize{xsz - 2 *
padding, 0};
82 ImVec2 ySize{0, 16 - 4 *
padding};
84 for (
size_t ir = iw;
ir < ((iw + WND > getNumRecords()) ? getNumRecords() : iw + WND); ++
ir) {
85 for (
size_t i = 0;
i < getNumItems(
ir); ++
i) {
93 xOffset + yOffset + winPos,
94 xOffset + xSize + yOffset + ySize + winPos,
99 size_t recordsWindow =
v * WND;
100 auto boxSizeX = std::min(
size.x / WND, MAX_BOX_X_SIZE);
101 auto numInputs = getNumInputs();
102 winPos = ImGui::GetCursorScreenPos() + ImVec2{0, 7};
103 ImGui::InvisibleButton(
"sensible area", ImVec2(
size.x,
size.y));
104 if (ImGui::IsItemHovered()) {
105 auto pos = ImGui::GetMousePos() - winPos;
106 auto slot = (
v - 1) * WND + std::lround(std::trunc(
pos.x /
size.x * WND));
107 auto row = std::lround(std::trunc(
pos.y /
size.y * numInputs));
108 describeCell(
row, slot);
111 drawList->AddRectFilled(
112 ImVec2(0., 0.) + winPos,
116 ImVec2(0. - 1, -1) + winPos,
117 ImVec2{
size.x + 1,
size.y - 1} + winPos,
120 size_t totalRects = 0;
121 for (
size_t ri = (
v - 1) * WND; ri < recordsWindow; ri++) {
122 auto record = getRecord(ri);
123 totalRects += getNumItems(record);
126 drawList->PrimReserve(totalRects * 6, totalRects * 4);
127 for (
size_t ri = (
v - 1) * WND; ri < recordsWindow; ri++) {
128 auto record = getRecord(ri);
129 ImVec2 xOffset{((ri - (
v - 1) * WND) * boxSizeX) +
padding, 0};
130 ImVec2 xSize{boxSizeX - 2 *
padding, 0};
131 auto me = getNumItems(record);
132 auto boxSizeY = std::min(
size.y / me, MAX_BOX_Y_SIZE);
133 for (
size_t mi = 0; mi < me; mi++) {
134 ImVec2 yOffSet{0, (mi * boxSizeY) +
padding};
135 ImVec2 ySize{0, boxSizeY - 2 *
padding};
138 xOffset + yOffSet + winPos,
139 xOffset + xSize + yOffSet + ySize + winPos,
140 getColor(
getValue(*getItem(record, mi))));
144 ImGui::SetCursorScreenPos(winPos +
size);