Due GUI (Graphical user interface) - [now community project]

DueGUI - Arduino Due Graphical User Interface, UTFT, SDI and Touch library.

DueGUI is a new library combining Henning Karlsen's UTFT and Touch libraries each already modified by CTE together with an SPI library from CTE. The combined library has then been further modified where some parts overlap and for compatibility.

The next stage was to add a complete graphical user interface or GUI. There are some basic drawing and text routines built into UTFT but I wanted something a lot more usable. The DueGUI library works on a set of objects which the user defines on a per page basis and then the library manages these objects.

To make it easier I will use the first post of the thread in order to keep people up to date with the library.

I released version 0.10 on 20/05/2013 as a working alpha test version after telling people about it two weeks earlier.

Downloads:

Current version of library: 0.13

www.cowasaki.co.uk/DueGUI/DUEGUI_013.zip

Current version of manual: 0.13

www.cowasaki.co.uk/DueGUI/DueGUI_0_13.pdf

Demonstation video now available:

Youtube

Current specifications:

Hardware support:

  • UTFT
  • Touch
  • SPI EEPROM
  • CTE UTFT shield (or alternative)

Interrupt driven GUI environment with dozens of functions and features (see manual for full list but redrawing all object/selected ones/testing all or single buttons etc etc

with the following Objects (so far - many more being added).

  • Panel (Box with options for text size, colour and location. Options for border and background colour.)
  • Label (Simple text placed on screen with options for colour, size, location etc
  • Button (All the options of Panel and Label plus options to make the button change colour as pressed etc
  • Check boxes ( traditional box, y/n, yes/no
  • Cycle box (each click cycles through a range of numerical values)
  • Analogue clock (with several variations and options all of which automatically update)
  • Digital time label (with options and automatically updating)
  • Digial date label (with options and automatically updating)
  • Text input (with options of a panel with label and box or simple text)
  • Graphical image (from EEPROM or data at the moment but from SDcard soon
  • Shape (wire frame and solid shapes which are fully user definable.
  • Progress bar (with various options including vertical and horizontal
  • Cycle text box (use a String array for list of options)
  • Image button (multiple option image button - normal image, click image and alternative image)

Version history:

Version 0.10 is the initial release giving:
Hardware support:

  • UTFT
  • Touch
  • SPI EEPROM
  • CTE UTFT shield (or alternative)

Interrupt driven GUI environment with the following Objects.

  • Panel (Box with options for text size, colour and location. Options for border and background colour.)
  • Label (Simple text placed on screen with options for colour, size, location etc
  • Button (All the options of Panel and Label plus options to make the button change colour as pressed etc
  • Check boxes ( traditional box, y/n, yes/no
  • Cycle box (each click cycles through a range of numerical values)
  • Analogue clock (with several variations and options all of which automatically update)
  • Digital time label (with options and automatically updating)
  • Digial date label (with options and automatically updating)
  • Text input (with options of a panel with label and box or simple text)
  • Graphical image (from EEPROM or data at the moment but from SDcard soon
  • Shape (wire frame and solid shapes which are fully user definable.

Version 0.11

Several minor bug fixes
addition of object - Progress bar (vertical and horizontal with option of automatic change in colour for parts of the bar over a certain value)

Version 0.12

Bug fixes:

  • FIXED: Popup keyboard debounce added and working.
  • FIXED: On occasion screen goes haywire when analogue clock drawn.
  • FIXED: Spurious values from calibration screen sometimes appear on the main menu.

Changes:

  • ADDITION: showCalibration() - This shows the calibration screen with no further code with a new "SAVE" button which will soon write the calibration data to a special data sector within the EEPROM of the screen.
  • CHANGE: Addition of two new functions HandleShowButtons(int URN) & HandleShowLoopStuff() - these functions pass control to the library during the loop function and button handler allowing the library to create it's own objects and handle them.
  • CHANGE: Removal of the calibration screen code from the demo program and switch to using the showCalibration() function which does the same thing.

Version 0.13

Changes:

  • ADDITION: Object - Image Button - with optional click image and alt image for on-off-on type button
  • ADDITION: Object - Cycle text button - like cycle button but you supply a String array for the list.
  • ADDITION: Shape - Line

Well I've mentioned it in other threads but now it is ongoing.

I've merged UTFT, serial Eprom & UTouch (later I will add SD card - this week) - This makes it much easier to create a library that can use and control elements of all 3/4 of the separate libraries and items of hardware.

I've used the CTE version of the UTFT but since then I have added:

void preserveColours(); {saves current foreground and background colours}
void restoreColours(); {restores current foreground and background colours - whilst changing them to do something else}
bool withinBounds(int chkX,int chkY,int X, int Y, int XS, int YS); {simple function checks if coordinate is inside a box}
int numberpad(...); {displays a pop up numeric keypad with decimal point option}
int addButton(...); {adds a button with numerous options, returning the object number}
void drawButton(int buttonnumber); {displays specific button}
bool checkButton(word buttonnumber); {checks whether a specific button is pressed}
int checkAllButtons(); {checks all objects which are buttons and returns object number if one is pressed or -1 if none}
int addPanel(...); {adds a simple panel with border containing specific text with options}
void drawPanel(int objectnumber); {displays specific panel}
int addLabel(...); {adds a label (text) with specific options}
void drawLabel(int objectnumber); {displays specific label}
int addImage(word x,word y,int imageNumber,bool visible); {adds an image from the eeprom or later SD card}
void drawImage(int objectNumber); {displays specific image}
void clearAllObjects(); {clears all object data}
void refreshAllObjects(); {redraw all objects}
void makeObjectInvisible(int objectNumber); {makes specified object invisible}
void makeObjectVisible(int objectNumber); {makes specified object visible}

All up and running and working....

Still need to add lots of other things such as:

Text input
Checkboxes
Radio groups
pop up hex keyboard
pop up alpha keyboard
pop up full keyboard
bar graph
rev counter style display
pop up "press here to continue" type box
pop up YES/NO/Other type box
digital clock
analogue clock
time input
date input

And more as I think of them

It will initially be 100% compatible with the CTE shield and 40 pin 5" & 7" displays. I have worked out the correct pin outs for the 32pin display now as well but want to double check - My 32 pin board's display had a cracked digitiser so I've removed it. I will give the pin outs of the CTE shield so it can be made to work with other displays too but some of the functions rely on their built in EEPROM or an SD card so you will have to pick and choose.

My test sketch currently compiles to 36K but that is with the combined library.

The reason I've posted now is that I would like to discuss what other people would like to see and get their ideas so that this might be a useful library for others too.

So just as an example:

The setup code:

At start of sketch:

#define BVS_13 10
#define BVS_15 12
#define BVS_19 14
#define BVS_22 18
#define BVS_28 22
#define BVS_34 28
#define BVS_43 38
#define BVS_52 53
#define BVS_74 78
#define BVS_112 122

extern uint8_t SmallFont[];

#include "SPI.h"
#include <UTFT.h>
UTFT TFT1(CTE70,25,26,27,28);

In setup:

TFT1.InitLCD();
TFT1.clrScr();
TFT1.setFont(SmallFont);
TFT1.SPI_Flash_init(52,2);
TFT1.UTouch(6,5,32,3,2);
TFT1.InitTouch();
TFT1.setPrecision(PREC_MEDIUM);

Then:

ob0=TFT1.addImage(0,0,287,true);  
ob1=TFT1.addPanel(0,0,799,50,0x0000FF,0xFFFFFF,0xFFFFFF,2,"Board   control   menu",250,8,BVS_34,true);
ob2=TFT1.addButton(50,100,299,50,0x0000FF,0xFFFFFF,0xFFFFFF,0xFF0000,0xFFFFFF,2,"Button 1",50,8,BVS_28,true); 
ob3=TFT1.addButton(50,175,299,50,0x0000FF,0xFFFFFF,0xFFFFFF,0xFF0000,0xFFFFFF,2,"Button 2",50,8,BVS_28,true); 
ob4=TFT1.addButton(50,250,299,50,0x0000FF,0xFFFFFF,0xFFFFFF,0xFF0000,0xFFFFFF,2,"Button 3",50,8,BVS_28,false); 
ob5=TFT1.addButton(50,325,299,50,0x0000FF,0xFFFFFF,0xFFFFFF,0xFF0000,0xFFFFFF,2,"Button 4",50,8,BVS_28,true); 
ob6=TFT1.addButton(49,700,300,50,50,0xFF0000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,2,"<",GUI_singlechar_center_x,GUI_singleline_center_y,GUI_buttonchar_font,true); 
ob7=TFT1.addButton(49,700,400,50,50,0xFF0000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,2,"<",GUI_singlechar_center_x,GUI_singleline_center_y,GUI_buttonchar_font,true); 
ob8=TFT1.addLabel(449,200,0x000000,0xFF00FF,"A String",0,0,BVS_52,true);

This adds to the object list: a large image the size of the whole screen, a panel 50 pixels tall across the top of the screen as a title with the words "Board control menu" in it then four buttons labelled "Button 1" to "Button 4" of which "Button 3" is invisible Plus two small buttons to the right side and some text

eg.

addButton(x,y,xs,ys,colour,borcolour,textcolour,presscolour,presstextcolour,borwidth,top,xo,yo,font,visible);

where:

// word x
// word y
// word xs
// word ys
// long colour
// long borcolour
// long textcolour
// long presscolour
// long presstextcolour
// byte borwidth
// String top
// word xo
// word yo
// int font
// bool visible

Then the command

TFT1.refreshAllObjects();

Displays all the above.

Then in the actual program loop:

found=TFT1.checkAllButtons();
if (found==ob6){
  TFT1.makeObjectVisible(ob4);
  TFT1.makeObjectInvisible(ob5); 
  TFT1.refreshAllObjects();
}

if (found==ob7){
  TFT1.makeObjectVisible(ob5);
  TFT1.makeObjectInvisible(ob4); 
  TFT1.refreshAllObjects();
}

Not very efficient but for testing:

The first line "found=TFT1.checkAllButtons();" checks all the buttons and returns the integer value of the button that was pressed or -1 if none were.

Then we have a check if button ob6 was pressed and if so if makes button ob4 visible, button ob5 invisible and refreshes the screen

Then we have a check if button ob7 was pressed and if so if makes button ob5 visible, button ob4 invisible and refreshes the screen

New additions for today so far:

General functions:

String displayNumFormat(int Num,int len); {returns string of integer limited to length len - used by setObjectTime so far}
void    setObjectTime(int objectNumber,int hh, int mm, int ss);  {sets the string value of the object specific as per the time specified.}
void    setObjectDate(int objectNumber,int yyyy, int month, int day, bool dateNorm, bool dateFour);  {sets the string value of the object specific as per the date specified.  Also allows reversed date format if dateNorm is false uses mm/dd/yyyy.  dateFour sets yy or yyyy}

Objects (in progress):

int     addAnalogueClock(word x,word y,long colour,long textcolour,String top,int xo,int yo,byte timeoptions, int font,bool visible);
void    drawAnalogueClock(int objectNumber);

With the setObjectDate and setObjectTime functions there is no need for a digital clock object anymore.

I'd like to see a slider control.
Up/Down push buttons for incrementing numbers.
Line Charting capability.

My biggest question is, are you able to have everything oriented properly once you initialize an instance of the LCD and Touch? Are the Touch/Graphical coordinate planes identical? Can you display text, graphical primitives, bitmaps and your UI elements without having to call functions to reverse them, mirror them, etc....?

Will your libraries enable us to incorporate an SDFat..and just call bitmaps, jpegs, etc... directly from the SDCard and then display to the LCD, without having to always preload into the CTE Font/Bitmap IC?

Lastly, will your UI elements include some sort of Touch Event? Or will we always have to develop our own system of keeping track of what objects/elements received a Touch when the Touch Controller indicates there is data in the touch queue?

Really interested in your UI framework.

Very essential work you are doing! Looking forward to some screen shots in the future.

ODwyerPW:
I'd like to see a slider control.
Up/Down push buttons for incrementing numbers.
Line Charting capability.

My biggest question is, are you able to have everything oriented properly once you initialize an instance of the LCD and Touch? Are the Touch/Graphical coordinate planes identical? Can you display text, graphical primitives, bitmaps and your UI elements without having to call functions to reverse them, mirror them, etc....?

Will your libraries enable us to incorporate an SDFat..and just call bitmaps, jpegs, etc... directly from the SDCard and then display to the LCD, without having to always preload into the CTE Font/Bitmap IC?

Lastly, will your UI elements include some sort of Touch Event? Or will we always have to develop our own system of keeping track of what objects/elements received a Touch when the Touch Controller indicates there is data in the touch queue?

Really interested in your UI framework.

Very essential work you are doing! Looking forward to some screen shots in the future.

Slider - yes sounds good
up/down push buttons for number - yes also sounds good.
Line Charting capability. - ???
Orientation will be correct because they are using the SAME variables for that :slight_smile:
I already have an object that is an image for the IC I am hoping to have a corresponding image from SDcard function.
An event handler function GUIevent or similar will need to be created in your sketch just like you have setup and loop. Inside the GUIevent will be everything needed to handle the GUI.

I was thinking of another object being a collection of lines in the format angle/length which you can then display at any size and angle

Just writing the functions for drawline(angle, length) function which sounds easy but is actually not! I'm using a 90 integer constant array to store the numbers which will make it very quick and avoid real numbers, cos and sin.

I am hoping to have a version available in maybe a week or so for initial alpha testing. I will just sending a zip of the entire library folder with sketches to avoid installation issues.

This all sounds great, and I really appreciate the effort you are putting into this, but I am having an issue with the CTE implementation for the DUE. I'm using the Arduino Ethernet library, and the call to SPI_Flash_init() completely trashes the ethernet functions. My guess is that it might also have an impact on SD, but I'm not there yet. Seems as if there is some error in the way SPI is implemented in the UTFT library from CTE. I've been using Henning's version on a Mega with ethernet, SD, xBee, DS temp sensors and a 3.2 display for quite a long time. I now have the DUE, the CTE 7-inch display, and the DUE CTE shield. Also can't get the touch functioning correctly. What settings are you using for the UTouch implementaion?

BDinWa:
This all sounds great, and I really appreciate the effort you are putting into this, but I am having an issue with the CTE implementation for the DUE. I'm using the Arduino Ethernet library, and the call to SPI_Flash_init() completely trashes the ethernet functions. My guess is that it might also have an impact on SD, but I'm not there yet. Seems as if there is some error in the way SPI is implemented in the UTFT library from CTE. I've been using Henning's version on a Mega with ethernet, SD, xBee, DS temp sensors and a 3.2 display for quite a long time. I now have the DUE, the CTE 7-inch display, and the DUE CTE shield. Also can't get the touch functioning correctly. What settings are you using for the UTouch implementaion?

Are you using:

myCGLD.UTouch(6,5,4,3,2);

by any chance :smiley:

For some reason the CTE shield uses pin 32 for TP-DIN rather than the 4 that everyone else uses. There are two options you have, one is the make jp10 which connects TP_DIN to pin 4 as well as pin 32 or use the following initiation line:

myCGLD.UTouch(6,5,32,3,2);

That should fix it.

I haven't used ethernet from the CTE yet (but I plan on doing) so I cannot say anything about it other than if it breaks I would be looking to fix it. SDcard library works with it and will be incorporated anyway.

The reason for choosing to use the CTE shield and LCD is that we have a known working starting point. I have build a CTE compatible board as a test for a device I am building (ie it just uses the same pin outs) but using this library should allow anyone to get up and running quickly. I have got the 32 pin and 40 pin 7" TFT devices to work and have a 5" device on route as we speak. Would like to try the smaller ones too.

I am also looking at implementing dual screens

I'm using the correct UTouch settings, but the touch points are not resolving to anything reasonable. I saw in some of your other posts that you had done some tweeking to get it to work correctly, but I could not really collect all the information from several posts to make it work for me.

I'll keep looking for the ethernet issue.

BDinWa:
I'm using the correct UTouch settings, but the touch points are not resolving to anything reasonable. I saw in some of your other posts that you had done some tweeking to get it to work correctly, but I could not really collect all the information from several posts to make it work for me.

I'll keep looking for the ethernet issue.

Watch out for the alpha test version as I have re-written the touch x/y bit anyway.

Well I've been working today so not as much done as I would have liked BUT quite a number of improvements...

Addition of a "changed" flag and a function "refreshChangedObjects()" which allows only changed objects to be re-drawn.

Addition of a variable linked and linked options which allows a button to be linked to another object and automatically modify that object e.g. a button can be set to increment another object so you can create a label with say 100 in it and have two buttons for up and down or implement a reset button for a value etc....

Functions so far:

// store and restore colours (used to make sure colours are not lost whilst drawing an object)
void    preserveColours();
void    restoreColours();

// checks if pixel is within a box
bool    withinBounds(int chkX,int chkY,int X, int Y, int XS, int YS);

// returns string of num with leading zeros
String  displayNumFormat(int Num,int len);

// functions to calculate x and y offsets for certain angle and radius eg clock hands 
int     calculate_x(int angle,int radius);
int     calculate_y(int angle,int radius);

// draw a line from x,y at specified angle and specified length
void    drawAngledLine(int x,int y,int angle,int radius);
  
int     numberpad(word x,word y,long colour,long borcolour,long buttoncolour,long buttonborcolour,long textcolour,long presscolour,long presstextcolour,byte borwidth,boolean fullstop,int input);

//
// function add BUTTON
//
//
// variable			  	stored in	description
//
// word x				[x]					{ location of label x }
// word y				[y]					{ location of label y }
// word xs				[xs]				{ size of the panel x in pixels }
// word ys				[ys]				{ size of the panel y in pixels }
// long colour			[colour]			{ colour of background }
// long borcolour		[borcolour]			{ colour of the border }
// long textcolour		[textcolour]		{ colour of text }
// byte borwidth		[borwidth]			{ width of the border }
// long presscolour		[presscolour]		{ colour of button when pressed }
// long presstextcolour	[presstextcolour]	{ Colour of text in button when pressed }
// String top			[top]				{ text of label }
// int xo				[xo]				{ location of text within the panel x }
// int yo				[yo]				{ location of text within the panel y }
// int font				[font]				{ font for text }
// bool visible   	    [visible]    		{ visibility flag }
// bool changed			[changed]			{ object has changed since drawn or not drawn at all }
//  
int     addButton(word x,word y,word xs,word ys,long colour,long borcolour,long textcolour,long presscolour,long presstextcolour,byte borwidth,String top,word xo,word yo,int font,bool visible);

// draw button
void    drawButton(int buttonnumber);

// check single button
bool    checkButton(word buttonnumber);

// check all buttons and return object number of pressed one (also implement link changes)
int     checkAllButtons();
  
//
// function add PANEL
//
//
// variable			 stored in		  description
//
// word x			[x]				{ location of label x }
// word y			[y]				{ location of label y }
// word xs			[xs]			{ size of the panel x in pixels }
// word ys			[ys]			{ size of the panel y in pixels }
// long colour		[colour]		{ colour of background }
// long borcolour	[borcolour]		{ colour of the border }
// long textcolour	[textcolour]	{ colour of text }
// byte borwidth	[borwidth]		{ width of the border }
// String top		[top]			{ text of label }
// int xo			[xo]			{ location of text within the panel x }
// int yo			[yo]			{ location of text within the panel y }
// int font			[font]			{ font for text }
// bool visible     [visible]    	{ visibility flag }
// bool changed		[changed]		{ object has changed since drawn or not drawn at all }
//
int     addPanel(word x,word y,word xs,word ys,long colour,long borcolour,long textcolour,byte borwidth,String top,int xo,int yo,int font,bool visible);

// draw panel
void    drawPanel(int objectnumber);
    
//
// function add Label
//
//
// variable			  	stored in	description
//
// word x				[x]			{ location of the image x }	
// word y				[y]			{ location of the image y }
// word xs				[x]			{ size of the image x <CALCULATED BY OBJECT INIT ROUTINE> }	
// word ys				[y]			{ size of the image y <CALCULATED BY OBJECT INIT ROUTINE> }	
// int imageNumber		[font]		{ image number from the rom }
// bool visible     	[visible]   { visibility flag }
// bool changed			[changed]	{ object has changed since drawn or not drawn at all }
//
int     addLabel(word x,word y,long colour,long textcolour,String top,int font,bool visible);

// draw label
void    drawLabel(int objectnumber);

//
// function add Image
//
//
// variable			  	stored in	description
//
// word x				[x]			{ location of the image x }	
// word y				[y]			{ location of the image y }
// word xs				[x]			{ size of the image x <CALCULATED BY OBJECT INIT ROUTINE> }	
// word ys				[y]			{ size of the image y <CALCULATED BY OBJECT INIT ROUTINE> }	
// int imageNumber		[font]		{ image number from the rom }
// bool visible     	[visible]   { visibility flag }
// bool changed			[changed]	{ object has changed since drawn or not drawn at all }
//
int     addImage(word x,word y,int imageNumber,bool visible);

// draw image
void    drawImage(int objectNumber);

//
// function add Clock
//
//
// variable		  stored in	description
//
// word x            [x]          		{ location of clock centre x }
// word y            [y]          		{ location of clock centre y }
// word xs           [xs]         		{ radius of whole clock }
// word centresize   [ys]         		{ radius of clock centre point }
// long facecolour   [colour]     		{ colour of clock face }
// long borcolour    [borcolour]  		{ colour of clock border }
// long borwidth     [borwidth]   		{ border width }
// long hourcolour   [textcolour] 		{ colour of hour hand }
// long hourlen      [pressedtextcolour]{ colour of hour hand }
// long mincolour    [xo]         		{ colour of minute hand }
// long minlen       [pressedcolour]    { colour of minute hand }
// long seccolour    [yo]         		{ colour of second hand }
// long seclen       [currentstate]    	{ colour of second hand }
// byte timeoptions  [font]       		{ clock options }
// bool visible      [visible]    		{ visibility flag }
// bool changed	 [changed]		{ object has changed since drawn or not drawn at all }
//
int     addAnalogueClock(word x,word y,word clocksize,word centresize,long facecolour,long borcolour,long hourcolour,int hourlen,long mincolour,int minlen,long seccolour,int seclen,byte borwidth, int options,bool visible);

// draw analogue clock
void    drawAnalogueClock(int objectNumber);

// sets the text of an object to the time specified
void    setObjectTime(int objectNumber,int hh, int mm, int ss);

// sets the text of an object to the specified date
void    setObjectDate(int objectNumber,int yyyy, int month, int day, bool dateNorm, bool dateFour);
  
// clears all the object data eg when clearing the screen and moving on to something else
void    clearAllObjects();

// re-draw everything
void    refreshAllObjects();

// re-draw all objects that have changed
void	  refreshChangedObjects();

// delete object off screen and make the object itself invisible
void    makeObjectInvisible(int objectNumber);

// make object visible and re-draw it.
void    makeObjectVisible(int objectNumber);

You've been busy.

Just an FYI, I fixed the issues with ethernet by changing these 2 defines in UTFT.cpp
#define USE_ARDUINO_SPI_LIBRARY 1
#define USE_NATIVE_SAM3X_SPI 0
It was direct DMA access causing the problem. Not sure why yet.

BDinWa:
You've been busy.

Just an FYI, I fixed the issues with ethernet by changing these 2 defines in UTFT.cpp
#define USE_ARDUINO_SPI_LIBRARY 1
#define USE_NATIVE_SAM3X_SPI 0
It was direct DMA access causing the problem. Not sure why yet.

Thanks, I will bare that in mind when I eventually start playing with an ethernet shield.

Ok just to let you see how simple it is going to be, here is my demo program commented:

This uses just 2 libraries: The DueGUI library and the library for the built in RTC.

The following program displays:

  • a "header" across the top of the screen entitled "Board control menu" with:
  • live date to the left of the header.
  • live digital clock placed on the header.
  • a "check box" button called and titled Testbutton1 with switches between two states "Y" and "N" (options for "true/false" and the traditional box with and without a tick will be added this week)
  • a "cycle button" called and titled Testbutton2 - this is a button that cycles between a range of numbers with user changeable step and direction {I'm just finishing this now hence the number not being lined up correctly yet!). (options for using a user's array of Strings will be added soon)
  • a "button" called "Remove 1&2" which is a standard button which when pressed makes "test button 1" and "test button 2" invisible then disappears itself making another button called "bring back 1&2" visible instead which reverses "Remove 1&2"
  • a "button" called "Refresh" which refreshes the screen
  • an "analogue clock" - (there are already lots of options for how it looks including a second segments, 5 minute segments etc etc )

Once setup the user does not need to update the live clocks or do any programming to get the cycle button or checkbox buttons to work.

Interupts are created by the library are started automatically.

You can see just how to do things with the buttons by looking at the code.

//  Due GUI demo
//

//
// Setup and initialise TFT and Touch
#include <UTFT.h>
UTFT DueGUI(CTE70);   // which is: UTFT TFT1(CTE70,25,26,27,28); 

//
// Setup for the RTC library
#include <rtc_clock.h>
RTC_clock rtc_clock(RC);
char* daynames[]={"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
int hh,mm,ss,dow,dd,mon,yyyy;

// Setup variables for Due GUI

// fast ticks for Due GUI interupt
volatile int l;
volatile int btnFound;

// user variables for objects
int clockDigital,clockDate,clockAnalogue,background,pnlTitle;

// user variables for buttons
int btnTB1;
#define URNTB1 1
int btnTB2; 
#define URNTB2 2 
int btnRemove; 
#define URNRemove 3 
int btnAdd; 
#define URNAdd 4
int btnRefresh; 
#define URNRefresh 5

// user variables for screens

#define main_menu 1

//
//  DueGUI Interupt handler routine
//
void DueGUI_tickHandler()
{
  //
  // We don't want timer called whilst it's being handled.
  //
  DueGUI.stopTimer(TC3_IRQn);
  //
  // routine is called several times per second ie "ticksPerSecond".
  // l is incremented each time and by checking this against "ticksPerSecond"
  // we can make sure that once a second events are only called once per second.
  //
  l+=1;
  //
  // This is the "once per second" event routine.
  //
  if (l==ticksPerSecond){
    // second passed
    l=0;
    if (DueGUI.anyClockVisible) {
      rtc_clock.get_time(&hh,&mm,&ss);
      rtc_clock.get_date(&dow,&yyyy,&mon,&dd);
      DueGUI.setObjectTime(clockDigital,hh,mm,ss);
      DueGUI.setObjectDate(clockDate,dd,mon,yyyy,true,true);
      DueGUI.setObjectTime(clockAnalogue,hh,mm,ss);
      DueGUI.redrawObject(clockDigital);
      DueGUI.redrawObject(clockDate);
      DueGUI.drawHands(clockAnalogue);
    }
  }
  
  if ((DueGUI.dataAvailable()==true) || (DueGUI.anyButtonPressed==true)){
    btnFound=DueGUI.checkAllButtons();
    if (btnFound!=-1){
      DueGUI_OnButtonPress(btnFound);
    }
  }
  
  //
  // Ok interupt handler is finished. 
  //
  TC_GetStatus(TC1, 0);
  DueGUI.restartTimer(TC3_IRQn);
}

//
//  DueGUI On button press routine
//
void DueGUI_OnButtonPress(int btnFound){
  int URN=DueGUI.GUIobject_data1[btnFound];

  if (URN==URNTB1){
  }
  if (URN==URNTB2){
  }
  if (URN==URNRefresh){
    DueGUI.redrawAllObjects();
  }
  if (URN==URNRemove){
    DueGUI.makeObjectInvisible(btnRemove,true); 
    DueGUI.makeObjectInvisible(btnTB1,true);
    DueGUI.makeObjectInvisible(btnTB2,true); 
    DueGUI.makeObjectVisible(btnAdd,true); 
  }
  if (URN==URNAdd){
    DueGUI.makeObjectInvisible(btnAdd,true); 
    DueGUI.makeObjectVisible(btnTB1,true);
    DueGUI.makeObjectVisible(btnTB2,true); 
    DueGUI.makeObjectVisible(btnRemove,true); 
  }
}

//
//  DueGUI display a new screen
//
void DueGUI_createScreen(int screen){
  // First stop interupts whilst we build screen
  DueGUI.stopTimer(TC3_IRQn);
  if (screen==main_menu){
    pnlTitle=DueGUI.addPanel(0,0,799,50,clrBlue,clrWhite,clrWhite,2,"Board   control   menu",280,8,BVS_34,true);
    btnRefresh=   DueGUI.addButton(350,100,120,50,clrBlue ,clrWhite ,clrWhite  ,clrRed     ,clrWhite       ,2       ,"Refresh"       ,20,12,BVS_28,true   ,URNRefresh); 
    btnAdd=       DueGUI.addButton(50 ,250,249,50,clrCyan ,clrWhite ,clrBlack  ,clrRed     ,clrWhite       ,2       ,"Bring back 1&2",50,12,BVS_28,false  ,URNAdd    ); 
    btnRemove=    DueGUI.addButton(50 ,350,249,50,clrGreen,clrWhite ,clrBlack  ,clrRed     ,clrWhite       ,2       ,"Remove  1&2"   ,50,12,BVS_28,true   ,URNRemove ); 
    btnTB1=       DueGUI.addCheckBox(50 ,100,249,50,clrBlue ,clrWhite ,clrWhite  ,clrRed     ,clrWhite       ,2       ,"Test button 1" ,50,12,BVS_28,false,true   ,URNTB1    ); 
    btnTB2=       DueGUI.addCycleButton(50 ,175,249,50,clrBlue ,clrWhite ,clrWhite  ,clrRed     ,clrWhite       ,2       ,"Test button 2" ,50,12,BVS_28,6,3,9,1,true   ,URNTB1    ); 
    clockDigital= DueGUI.addDigitalClock_Time(681,11,clrBlue,clrWhite  ,0      ,BVS_34,true);
    clockDate=    DueGUI.addDigitalClock_Date(15 ,11,clrBlue,clrWhite  ,0      ,BVS_34,true);
    clockAnalogue=DueGUI.addAnalogueClock(500,225,270      ,15        ,clrBlack  ,clrYellow ,clrRed  ,80     ,clrGreen ,90    ,clrWhite ,100   ,15      ,24     ,true);
  }
  // ok draw all the new objects that are supposed to be visible
  DueGUI.redrawAllObjects();
  // we can restart the interupts now
  DueGUI.restartTimer(TC3_IRQn);
};

void setup(){ 
  //
  // Initialise serial on the programming port (this section is for debugging)....
  Serial.begin(115200); Serial.println("\n\nSERIAL CONNECTED AT 115200\n\n");

  //
  // Initialise for RTC
  rtc_clock.init(); rtc_clock.set_time(__TIME__); rtc_clock.set_date(__DATE__);
  
  //
  // Initialise DueGUI, touch, interupts etc etc
  DueGUI.InitGUI(6,5,32,3,2,52,2);
  
  // Display "main_menu" screen
  DueGUI_createScreen(main_menu);
  
 }


void loop(){
  //
  //  Main program control loop
  //
  
  // Do things here :-)

}

The current list of functions:

void InitGUI(byte tclk, byte tcs, byte tdin, byte dout, byte irq,int CS_pin, int Rate);
void preserveColours();
void restoreColours();
void updatingScreen();
void finishedUpdatingScreen();
bool withinBounds(int chkX,int chkY,int X, int Y, int XS, int YS);
String displayNumFormat(int Num,int len);
int calculate_x(int angle,int radius);
int calculate_y(int angle,int radius);
void drawAngledLine(int x,int y,int angle,int radius);
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency);
void stopTimer(IRQn_Type irq);
void restartTimer(IRQn_Type irq);

int addCheckBox(word x,word y,word xs,word ys,long colour,long borcolour,long textcolour,long presscolour,long presstextcolour,byte borwidth,String top,word xo,word yo,int font,int initialstate,bool visible,int URN);
int addCycleButton(word x,word y,word xs,word ys,long colour,long borcolour,long textcolour,long presscolour,long presstextcolour,byte borwidth,String top,word xo,word yo,int font,int initialstate,int cyclemin,int cyclemax,int cyclestep,bool visible,int URN);
int addButton(word x,word y,word xs,word ys,long colour,long borcolour,long textcolour,long presscolour,long presstextcolour,byte borwidth,String top,word xo,word yo,int font,bool visible,int URN);
void drawButton(int buttonnumber);
bool checkButton(word buttonnumber);
int checkAllButtons();

int addPanel(word x,word y,word xs,word ys,long colour,long borcolour,long textcolour,byte borwidth,String top,int xo,int yo,int font,bool visible);
void drawPanel(int objectnumber);

int addLabel(word x,word y,long colour,long textcolour,String top,int font,bool visible);
void drawLabel(int objectnumber);

int addShape(word x,word y,long colour,int type,int a,int b,int c,int d,int e,int f,int g,int h,int i,int j,bool visible);
void drawShape(int objectnumber);

int addImage(word x,word y,int imageNumber,bool visible);
void drawImage(int objectNumber);

int addAnalogueClock(word x,word y,word clocksize,word centresize,long facecolour,long borcolour,long hourcolour,int hourlen,long mincolour,int minlen,long seccolour,int seclen,byte borwidth, int options,bool visible);
void drawAnalogueClock(int objectNumber);
int addDigitalClock_Time(word x,word y,long colour,long textcolour,int options,int font,bool visible);
void drawDigitalClock_Time(int objectNumber);
int addDigitalClock_Date(word x,word y,long colour,long textcolour,int options,int font,bool visible);
void drawDigitalClock_Date(int objectNumber);
void drawHands(int objectNumber);
void drawAnalogueClock_dividers(int objectNumber,int cx,int cy,int inner,int outer,int number,bool lines);
void setObjectTime(int objectNumber,int hh, int mm, int ss);
void setObjectDate(int objectNumber,int yyyy, int month, int day, bool dateNorm, bool dateFour);

void clearAllObjects();
void redrawAllObjects();
void redrawChangedObjects();
void redrawObject(int objectNumber);
void clearObjectArea(int objectNumber);
void makeObjectInvisible(int objectNumber,bool redraw);
void makeObjectVisible(int objectNumber,bool redraw);

Hi and Many thanks for your extensive efforts -

is there any downloadable form or repository where i can download the files for testing and verifying - would be great as you really hit the spot by combining the essential libs to one Gui tooolbox
i'm thinking about an Dali based lighting control with an Due and 5" touch display which i will put on the playgroud once i have everything put together - your toolbox would be very helpfull for this project.

Kind regards, Mike

Michael__MA:
Hi and Many thanks for your extensive efforts -

is there any downloadable form or repository where i can download the files for testing and verifying - would be great as you really hit the spot by combining the essential libs to one Gui tooolbox
i'm thinking about an Dali based lighting control with an Due and 5" touch display which i will put on the playgroud once i have everything put together - your toolbox would be very helpfull for this project.

Kind regards, Mike

I have got checkboxs and a variant of them called cycleboxs working. I am just working on an input box for text and will then release a downloadable version for testing whilst I finish the other planned bits.I have a demo running here that has three pages and allows people to switch between them and keep the variables consistent etc. The input box effectively scrolls up the part of the screen with the input and creates a keyboard across the bottom half of the screen so quite a bit of work... I will also be adding the option of PS2 and bluetooth keyboard support etc but that is for later.......

Hi!
Amazing work, I haven't my Due yet but I can't wait to test that one!
Maybe later we could add a kernel, some drivers, an ethernet shield, and... :stuck_out_tongue:
Ardubian is coming! :stuck_out_tongue:

Thanks!

I have a full qwerty keyboard with number pad very nearly finished. This will be for text input boxes. I am hoping that it will be in a fit state to go out for alpha testing within the week. There are dozens of functions added and a demo program which shows them in action. All the object orientated stuff works via an interrupt which is added by the library so you can even end up with the loop function empty!

Anyway will update with more pictures etc soon.

Well I've had a useful day with the library. There was a bug that was corrupting the variables and causing hours of wasted time but I've fixed it now!

Anyway new additions to the working objects list:

addInputBox !!!
drawInputBox
updateInputBox
updateLabel (automates the sequence.. if variable has changed then remove old value,display new value, update object.
setColorLong (these new colour commands allow setting of a colour using 1 long int in the form 0xFFFFFF where value is 0xRRGGBB
setBackColorLong having it as one value makes it easy to have presets such as clrBlack,clrBlue,clrYellow etc)

This scrolls the screen up so that the object is visible in the top half of the screen and displays a keyboard at the bottom half of the screen. The keyboard is definable with a caps key and a symbol key allowing 3 full 52 key keyboards.

So we are nearing the point where it is alpha testable.....

I need to write a manual for it first but as my code is very heavily remarked that will make it much easier.

There are still parts not finished but I will highlight those in the manual.....

Ok....

This is an ALPHA test version but here is the first downloadable version with early manual:

www.cowasaki.co.uk/DueGUI/DueGUI_manual001.pdf

www.cowasaki.co.uk/DUEGUI_001.zip