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.
1. Home
2. Introduction
3. Simple level
4. Basic level
5. Extensions
Downloads
Guestbook