Skip to content

Commit

Permalink
Added additional drawing optimisations, changed values from signed in…
Browse files Browse the repository at this point in the history
…ts to doubles for greater precision, removed redundant function calls and attributes
  • Loading branch information
joestanding committed Apr 16, 2024
1 parent 6c2736d commit 7235920
Show file tree
Hide file tree
Showing 14 changed files with 355 additions and 236 deletions.
159 changes: 91 additions & 68 deletions BarGauge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/* ------------------------------------------------------------------------- */

BarGauge::BarGauge(Adafruit_ILI9341 * display, Measurement * measurement,
char * name, int32_t range_min, int32_t range_max)
char * name, double range_min, double range_max)
: Gauge(display, measurement, name, range_min, range_max) {

this->bar_colour = GREEN;
Expand All @@ -25,14 +25,20 @@ BarGauge::BarGauge(Adafruit_ILI9341 * display, Measurement * measurement,
/* ------------------------------------------------------------------------- */

uint16_t BarGauge::get_bar_y_for_value(uint16_t x, uint16_t y, uint16_t w,
uint16_t h, uint32_t value) {
uint16_t max_avail_height = h - (this->padding * 2) -
this->label_section_height;
int new_value_height = ((value - this->value_min) * max_avail_height) /
(this->value_max - this->value_min);
uint16_t new_value_y = y + (h - new_value_height) -
this->padding - this->label_section_height;
return new_value_y;
uint16_t h, double value) {
if (this->value_max == this->value_min) {
return y + this->padding;
}

uint16_t max_avail_height =
(h > (this->padding * 2 + this->label_section_height)) ?
h - (this->padding * 2 + this->label_section_height) : 0;

double range = this->value_max - this->value_min;
double scaled_value = (value - this->value_min) / range;
uint16_t new_value_height = round(scaled_value * max_avail_height);

return y + h - new_value_height - this->padding - this->label_section_height;
}

/* ------------------------------------------------------------------------- */
Expand All @@ -57,7 +63,7 @@ uint16_t BarGauge::get_max_bar_height(uint16_t frame_h) {
/* ------------------------------------------------------------------------- */

void BarGauge::draw_limit_bar(uint16_t x, uint16_t y, uint16_t w,
uint16_t h, uint16_t colour, int32_t value) {
uint16_t h, uint16_t colour, double value) {
int limit_x1 = x;
int limit_x2 = x + w - 1;
int limit_y = this->get_bar_y_for_value(x,
Expand All @@ -83,8 +89,9 @@ void BarGauge::draw_reading(uint16_t x, uint16_t y, uint16_t width,

this->display->setTextSize(2);

char str[8];
sprintf(str, "%d", this->value);
double value = this->measurement->get_value();
char str[8];
dtostrf(value, 0, 0, str);

/* If we're writing a shorter string than last time we'll need to redraw
the area */
Expand Down Expand Up @@ -120,23 +127,23 @@ void BarGauge::draw_name(uint16_t x, uint16_t y, uint16_t width,
* @width: The width of the gauge to be drawn.
* @height: The height of the gauge to be drawn.
*/
void BarGauge::draw(uint16_t gauge_x, uint16_t gauge_y, uint16_t gauge_w, uint16_t gauge_h) {
void BarGauge::draw(uint16_t gauge_x, uint16_t gauge_y, uint16_t gauge_w,
uint16_t gauge_h) {
/* --------------- */
/* Bounds Clamping */
/* --------------- */

this->value = this->measurement->get_value();

uint32_t bar_value = 0;

double bar_value = 0;
if(this->value > this->value_max) {
bar_value = this->value_max;
} else {
bar_value = this->value;
}

if(this->value < 0) {
bar_value = 0;
if(this->value < this->value_min) {
bar_value = this->value_min;
}

/* --------------------------------------- */
Expand All @@ -161,27 +168,32 @@ void BarGauge::draw(uint16_t gauge_x, uint16_t gauge_y, uint16_t gauge_w, uint16

/* Calculate the X and Y co-ordinates of where our bar will begin */
uint16_t bar_x, bar_y, prev_x, prev_y = 0;
this->get_bar_xy(frame_x, frame_y, frame_w, frame_h, &bar_x, &bar_y, bar_height);
this->get_bar_xy(frame_x, frame_y, frame_w, frame_h, &prev_x, &prev_y, prev_bar_height);
this->get_bar_xy(frame_x, frame_y, frame_w, frame_h, &bar_x, &bar_y,
bar_height);
this->get_bar_xy(frame_x, frame_y, frame_w, frame_h, &prev_x, &prev_y,
prev_bar_height);

/* ---------------- */
/* Bar Border Frame */
/* ---------------- */

/* Draw a frame around the bar bounds */
uint16_t bar_frame_width = bar_width + (BAR_FRAME_PADDING * 2);
uint16_t bar_frame_height = max_bar_height + BAR_FRAME_PADDING;
this->display->drawRect(frame_x,
frame_y,
frame_w,
frame_h,
this->frame_colour);
/* Draw a frame around the bar bounds */
if(this->requires_redraw) {
this->display->drawRect(frame_x,
frame_y,
frame_w,
frame_h,
this->frame_colour);
}

/* ------------- */
/* Bar Rendering */
/* ------------- */

uint16_t bar_colour = this->colour_normal;
uint16_t text_colour = WHITE;
if(this->has_limit_higher && (this->value >= this->limit_higher)) {
bar_colour = this->colour_high;
}
Expand All @@ -190,9 +202,8 @@ void BarGauge::draw(uint16_t gauge_x, uint16_t gauge_y, uint16_t gauge_w, uint16
bar_colour = this->colour_low;
}

/* If we have a new alarm state, we'll need to re-render the entire bar in the
colour appropriate for the state */
if(bar_colour != this->last_bar_colour) {
/* If the bar has changed colour, we'll have to re-render the whole bar */
if(bar_colour != this->last_colour) {
this->display->fillRect(bar_x,
bar_y,
bar_width,
Expand All @@ -202,15 +213,13 @@ void BarGauge::draw(uint16_t gauge_x, uint16_t gauge_y, uint16_t gauge_w, uint16

/* If this is the first time rendering, render the full bar and do no more
checks */
if(this->initialised == 0) {
if(this->requires_redraw == 1) {
this->display->fillRect(bar_x,
bar_y,
bar_width,
bar_height,
bar_colour);
this->value_last = bar_value;
this->initialised = 1;
return;
}

/* If the value hasn't changed, we don't need to render anything */
Expand Down Expand Up @@ -243,70 +252,84 @@ void BarGauge::draw(uint16_t gauge_x, uint16_t gauge_y, uint16_t gauge_w, uint16

/* The limit bar indicates where the alarm limit is on the bar, and changes
colour when the limit has been reached. */

if(this->has_limit_higher) {
if(this->value >= this->limit_higher) {
this->draw_limit_bar(bar_x - BAR_FRAME_PADDING,
gauge_y,
bar_frame_width,
gauge_h,
YELLOW,
this->limit_higher);
} else {
this->draw_limit_bar(bar_x - BAR_FRAME_PADDING,
gauge_y,
bar_frame_width,
gauge_h,
WHITE,
this->limit_higher);
if(this->requires_redraw
|| (bar_value >= limit_higher-(limit_higher * 0.05) && bar_value <= limit_higher+(limit_higher * 0.05)
|| bar_colour != this->last_colour)) {
if(this->has_limit_higher) {
if(this->value >= this->limit_higher) {
this->draw_limit_bar(bar_x - BAR_FRAME_PADDING,
gauge_y,
bar_frame_width,
gauge_h,
YELLOW,
this->limit_higher);
} else {
this->draw_limit_bar(bar_x - BAR_FRAME_PADDING,
gauge_y,
bar_frame_width,
gauge_h,
WHITE,
this->limit_higher);
}
}
}

if(this->has_limit_lower) {
this->draw_limit_bar(bar_x - BAR_FRAME_PADDING,
gauge_y,
bar_frame_width,
gauge_h,
WHITE,
this->limit_lower);
if(this->requires_redraw
|| (bar_value >= limit_lower-(limit_lower * 0.05) && bar_value <= limit_lower+(limit_lower * 0.05))
|| bar_colour != this->last_colour) {
if(this->has_limit_lower) {
this->draw_limit_bar(bar_x - BAR_FRAME_PADDING,
gauge_y,
bar_frame_width,
gauge_h,
WHITE,
this->limit_lower);
}
}

/* --------------- */
/* Label Rendering */
/* --------------- */

if(this->label_enabled) {
this->draw_reading(gauge_x, gauge_y, gauge_w, gauge_h);
this->draw_name(gauge_x, gauge_y, gauge_w, gauge_h);
if(this->requires_redraw
|| fabs(this->measurement->get_value() - this->value_last) > EPSILON)
this->draw_reading(gauge_x, gauge_y, gauge_w, gauge_h);
if(this->requires_redraw)
this->draw_name(gauge_x, gauge_y, gauge_w, gauge_h);
}

this->value_last = bar_value;
this->last_bar_colour = bar_colour;
this->last_colour = bar_colour;
this->requires_redraw = false;
}

/* ------------------------------------------------------------------------- */
/* Setters and Getters */
/* ------------------------------------------------------------------------- */

void BarGauge::set_frame_colour(uint16_t frame_colour) {
this->frame_colour = frame_colour;
void BarGauge::set_frame_colour(uint16_t value) {
this->frame_colour = value;
}

/* ------------------------------------------------------------------------- */

void BarGauge::set_limit_bar_height(uint32_t height) {
this->limit_bar_height = height;
void BarGauge::set_limit_bar_height(uint32_t value) {
this->limit_bar_height = value;
}

/* ------------------------------------------------------------------------- */

void BarGauge::set_label_state(uint8_t state) {
this->label_enabled = state;
if(state == 0) {
this->label_section_height = 0;
} else {
this->label_section_height = LABEL_SECTION_HEIGHT;
}
void BarGauge::enable_labels() {
this->label_enabled = true;
this->label_section_height = LABEL_SECTION_HEIGHT;
}

/* ------------------------------------------------------------------------- */

void BarGauge::disable_labels() {
this->label_enabled = false;
this->label_section_height = 0;
}

/* ------------------------------------------------------------------------- */
60 changes: 34 additions & 26 deletions BarGauge.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,46 @@
/* ------------------------------------------------------------------------- */

class BarGauge : public Gauge {

public:
BarGauge(Adafruit_ILI9341 * display, Measurement * easurement,
char * name, int32_t range_min, int32_t range_max);

void draw(uint16_t gauge_x, uint16_t gauge_y, uint16_t gauge_w, uint16_t gauge_h) override;
void draw_limit_bar(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t colour, int32_t value);
void draw_reading(uint16_t x, uint16_t y, uint16_t width, uint16_t height);
void draw_name(uint16_t x, uint16_t y, uint16_t width, uint16_t height);
BarGauge(Adafruit_ILI9341 * display, Measurement * easurement,
char * name, double range_min, double range_max);

void set_frame_colour(uint16_t frame_colour);
void set_limit_bar_height(uint32_t height);
void set_label_state(uint8_t state);
void draw(uint16_t gauge_x, uint16_t gauge_y, uint16_t gauge_w,
uint16_t gauge_h) override;

void set_frame_colour(uint16_t value);
void set_limit_bar_height(uint32_t value);

void enable_labels();
void disable_labels();

uint16_t get_bar_y_for_value(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t value);
void get_bar_xy(uint16_t gauge_x, uint16_t gauge_y, uint16_t gauge_w, uint16_t gauge_h, uint16_t * dst_x, uint16_t * dst_y, uint16_t bar_height);
uint16_t get_max_bar_height(uint16_t frame_h);
private:
uint8_t last_reading_length;

uint16_t bar_colour;
uint16_t bar_colour_high;
uint16_t bar_colour_low;
uint16_t last_bar_colour;
uint16_t frame_colour;

int32_t min_bar_value;
int32_t max_bar_value;
uint16_t frame_padding;
uint16_t label_section_height;
uint8_t limit_bar_height;
uint8_t label_enabled;

void draw_limit_bar(uint16_t x, uint16_t y, uint16_t w, uint16_t h,
uint16_t colour, double value);
void draw_reading(uint16_t x, uint16_t y, uint16_t width, uint16_t height);
void draw_name(uint16_t x, uint16_t y, uint16_t width, uint16_t height);

uint16_t get_bar_y_for_value(uint16_t x, uint16_t y, uint16_t w,
uint16_t h, double value);
uint16_t get_max_bar_height(uint16_t frame_h);
void get_bar_xy(uint16_t gauge_x, uint16_t gauge_y, uint16_t gauge_w,
uint16_t gauge_h, uint16_t * dst_x, uint16_t * dst_y,
uint16_t bar_height);

uint8_t last_reading_length;

uint16_t bar_colour;
uint16_t bar_colour_high;
uint16_t bar_colour_low;
uint16_t frame_colour;

uint16_t frame_padding;
uint16_t label_section_height;
uint8_t limit_bar_height;
uint8_t label_enabled;
};

/* ------------------------------------------------------------------------- */
Expand Down
Loading

0 comments on commit 7235920

Please sign in to comment.