c++ - graphic drawing class organisation -


i have basic 4x20 character lcd use displaying menu buttons using arduino driver (limited standard library support).

example lcd menu , buttons

i'm thinking of producing interface class graphicobject graphical objects inherit (such button, menuitem etc.). seems logical graphicobject class should have draw method can overridden.

at moment, have class called lcd covers low level drawing of text , character positioning. in order draw anything, need access 1 of these lcd objects. if include pointer lcd object within graphicobject or derived objects, couple them , make them lcd objects. if change type of display device these classes aren't suitable more.

how can classes organised keep them loosely coupled , allow change in display types @ later date? should have lcdbutton lcdmenuitem inherit button , menuitem interface, create additional objects other display device (otherdisplaybutton otherdisplaymenuitem)?

any suggested reading? i've looked @ many examples, none of them seem go details function of draw method , whether device should accessed directly or through controlling object.

thanks

edit 1

brief code idea overview

#include "arduino.h"  class lcd { public:   struct parameters {     uint_fast8_t numberlines;     uint_fast8_t numbercharacters; //  uint_fast8_t* lineoffsets;     print* serial; // can serial device (all inherit print).   };  protected:   parameters parameters_;   const uint_fast8_t escapecode_ = 0x1b;   const uint_fast8_t directcode_ = 0xfe;    void sendcommand_(uint_fast8_t command, uint_fast8_t parameter = 0);   void sendcommanddirect_(uint_fast8_t command);  public:   lcd(parameters parameters);   void cleardisplay(void);   void movecursor(uint_fast8_t line, uint_fast8_t character);   void resetdisplay(void);   void customcharacter(const uint_fast8_t address,       const uint_fast8_t charactermap[8]);    void write(uint8_t character);    // boilerplate print forwarders.   void print(const char character);   void print(const string &string);   void print(const char string[]);    // boilerplate println forwarders.   void println(const char character);   void println(const string &string);   void println(const char string[]);   void println(void); };  class graphicobject {   virtual void draw(void)=0; };  class button: public graphicobject { public:   typedef void (*buttonaction)(void);   virtual void settext(const string text)=0;   virtual const string gettext() =0;   virtual bool isactive()=0;   virtual void setactive(bool)=0;   virtual void setaction(buttonaction action)=0; };  class menuitem: public button { public:   typedef void (*menuaction)(void);   virtual menuitem* parentitem()=0;   virtual const menuitem* additem(string text, menuaction action)=0; };  class vscrollbar: public graphicobject { public:   virtual void setattop(bool attop);   virtual void setatbottom(bool atbottom); };  class lcdbutton: public button { private:   lcd* lcd_;   string text_;bool active_; public:   lcdbutton(lcd* lcd);   void draw(void);   void settext(string text);   const string gettext();bool isactive();   void setactive(bool);   void setaction(button::buttonaction action); };  class lcdwindow: public graphicobject { private:   lcdbutton* lcdbuttons_ = nullptr; public:   enum class position     : uint_fast8_t {       left,     right   };    bool addbutton(lcdbutton* lcdbutton, uint_fast8_t line, uint_fast8_t offset);    bool addvscrollbar(vscrollbar* vscrollbar, position position);   void draw(); };  int main(void) {   lcd::parameters lcdparameters;   lcdparameters.numbercharacters = 20;   lcdparameters.numberlines = 4;   lcdparameters.serial = &serial1;   lcd lcd = lcd(lcdparameters);   lcdbutton mybutton(&lcd);   mybutton.settext("select");   mybutton.setactive(true);   lcdwindow lcdwindow;   lcdwindow.addbutton(&mybutton, 1, 1);   lcdwindow.draw();   while (1){}   return 0; } 

there different ways this. in principle, should define interface (api) low-level lcd driver module(s) , call functions of low level api draw something. implementations of api can exchanged without need change high level code.

the simplest way define abstract c++ base class lcd driver implementations have derived from. base class should have virtual methods need overloaded derived implementations.

but litte information: virtual methods in c++ classes requires compiler generate method pointer table every object created when object instantiated; needs more memory. also, function calls objects of these classes indirect (the compiler generates code first lookup real function pointer , calls function using pointer), makes resulting code slower.


Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -