ugfx/src/gwin/gwin_widget.h

458 lines
14 KiB
C

/*
* This file is subject to the terms of the GFX License. If a copy of
* the license was not distributed with this file, you can obtain one at:
*
* http://ugfx.io/license.html
*/
/**
* @file src/gwin/gwin_widget.h
* @brief GWIN Widgets header file.
*
* @defgroup Widget Widget
* @ingroup Widgets
*
* @brief The basic widget implementation (base class).
*
* @details A widget is a Window that supports interacting with the user
* via an input device such as a mouse or toggle buttons. It is the
* base class for widgets such as buttons and sliders.
*
* @pre GFX_USE_GWIN and GWIN_NEED_WIDGET must be set to GFXON in your gfxconf.h
* @{
*/
#ifndef _GWIDGET_H
#define _GWIDGET_H
/* This file is included within "src/gwin/gwin.h" */
// Forward definition
struct GWidgetObject;
/**
* @brief The GColorSet structure
* @{
*/
typedef struct GColorSet {
gColor text; /**< The text color */
gColor edge; /**< The edge color */
gColor fill; /**< The fill color */
gColor 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 {
gColor background; /**< The window background color */
gColor 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;
/** @} */
/**
* @brief We define a couple of GWidgetStyle's that you can use in your
* application. The Black style is the default style if you don't
* specify one.
* @note BlackWidgetStyle means that it is designed for a Black background.
* Similarly WhiteWidgetStyle is designed for a White background.
* @{
*/
extern const GWidgetStyle BlackWidgetStyle;
extern const GWidgetStyle WhiteWidgetStyle;
/** @} */
/**
* @brief Defines a custom drawing function for a widget
*/
typedef void (*CustomWidgetDrawFunction)(struct GWidgetObject *gw, void *param);
/**
* @brief Defines a the type of a tag on a widget
*/
typedef gU16 WidgetTag;
/**
* @brief The structure to initialise a widget.
*
* @note Some widgets may have extra parameters.
* @note If you create this structure on the stack, you should always memset
* it to all zero's first in case a future version of the software
* add's extra fields. Alternatively you can use @p gwinWidgetClearInit()
* to clear it.
* @note The text element must be static string (not stack allocated). If you want to use
* a dynamic string (eg a stack allocated string) use NULL for this member and then call
* @p gwinSetText() with useAlloc set to gTrue.
*
* @{
*/
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 */
#if GWIN_WIDGET_TAGS || defined(__DOXYGEN__)
WidgetTag tag; /**< The tag to associate with the widget */
#endif
} GWidgetInit;
/** @} */
/**
* @brief The GWIN Widget structure
* @note A widget is a GWIN window that accepts user input.
* It also has a number of other properties such as its ability
* to redraw itself (a widget maintains drawing state).
* @note Do not access the members directly. Treat it as a black-box and use the method functions.
*
* @{
*/
typedef struct GWidgetObject {
GWindowObject g; /**< This is still a GWIN */
const char * text; /**< The widget text */
CustomWidgetDrawFunction fnDraw; /**< The current draw function */
void * fnParam; /**< A parameter for the current draw function */
const GWidgetStyle * pstyle; /**< The current widget style colors */
#if GWIN_WIDGET_TAGS || defined(__DOXYGEN__)
WidgetTag tag; /**< The widget tag */
#endif
} GWidgetObject;
/** @} */
/**
* A comment/rant on the above structure:
* We would really like the GWindowObject member to be anonymous. While this is
* allowed under the C11, C99, GNU and various other standards which have been
* around forever - compiler support often requires special flags e.g
* gcc requires the -fms-extensions flag (no wonder the language and compilers have
* not really progressed in 30 years). As portability is a key requirement
* we unfortunately won't use this useful feature in case we get a compiler that
* won't support it even with special flags.
*/
/**
* @brief A Generic GWIN Event
* @note All gwin windows when sending events will either use this structure or a
* structure that is 100% compatible except that it may also have extra fields.
* @note There are currently no GEventGWin listening flags - use 0 as the flags to @p gwinAttachListener()
*
* @{
*/
typedef struct GEventGWin {
GEventType type; /**< The type of this event */
GHandle gwin; /**< The gwin window handle */
#if GWIN_NEED_WIDGET && GWIN_WIDGET_TAGS
WidgetTag tag; /**< The tag (if applicable) */
#endif
} GEventGWin;
/** @} */
/**
* @brief The list of predefined GWIN events.
* @note The definition of an event type does not mean it is always sent. For example,
* close events are sent by Frame windows but by little else. They are normally
* only sent if there is a specific reason that the event should be sent.
* @{
*/
#define GEVENT_GWIN_OPEN (GEVENT_GWIN_FIRST+0x00)
#define GEVENT_GWIN_CLOSE (GEVENT_GWIN_FIRST+0x01)
#define GEVENT_GWIN_RESIZE (GEVENT_GWIN_FIRST+0x02)
#define GEVENT_GWIN_CTRL_FIRST (GEVENT_GWIN_FIRST+0x40)
/** @} */
/**
* @brief Clear a GWidgetInit structure to all zero's
* @note This function is provided just to prevent problems
* on operating systems where using memset() causes issues
* in the users application.
*
* @param[in] pwi The GWidgetInit structure to clear
*
* @api
*/
void gwinWidgetClearInit(GWidgetInit *pwi);
/**
* @brief Set the default style for widgets created hereafter.
*
* @param[in] pstyle The default style. Passing NULL uses the system compiled style.
* @param[in] updateAll If gTrue then all existing widgets that are using the current default style
* will be updated to use this new style. Widgets that have custom styles different
* from the default style will not be updated.
*
* @note The style must be allocated statically (not on the stack) as only the pointer is stored.
*
* @api
*/
void gwinSetDefaultStyle(const GWidgetStyle *pstyle, gBool updateAll);
/**
* @brief Get the current default style.
*
* @return The current default style.
*
* @api
*/
const GWidgetStyle *gwinGetDefaultStyle(void);
/**
* @brief Set the text of a widget.
*
* @param[in] gh The widget handle
* @param[in] text The text to set. This must be a constant string unless useAlloc is set.
* @param[in] useAlloc If gTrue the string specified will be copied into dynamically allocated memory.
*
* @note The widget is automatically redrawn
* @note Non-widgets will ignore this call.
*
* @api
*/
void gwinSetText(GHandle gh, const char *text, gBool useAlloc);
/**
* @brief Get the text of a widget.
* @return The widget text or NULL if it isn't a widget
*
* @param[in] gh The widget handle
*
* @api
*/
const char *gwinGetText(GHandle gh);
#if (GFX_USE_GFILE && GFILE_NEED_PRINTG && GFILE_NEED_STRINGS) || defined(__DOXYGEN__)
/**
* @brief Set the text of a widget using a printf style format.
* @pre GFX_USE_GFILE, GFILE_NEED_PRINTG and GFILE_NEED_STRINGS must all be GFXON
*
* @param[in] gh The widget handle
* @param[in] fmt The format string using a printf/g syntax. See @p vsnprintg()
* @param[in] ... The printg paramters.
*
* @note The widget is automatically redrawn
* @note Non-widgets will ignore this call.
* @note The memory for the text is always allocated by this function.
*
* @api
*/
void gwinPrintg(GHandle gh, const char * fmt,...);
#endif
/**
* @brief Check whether a handles is a widget handle or not
*
* @param[in] gh The handle to check.
*
* @return gTrue if the passed handle is a widget handle. gFalse otherwise.
*
* @api
*/
gBool gwinIsWidget(GHandle gh);
#if GWIN_WIDGET_TAGS || defined(__DOXYGEN__)
/**
* @brief Set the tag of a widget.
*
* @param[in] gh The widget handle
* @param[in] tag The tag to set.
*
* @note Non-widgets will ignore this call.
*
* @pre Requires GWIN_WIDGET_TAGS to be GFXON
*
* @api
*/
void gwinSetTag(GHandle gh, WidgetTag tag);
/**
* @brief Get the tag of a widget.
* @return The widget tag value (or 0 if it is not a widget)
*
* @param[in] gh The widget handle
*
* @pre Requires GWIN_WIDGET_TAGS to be GFXON
*
* @api
*/
WidgetTag gwinGetTag(GHandle gh);
#endif
/**
* @brief Set the style of a widget.
*
* @param[in] gh The widget handle
* @param[in] pstyle The style to set. This must be a static structure (not allocated on a transient stack).
* Use NULL to reset to the default style.
*
* @note The widget is automatically redrawn
* @note Non-widgets will ignore this call.
*
* @api
*/
void gwinSetStyle(GHandle gh, const GWidgetStyle *pstyle);
/**
* @brief Get the style of a widget.
* @return The widget style or NULL if it isn't a widget
*
* @param[in] gh The widget handle
*
* @api
*/
const GWidgetStyle *gwinGetStyle(GHandle gh);
/**
* @brief Set the routine to perform a custom widget drawing.
*
* @param[in] gh The widget handle
* @param[in] fn The function to use to draw the widget
* @param[in] param A parameter to pass to the widget drawing function
*
* @note The widget is not automatically redrawn. Call @p gwinDraw() to redraw the widget.
* @note Non-widgets will ignore this call.
*
* @api
*/
void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param);
/**
* @brief Attach a Listener to listen for widget events
* @return gTrue on success
*
* @param[in] pl The listener
*
* @api
*/
gBool gwinAttachListener(GListener *pl);
#if (GFX_USE_GINPUT && GINPUT_NEED_MOUSE) || defined(__DOXYGEN__)
gBool DEPRECATED("This call can now be removed. Attaching the mouse to GWIN is now automatic.") gwinAttachMouse(gU16 instance);
#endif
#if (GFX_USE_GINPUT && GINPUT_NEED_TOGGLE) || defined(__DOXYGEN__)
/**
* @brief Attach a toggle to a widget
* @return gTrue on success
*
* @param[in] gh The widget handle
* @param[in] role The function the toggle will perform for the widget
* @param[in] instance The toggle instance
*
* @note See the documentation on the specific widget to see the possible
* values for the role parameter. If it is out of range, this function
* will return gFalse
*
* @api
*/
gBool gwinAttachToggle(GHandle gh, gU16 role, gU16 instance);
/**
* @brief Detach a toggle from a widget
* @return gTrue on success
*
* @param[in] gh The widget handle
* @param[in] role The function the toggle will perform for the widget
*
* @note See the documentation on the specific widget to see the possible
* values for the role parameter. If it is out of range, this function
* will return gFalse
*
* @api
*/
gBool gwinDetachToggle(GHandle gh, gU16 role);
#endif
#if (GFX_USE_GINPUT && GINPUT_NEED_DIAL) || defined(__DOXYGEN__)
/**
* @brief Attach a toggle to a widget
* @return gTrue on success
*
* @param[in] gh The widget handle
* @param[in] role The function the dial will perform for the widget
* @param[in] instance The dial instance
*
* @note See the documentation on the specific widget to see the possible
* values for the role parameter. If it is out of range, this function
* will return gFalse
*
* @api
*/
gBool gwinAttachDial(GHandle gh, gU16 role, gU16 instance);
#endif
#if (GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD) || GWIN_NEED_KEYBOARD || defined(__DOXYGEN__)
/**
* @brief Set the keyboard focus to a specific window
* @return Returns gTrue if the focus could be set to that window
*
* @param[in] gh The window
*
* @note Passing NULL will remove the focus from any window.
* @note Only visible enabled widgets are capable of getting the focus.
*
* @api
*/
gBool gwinSetFocus(GHandle gh);
/**
* @brief Get the widget that is currently in focus
*
* @details The widget that is currently in focus is the widget that
* receives mouse and keyboard events.
*
* @return The handle of the widget that is currently in focus. May be NULL.
*
* @api
*/
GHandle gwinGetFocus(void);
#else
#define gwinGetFocus() (0)
#define gwinSetFocus(gh) (gFalse)
#endif
/* Include extra widget types */
#if GWIN_NEED_BUTTON || defined(__DOXYGEN__)
#include "gwin_button.h"
#endif
#if GWIN_NEED_SLIDER || defined(__DOXYGEN__)
#include "gwin_slider.h"
#endif
#if GWIN_NEED_CHECKBOX || defined(__DOXYGEN__)
#include "gwin_checkbox.h"
#endif
#if GWIN_NEED_RADIO || defined(__DOXYGEN__)
#include "gwin_radio.h"
#endif
#if GWIN_NEED_LABEL || defined(__DOXYGEN__)
#include "gwin_label.h"
#endif
#if GWIN_NEED_LIST || defined(__DOXYGEN__)
#include "gwin_list.h"
#endif
#if GWIN_NEED_PROGRESSBAR || defined(__DOXYGEN__)
#include "gwin_progressbar.h"
#endif
#if GWIN_NEED_KEYBOARD || defined(__DOXYGEN__)
#include "gwin_keyboard.h"
#endif
#if GWIN_NEED_TEXTEDIT || defined(__DOXYGEN__)
#include "gwin_textedit.h"
#endif
#endif /* _GWIDGET_H */
/** @} */