Sim GUI: Add support for LED displays (#2138)

LED displays connect the LEDs in various ways (column major vs row major,
different starting locations, serpentine connection order), so add
configuration parameters for these options.
This commit is contained in:
Peter Johnson
2019-12-01 21:28:02 -08:00
committed by GitHub
parent 57c5523d67
commit e37ecd33ae
3 changed files with 158 additions and 34 deletions

View File

@@ -10,30 +10,87 @@
namespace halsimgui {
void DrawLEDs(const int* values, int numValues, int cols, const ImU32* colors,
float size, float spacing) {
if (numValues == 0) return;
float size, float spacing, const LEDConfig& config) {
if (numValues == 0 || cols < 1) return;
if (size == 0) size = ImGui::GetFontSize() / 2.0;
if (spacing == 0) spacing = ImGui::GetFontSize() / 3.0;
int rows = (numValues + cols - 1) / cols;
float inc = size + spacing;
ImDrawList* drawList = ImGui::GetWindowDrawList();
const ImVec2 p = ImGui::GetCursorScreenPos();
float x = p.x + size / 2, y = p.y + size / 2;
int rows = 1;
for (int i = 0; i < numValues; ++i) {
if (i >= (rows * cols)) {
++rows;
x = p.x + size / 2;
y += size + spacing;
}
if (values[i] > 0)
drawList->AddRectFilled(ImVec2(x, y), ImVec2(x + size, y + size),
colors[values[i] - 1]);
else if (values[i] < 0)
drawList->AddRect(ImVec2(x, y), ImVec2(x + size, y + size),
colors[-values[i] - 1], 0.0f, 0, 1.0);
x += size + spacing;
float ystart, yinc;
if (config.start & 1) {
// lower
ystart = p.y + size / 2 + inc * (rows - 1);
yinc = -inc;
} else {
// upper
ystart = p.y + size / 2;
yinc = inc;
}
ImGui::Dummy(ImVec2((size + spacing) * cols, (size + spacing) * rows));
float xstart, xinc;
if (config.start & 2) {
// right
xstart = p.x + size / 2 + inc * (cols - 1);
xinc = -inc;
} else {
// left
xstart = p.x + size / 2;
xinc = inc;
}
float x = xstart, y = ystart;
if (config.order == LEDConfig::RowMajor) {
// row major
int row = 1;
for (int i = 0; i < numValues; ++i) {
if (i >= (row * cols)) {
++row;
if (config.serpentine) {
x -= xinc;
xinc = -xinc;
} else {
x = xstart;
}
y += yinc;
}
if (values[i] > 0)
drawList->AddRectFilled(ImVec2(x, y), ImVec2(x + size, y + size),
colors[values[i] - 1]);
else if (values[i] < 0)
drawList->AddRect(ImVec2(x, y), ImVec2(x + size, y + size),
colors[-values[i] - 1], 0.0f, 0, 1.0);
x += xinc;
}
} else {
// column major
int col = 1;
for (int i = 0; i < numValues; ++i) {
if (i >= (col * rows)) {
++col;
if (config.serpentine) {
y -= yinc;
yinc = -yinc;
} else {
y = ystart;
}
x += xinc;
}
if (values[i] > 0)
drawList->AddRectFilled(ImVec2(x, y), ImVec2(x + size, y + size),
colors[values[i] - 1]);
else if (values[i] < 0)
drawList->AddRect(ImVec2(x, y), ImVec2(x + size, y + size),
colors[-values[i] - 1], 0.0f, 0, 1.0);
y += yinc;
}
}
ImGui::Dummy(ImVec2(inc * cols, inc * rows));
}
} // namespace halsimgui