|
|
@@ -0,0 +1,176 @@
|
|
|
+#include <iostream>
|
|
|
+
|
|
|
+
|
|
|
+typedef enum
|
|
|
+{
|
|
|
+ NORMAL = 0,
|
|
|
+ HIGHLIGHT = 1
|
|
|
+} t_DrawInvers;
|
|
|
+
|
|
|
+typedef enum
|
|
|
+{
|
|
|
+ LEFT = 0,
|
|
|
+ CENTER = 1,
|
|
|
+ RIGHT = 2
|
|
|
+} t_HorizontalPosition;
|
|
|
+
|
|
|
+typedef enum
|
|
|
+{
|
|
|
+ TOP = 0,
|
|
|
+ MIDDLE = 1,
|
|
|
+ BOTTOM = 2
|
|
|
+} t_VerticalPosition;
|
|
|
+
|
|
|
+// Mock graphics class
|
|
|
+class MockGfx {
|
|
|
+public:
|
|
|
+
|
|
|
+ /**********************************************************************************************
|
|
|
+ * @brief Constructor
|
|
|
+ *
|
|
|
+ * This is a blank constructor since the constructor is already defined in the base class.
|
|
|
+ * The constructor in the base class is used to initialize the u8g2 object.
|
|
|
+ * It is necessary to define a constructor in this class to avoid errors from the compiler.
|
|
|
+ */
|
|
|
+ MockGfx() {
|
|
|
+ std::cout << "MockGfx constructor\n";
|
|
|
+ }; // Initialize with specific display settings
|
|
|
+
|
|
|
+ void drawPixel(uint16_t x, uint16_t y, uint16_t color) { std::cout << "MockGfx::drawPixel()\n"; }
|
|
|
+ void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color) { std::cout << "MockGfx::drawLine()\n"; }
|
|
|
+ void drawRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) { std::cout << "MockGfx::drawRect()\n"; }
|
|
|
+ void fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) { std::cout << "MockGfx::fillRect()\n"; }
|
|
|
+ void drawCircle(uint16_t x, uint16_t y, uint16_t r, uint16_t color) { std::cout << "MockGfx::drawCircle()\n"; }
|
|
|
+ void fillCircle(uint16_t x, uint16_t y, uint16_t r, uint16_t color) { std::cout << "MockGfx::fillCircle()\n"; }
|
|
|
+ void drawText(uint16_t x, uint16_t y, const char* str, uint16_t color) { std::cout << "MockGfx::drawText()\n"; }
|
|
|
+ void setFont(uint16_t font) { std::cout << "MockGfx::setFont()\n"; }
|
|
|
+ void setTextColor(uint16_t color) { std::cout << "MockGfx::setTextColor()\n"; }
|
|
|
+ void setTextSize(uint16_t size) { std::cout << "MockGfx::setTextSize()\n"; }
|
|
|
+ void setCursor(uint16_t x, uint16_t y) { std::cout << "MockGfx::setCursor()\n"; }
|
|
|
+ void clearDisplay() { std::cout << "MockGfx::clearDisplay()\n"; }
|
|
|
+ void setRotation(uint16_t rotation) { std::cout << "MockGfx::setRotation(" << rotation << ")\n"; }
|
|
|
+ void sendBuffer() { std::cout << "MockGfx::sendBuffer()\n"; }
|
|
|
+};
|
|
|
+
|
|
|
+class u8g2Gfx {
|
|
|
+public:
|
|
|
+
|
|
|
+ u8g2Gfx() {
|
|
|
+ std::cout << "u8g2Gfx constructor\n";
|
|
|
+ }; // Initialize with specific display settings
|
|
|
+
|
|
|
+ void drawPixel(uint16_t x, uint16_t y, uint16_t color) { std::cout << "u8g2Gfx::drawPixel()\n"; }
|
|
|
+
|
|
|
+ void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color) { std::cout << "u8g2Gfx::drawLine()\n"; }
|
|
|
+
|
|
|
+ void drawRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) {
|
|
|
+ std::cout << "u8g2Gfx::drawRect(" << x << ", " << y << ", " << w << ", " << h << ")\n";
|
|
|
+ }
|
|
|
+
|
|
|
+ void fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) {
|
|
|
+ std::cout << "u8g2Gfx::fillRect(" << x << ", " << y << ", " << w << ", " << h << ")\n";
|
|
|
+ }
|
|
|
+
|
|
|
+ void drawCircle(uint16_t x, uint16_t y, uint16_t r, uint16_t color) { std::cout << "u8g2Gfx::drawCircle()\n"; }
|
|
|
+ void fillCircle(uint16_t x, uint16_t y, uint16_t r, uint16_t color) { std::cout << "u8g2Gfx::fillCircle()\n"; }
|
|
|
+ void drawText(uint16_t x, uint16_t y, const char* str, uint16_t color) { std::cout << "u8g2Gfx::drawText()\n"; }
|
|
|
+ void setFont(uint16_t font) { std::cout << "u8g2Gfx::setFont()\n"; }
|
|
|
+ void setTextColor(uint16_t color) { std::cout << "u8g2Gfx::setTextColor()\n"; }
|
|
|
+ void setTextSize(uint16_t size) { std::cout << "u8g2Gfx::setTextSize()\n"; }
|
|
|
+ void setCursor(uint16_t x, uint16_t y) { std::cout << "u8g2Gfx::setCursor()\n"; }
|
|
|
+ void clearDisplay() { std::cout << "u8g2Gfx::clearDisplay()\n"; }
|
|
|
+ void setRotation(uint16_t rotation) { std::cout << "u8g2Gfx::setRotation(" << rotation << ")\n"; }
|
|
|
+ void sendBuffer() { std::cout << "u8g2Gfx::sendBuffer()\n"; }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+// For u8g2
|
|
|
+// u8g2_t gfx;
|
|
|
+
|
|
|
+// For TFT_eSPI
|
|
|
+// TFT_eSPI gfx;
|
|
|
+MockGfx gfx;
|
|
|
+u8g2Gfx u8g2gfx;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// New: CRTP base class
|
|
|
+template<typename Derived>
|
|
|
+class cBaseGraphics {
|
|
|
+public:
|
|
|
+
|
|
|
+ void draw() {
|
|
|
+ static_cast<Derived*>(this)->drawImpl();
|
|
|
+ }
|
|
|
+ void setVisible(bool visible) {
|
|
|
+ static_cast<Derived*>(this)->setVisibleImpl(visible);
|
|
|
+ }
|
|
|
+ // ... repeat for other methods
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+template <typename Graphics>
|
|
|
+class Button : public cBaseGraphics<Button<Graphics>> {
|
|
|
+public:
|
|
|
+ Button(Graphics* gfx, uint16_t x, uint16_t y, uint16_t w, uint16_t h, const char* label)
|
|
|
+ : _gfx(gfx), x_(x), y_(y), w_(w), h_(h), label_(label) {
|
|
|
+ }
|
|
|
+
|
|
|
+ void setup() {
|
|
|
+ std::cout << "Button class - setup()" << std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+protected:
|
|
|
+ void drawImpl() {
|
|
|
+ // Pseudocode: Replace with actual drawing code for your library
|
|
|
+ _gfx->drawRect(x_, y_, w_, h_, 1);
|
|
|
+ _gfx->drawText(x_ + 2, y_ + h_ / 2, label_, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+private:
|
|
|
+ Graphics* _gfx;
|
|
|
+ uint16_t x_, y_, w_, h_;
|
|
|
+ const char* label_;
|
|
|
+};
|
|
|
+
|
|
|
+template <typename Graphics>
|
|
|
+class ProgressBar : public cBaseGraphics<ProgressBar<Graphics>> {
|
|
|
+public:
|
|
|
+ ProgressBar(Graphics* gfx, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t value)
|
|
|
+ : _gfx(gfx), x_(x), y_(y), w_(w), h_(h), value_(value) {
|
|
|
+ }
|
|
|
+
|
|
|
+ void setup() {
|
|
|
+ std::cout << "ProgressBar class - setup()" << std::endl;
|
|
|
+ _gfx->drawText(x_, y_ - 10, "ProgressBar setup", 1);
|
|
|
+ }
|
|
|
+
|
|
|
+protected:
|
|
|
+ void drawImpl() {
|
|
|
+ _gfx->drawRect(x_, y_, w_, h_, 1);
|
|
|
+ uint16_t fillWidth = (w_ * value_) / 100;
|
|
|
+ _gfx->fillRect(x_, y_, fillWidth, h_ , 1);
|
|
|
+ }
|
|
|
+
|
|
|
+private:
|
|
|
+ Graphics* _gfx;
|
|
|
+ uint16_t x_, y_, w_, h_, value_;
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+Button<MockGfx> btn(&gfx, 10, 10, 80, 30, "OK");
|
|
|
+ProgressBar<MockGfx> bar(&gfx, 10, 50, 100, 20, 75);
|
|
|
+
|
|
|
+Button<u8g2Gfx> btn1(&u8g2gfx, 10, 10, 80, 30, "OK");
|
|
|
+ProgressBar<u8g2Gfx> bar2(&u8g2gfx, 10, 50, 100, 20, 75);
|
|
|
+
|
|
|
+uint16_t main() {
|
|
|
+
|
|
|
+ btn.setup();
|
|
|
+ btn.draw();
|
|
|
+ bar.draw();
|
|
|
+
|
|
|
+ btn1.draw();
|
|
|
+ bar2.draw();
|
|
|
+ return 0;
|
|
|
+}
|