Good programming is, in my opinion, as general as it can be without impacting the performance of your particular application. I haven't found much in the way of versatile libraries for GUI though, so I'm trying to build my own...
I've been grappling with ways to create a rotary-encoder-driven GUI on an atmega328p for the last few weeks. I'm specifically working with the AdafruitGFX library on an SSD1306, intending to make a simple GUI to control a reflow oven (with the ability to create, edit, and name profiles to be saved/loaded from EEPROM) but this discussion isn't really limited to that, and should also be applicable to touchscreens or other input methods.
Here's a short list of frustrations I've unearthed while I work on this:
1: Defining a button as a struct in Progmem is really hard to manage because Arduino does not allow you to use lambda expressions to put function pointers in progmem.
typedef (*funcPtr)();
const funcPtr P PROGMEM= (funcPtr) [] () {delay(1);};
will just yield P = 0x00 instead of any meaningful address, so if you want to put callbacks on buttons and store those buttons in progmem then you need to create a unique, named function for every single button in your menu. That makes your code turn into a really massive, unorganized mess. I have no good solution for this.
2: Defining a button as a struct in ram is much easier to work with but if the buttons have display text of any substantial length, you'll run out of RAM too fast to make anything sophisticated.
2: Singleton objects are really hard to avoid without storing a bunch of redundant pointers in memory. If you want your general-purpose GUI to control physical resources like the digital pins, it looks like the only way to avoid hard-coding that functionality into the GUI is to either pass in functions to global pointers or maybe just create an object describing that physical interface and pass a reference to that object into the GUI. Both of these strike me as inelegant.
What is your ideas or practices on building a general purpose graphical interface? Have you worked with a library you would recommend?