Basic Level: Buttons, Labels, and more graphics tools

We will now take the GUI further by introducing ready-made buttons, labels and other components. With this level of the GUI, the application programmer will be able to use arbitrarily sized components which will react properly to touch events without the application code having to handle these issues. However, all such events are funneled through three interrupt routines (touchDownEvent, touchUpEvent, touchMotionEvent) which can be overridden if the application requires a different behavior.


The view structure is now extended with several more attributes. We add a type descriptor, a tag attribute, a short (16 character)  text field, three integers to hold color values,  a "state" indicator and a "flag" variable. The type descriptor is used to indicate the component type (button, label etc). The tag attribute is an integer that can be used by the application to differentiate the views. The text field is used to hold button and label text while the state indicator (an integer)  is used to keep track of the state of a button (on/off) or the current value of a slider or indicator bar. The three color integers are typically used to specify the border, background and foreground colors for buttons and other components. Each color integer is assumed to be 32 bit and contains a packed RGB value. The most significant byte is not used but if the integer value is equal to -1 then that particular color  is not rendered. The flag variable contains the "active" flag which controls whether the component itself is rendered (ACTIVE/INACTIVE) or not (INVISIBLE). Inactive and invisible components are also disconnected from touch events.

One can still use the insertView function when specifying the GUI. However, this function now includes 12 arguments. For this reason "default definition functions" have been added to simplify the GUI specification. For example, instead of making a label by writing

insertView(LABEL, 60,30, 100, 120, 0, "My Label", -1, -1, WHITE, 0, ACTIVE);

for a visible label with white text, no border or background color, of size 60*30 and located at (100,120) we can write,

newLabel(60,30,100,120, "My Label");

which is more intuitive for labels. Of course, this assumes that the default colors for the label are set appropriately. Default definition functions for the other components work accordingly. (The "flag" is set automatically to "ACTIVE" for all new views and is not part of the parameter list of these functions).

Additional graphic tools are included to support the handling of the new components. Here is a list of all the additional functions:


Additional handling of views

newView: inserts a generic view on the view list. Only size and position data are used, all other attributes are set to zero (active flag is set to ACTIVE to enable touch events).

newLabel: inserts a view of type "label" on the view list. It uses default color values as given by the defined Color theme.

newButton: inserts a view of type "button" on the view list. It uses default color values as given by the defined Color theme.

newNumView: inserts a view of type "numview", a simple numeric display. Colors given by Color theme. Displays either the integer attribute "state" or the attribute string "text" if the latter is not the null string.

newGraphicView: inserts a view of type "graphicview", a general graphics view defined by the application. The rendering of this view is defined in the application code.

lastView: a macro that is useful to change the value of an attribute belonging to the most recently defined view.  E.g lastView->fgcolor = RED will set the foreground color to red.


Additional handling of events

touchUpEvent: an interrupt function that is called when the touch is released. Input arguments are the screen coordinates of the touch event,

touchMotionEvent: an interrupt function that is called when there is a motion touch. Input arguments are current screen coordinates.

buttonDownEvent: an interrupt function that is called when a button is touched. Input argument is the pointer to the button view,

buttonUpEvent: an interrupt function that is called when a button is released. Input argument is the pointer to the button view,

viewDownEvent: an interrupt function that is called whenever a view other than a button or a slider is touched. Input arguments are the pointer to the view and local coordinates of the touch event inside the view,

viewUpEvent: an interrupt function that is called whenever a view other than a button or a slider is released. Input arguments are the pointer to the view and local coordinates of the touch event inside the view.

viewMotionEvent: an interrupt function that is called whenever a view other than a slider is touched and moved. Input arguments are the pointer to the view and local coordinates of the touch event inside the view.


Additional graphics functions

fillScreen: a function that fills the entire screen with a given color,

drawBlock: a function that draws a filled square block. Arguments are position, block size and color,

drawLine: a function that draws a line. Arguments are starting and ending positions, line thickness and color,

drawRectangle: a function that draws a rectangle with a given size at a given position, with a given pen thickness and pen color,

drawRoundedRectangle: similar to drawRectangle but with rounded corners and one-pixel border width,  

drawFilledRectangle: a function that draws a filled rectangle with a given size, at a given position and fill color,

drawFilledRoundedRectangle: similar to drawFilledRectangle but with rounded corners,

drawEllipse: a function that draws an ellips with one-pixel border width. The ellipse is defined by its circumscribed rectangle,

drawFilledEllips: a function that draws a filled ellipse defined by its circumscribed rectangle

drawView: a function that renders a view, using its type and attributes to control the rendering. This function overrides the INVISIBLE flag.

drawAllViews:  a function that renders all visible and drawable views,

font5: an array of size 86*35 bytes that holds a 5*7 font of the ISO-Latin characters,

drawChar5: a function that draws a font5 character. Input arguments are the character, screen position, size and color,

drawText: a function that draws a string. Input arguments are the string, screen position, dotsize and color,

fillArea: a function that fills a closed area with a given color. Input arguments are seed location and color,

drawNumView: a function that renders an alfanumeric field using default attributes. Input argument is view pointer,

drawLabel: a function that renders a label using default attributes. Input argument is view pointer,

drawButton: a function that renders a button using default attributes. Input argument is view pointer.

drawGraphicView: a function that is called by drawView and drawAllViews whenever the view is of type graphicview.


Additional support functions

setButtonTheme: a function that redefines the default button colors. Arguments are pen color, background color and foreground color.

setLabelTheme: a function that redefines the default label colors. Arguments are pen color, background color and foreground color.

setNumViewTheme: a function that redefines the default numview colors. Arguments are pen color, background color and foreground color.

intToString: a function that converts an integer into string representation.

sqr: a function that computes the square-root of a float. This is to avoid having to include the math library.


Altogether, about 850 lines of C code are required to implement this level (version 1.1) of the GUI.


The following components are available:

VIEW: a generic view that does not contain any visible parts. Useful to catch touch events
BUTTON: a button component with centered text
LABEL: a label component for static or dynamic text display. Text is centered in the view
NUMVIEW: similar to LABEL but with a different color theme. The number characters fill up the whole view height and are right justified
GRAPHICVIEW: similar to VIEW but is visible through an application-specific draw function



How to use these functions in an application

The first example (Polyview) is taken from a Stanford iPhone course home assignment. Here, the screen shows two buttons and a drawing area where a polygon with a variable number of sides is drawn. Labels tell the number of sides, corner angle and polygon type .  Observe that it is not necessary to assign names for all views (see the buttons in this example). The application can instead use the tag or text field to identify them.

The polygon is drawn in its own view and is refreshed every time the view is called to draw itself. Like other views this view is scaled and positioned according to its view parameters. Its background and foreground color attributes are used as well. The number of sides in the polygon is given by the value of the state indicator. In this sense the polygon view can be considered as a new GUI component although it is does not have its own type name.

The GUI part is evident from the main function:


int main(int argc, char *argv[])
{
    // Define GUI
    newButton(120,40,230,190,1,"Increase");
    newButton(120,40,50,190,2, "Decrease");
    newLabel(240,35,50,50, "Number of sides:");
    newLabel(240,35,50,90, "Angles (degrees):");
    newLabel(240,35,50,130, "Polygon type:");
    polysides = newLabel(35,35,250,50, "3");
    polyangles = newLabel(40,35,260,90,"60");
    polytype = newLabel(120,32,210,130,"triangle");
    polyview = newGraphicView(300,300, 50, 260);
        lastView->fgcolor=RED;
        lastView->bgcolor=GREY;
        lastView->stat=3;

    // Start application
    
      initGraphics();
    drawBackground();
    drawAllViews();
    while (!quit)
    {
        eventLoop();
    }
    SDL_Quit();
    return 0;
}






In the next example we show the main function of a simple calculator. Here, the buttons use two different color themes.

int main(int argc, char *argv[])
{
    // GUI definition

    screenview = newLabel(400,600,0,0,"");
    dispframe = newLabel(320,60,40,90,"");
        lastView->bgcolor = LIGHTGREY;
    textarea = newAlfanumfield(300,40,50,100,"");
    setButtonTheme(WHITE,BLACK,SHADEWHITE);
    newButton(60,50,50,230,1, "1");
    newButton(60,50,125,230,2, "2");
    newButton(60,50,200,230,3, "3");
    newButton(60,50,50,300,4, "4");
    newButton(60,50,125,300,5, "5");
    newButton(60,50,200,300,6, "6");
    newButton(60,50,50,370,7, "7");
    newButton(60,50,125,370,8, "8");
    newButton(60,50,200,370,9, "9");
    newButton(60,50,125,440,0, "0");
    setButtonTheme(WHITE,GREY,SHADEWHITE);
    newButton(60,50,50,440,15, "C");
    newButton(60,50,200,440,10, ".");
    newButton(70,50,280,230,11, "+");
    newButton(70,50,280,300,12, "-");
    newButton(70,50,280,370,13, "*");
    newButton(70,50,280,440,14, "/");
    newLabel(320,30,40,520,"CALCULATOR 3");

    // Start application
    
      initGraphics(); // Initiate graphics
    drawRectangle(390,590,5,5,1,WHITE); // just for decoration
    drawRoundedRectangle(350,550,25,30, LIGHTGREY); // just for decoration
    fillView(dispframe, LIGHTGREY); // Make a frame for the textview window
    drawAllViews(); // Draw all visible components

    clear();
    
    while (!quit)
    {
        eventLoop();
    }
    
    SDL_Quit();
 
    return 0;
}









This site is © Copyright Robert Forchheimer 2011-2012, All Rights Reserved.
1. Home
2. Introduction
3. Simple level
4. Basic level
5. Extensions
Downloads
Guestbook