Difference between revisions of "Widgets"

From uGFX Wiki
Jump to: navigation, search
(Custom render interface)
(Custom render interface)
 
(42 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''''Note:''' Make sure you read the [[Windows|window]] article first!''
+
'''''Note:''' Make sure you read the article about [[Windows|windows]] first!''
  
The widget class is based on the window. In addition to the window functionalities, it implements the following features:
+
The widget class is based on the [[Windows|window class]]. In addition to the window functionalities, it implements the following features:
  
 +
* Widgets have a text
 
* Widgets can always redraw themselves
 
* Widgets can always redraw themselves
 
* Widgets are able to accept user input such as from a touchscreen/toggle/dial/keyboard
 
* Widgets are able to accept user input such as from a touchscreen/toggle/dial/keyboard
 
* Widgets can have their drawing routine overwritten to provide fancier versions of the object. For example, their are predefined drawing routines for round buttons, image buttons, arrow buttons etc. along with the normal button drawing routine.
 
* Widgets can have their drawing routine overwritten to provide fancier versions of the object. For example, their are predefined drawing routines for round buttons, image buttons, arrow buttons etc. along with the normal button drawing routine.
* Widgets support a "style". By changing the style you can affect the colors used to draw the widget similar to the way you can apply color schemes in Windows and Linux.
+
* Widgets support a "style". By changing the style you can affect the colors used to draw the widget similar to the way you can apply color schemes in Windows and Linux. See [[Widgets#Widget_Style|Widget Style]].
A list with descriptions of the common container API can be found [http://ugfx.org/images/resources/doxygen/master/group___widget.html here].
+
 
 +
== API reference ==
 +
The generic widget API reference can be found [http://api.ugfx.org/group___widget.html here].
  
 
== Initialization ==
 
== Initialization ==
If widgets are used, a default font and a default styling have to be selected:
+
If widgets are used, a default font and a default styling have to be set:
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
gwinSetDefaultFont(gdispOpenFont("DejaVu Sans 16"));  // Select your font
+
gwinSetDefaultFont(gdispOpenFont("DejaVu Sans 16"));  // Set default font
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);        // Select the widget style
+
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);        // Set default widget style
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
A widget will always use the current default font/style unless a font/style has been assigned explicitly using <code>gwinSetFont()</code> / <code>gwinSetStyle()</code>.
 +
 +
Note that both fonts and styles can be changed during runtime.
  
 
== Widget creation ==
 
== Widget creation ==
Line 33: Line 39:
 
<code>gwinDestroy()</code> can be used to destroy a window that is no longer needed.
 
<code>gwinDestroy()</code> can be used to destroy a window that is no longer needed.
  
== Custom render interface ==
+
== Focus ==
Every widget comes with a custom render interface. The default style in which a widget is drawn is very basic and minimalistic in order to make it run on the even lowest performance systems smoothly. However, the custom render interface allows you to submit your own rendering routines. This does not only provide a very flexible way to render a widget matching to your systems performance, but it gives you also the possibility to render a widget matching your applications style.
+
Widgets become focusable when a keyboard is used (either a physical one through the [[GINPUT]] module or a virtual on-screen one using the [[Keyboard|keyboard widget]]. A widget in focus will receive the keyboard events. Focus can be changed by either directly clicking on the widget (eg. by using the touchscreen or a mouse) or by using the <code>TAB</code> key on the keyboard. Note that for code-size and performance reasons it's currently only possible to loop forward.
  
Every widget provides an API call like the the following:
+
Most widgets come with default keyboard handlers. For example, the [[PushButton]] widget can be clicked by using the <code>SPACE</code> or <code>RETURN</code> key, [[List|lists]] can be scrolled using the arrow keys and so on.
  
<syntaxhighlight lang=c>void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param);</syntaxhighlight>
+
== Widget Style ==
The CustomWidgetDrawFunction is a typedef'ed function pointer:
+
The GWIN module provides a simple implementation of widget styles. The widget style allows to change the look of a widget.
 +
Currently the widget style is just a struct of different colors. However, for the future it would be possible to add additional parameters to the widget style.
 +
The widget style contains the same set of colors multiple times but for different states of the widget.
  
<syntaxhighlight lang=c>typedef void (*CustomWidgetDrawFunction)(struct GWidgetObject *gw, void *param);</syntaxhighlight>
+
'''Note:''' If you need more control over how a widget is rendering have a look at [[Widgets#Custom_render_interface|Custom Rendering Interface]].
The param parameter can be used to pass a custom parameter such as a file pointer. However, in most of the cases, this parameter will be '''NULL'''.
+
  
All the information required to write a custom render function for a widget, such as the position, size, state, text, fonts etc. can be obtained from the [[GHandle]].
+
The widget style struct looks like this (pseudo-code):
 +
<syntaxhighlight lang=c>
 +
WidgetStyle {
 +
Widget background color
 +
Focus highlight border color
  
'''''Note:''' The pointer to the custom rendering routine can also be passed through the initialization struct. See above.''</br>
+
// Colors for when the widget is enabled
'''''Note:''' Do never use the <code>gwinDrawXxx()</code> calls inside a rendering routine as this would lock the widget again. Use <code>gdispDrawXxx()</code> instead ''
+
{
 +
Text Color
 +
Edge Color
 +
Fill Color
 +
Progress Color
 +
}
  
== API reference ==
+
// Colors for when the widget is disabled
The generic widget API reference can be found [http://ugfx.org/images/resources/doxygen/master/group___widget.html here].
+
{
 +
Text Color
 +
Edge Color
 +
Fill Color
 +
Progress Color
 +
}
 +
 
 +
// Colors for when the widget is pressed
 +
{
 +
Text Color
 +
Edge Color
 +
Fill Color
 +
Progress Color
 +
}
 +
}
 +
</syntaxhighlight>
 +
 
 +
The real implementation of the widget styles looks like this:
 +
<syntaxhighlight lang=c>
 +
/**
 +
* @brief The GColorSet structure
 +
*/
 +
typedef struct GColorSet {
 +
    color_t      text;        /* The text color */
 +
    color_t      edge;        /* The edge color */
 +
    color_t      fill;        /* The fill color */
 +
    color_t      progress;    /* The color of progress bars */
 +
} GColorSet;
 +
 
 +
/**
 +
* @brief The GWidgetStyle structure
 +
* @details A GWidgetStyle is a set of colors that together form a "style".
 +
* These colors should not be confused with the GWindow foreground
 +
* and background colors which are used for drawing operations.
 +
*/
 +
typedef struct GWidgetStyle {
 +
    color_t      background;  /* The window background color */
 +
    color_t      focus;        /* The color when a widget is focused */
 +
    GColorSet    enabled;      /* The colors when enabled */
 +
    GColorSet    disabled;    /* The colors when disabled */
 +
    GColorSet    pressed;      /* The colors when pressed */
 +
} GWidgetStyle;
 +
</syntaxhighlight>
 +
 
 +
Therefore, a widget style can be created like this:
 +
<syntaxhighlight lang=c>
 +
const GWidgetStyle MyCustomStyle = {
 +
HTML2COLOR(0xFFFFFF), // window background
 +
HTML2COLOR(0x2A8FCD), // focused
 +
 
 +
// enabled color set
 +
{
 +
HTML2COLOR(0x000000), // text
 +
HTML2COLOR(0x404040), // edge
 +
HTML2COLOR(0xE0E0E0), // fill
 +
HTML2COLOR(0x00E000) // progress - active area
 +
},
 +
 
 +
// disabled color set
 +
{
 +
HTML2COLOR(0xC0C0C0), // text
 +
HTML2COLOR(0x808080), // edge
 +
HTML2COLOR(0xE0E0E0), // fill
 +
HTML2COLOR(0xC0E0C0) // progress - active area
 +
},
 +
 
 +
// pressed color set
 +
{
 +
HTML2COLOR(0x404040), // text
 +
HTML2COLOR(0x404040), // edge
 +
HTML2COLOR(0x808080), // fill
 +
HTML2COLOR(0x00E000) // progress - active area
 +
}
 +
};
 +
</syntaxhighlight>
 +
 
 +
=== Applying styles ===
 +
A widget style can either be applied to an individual widget using <code>gwinSetStyle()</code> or it can be set as the default style for all widgets that did not receive a specific widget style using <code>gwinSetDefaultStyle()</code>
 +
 
 +
=== Built-In styles ===
 +
GWIN comes with the following built-in widget styles:
 +
* WhiteWidgetStyle
 +
* BlackWidgetStyle
 +
 
 +
== Text ==
 +
The text of a widget can be accessed through <code>gwinSetText()</code> and <code>gwinGetText()</code>. Additionally, <code>gwinPrintg()</code> is available which is a wrapper around <code>printg()</code> that allows setting the text of a widget using the common well known <code>printf()</code> syntax.
 +
 
 +
== Custom render interface ==
 +
Every widget provides a custom render interface. This simple and easy to use interface allows to overwrite the default rendering of the widget and render each widget as want. This is what you're looking for if you want to improve the look of your GUI. See [[Creating a custom rendering routine]].
 +
 
 +
== Tag ==
 +
If <code>GWIN_WIDGET_TAGS</code> is set to <code>TRUE</code> in the [[configuration|configuration file]], an additional parameter is added to the widget object: The widget tag. The widget tag is an <code>uint16_t</code> and it allows the user to give a widget a numeric ID. The tag can be accessed via <code>gwinSetTag()</code> and <code>gwinGetTag()</code>.
 +
Widget tags are useful to identify a widget without knowing its type.
  
 
== Widget implementations ==
 
== Widget implementations ==
Line 60: Line 168:
 
* [[Slider]]
 
* [[Slider]]
 
* [[Progressbar]]
 
* [[Progressbar]]
* [[Tabs]]
 
 
* [[ImageBox]]
 
* [[ImageBox]]
 +
* [[List]]
 +
* [[TextEdit]]
 +
* [[Keyboard]]
  
  
  
 
[[Category:GWIN]]
 
[[Category:GWIN]]

Latest revision as of 11:19, 27 July 2016

Note: Make sure you read the article about windows first!

The widget class is based on the window class. In addition to the window functionalities, it implements the following features:

  • Widgets have a text
  • Widgets can always redraw themselves
  • Widgets are able to accept user input such as from a touchscreen/toggle/dial/keyboard
  • Widgets can have their drawing routine overwritten to provide fancier versions of the object. For example, their are predefined drawing routines for round buttons, image buttons, arrow buttons etc. along with the normal button drawing routine.
  • Widgets support a "style". By changing the style you can affect the colors used to draw the widget similar to the way you can apply color schemes in Windows and Linux. See Widget Style.

API reference

The generic widget API reference can be found here.

Initialization

If widgets are used, a default font and a default styling have to be set:

gwinSetDefaultFont(gdispOpenFont("DejaVu Sans 16"));   // Set default font
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);         // Set default widget style

A widget will always use the current default font/style unless a font/style has been assigned explicitly using gwinSetFont() / gwinSetStyle().

Note that both fonts and styles can be changed during runtime.

Widget creation

Each widget provides a creation call with is named gwinXxxCreate() where Xxx is the name of the widget. The first parameter is either a pointer to a static widget object or NULL. If NULL, the object will be allocated dynamically from the heap. The second parameter is a pointer to a GWidgetInit struct. This struct contains all the attributes which are needed to create the widget (position, size, font, colors...):

typedef struct GWidgetInit {
    GWindowInit                g;			// The GWIN initializer
    const char*                text;			// The initial text
    CustomWidgetDrawFunction   customDraw;		// A custom draw function - use NULL for the standard
    void*                      customParam;		// A parameter for the custom draw function (default = NULL)
    const GWidgetStyle*        customStyle;		// A custom style to use - use NULL for the default style
} GWidgetInit;

As the widget class is based on the window class, the widget initialization structure contains a window initialization structure. See window creation to learn more about the window initialization structure.
Examples on how to use this struct correctly can be found on each widget documentation page.

gwinDestroy() can be used to destroy a window that is no longer needed.

Focus

Widgets become focusable when a keyboard is used (either a physical one through the GINPUT module or a virtual on-screen one using the keyboard widget. A widget in focus will receive the keyboard events. Focus can be changed by either directly clicking on the widget (eg. by using the touchscreen or a mouse) or by using the TAB key on the keyboard. Note that for code-size and performance reasons it's currently only possible to loop forward.

Most widgets come with default keyboard handlers. For example, the PushButton widget can be clicked by using the SPACE or RETURN key, lists can be scrolled using the arrow keys and so on.

Widget Style

The GWIN module provides a simple implementation of widget styles. The widget style allows to change the look of a widget. Currently the widget style is just a struct of different colors. However, for the future it would be possible to add additional parameters to the widget style. The widget style contains the same set of colors multiple times but for different states of the widget.

Note: If you need more control over how a widget is rendering have a look at Custom Rendering Interface.

The widget style struct looks like this (pseudo-code):

WidgetStyle {
	Widget background color
	Focus highlight border color
 
	// Colors for when the widget is enabled
	{
		Text Color
		Edge Color
		Fill Color
		Progress Color
	}
 
	// Colors for when the widget is disabled
	{
		Text Color
		Edge Color
		Fill Color
		Progress Color
	}
 
	// Colors for when the widget is pressed
	{
		Text Color
		Edge Color
		Fill Color
		Progress Color
	}
}

The real implementation of the widget styles looks like this:

/**
 * @brief	The GColorSet structure
 */
typedef struct GColorSet {
    color_t      text;         /* The text color */
    color_t      edge;         /* The edge color */
    color_t      fill;         /* The fill color */
    color_t      progress;     /* The color of progress bars */
} GColorSet;
 
/**
 * @brief	The GWidgetStyle structure
 * @details	A GWidgetStyle is a set of colors that together form a "style".
 * 		These colors should not be confused with the GWindow foreground
 * 		and background colors which are used for drawing operations.
 */
typedef struct GWidgetStyle {
    color_t      background;   /* The window background color */
    color_t      focus;        /* The color when a widget is focused */
    GColorSet    enabled;      /* The colors when enabled */
    GColorSet    disabled;     /* The colors when disabled */
    GColorSet    pressed;      /* The colors when pressed */
} GWidgetStyle;

Therefore, a widget style can be created like this:

const GWidgetStyle MyCustomStyle = {
	HTML2COLOR(0xFFFFFF),			// window background
	HTML2COLOR(0x2A8FCD),			// focused
 
	// enabled color set
	{
		HTML2COLOR(0x000000),		// text
		HTML2COLOR(0x404040),		// edge
		HTML2COLOR(0xE0E0E0),		// fill
		HTML2COLOR(0x00E000)		// progress - active area
	},
 
	// disabled color set
	{
		HTML2COLOR(0xC0C0C0),		// text
		HTML2COLOR(0x808080),		// edge
		HTML2COLOR(0xE0E0E0),		// fill
		HTML2COLOR(0xC0E0C0)		// progress - active area
	},
 
	// pressed color set
	{
		HTML2COLOR(0x404040),		// text
		HTML2COLOR(0x404040),		// edge
		HTML2COLOR(0x808080),		// fill
		HTML2COLOR(0x00E000)		// progress - active area
	}
};

Applying styles

A widget style can either be applied to an individual widget using gwinSetStyle() or it can be set as the default style for all widgets that did not receive a specific widget style using gwinSetDefaultStyle()

Built-In styles

GWIN comes with the following built-in widget styles:

  • WhiteWidgetStyle
  • BlackWidgetStyle

Text

The text of a widget can be accessed through gwinSetText() and gwinGetText(). Additionally, gwinPrintg() is available which is a wrapper around printg() that allows setting the text of a widget using the common well known printf() syntax.

Custom render interface

Every widget provides a custom render interface. This simple and easy to use interface allows to overwrite the default rendering of the widget and render each widget as want. This is what you're looking for if you want to improve the look of your GUI. See Creating a custom rendering routine.

Tag

If GWIN_WIDGET_TAGS is set to TRUE in the configuration file, an additional parameter is added to the widget object: The widget tag. The widget tag is an uint16_t and it allows the user to give a widget a numeric ID. The tag can be accessed via gwinSetTag() and gwinGetTag(). Widget tags are useful to identify a widget without knowing its type.

Widget implementations

These are the currently implemented widgets: