Skip to content

Commit

Permalink
gauge widget
Browse files Browse the repository at this point in the history
  • Loading branch information
mvladic committed Jul 26, 2021
1 parent 572206f commit db321d2
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 1 deletion.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ set(src_eez_gui_widgets
src/eez/gui/widgets/canvas.cpp
src/eez/gui/widgets/container.cpp
src/eez/gui/widgets/display_data.cpp
src/eez/gui/widgets/gauge.cpp
src/eez/gui/widgets/grid.cpp
src/eez/gui/widgets/layout_view.cpp
src/eez/gui/widgets/list.cpp
Expand Down
2 changes: 1 addition & 1 deletion src/eez/gui/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ struct Value {
bool isMega() const;

public:
ValueType type_;
uint8_t type_;
uint8_t unit_;
uint16_t options_;
uint32_t reserved_;
Expand Down
135 changes: 135 additions & 0 deletions src/eez/gui/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#if OPTION_DISPLAY

#include <string.h>
#define _USE_MATH_DEFINES
#include <math.h>

#include <eez/util.h>
Expand Down Expand Up @@ -704,6 +705,140 @@ void drawAntialiasedLine(int x0, int y0, int x1, int y1) {
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int compareInt(const void *a, const void *b) {
return (*(const int *)a) - (*(const int *)b);
}

int fillPolygon(const int16_t *vx, const int16_t *vy, int n, int *polyInts) {
int result;
int i;
int y, xa, xb;
int miny, maxy;
int x1, y1;
int x2, y2;
int ind1, ind2;
int ints;

/*
* Vertex array NULL check
*/
if (vx == NULL) {
return (-1);
}
if (vy == NULL) {
return (-1);
}

/*
* Sanity check number of edges
*/
if (n < 3) {
return -1;
}

/*
* Determine Y maxima
*/
miny = vy[0];
maxy = vy[0];
for (i = 1; (i < n); i++) {
if (vy[i] < miny) {
miny = vy[i];
} else if (vy[i] > maxy) {
maxy = vy[i];
}
}

/*
* Draw, scanning y
*/
result = 0;
for (y = miny; (y <= maxy); y++) {
ints = 0;
for (i = 0; (i < n); i++) {
if (!i) {
ind1 = n - 1;
ind2 = 0;
} else {
ind1 = i - 1;
ind2 = i;
}
y1 = vy[ind1];
y2 = vy[ind2];
if (y1 < y2) {
x1 = vx[ind1];
x2 = vx[ind2];
} else if (y1 > y2) {
y2 = vy[ind1];
y1 = vy[ind2];
x2 = vx[ind1];
x1 = vx[ind2];
} else {
continue;
}
if (((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2))) {
polyInts[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1);
}
}

qsort(polyInts, ints, sizeof(int), compareInt);

/*
* Set color
*/
for (i = 0; (i < ints); i += 2) {
xa = polyInts[i] + 1;
xa = (xa >> 16) + ((xa & 32768) >> 15);
xb = polyInts[i + 1] - 1;
xb = (xb >> 16) + ((xb & 32768) >> 15);
mcu::display::drawHLine(xa, y, xb - xa + 1);
}
}

return 0;
}

void arcBarAsPolygon(
int xCenter,
int yCenter,
int radius,
float fromAngleDeg,
float toAngleDeg,
float width,
int16_t *vx,
int16_t *vy,
size_t n
) {
fromAngleDeg *= float(M_PI / 180);
toAngleDeg *= float(M_PI / 180);

n -= 2;

for (size_t i = 0; i <= n / 2; i++) {
auto angle = fromAngleDeg + (i / (n / 2.0f)) * (toAngleDeg - fromAngleDeg);
vx[i] = floor(xCenter + (radius + width / 2.0f) * cosf(angle));
vy[i] = floor(yCenter - (radius + width / 2.0f) * sinf(angle));
}

for (size_t i = 0; i <= n / 2; i++) {
auto angle = toAngleDeg + (i / (n / 2.0f)) * (fromAngleDeg - toAngleDeg);
vx[n / 2 + 1 + i] = floor(xCenter + (radius - width / 2.0f) * cosf(angle));
vy[n / 2 + 1 + i] = floor(yCenter - (radius - width / 2.0f) * sinf(angle));
}
}


void fillArcBar(int xCenter, int yCenter, int radius, float fromAngleDeg, float toAngleDeg, int width) {
static const size_t N = 100;
int16_t vx[N];
int16_t vy[N];
int polyInts[N];
arcBarAsPolygon(xCenter, yCenter, radius, fromAngleDeg, toAngleDeg, width, vx, vy, N);
fillPolygon(vx, vy, N, polyInts);
}

} // namespace gui
} // namespace eez

Expand Down
2 changes: 2 additions & 0 deletions src/eez/gui/draw.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,7 @@ void expandRectWithShadow(int &x1, int &y1, int &x2, int &y2);
void drawLine(int x1, int y1, int x2, int y2);
void drawAntialiasedLine(int x1, int y1, int x2, int y2);

void fillArcBar(int xCenter, int yCenter, int radius, float fromAngleDeg, float toAngleDeg, int width);

} // namespace gui
} // namespace eez
1 change: 1 addition & 0 deletions src/eez/gui/widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace gui {
WIDGET_TYPE(SCROLL_BAR, 20) \
WIDGET_TYPE(PROGRESS, 21) \
WIDGET_TYPE(CANVAS, 22) \
WIDGET_TYPE(GAUGE, 23) \

#define WIDGET_TYPE(NAME, ID) WIDGET_TYPE_##NAME = ID,
enum WidgetTypes {
Expand Down
71 changes: 71 additions & 0 deletions src/eez/gui/widgets/gauge.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* EEZ Modular Firmware
* Copyright (C) 2020-present, Envox d.o.o.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#if OPTION_DISPLAY

#include <math.h>

#include <eez/util.h>

#include <eez/gui/gui.h>
#include <eez/gui/data.h>

namespace eez {
namespace gui {

EnumFunctionType GAUGE_enum = nullptr;

DrawFunctionType GAUGE_draw = [](const WidgetCursor &widgetCursor) {
const Widget *widget = widgetCursor.widget;

widgetCursor.currentState->size = sizeof(WidgetState);

widgetCursor.currentState->data = get(widgetCursor, widget->data);

bool refresh = !widgetCursor.previousState || widgetCursor.previousState->data != widgetCursor.currentState->data;

if (refresh) {
const Style* style = getStyle(widget->style);

mcu::display::setColor16(RGB_TO_COLOR(255, 0, 0));
mcu::display::fillRect(widgetCursor.x, widgetCursor.y, widgetCursor.x + widget->w - 1, widgetCursor.y + widget->h - 1, 0);

mcu::display::setColor16(RGB_TO_COLOR(0, 255, 0));

static const int BAR_WIDTH = 20;
float min = 0.0f;
float max = 40.0f;
fillArcBar(
widgetCursor.x + widget->w / 2,
widgetCursor.y + widget->h - 4,
(widget->w - 8) / 2 - BAR_WIDTH / 2,
remap(widgetCursor.currentState->data.getFloat(), min, 180.0f, max, 0.0f),
180.0f,
BAR_WIDTH
);
}
};

OnTouchFunctionType GAUGE_onTouch = nullptr;

OnKeyboardFunctionType GAUGE_onKeyboard = nullptr;

} // namespace gui
} // namespace eez

#endif

0 comments on commit db321d2

Please sign in to comment.