This is a question about best practice when using functions to repeat tasks. The attached sketch has the full code (less the UTFT libraries).
I am trying to create a menu handler for the 3.2" TFT Touch Screen using Henning Karlsen's UTFT library. I need to pre-define colours for menus with each menu "button" having:
- a background colour
- a border colour
- a text colour
- a text background colour (= background colour)
I have a struct to hold the RGB values:
struct RGB {
byte r;
byte g;
byte b;
};
and a further struct to hold the menu colours as defined above:
struct BtnCol {
struct RGB fill;
struct RGB border;
struct RGB text;
};
I can now define various menu colours using the BtnCol struct as shown in this snippet:
BtnCol vMain = {{0, 32, 0},{34, 139, 34},{144, 238, 144}}; // main (vertical) menu
BtnCol hSubs = {{12, 78, 28},{56, 144, 64},{144, 238, 144}}; // subsidiary (horizontal) menu
// etc....
I can create an array of menu items:
// Up to 6 vertical menu items each of 1 to 9 characters
const char* vMenuTxt [][6] = {
{"Date-Time", "Co-ords", "Solar", "Equations", "Setup", "RESET"}, // 6 items
{"Set Date", "Set Time", "Time Zone", "", "", "BACK"}
// etc...
};
...and to each of those items I can assign a colour from the previously-defined Button Colour struct:
// assign appropriate menu colours to each of the above buttons
BtnCol vMenu [][6] = {
{{vMain}, {vMain}, {vMain}, {vMain}, {vMain}, {aWarn}},
{{vMain}, {vMain}, {vMain}, {aGrey}, {aGrey}, {aSpec}}
};
Menus are drawn using a generalised function:
void vDrawMenu (int menu, int vMOX, int vMOY, int vMP, int vBH, int vBW, int FW, int FH) {
myGLCD.drawBitmap (1, 54, 78, 22, bmenu[menu]);
for (int i=0; i<6; i++) {
myGLCD.setBackColor(vMenu[menu][i].fill.r,vMenu[menu][i].fill.g,vMenu[menu][i].fill.b); // Text Background, index 0
myGLCD.setColor(vMenu[menu][i].fill.r,vMenu[menu][i].fill.g,vMenu[menu][i].fill.b); // Button Fill, index 0
myGLCD.fillRoundRect(vMOX, vMOY + i * vMP, vBW, vMOY + i * vMP + vBH);
myGLCD.setColor(vMenu[menu][i].border.r,vMenu[menu][i].border.g,vMenu[menu][i].border.b); // Button Border, index 1
myGLCD.drawRoundRect(vMOX, vMOY + i * vMP, vBW, vMOY + i * vMP + vBH);
myGLCD.setColor(vMenu[menu][i].text.r,vMenu[menu][i].text.g,vMenu[menu][i].text.b); // Text Colour, index 2
int xpos = vMOX + vBW/2 - strlen(vMenuTxt[menu][i]) * FW/2;
int vTextOffset = (vBH-FH)/2 + 3;
myGLCD.print(vMenuTxt[menu][i], vMOX + xpos, vMOY + vTextOffset + i * vMP);
}
}
All of the function arguments are positional. None of them are to do with the colour definitions. The specification of colours via the arrays previously defined at global level is handled by statements such as:
myGLCD.setColor(vMenu[menu][i].text.r,vMenu[menu][i].text.g,vMenu[menu][i].text.b);
This means that whilst positional information is passed via parameters, colour information is picked up directly from the global values.
I have read that globals ought not to be used this way so the question is:
Given that eventually I want to reduce the above function (as well as others) to a library, is the above way acceptable or are there better ways of organising this code? Or is it just down to personal preference?
(At the moment the button size and position parameters as well as the colours are defined in the sketch. Eventually they will be hived off to a separate file of user-definable values).
Thanks,
Ric
touch_interface_v15.ino (13 KB)
TFT.h (339 Bytes)