/******************************************* * Most Awesome Renderer Ever *******************************************/ #include #include #include extern "C" { #include #include } #include #include #include #include #include namespace Render{ struct pos_t { uint16_t x; uint16_t y; }; struct bbox2d_t { uint16_t xMin, Ymin; uint16_t Xmax, Ymax; }; enum class ScreenRotation { Rot0 = 0, Rot90 = 90, Rot180 = 180, Rot270 = 270 }; enum class BlendMode { Add, Intersect }; enum class Color { White, Black }; class Page; class Drawable; class DrawablePoint; typedef pos_t dim_t; typedef std::vector> Pages; typedef std::vector> Drawables; class Mare { friend class Drawable; friend class Page; public: Mare(dim_t size); ~Mare(); // getters, setters public: void setSize(const dim_t size); const dim_t getSize() {return _screenSize;}; void setRotation(const ScreenRotation r); const ScreenRotation getRotation() {return _rotation;}; void setCurrentPage(const uint8_t p); const Page& getCurrentPage() {return *_pages.at(0).get();}; // drawables, pages public: template T* addDrawable(Args... args) { static size_t lastDrawableIndex(0); static_assert(std::is_base_of_v, "Mare::addDrawable() error, type T is not inherited from Drawable."); auto newD = std::shared_ptr(new T(lastDrawableIndex++, nullptr, this, args...)); _drawables.push_back(std::move(newD)); auto foo = _drawables.back().get(); return static_cast(foo); } void removeDrawable(const size_t id) {}; void addPage() {}; void removePage(const uint8_t num) {}; const Drawables& getDrawables() {return _drawables;}; const Pages& getPages() {return _pages;}; //render private: void clearBuffer(uint8_t* buffer, uint16_t len, Color col); void visitDrawables(Drawable* parent) {}; public: void render(); void setPixel(uint8_t* img, uint16_t x, uint16_t y, bool value); void clearScreen() { EPD_2IN9_V2_Clear(); clearBuffer(_screenBufferBackground, _bufferDim, Color::White); EPD_2IN9_V2_Display(_screenBufferBackground); } // members private: dim_t _screenSize; Pages _pages; uint8_t* _screenBufferForeground; uint8_t* _screenBufferBackground; uint16_t _bufferDim; Drawables _drawables; // background drawables for all the pages ScreenRotation _rotation; public: uint8_t* bBuffer() { return _screenBufferBackground; } uint8_t* fBuffer() { return _screenBufferForeground; } }; class Drawable { public: Drawable(const size_t id, Drawable* parent, Mare* engine); ~Drawable(); public: virtual void render() {}; public: void setId(const size_t id) { _id = id; }; void setOrigin(const pos_t origin) { _origin = origin; }; void setDirty() {_dirty = true;}; void resetDirty() {_dirty = false;}; void setBlendMode(const BlendMode mode) { _blendMode = BlendMode::Intersect; }; const bool isDirty() {return _dirty;} const pos_t getOrigin() { return _origin; }; const bbox2d_t getBBox() { return _bbox; }; const BlendMode getBlendMode() { return _blendMode; }; uint8_t* getBuffer() { if (_parent == nullptr) return engine()->bBuffer(); else return engine()->fBuffer(); } Mare* engine() { return _engine; }; Drawable* parent() { return _parent; }; private: Drawable* _parent; Mare* _engine; bool _dirty; size_t _id; pos_t _origin; bbox2d_t _bbox; BlendMode _blendMode; Drawables _children; }; class DrawablePoint: public Drawable { public: DrawablePoint(const size_t id, Drawable* parent, Mare* engine, dim_t size); ~DrawablePoint(); public: void setSize(dim_t size) { _size = size; }; const dim_t getSize() { return _size; }; private: void render(); // members private: dim_t _size; }; class DrawableLine: public Drawable { public: DrawableLine(const size_t id, Drawable* parent, Mare* engine); ~DrawableLine(); public: void setThickness(uint16_t thickness) {_thickness = thickness;}; const uint16_t getThickness() {return _thickness;}; void setRotation(float rotation) {_rotation = rotation;}; const float getRotation() {return _rotation;}; void setLength(uint16_t length) {_lenght = length;}; const uint16_t getLength() {return _lenght;}; private: void render(); // difficult business // members private: uint16_t _thickness; uint16_t _lenght; float _rotation; }; class DrawableRectangle: public Drawable { DrawableRectangle(); ~DrawableRectangle(); public: private: void render() {}; // members private: }; class DrawableCircle: public Drawable { DrawableCircle(); ~DrawableCircle(); public: private: void render() {}; // members private: }; class DrawableChar: public Drawable { DrawableChar(); ~DrawableChar(); public: private: void render() {}; // members private: }; class DrawableString: public Drawable { DrawableString(); ~DrawableString(); public: private: void render() {}; // members private: }; class DrawableCustom: public Drawable { DrawableCustom(); ~DrawableCustom(); public: private: void render() {}; // members private: }; class Page { Page(); ~Page(); public: private: Drawables _backDrawables; Drawables _frontDrawables; }; }