The following code works fine, but I want it to be organized differently.
It creates buttons on a 480x320 display and I have a lot of it in the class but still require too much button stuff in the share.ino.
I would like the ary[12] and buttonCount to be located in the class and somehow give share.ino access to them. That way I could move other fuctions like setInvert and StoreButtonData into the class.
I can’t figure out how to give share.ino access to the ary[12] and the buttonData. I would need to be able to do something like this from share: ary[i].invert = true; or inverted = ary[i].invert and bc = 0.
Can someone help me understand how to do that?
Share.ino
// for teensy 4.0
/***************************************************************************************************************/
#include "display.h" // display functions, touchscreen functions anda button class
struct ButtonData // all button information is stored here
{
int tSize; // the size of the text (1-5)
int x; // x location of the button
int y; // y location of the button
int w; // width of the button text
int h; // height of the button text
int invert; // whether the button clrs are inverted (background/text)
String text; // the button text
int tx; // start x of the button text
int ty; // start y of the button text
int txClr; // the text clr
int bgClr; // the background colot
int bw; // total width of the button
int bh; // total height of the button
void (*funct)(int n); // the function to call if the button is pressed
int arg; // the argument for the called function
};
ButtonData ary[12];
int bc = 0;
unsigned long tstart, tend;
/***************************************************************************************************************/
void setup(void)
{
Serial.begin(115200);
delay(250);
StartDisplay(); // start the 3.5" display
DrawHomePage(0);
}
/***************************************************************************************************************/
void loop(void)
{
TSPoint p;
p = GetTouch();
if (p.z != -1)
{
Press(p.x, p.y);
}
}
/***************************************************************************************************************/
void Press(int x, int y)
{
static int cnt = bc, dly = 750;;
for (int i = 0; i < cnt; i++)
{
if (x >= ary[i].x && x <= ary[i].x + ary[i].w) // search for x,y inside a button
if (y >= ary[i].y && y <= ary[i].y + ary[i].h)
{
ary[i].funct(ary[i].arg); // call the button's function
delay(dly); // this is the keypress repeat rate
dly = 200;
return;
}
}
dly = 750;
}
/***************************************************************************************************************/
void DrawHomePage(int n)
{
if (n == 1)
ClearScreen();
Rotation(1);
bc = 0;
// create 5 buttons
Button(1, 100, 50, 50, 20, false, "LAKE", WHITE, RED, Lake, 88);
Button(2, 100, 100, 70, 25, false, "HOME", WHITE, GREEN, Home, 88);
Button(3, 100, 150, 90, 30, false, "BASE", WHITE, BLUE, Base, 77);
delay(1000);
// invert all 3 buttons
SetInvert("LAKE", true);
SetInvert("HOME", true);
SetInvert("BASE", true);
}
/***************************************************************************************************************/
void Button(int tSize, int x, int y, int w, int h, boolean invert, String text, int txClr, int bgClr, void (funct)(int n), int arg)
{
NewButton(tSize, x, y, w, h, invert, text, txClr, bgClr, funct, arg); // create the button
StoreButtonData(tSize, x, y, w, h, invert, text, txClr, bgClr, funct, arg);
bc++;
}
void ReButton(int tSize, int x, int y, int w, int h, boolean invert, String text, int txClr, int bgClr, void (funct)(int n), int arg)
{
NewButton(tSize, x, y, w, h, invert, text, txClr, bgClr, funct, arg);
StoreButtonData(tSize, x, y, w, h, invert, text, txClr, bgClr, funct, arg);
}
void StoreButtonData(int tSize, int x, int y, int w, int h, int invert, String text, int txClr, int bgClr, void (funct)(int n), int arg)
{
ary[bc].tSize = tSize;
ary[bc].x = x;
ary[bc].y = y;
ary[bc].invert = invert;
ary[bc].text = text;
ary[bc].txClr = txClr;
ary[bc].bgClr = bgClr;
ary[bc].w = w;
ary[bc].h = h;
ary[bc].funct = funct;
ary[bc].arg = arg; // increment the button count
}
/***************************************************************************************************************/
void SetInvert(String name, boolean tf)
{
int a = 0;
for (int i = 0; i < bc; i++)
{
if (ary[i].text == name)
{
ary[i].invert = tf;
a = i;
}
}
ReButton(ary[a].tSize, ary[a].x, ary[a].y, ary[a].w, ary[a].h, ary[a].invert, ary[a].text, ary[a].txClr, ary[a].bgClr, ary[a].funct, ary[a].arg);
}
/***************************************************************************************************************/
void SetInvert(int id, boolean tf)
{
ary[id].invert = tf;
ReButton(ary[id].tSize, ary[id].x, ary[id].y, ary[id].w, ary[id].h, ary[id].invert, ary[id].text, ary[id].txClr, ary[id].bgClr, ary[id].funct, ary[id].arg);
}
/***************************************************************************************************************/
void Lake(int n)
{
Serial.println("Lake Pressed");
}
/***************************************************************************************************************/
void Home(int n)
{
Serial.println("Home Pressed");
}
/***************************************************************************************************************/
void Base(int n)
{
Serial.println("Base Pressed");
}
display.h
// display functions, touchscreen functions and a button class
#ifndef __DISPLAY_H__
#define __DISPLAY_H__
/**************************************************************************************************************/
#define MISTER // SPRINKLER or MISTER
/**************************************************************************************************************/
#include <arduino.h>
#include "Adafruit_HX8357.h" // the 480x320 display
#include <Adafruit_GFX.h> // Core graphics library
#include "TouchScreen.h" // the touch screen
// externally visible functions
void StartDisplay(); // start the display
TSPoint GetTouch(); // check for a screen touch (must be continually polled)
void Rotation(int r); // set the screen rotation
void ClearScreen(); // clears the screen
// The display uses hardware SPI, plus pins 9 & 10
#define TFT_DC_PIN 9
#define TFT_CS_PIN 10
#define TFT_RST_PIN 15 // tie this to arduino RST if you like
// These are the four touchscreen pins
#ifdef SPRINKLER
#define YM_PIN A0 // (pin 14) can be a digital pin
#define XP_PIN A1 // (pin 15) can be a digital pin
#endif
#ifdef MISTER
#define YM_PIN 7 // can be a digital pin
#define XP_PIN 8 // can be a digital pin
#endif
#define YP_PIN A2 // (pin 16) must be an analog pin, use "An" notation!
#define XM_PIN A3 // (pin 17) must be an analog pin, use "An" notation!
#define MINPRESSURE 100 // minimum touch pressure to recognize a touch
#define MAXPRESSURE 1000 // maximum touch pressure to recognize a touch
// This is calibration data for the raw touch data to align the screen coordinates
#define TS_MINX 105 // bottom
#define TS_MINY 60 // right
#define TS_MAXX 945 // top
#define TS_MAXY 930 // left
// Colors
#define BACKGROUND 0xA514
#define FILL 0xAD75
#define BLACK 0x0000
#define BLUE 0x0019
#define YELLOW 0xFFE0
#define RED 0xA800
#define GREEN 0x0360
#define WHITE 0xFFFF
#define GRAY 0x9CD3
/**********************************************************************************/
class NewButton
{
private:
// private variables
int _tSize; // the size of the text (1-5)
int _x; // x location of the button
int _y; // y location of the button
int _w; // width of the button text
int _h; // height of the button text
boolean _invert; // whether the button clrs are inverted (background/text)
String _text; // the button text
int _tx; // start x of the button text
int _ty; // start y of the button text
int _txClr; // the text clr
int _bgClr; // the background colot
void (*_funct)(int n); // the function to call if the button is pressed
int _arg; // the argument for the called function
public:
// public methods
NewButton(int tSize, int x, int y, int w, int h, boolean invert, String text, int txClr, int bgClr, void (funct)(int n), int arg);
};
#endif
display.cpp
#include "display.h" // display functions, touchscreen functions anda button class
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN);
TouchScreen tscr = TouchScreen(XP_PIN, YP_PIN, XM_PIN, YM_PIN, 500);
/**********************************************************************************/
NewButton::NewButton(int tSize, int x, int y, int w, int h, boolean invert, String text, int txClr, int bgClr, void (funct)(int n), int arg)
{
double charWidth[6] = {6, 6, 12, 18, 24, 29};
double charHeight[6] = {7, 12, 18, 24, 30, 38};
int txtw;
// prepare to center the text horizontally
txtw = charWidth[tSize] * text.length();
// save the button information
_tSize = tSize;
_x = x;
_y = y;
_w = w;
_h = h;
_invert = invert;
_text = text;
_tx = x + (_w - txtw) / 2 + 1;
_ty = y + (_h - charHeight[tSize]) / 2 + 2;
_txClr = txClr;
_bgClr = bgClr;
_funct = funct;
_arg = arg;
// Draw the button
tft.drawRoundRect(_x, _y, _w, _h, 10, BLACK); // draw the outline clr
if (_invert)
tft.fillRoundRect(_x + 1, _y + 1, _w - 2, _h - 2, 10, _txClr); // draw the fill clr inverted
else
tft.fillRoundRect(_x + 1, _y + 1, _w - 2, _h - 2, 10, _bgClr); // draw the fill clr normal
tft.setCursor(_tx, _ty );
if (_invert)
tft.setTextColor(_bgClr); // draw the text clr
else
tft.setTextColor(_txClr); // draw the text clr
tft.setTextSize(_tSize);
tft.print(_text);
}
void Rotation(int r)
{
tft.setRotation(r);
}
/**********************************************************************************/
TSPoint GetTouch()
{
TSPoint p;
int16_t sav;
tft.setRotation(0);
// Retrieve a point
p = tscr.getPoint();
if (p.z < MINPRESSURE || p.z > MAXPRESSURE)
{
p.x = p.y = p.z = -1;
}
// Scale it from ~0->1000 to tft.width using the calibration #'s
p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
// swap x & y
sav = p.x;
p.x = p.y;
p.y = sav;
return p;
}
/**********************************************************************************/
void ClearScreen()
{
tft.setRotation(1);
tft.fillScreen(BACKGROUND);
};
/**********************************************************************************/
void StartDisplay()
{
tft.begin();
delay(200);
Rotation(1);
tft.fillScreen(BACKGROUND);
}