mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 12:15:33 +01:00
Introduce a local coordinate drawing system to display and display_buffer
This commit is contained in:
parent
a6f1701902
commit
313cb2bff5
@ -334,6 +334,35 @@ bool Display::clip(int x, int y) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Display::set_local_coordinates_relative_to_current(int x_offset, int y_offset) {
|
||||
Point p(0, 0);
|
||||
if (!this->local_coordinate_.empty()) {
|
||||
p = this->local_coordinate_.back();
|
||||
}
|
||||
p.x += x_offset;
|
||||
p.y += y_offset;
|
||||
|
||||
this->local_coordinate_.push_back(p);
|
||||
|
||||
}
|
||||
void Display::pop_local_coordinates() {
|
||||
if (this->local_coordinate_.empty()) {
|
||||
ESP_LOGE(TAG, "pop_local_coordinates: No local coordinates set");
|
||||
} else {
|
||||
this->local_coordinate_.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
Point Display::get_local_coordinates() {
|
||||
Point p(0, 0);
|
||||
if (!this->local_coordinate_.empty()) {
|
||||
p = this->local_coordinate_.back();
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
bool Display::clamp_x_(int x, int w, int &min_x, int &max_x) {
|
||||
min_x = std::max(x, 0);
|
||||
max_x = std::min(x + w, this->get_width());
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "rect.h"
|
||||
#include "point.h"
|
||||
|
||||
#include "esphome/core/color.h"
|
||||
#include "esphome/core/automation.h"
|
||||
@ -480,6 +481,36 @@ class Display : public PollingComponent {
|
||||
*/
|
||||
bool clip(int x, int y);
|
||||
|
||||
/** Changes the local coordinates to be relative to (x, y). After calling a pixel
|
||||
* drawn at (10, 20) would be drawn to the screen at (x + 10, y + 20)
|
||||
*
|
||||
* @param[in] x: x coordinate as the new local. Absolute to the displays underlying 0
|
||||
* @param[in] y: y coordinate as the new local. Absolute to the displays underlying 0
|
||||
*/
|
||||
void set_local_coordinate(int x, int y) { this->local_coordinate_.push_back(Point(x, y)); };
|
||||
|
||||
/** Changes the local coordinates to be to be (x_local + x_offset, y_local + y_offset)
|
||||
* After calling a pixel drawn at (10, 20) would be drawn to the screen at
|
||||
* (x_local + x_offset + 10, y_local + y_offset + 20)
|
||||
*
|
||||
* @param[in] x_offset: x offset from the current local. Relative to the local x
|
||||
* @param[in] y_offset: y offset from the current local. Relative to the local y
|
||||
*/
|
||||
void set_local_coordinates_relative_to_current(int x_offset, int y_offset);
|
||||
|
||||
/** Removes the most recent local coordinate system from use
|
||||
*/
|
||||
void pop_local_coordinates();
|
||||
|
||||
/** Gets the current local coordinates in the displays absolute coordinate system
|
||||
*/
|
||||
Point get_local_coordinates();
|
||||
|
||||
/** Clears all the local coordinate systems and revers to the displays absolute coordinate
|
||||
* system
|
||||
*/
|
||||
void clear_local_coordinates() { this->local_coordinate_.clear(); };
|
||||
|
||||
protected:
|
||||
bool clamp_x_(int x, int w, int &min_x, int &max_x);
|
||||
bool clamp_y_(int y, int h, int &min_y, int &max_y);
|
||||
@ -495,6 +526,7 @@ class Display : public PollingComponent {
|
||||
std::vector<DisplayOnPageChangeTrigger *> on_page_change_triggers_;
|
||||
bool auto_clear_enabled_{true};
|
||||
std::vector<Rect> clipping_rectangle_;
|
||||
std::vector<Point> local_coordinate_;
|
||||
};
|
||||
|
||||
class DisplayPage {
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "point.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace display {
|
||||
@ -45,6 +46,11 @@ int DisplayBuffer::get_height() {
|
||||
}
|
||||
|
||||
void HOT DisplayBuffer::draw_pixel_at(int x, int y, Color color) {
|
||||
// Convert (x, y) from the local coordinate system to the display absolute coordinate system
|
||||
Point local_coord = this->get_local_coordinates();
|
||||
x += local_coord.x;
|
||||
y += local_coord.y;
|
||||
|
||||
if (!this->get_clipping().inside(x, y))
|
||||
return; // NOLINT
|
||||
|
||||
|
18
esphome/components/display/point.h
Normal file
18
esphome/components/display/point.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace display {
|
||||
|
||||
class Point {
|
||||
public:
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
|
||||
Point() : x(VALUE_NO_SET), y(VALUE_NO_SET) {};
|
||||
inline Point(int16_t x, int16_t y) ALWAYS_INLINE : x(x), y(y) {};
|
||||
};
|
||||
|
||||
} // namespace display
|
||||
} // namespace esphome
|
Loading…
Reference in New Issue
Block a user