|
|
Adding
new
GUI components to TouchableViews
A
component is defined
by its graphical appearance and its behavior when the user or the
application interacts with it. If only a single instance is needed than
it is not necessary to define a new component type. Instead, the
component can be implemented from the general View type as was done in
the polygon view example above. However, if the new component is going
to be instantiated several times in the application or be used in
different applications than it is recommended to add it to the standard
list of components.
A number
of functions
and modifications are necessary to integrate a new component into
TouchableVIews. It is advisable to check out the current available
components as their implementation follow the scheme below:
1)
newMyComponent: a
function that generates a view instance of type MyComponent and puts it
in the view list. This function also sets default values of attributes
if applicable.
2)
drawMyComponent: a
function that draws the view of MyComponent, taking into account the
value of color and state attributes.
If the
component shall
react to touch events, then it will be necessary to also define one or
more event handlers (cp. the event handlers for buttons):
3)
myComponentDownEvent: an interrupt function that is called whenever the
user touches the component.
4)
myComponentUpEvent:
an interrupt function that is called whenever the user untouches the
component.
5)
myComponentsMotionEvent: an interrupt function that is called whenever
the user touches and moves the view.
Finally,
some
modifications to the current code are necessary:
6) Add a
macro that
associates an unique component number with your component. It may look
like: #define MYCOMPONENT 17
7) If your
component
also reacts to events, modify the functions touchDownEvent,
touchUpEvent and touchMotionEvents so that they call
"myComponentDownEvent" and/or "myComponentUpEvent" and/or
"myComponentMotionEvent" for your component type, making changes to the
attributes (such as the state variable) if necessary.
8) Add
your component
to the drawView-function.
Examples:
Meters and Sliders
Here, we
introduce two
more components:
METER: an
output
device for analog values. This component is either of vertical (VMETER)
or horizonal (HMETER) type.
SLIDER: an
input
device for analog values, This component is either of vertical
(VSLIDER) or horizontal (HSLIDER) type.
Meters are
output
devices which show numeric data graphically as a vertical or horizontal
"analog bar". The actual digital value is optionally displayed
alongside the bar. The stat-variable of these components holds not only
the actual value but also the range given by the maximum and minimum
value. Similarly, Sliders also come in vertical and horizontal
versions. These are analog input devices controlled by touching and
moving the slider handle along the slider.
Additional
graphics
functions are:
drawVMeter:
a function
that renders a vertical scale indicator using default attributes. Input
argument is a view pointer,
drawHMeter:
a function
that renders a horizontal scale indicator using default attributes.
Input argument is a view pointer,
drawVSlider:
a
function that renders a vertical slider using default attributes. Input
argument is a view pointer,
drawHSlider:
a
function that renders a horizontal slider using default attributes.
Input argument is a view pointer.
Additional
support
functions are:
newVMeter:
inserts a
view of type "vertical meter", an analog indicator. Arguments are max,
min and value. Colors are given by Color theme,
newHMeter:
inserts a
view of type "horizontal meter", an analog indicator.Arguments are max,
min and value. Colors are given by Color theme,
newVSlider:
inserts a
view of type "vertical slider", an analog input device. Arguments are
max, min and value,
newHSlider:
inserts a
view of type "horizontal slider", an analog input device. Arguments are
max, min and value,
setMeterTheme:
a
function that redefines the default scale indicator colors. Arguments
are pen color, background color and foreground color.
setMeterValue:
a
function that sets the value attribute of an indicator scale. Input
parameters are view pointer and (integer) value,
setSliderValue:
a
function that sets the value attribute of a slider. Input parameters
are view pointer and (integer) value.
Altogether,
less than
1200 lines of C code are used to implement the this level (version 1.3)
of the GUI including the Meter and the Slider components.
Tips
and tricks
TouchableViews
is
mainly designed for static screen appearances. Icons which move around
and screen contents that change from one appearance to another is not
supported directly. However, with some tricks it is also possible to
achieve such functions as well.
An
important property
is that all views are stored in the view list in the order they are
defined. This is also the order in which they are rendered by the
drawAllViews function. This has the effect that a view that covers
another view will be overlayed on that other view. Additionally, the
application program itself can change the order of the rendering of the
components by individually calling the drawView function.
A similar
mechanism is
true for the event sensing. The view list is parsed and the last
component that incorporates the touch position is reported to the
touchDownEvent or touchUpEvent routines. The drawing order and the
event sensing order can be disconnected from each other by placing an
invisible view on top of one or more views in the GUI definition. The
invisible view will then catch the event rather than the visible views.
The
"active" flag is
also a very helpful tool to use. Setting this flag to INVISIBLE will
make the component both invisible as well as not touch sensitive.
"Pop-up" components or groups of components can be implemented through
the use of this flag.
Since all
views have
the same basic structure, it is easy to change the function of one view
to mimic another. As an example, to implement a rectangular button
(instead of one with rounded corners) a label can be used and the touch
event sensed through the "viewDownEvent" function.
A "toggle
button" (aka
On-Off button) can be implemented from a regular button by forcing it
back to the on-state in the buttonUpEvent-routine followed by a
drawView call to re-render the button. This is e.g. used in the
Calculator-3 example.
By setting the button background color to "invisible", a background
motif such as a graphical symbol or picture can be used for the button
background. See the "sqrt_app" for an example. Observe that a
minor modification needs to be done in the button code (version 1.3 or
lower).
A
component, or a
group of components can be "shielded" from touch events by putting a
generic View component on top of the group. Touching anywhere within
the new view will then invoke the "viewDownEvent" , "viewUpEvent" and
"viewMotionEvent" functions directly.
In
addition to the
above, the application may build its own separate lists of components
belonging to different screen appearances, both for rendering and for
event handling.
Example:
A
simple GUI editor implemented in TouchableViews

This site is © Copyright Robert Forchheimer
2011-2012, All Rights Reserved.
|
|
|