diff --git a/firmware/common/ui_widget.cpp b/firmware/common/ui_widget.cpp index d8babd5a..3c9bc96a 100644 --- a/firmware/common/ui_widget.cpp +++ b/firmware/common/ui_widget.cpp @@ -1465,7 +1465,7 @@ int32_t SymField::clip_value(const uint32_t index, const uint32_t value) { Waveform::Waveform( Rect parent_rect, - int8_t * data, + int16_t * data, uint32_t length, uint32_t offset, bool digital, @@ -1480,6 +1480,16 @@ Waveform::Waveform( //set_focusable(false); } +void Waveform::set_cursor(const uint32_t i, const int16_t position) { + if (i < 2) { + if (position != cursors[i]) { + cursors[i] = position; + set_dirty(); + } + show_cursors = true; + } +} + void Waveform::set_offset(const uint32_t new_offset) { if (new_offset != offset_) { offset_ = new_offset; @@ -1495,28 +1505,26 @@ void Waveform::set_length(const uint32_t new_length) { } void Waveform::paint(Painter& painter) { - uint32_t n, point_count; + size_t n; Coord y, y_offset = screen_rect().location().y(); Coord prev_x = screen_rect().location().x(), prev_y; float x, x_inc; Dim h = screen_rect().size().height(); - int8_t * data_start = data_ + offset_; + const float y_scale = (float)(h - 1) / 65536.0; + int16_t * data_start = data_ + offset_; // Clear painter.fill_rectangle(screen_rect(), Color::black()); + if (!length_) return; + x_inc = (float)screen_rect().size().width() / length_; - point_count = length_; - const float y_scale = (float)(h - 1) / 256; // TODO: Make variable - - if (!point_count) return; - if (digital_) { // Digital waveform: each value is an horizontal line x = 0; h--; - for (n = 0; n < point_count; n++) { + for (n = 0; n < length_; n++) { y = *(data_start++) ? h : 0; if (n) { @@ -1532,9 +1540,9 @@ void Waveform::paint(Painter& painter) { } else { // Analog waveform: each value is a point's Y coordinate x = prev_x + x_inc; - h = h / 2; + h /= 2; prev_y = y_offset + h - (*(data_start++) * y_scale); - for (n = 1; n < point_count; n++) { + for (n = 1; n < length_; n++) { y = y_offset + h - (*(data_start++) * y_scale); display.draw_line( {prev_x, prev_y}, {(Coord)x, y}, color_); @@ -1543,6 +1551,17 @@ void Waveform::paint(Painter& painter) { x += x_inc; } } + + // Cursors + if (show_cursors) { + for (n = 0; n < 2; n++) { + painter.draw_vline( + Point(std::min(screen_rect().size().width(), (int)cursors[n]), y_offset), + screen_rect().size().height(), + cursor_colors[n] + ); + } + } } diff --git a/firmware/common/ui_widget.hpp b/firmware/common/ui_widget.hpp index 995db50e..7874d448 100644 --- a/firmware/common/ui_widget.hpp +++ b/firmware/common/ui_widget.hpp @@ -598,7 +598,7 @@ private: class Waveform : public Widget { public: - Waveform(Rect parent_rect, int8_t * data, uint32_t length, uint32_t offset, bool digital, Color color); + Waveform(Rect parent_rect, int16_t * data, uint32_t length, uint32_t offset, bool digital, Color color); Waveform(const Waveform&) = delete; Waveform(Waveform&&) = delete; @@ -607,15 +607,20 @@ public: void set_offset(const uint32_t new_offset); void set_length(const uint32_t new_length); + void set_cursor(const uint32_t i, const int16_t position); void paint(Painter& painter) override; private: - int8_t * data_; + const Color cursor_colors[2] = { Color::cyan(), Color::magenta() }; + + int16_t * data_; uint32_t length_; uint32_t offset_; bool digital_ { false }; Color color_; + int16_t cursors[2] { }; + bool show_cursors { false }; }; class VuMeter : public Widget {