|
|
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.
|
|
|