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 ? 1 : 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 * getNumInputs() + 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 = 1; iw <= nw; ++iw) {
79 ImVec2 xOffset{(iw - 1) * xsz + 2 *
padding, 0};
80 ImVec2 xSize{xsz - 2 *
padding, 0};
82 ImVec2 ySize{0, MAX_BOX_Y_SIZE - 4 *
padding};
84 for (
size_t ir = (iw - 1) * WND;
ir < ((iw * WND > getNumRecords()) ? getNumRecords() : iw * WND); ++
ir) {
85 for (
size_t i = 0;
i < getNumItems(getRecord(
ir)); ++
i) {
96 xOffset + yOffset + winPos,
97 xOffset + xSize + yOffset + ySize + winPos,
102 auto boxSizeX = std::min(
size.x / WND, MAX_BOX_X_SIZE);
103 auto boxSizeY = std::min(
size.y / getNumInputs(), MAX_BOX_Y_SIZE);
105 winPos = ImGui::GetCursorScreenPos() + ImVec2{0, 7};
106 ImGui::InvisibleButton(
"sensitive area", ImVec2(
size.x,
size.y));
107 if (ImGui::IsItemHovered()) {
108 auto pos = ImGui::GetMousePos() - winPos;
109 auto slot = (
v - 1) * WND + std::lround(std::trunc(
pos.x / boxSizeX));
110 auto row = std::lround(std::trunc(
pos.y / boxSizeY));
111 describeCell(
row, slot);
115 drawList->AddRectFilled(
116 ImVec2(0., 0.) + winPos,
121 ImVec2(0. - 1, -1) + winPos,
122 ImVec2{
size.x + 1,
size.y - 1} + winPos,
126 size_t totalPrims = WND * getNumInputs();
127 drawList->PrimReserve(totalPrims * 6, totalPrims * 4);
128 for (
size_t ri = (
v - 1) * WND; ri < (((size_t)(
v)*WND > getNumRecords()) ? getNumRecords() :
v * WND); ++ri) {
129 auto record = getRecord(ri);
130 ImVec2 xOffset{((float)(ri - (
v - 1) * WND) * boxSizeX) +
padding, 0};
131 ImVec2 xSize{boxSizeX - 2 *
padding, 0};
133 for (
auto mi = 0U; mi < getNumItems(record); mi++) {
134 ImVec2 yOffSet{0, ((float)mi * boxSizeY) +
padding};
135 ImVec2 ySize{0, boxSizeY - 2 *
padding};
137 ImVec2
A = xOffset + yOffSet + winPos;
138 ImVec2
B = xOffset + xSize + yOffSet + ySize + winPos;
142 getColor(
getValue(*getItem(record, mi))));
146 ImGui::SetCursorScreenPos(winPos +
size);