AG_Widget
— agar
user interface element
#include <agar/core.h>
#include <agar/gui.h>
Agar widget classes are described by the following structure:
typedef struct ag_widget_class {
struct ag_object_class _inherit;
void (*draw)(void *obj);
void (*size_request)(void *obj, AG_SizeReq *req);
int (*size_allocate)(void *obj, const AG_SizeAlloc *alloc);
void (*mouse_button_down)(void *obj, AG_MouseButton btn,
int x, int y);
void (*mouse_button_up)(void *obj, AG_MouseButton btn,
int x, int y);
void (*mouse_motion)(void *obj, int x, int y, int dx, int dy);
void (*key_down)(void *obj, AG_KeySym ksym, AG_KeyMod kmod,
AG_Char ch);
void (*key_up)(void *obj, AG_KeySym ksym, AG_KeyMod kmod,
AG_Char ch);
void (*touch)(void *obj, void *inputDevice,
const AG_DriverEvent *event);
void (*ctrl)(void *obj, void *inputDevice,
const AG_DriverEvent *event);
void (*joy)(void *obj, void *inputDevice,
const AG_DriverEvent *event);
} AG_WidgetClass;
The
draw
() method
renders the widget to the graphics display (using GL,
AG_WidgetPrimitives(3)
or other methods). The code under draw
() is referred
to as
rendering
context. Widget primitives and operations such as
AG_WidgetBlitSurface
() must be called only from
rendering context.
size_request
()
should return an initial, preferred geometry in pixels (without any
guarantee that the request will be satisfied). For example, an
AG_Label(3),
might return the expected size of a rendered text label.
size_allocate
()
is called once the widget has been successfully allocated a new size or
position within its parent (as described by the w,
h, x and y
members of the AG_SizeAlloc argument). Container
widgets allocate the position and size of their children in
size_allocate
().
size_allocate
()
should return 0 on success and -1 if the allocation is not satisfactory for
draw
() to work at all (in which case the
UNDERSIZE
flag will be set and
draw
() will not run).
The
mouse_button_down
()
method is invoked if the user presses a button while the cursor is located
at coordinates x, y inside the
widget's local coordinates system.
The
mouse_button_up
()
method is invoked if the user releases a mouse button while the cursor is
located at coordinates x, y
relative to the widget's local coordinates system. The cursor must intersect
the widget (or the widget hold an
AG_WIDGET_UNFOCUSED_BUTTONUP
grab).
The
mouse_motion
()
method is invoked if the user moves the cursor to coordinates
x, y in the widget's local
coordinate system. The widget must hold focus (or hold an
AG_WIDGET_UNFOCUSED_MOTION
grab). The
dx and dy arguments provide the
displacement (in px) relative to the last mouse motion event.
The
key_down
()
and
key_up
()
methods are invoked whenever the user presses or releases a key on the
keyboard. The widget must hold focus (or a
AG_WIDGET_UNFOCUSED_KEYDOWN /
AG_WIDGET_UNFOCUSED_KEYUP
grab).
void
AG_ExpandHoriz
(AG_Widget
*obj);
void
AG_ExpandVert
(AG_Widget
*obj);
void
AG_Expand
(AG_Widget
*obj);
void
AG_WidgetSizeReq
(AG_Widget
*obj, AG_SizeReq
*req);
void
AG_WidgetSizeAlloc
(AG_Widget
*obj, AG_SizeAlloc
*alloc);
void
AG_WidgetSetPosition
(AG_Widget
*obj, int x,
int y);
void
AG_WidgetSetSize
(AG_Widget
*obj, int w,
int h);
void
AG_WidgetSetGeometry
(AG_Widget
*obj, AG_Rect
rect);
void
AG_WidgetUpdate
(AG_Widget
*obj);
void
AG_WidgetUpdateCoords
(AG_Widget
*obj, int x,
int y);
The AG_WIDGET_HFILL
flag hints to
vertically-packing containers that this widget wants to fill any remaining
space along the horizontal axis. AG_WIDGET_VFILL
flag hints to horizontally-packing containers that this widget wants to fill
any remaining space along the horizontal axis.
The
AG_ExpandHoriz
()
and AG_ExpandVert
() functions set
AG_WIDGET_HFILL
and
AG_WIDGET_VFILL
, respectively.
AG_Expand
() is equivalent to calling both
AG_ExpandHoriz
() and
AG_ExpandVert
().
AG_WidgetSizeReq
()
invokes the size_request
() operation of the widget
and returns its size requisition into req.
AG_WidgetSizeAlloc
() allocates the given position
and geometry of the widget. If the w or
h argument is <= 0, the
AG_WIDGET_UNDERSIZE
flag is set, preventing the
widget from subsequent rendering.
AG_WidgetSizeReq
()
and AG_WidgetSizeAlloc
() are meant to be called only
from within the size_request
() and
size_allocate
() functions of a container widget
implementation, in order to size and position the child widgets attached to
the container.
The AG_SizeReq and
AG_SizeAlloc structures are defined as follows:
typedef struct ag_size_req {
int w, h; /* Requested geometry in pixels */
} AG_SizeReq;
typedef struct ag_size_alloc {
int w, h; /* Allocated geometry in pixels */
int x, y; /* Allocated position in pixels */
} AG_SizeAlloc;
AG_WidgetSetPosition
()
sets the effective position of the widget relative to its parent container.
AG_WidgetSetSize
() sets the size of the widget in
pixels. AG_WidgetSetGeometry
() sets both position
and size of a widget from the specified AG_Rect. These
functions are typically only used in the context of the
size_request
() and
size_allocate
() routines of container widgets.
AG_WidgetUpdate
()
requests an update of the computed coordinates and geometries of all widgets
attached to the widget's current window. The widget may or may not be
attached to a parent window (the actual update will be performed later,
before rendering starts in
AG_WindowDraw
()).
AG_WidgetUpdate
() should be called following
AG_ObjectAttach(3)
or
AG_ObjectDetach(3)
calls made in event context, or external modifications to the
x, y, w,
h fields of the AG_Widget
structure.
AG_WidgetUpdateCoords
()
is called internally to update the cached absolute display coordinates (the
rView rectangle) of wid and its
descendents based on their current relative coordinates (the
x, y, w,
h members). The widget and its parent VFS must be
locked.
void
AG_SetStyle
(AG_Widget
*obj, const char
*attr, const char
*value);
void
AG_SetStyleF
(AG_Widget
*obj, const char
*attr, const char
*fmt, ...);
void
AG_SetFontFamily
(AG_Widget
*obj, const char
*family);
void
AG_SetFontSize
(AG_Widget
*obj, const char
*size);
void
AG_SetFontWeight
(AG_Widget
*obj, const char
*weight);
void
AG_SetFontStyle
(AG_Widget
*obj, const char
*style);
void
AG_SetFontStretch
(AG_Widget
*obj, const char
*stretch);
void
AG_SetFont
(AG_Widget
*obj, const AG_Font
*font);
void
AG_SetMargin
(AG_Widget
*obj, const char
*margin);
void
AG_SetPadding
(AG_Widget
*obj, const char
*padding);
void
AG_Set<Color>
(AG_Widget
*obj, const char
*color);
void
AG_Set<Color>Disabled
(AG_Widget
*obj, const char
*color);
void
AG_Set<Color>Focused
(AG_Widget
*obj, const char
*color);
void
AG_Set<Color>Hover
(AG_Widget
*obj, const char
*color);
AG_SetStyle
()
sets the style attribute attr to the given
value.
See
AG_StyleSheet(3)
for the list of available attributes.
The following routines are shorthand forms for
AG_SetStyle
().
AG_SetFontFamily
()
sets the "font-family" attribute, which can be either a font name
or the name of a file located in one of the directories in the
PATH_FONTS
of
AG_Config(3).
AG_SetFontSize
()
sets the "font-size" attribute, which may contain the suffix
"%" (relative size to the parent widget's font), the suffix
"pt" (explicit size in vector-font points) or the suffix
"px" (explicit size in bitmap-font pixels).
Font sizes should normally be given in "%" so that the
zoom function can work as expected (Agar's zoom works simply by increasing
or decreasing the "font-size" of the target window).
AG_SetFontWeight
()
sets the "font-weight" attribute, which can be one of
"Thin", "ExtraLight", "Light",
"Regular" (default), "SemiBold", "Bold",
"ExtraBold", "Black" or "!parent".
AG_SetFontStyle
()
sets the "font-style" attribute, which be one of
"Normal" / "Regular", "Oblique",
"Italic" or "!parent".
AG_SetFontStretch
()
sets the "font-stretch" attribute, which can be one of
"Normal" / "Regular", "UltraCondensed",
"Condensed", "SemiCondensed", "SemiExpanded",
"Expanded" or "UltraExpanded".
AG_SetFont
()
sets (inherits) font style attributes "font-family",
"font-weight" and "font-stretch" from those of the given
font.
AG_SetMargin
()
sets the margin area around the widget. The argument can be of the form
"<HORIZ> <VERT>" to set horizontal and vertical
spacing in pixels, respectively. A single argument sets both horizontal and
vertical spacings to the same value.
AG_SetPadding
()
sets the padding inside the widget area. The argument can be of the form
"<TOP> <RIGHT> <BOTTOM> <LEFT>" to set
each padding in pixels. A single argument sets all paddings to the same
value.
The following routines set color attributes. For the list of
accepted formats for specifying colors, see
AG_Color(3).
AG_SetColor
()
sets the foreground primary ("color").
AG_SetBgColor
()
sets the background primary ("background-color").
AG_SetTextColor
()
sets the color for text and vector icons ("text-color").
AG_SetLineColor
()
sets the color for lines and filled shapes ("line-color").
AG_SetHighColor
()
sets the shading color for top and left 3D-style edges
("high-color").
AG_SetLowColor
()
sets the shading color for bottom and right 3D-style edges
("low-color").
AG_SetSelColor
()
sets the primary for indicating active selections
("selection-color").
The following routines set
state-dependent color attributes
AG_Set<Color>Disabled
()
sets the given color for the widget "#disabled" state.
AG_Set<Color>Focused
() sets the given color
for the "#focused" state.
AG_Set<Color>Hover
() sets the given color for
the "#hover" state.
void
AG_WidgetEnable
(AG_Widget
*obj);
void
AG_WidgetDisable
(AG_Widget
*obj);
int
AG_WidgetEnabled
(AG_Widget
*obj);
int
AG_WidgetDisabled
(AG_Widget
*obj);
void
AG_PushDisabledState
(AG_Widget
*obj);
void
AG_PopDisabledState
(AG_Widget
*obj);
A widget in DISABLED state will not accept
user input other than that required for navigation (i.e., scrolling).
AG_WidgetEnable
()
clears the DISABLED state and AG_WidgetDisable
()
sets it. These functions will raise the ‘widget-enabled’ and
‘widget-disabled’ events accordingly.
AG_WidgetEnabled
()
and AG_WidgetDisabled
() return the current
state.
AG_PushDisabledState
()
arranges for widgets subsequently attached to a container widget
obj to start in DISABLED state. The
AG_WIDGET_DISABLED flag will be set on attach (without
raising "widget-disabled").
Focus enables reception of input events that would be filtered out
by default. The focused widget (in the currently focused window) will
receive "mouse-motion", "mouse-button-up",
"key-up" and "key-down" events.
int
AG_WidgetSetFocusable
(AG_Widget
*obj, int
enable);
int
AG_WidgetFocus
(AG_Widget
*obj);
void
AG_WidgetUnfocus
(AG_Widget
*obj);
int
AG_WidgetIsFocused
(const
AG_Widget *obj);
int
AG_WidgetIsFocusedInWindow
(const
AG_Widget *obj);
void
AG_WidgetForwardFocus
(AG_Widget
*obj, AG_Widget
*widgetToFocus);
AG_WidgetSetFocusable
()
clears or sets the AG_WIDGET_FOCUSABLE
flag and
returns the previous setting (0 = Not focusable, 1 = Focusable).
AG_WidgetFocus
()
focuses the specified widget and all of its parent widgets including the
parent
AG_Window(3).
Returns 1 on success and 0 if the widget is not accepting focus.
AG_WidgetUnfocus
()
removes the focus state from the given widget and its children,
recursively.
AG_WidgetIsFocused
()
returns 1 if the widget is both focused in relation to its parent window,
and the parent window itself is focused.
AG_WidgetIsFocusedInWindow
() returns 1 if the widget
is focused regardless of the focus state of its parent.
AG_WidgetForwardFocus
()
arranges automatic forwarding of the focus to a specified widget. Whenever
obj gains focus, Agar will arrange for the focus to be
transferred automatically to widgetToFocus.
int
AG_WidgetArea
(AG_Widget
*obj, int x,
int y);
int
AG_WidgetRelativeArea
(AG_Widget
*obj, int x,
int y);
The
AG_WidgetArea
()
routine tests whether view coordinates x and
y lie inside of the widget's allocated space. The
AG_WidgetRelativeArea
() variant accepts widget
coordinates.
These routines allow graphical surfaces to be managed (mapped in
hardware or software) and transferred efficiently. They must be called from
rendering context (i.e., the draw
() operation of
AG_Widget
) only.
void
AG_WidgetBlit
(AG_Widget
*obj, AG_Surface
*src, int x,
int y);
int
AG_WidgetMapSurface
(AG_Widget
*obj, AG_Surface
*su);
int
AG_WidgetMapSurfaceNODUP
(AG_Widget
*obj, AG_Surface
*su);
void
AG_WidgetReplaceSurface
(AG_Widget
*obj, int
surface_id, AG_Surface
*newSurface);
void
AG_WidgetReplaceSurfaceNODUP
(AG_Widget
*obj, int
surface_id, AG_Surface
*newSurface);
void
AG_WidgetUnmapSurface
(AG_Widget
*obj, int
surface_id);
void
AG_WidgetUpdateSurface
(AG_Widget
*obj, int
surface_id);
void
AG_WidgetBlitFrom
(AG_Widget
*obj, AG_Widget
*srcWidget, int
surface_id, AG_Rect
*rs, int x,
int y);
void
AG_WidgetBlitSurface
(AG_Widget
*obj, int
surface_id, int x,
int y);
The
AG_WidgetBlit
()
function performs a software->hardware block image transfer
("blit") from the surface src to the video
display at the given widget coordinates.
AG_WidgetBlit
() must invoked in rendering context.
See
AG_Surface(3)
for more information on the Agar surface structure.
Software to hardware blits are slow, so the
AG_Widget
system provides a way to manage hardware
surfaces (i.e., textures) and take advantage the texture capabilities of
graphics hardware where it is available.
AG_WidgetMapSurface
()
registers the specified
AG_Surface(3)
with the widget, returning an integer handle to that surface. The surface
can be subsequently rendered by calling
AG_WidgetBlitSurface
() or
AG_WidgetBlitFrom
() using this handle. The exact
manner in which the surface is rendered depends on the Agar driver in use.
For OpenGL-based drivers, a matching hardware texture is typically generated
on the initial call to AG_WidgetBlitSurface
() and
kept in cache for later use.
By default, mapped surfaces are
freed when the widget is destroyed.
AG_WidgetMapSurfaceNODUP
()
sets the "NODUP" flag on the given surface such that the widget
system will never attempt to free the surface.
Note that
AG_WidgetMapSurface
()
will not duplicate the surface. Instead, it will register the given surface
pointer to be managed by the AG_Widget
system. The
surface pointer must remain valid for the lifetime of the widget (if in
doubt, you can always use
AG_SurfaceDup(3)
to map a duplicate of the surface instead).
AG_WidgetReplaceSurface
()
replaces the contents of a previously-mapped surface with
newSurface. The
AG_WidgetReplaceSurfaceNODUP
() variant avoids
duplicating the surface and sets the "NODUP" flag.
AG_WidgetUnmapSurface
()
destroys the given surface mapping. It is equivalent to invoking
AG_WidgetReplaceSurface
() with a NULL surface.
In OpenGL mode,
AG_WidgetReplaceSurface
()
and AG_WidgetUnmapSurface
() do not operate on
textures immediately. GL texture delete operations are queued to be
performed at the end of the current event-processing cycle.
The
AG_WidgetUpdateSurface
()
function should be invoked whenever a mapped surface is changed. If hardware
surfaces are supported, it will cause an upload of the software surface to
the hardware (otherwise it is a no-op).
The
AG_WidgetBlitFrom
()
function renders a previously mapped (possibly hardware) surface from the
source widget srcWidget (using source rectangle
rs) onto the destination widget
obj, at coordinates x,
y. This function must be invoked in rendering
context.
The
AG_WidgetBlitSurface
()
variant invokes AG_WidgetBlitFrom
() with the same
argument for both srcWidget and
obj (and rs set to NULL).
Widget states can be bound to memory locations containing data in
a supported format. For example, the "state" binding of
AG_Button(3)
can be tied to an integer (or bits in an integer), such that the user
pressing the button directly manipulates the integer value in memory.
Bindings are documented under the heading “BINDINGS”
section of the widget's manual page. For instance,
AG_Slider(3)
mentions "value" bindings to integers. Therefore, to control a
byte of memory, one might use:
static Uint8 myByte = 0;
AG_Slider *slider = AG_SliderNew(window, AG_SLIDER_HORIZ, 0);
AG_BindUint8(slider, "value", &myByte);
Or alternatively, using a shorthand constructor:
AG_SliderNewUint8(window, AG_SLIDER_HORIZ, 0, &myByte, NULL, NULL);
This method is not limited to primitive data types. For example,
AG_Textbox(3)
can bind to a fixed-size memory buffer containing a C string in ASCII, UTF-8
or other supported encoding.
The
AG_Bind<Type>
()
family of functions bind widget states to memory data. The
AG_Bind<Type>Mp
()
variants accept a pointer to a mutex which will be acquired prior to
accessing the data.
Since the state of a widget can influence
its appearance (e.g.,
AG_Button(3)
is drawn as a pressed button if its "state" is 1), it may be
necessary to monitor the value and redraw when it changes.
AG_RedrawOnChange
()
arranges for this to occur automatically (see below).
void
AG_Redraw
(AG_Widget
*obj);
void
AG_RedrawOnChange
(AG_Widget
*obj, int
refresh_ms, const char
*binding_name);
int
AG_RedrawOnTick
(AG_Widget
*obj, int
refresh_ms);
The
AG_Redraw
()
call signals that the widget must be redrawn to the display. It is
equivalent to setting the dirty flag on the parent
window. If called from rendering context,
AG_Redraw
() is a no-op.
AG_RedrawOnChange
()
arranges for the widget to be automatically redrawn whenever the value
associated with the existing binding binding_name
changes. The value of the binding will be checked at the specified interval
refresh_ms in milliseconds. If a
refresh_ms argument of -1 is passed, the effect of any
previous AG_RedrawOnChange
() call with the specified
binding is disabled.
AG_RedrawOnTick
()
enables or disables auto-refresh. Auto-refresh forces the widget to be
redrawn unconditionally every refresh_ms milliseconds.
If the refresh_ms argument is -1, auto-refresh is
disabled. The AG_RedrawOnTick
() function returns the
previous setting in ms (or -1 if auto-refresh was not set).
AG_Window *
AG_ParentWindow
(AG_Widget
*widget);
AG_Widget *
AG_WidgetFindFocused
(AG_Window
*win);
AG_Widget *
AG_WidgetFindPoint
(const
char *className, int
x, int y);
AG_Widget *
AG_WidgetFindRect
(const
char *className, int
x, int y,
int w,
int h);
AG_ParentWindow
()
returns a pointer to the parent
AG_Window(3)
for the given widget instance. The pointer is valid only as long as the
parent VFS remains locked. If the widget is not attached, NULL is
returned.
AG_WidgetFindFocused
()
returns the top-most focused widget under win.
AG_WidgetFindPoint
()
searches for the top-most widget which contains the point at display
coordinates x, y.
AG_WidgetFindRect
()
searches for the top-most widget which encloses the rectangle described by
display coordinates x, y,
w, h completely.
Both
AG_WidgetFindPoint
()
and AG_WidgetFindRect
() will only match widgets that
are instances of className. The pattern
"AG_Widget:*" would match any class. For details on the
class-membership test, see:
AG_OfClass(3).
Under threads, the object pointer
returned by
AG_WidgetFindFocused
(),
AG_WidgetFindPoint
() and
AG_WidgetFindRect
() is valid only for as long as the
parent VFS is locked.
void
AG_PushClipRect
(AG_Widget
*obj, const AG_Rect
*r);
void
AG_PushClipRectInner
(AG_Widget
*obj, const AG_Rect
*r);
void
AG_PopClipRect
(AG_Widget
*obj);
void
AG_PushBlendingMode
(AG_Widget
*obj, AG_AlphaFn
src, AG_AlphaFn
dst);
void
AG_PopBlendingMode
(AG_Widget
*obj);
void
AG_WidgetDraw
(AG_Widget
*obj);
void
AG_BeginRendering
(AG_Driver
*drv);
void
AG_EndRendering
(AG_Driver
*drv);
void
AG_WidgetHide
(AG_Widget
*obj);
void
AG_WidgetShow
(AG_Widget
*obj);
void
AG_WidgetHideAll
(AG_Widget
*obj);
void
AG_WidgetShowAll
(AG_Widget
*obj);
int
AG_WidgetVisible
(AG_Widget
*obj);
AG_Surface *
AG_WidgetSurface
(AG_Widget
*obj);
The
AG_PushClipRect
()
function pushes a rectangle (in widget-relative coordinates) onto the stack
of clipping rectangles, and AG_PopClipRect
() pops
the last entry from the clipping rectangle stack. The effective clipping
rectangle will be the intersection of all rectangles on this stack. Both
functions must be invoked in rendering context.
The
AG_PushClipRectInner
()
variant of AG_PushClipRect
() offsets the width and
height of the rectangle by -2px.
AG_PushBlendingMode
()
selects the source and destination functions for further pixel blending
operations. It also pushes the current state onto the stack of alpha
blending modes. Setting src to
AG_ALPHA_ZERO
and dst to
AG_ALPHA_ONE
(the default) effectively disables
blending. Setting src to
AG_ALPHA_SRC
and dst to
AG_ALPHA_ONE_MINUS_SRC
is the most common case. See
AG_AlphaFn(3)
for the list of possible alpha blending modes.
AG_PopBlendingMode
() pops the the last entry off of
the stack of alpha blending modes. Both functions must be invoked from
rendering context.
The
AG_WidgetDraw
()
routine renders a widget to the display. It is invoked from either the event
loop routine (such as
AG_EventLoop(3))
or from the draw
() operation of a widget. Container
widgets must call AG_WidgetDraw
() explicitely in
order to render their children.
In an event loop,
AG_WidgetDraw
()
invocations must be enclosed between calls to
AG_BeginRendering
() and
AG_EndRendering
().
The
AG_WidgetHide
()
and AG_WidgetShow
() functions toggle the visibility
of the specified widget (setting the AG_WIDGET_HIDE
flag as appropriate).
The
AG_WidgetHideAll
()
and AG_WidgetShowAll
() routines toggle the
visibility of the specified widget and its children by setting the
AG_WIDGET_VISIBLE
flag (which works independently of
AG_WIDGET_HIDE
). These routines are intended to be
used by container widgets (for example,
AG_Notebook(3)
which needs to show or hide tabbed containers).
AG_WidgetVisible
()
returns 1 if the widget is currently visible (equivalent to checking the
AG_WIDGET_VISIBLE
flag).
The
AG_WidgetSurface
()
routine renders the widget to a newly-allocated
AG_Surface(3).
This surface should be freed after use.
User-generated events such as key presses or mouse button events
can be connected to
high-level
actions such as executing a specified routine or controlling a
boolean. The high-level actions of a widget are described by an array of
AG_Action structures.
Where the conditions for execution of an Action
are fixed (e.g., a specific mouse button was clicked, or a specific key was
pressed), use of
AG_ActionOn*
()
is preferred over low-level event handlers (such as "key-down" or
"mouse-button-down") because it allows keyboard and mouse bindings
to be configured by the end-user in a standard way.
AG_Menu(3)
also provides interfaces for working with widget actions.
AG_Action *
AG_ActionFn
(AG_Widget
*obj, const char
*action, void
(*fn)(AG_Event *), const
char *fnArgs,
...);
AG_Action *
AG_ActionSetInt
(AG_Widget
*obj, const char
*action, int
*variable, int
value);
AG_Action *
AG_ActionSetFlag
(AG_Widget
*obj, const char
*action, Uint
*variable, Uint
bitmask, int
value);
AG_Action *
AG_ActionToggleInt
(AG_Widget
*obj, const char
*action, int
*variable);
AG_Action *
AG_ActionToggleFlag
(AG_Widget
*obj, const char
*action, Uint
*variable, Uint
bitmask);
void
AG_ActionOnButtonDown
(AG_Widget
*obj, int button,
const char *action);
void
AG_ActionOnButtonUp
(AG_Widget
*obj, int button,
const char *action);
void
AG_ActionOnKeyDown
(AG_Widget
*obj, AG_KeySym
sym, AG_KeyMod mod,
const char *action);
void
AG_ActionOnKeyUp
(AG_Widget
*obj, AG_KeySym
sym, AG_KeyMod mod,
const char *action);
void
AG_ActionOnKey
(AG_Widget
*obj, AG_KeySym
sym, AG_KeyMod mod,
const char *action);
int
AG_ExecMouseAction
(AG_Widget
*obj, AG_ActionEventType
type, int button,
int x,
int y);
int
AG_ExecKeyAction
(AG_Widget
*obj, AG_ActionEventType
type, AG_KeySym
sym, AG_KeyMod
mod);
int
AG_ExecAction
(AG_Widget
*obj, AG_Action
*a);
AG_ActionFn
()
registers a new widget action which is to invoke a callback function
fn, with arguments fnArgs. See
AG_Event(3)
for a description of the fnArgs format.
AG_ActionSetInt
()
registers a new action which is to set an integer
variable to a specified value.
Instead of an integer variable, AG_ActionSetFlag
()
sets the bits specified by bitmask to the specified
value (of 1 or 0). The
AG_ActionToggleInt
() and
AG_ActionToggleFlag
() variants do not take an
explicit value argument, and toggle the current value
instead.
AG_ActionOnButtonDown
()
and AG_ActionOnButtonUp
() tie an action to a button
press and a button release event, respectively. The
button argument specifies the button index (see
AG_MouseButton(3)).
AG_ActionOnKeyDown
() and
AG_ActionOnKeyUp
() tie an action to a key press and
key release event, respectively. The sym argument
specifies the key (see
AG_KeySym(3)),
and mod specifies the modifier keys which must be in
effect. To match any key or any modifier state,
AG_KEY_ANY
or AG_KEYMOD_ANY
can be used.
With
AG_ActionOnKeyDown
()
and AG_ActionOnKeyUp
(), the action is triggered once
immediately on key press or key release. The
AG_ActionOnKey
() variant ties an action to a key
press, but with "key repeat" behavior. The action is triggered
immediately once after an initial key press. If the key combination is held
longer than the "key delay" (by default 250ms), the event is
repeated with the "key repeat" interval (by default 30ms).
If there are currently no event handlers
registered for "key-up", "key-down",
"mouse-button-up" and "mouse-button-down", the
AG_ActionOn*
()
functions automatically register event handlers which will invoke
AG_ExecMouseAction
() or
AG_ExecKeyAction
() as appropriate (see below).
AG_ExecMouseAction
()
executes any action associated with mouse button events. It is typically
invoked from the "mouse-button-down" and
"mouse-button-up" event handlers of the widget. Accepted
type values are
AG_ACTION_ON_BUTTONDOWN
and
AG_ACTION_ON_BUTTONUP
. button
is the pressed button index (see
AG_MouseButton(3)).
x and y is the position of the
cursor in the widget's coordinate system.
AG_ExecKeyAction
()
executes any action associated with keyboard events. It is typically invoked
from the "key-down" and "key-up" event handlers of the
widget. Accepted type values are
AG_ACTION_ON_KEYDOWN
and
AG_ACTION_ON_KEYUP
. sym and
mod specify the key index and modifier state (see
AG_KeySym(3)
and
AG_KeyMod(3)).
AG_ExecAction
()
executes the specified action. AG_ExecAction
() is
rarely used directly, but it is invoked internally by the
AG_ExecFooAction
()
functions.
The GUI system may send AG_Widget
objects
the following events:
font-changed
(void)
- The active font family, size or style attributes have changed. The new
font may be accessed by the font pointer of
AG_Widget
.
padding-changed
(void)
- The padding attribute has changed.
palette-changed
(void)
- At least one entry in the color palette of the widget has changed.
widget-shown
(void)
- The widget is now visible. User-defined handlers must be appended with
AG_AddEvent(3)
(as opposed to replaced by
AG_SetEvent(3))
since the base class needs its own "widget-shown" handler.
widget-hidden
(void)
- The widget is no longer visible. User-defined handlers must be appended
with
AG_AddEvent(3)
(as opposed to replaced by
AG_SetEvent(3))
since the base class needs its own "widget-hidden" handler.
widget-enabled
(void)
- Input state has been enabled with
AG_WidgetEnable(3).
widget-disabled
(void)
- Input state has been disabled with
AG_WidgetDisable(3).
widget-gainfocus
(void)
- The widget now holds focus inside its parent container.
widget-lostfocus
(void)
- The widget no longer holds focus.
widget-reshape
(void)
- The widget was resized and
USE_OPENGL
is set. The
handler is expected to update the GL_PROJECTION
or
GL_MODELVIEW
matrices.
widget-overlay
(void)
- Invoked following the
draw
() operation; requires
USE_OPENGL
.
widget-underlay
(void)
- Invoked prior to the
draw
() operation; requires
USE_OPENGL
.
The following events are usually generated by input devices.
DEPRECATED: As of Agar 1.7.0 the events described below have been
superceded by the input device methods of
AG_WidgetClass. If a method is defined then the method
is called and no event is generated.
mouse-motion
(int
x, int y, int xRel,
int yRel, int buttons)
- The widget is receiving mouse motion events, and the cursor has been
moved. x and y are the
coordinates of the cursor in the widget's local coordinate system (these
coordinates may be negative or exceed the widget's dimensions if the
cursor is not in the widget's area). xRel and
yRel represent the displacement relative to the last
position of the mouse cursor. The buttons argument
is a bitmask representing the state of mouse buttons (see
AG_MouseButton(3)).
mouse-button-up
(int
button, int x, int y)
- The widget is receiving mouse button release events, and
button has been released. x
and y are the cursor coordinates in the widget's
local coordinate system.
mouse-button-down
(int
button, int x, int y)
- The widget is receiving mouse button events, and
button has been pressed. x and
y are the cursor coordinates in the widget's local
coordinate system.
mouse-over
(void)
- The cursor has entered or is leaving the widget's allocated area and the
AG_WIDGET_USE_MOUSEOVER
option is set.
key-down
(int
key, int mod, Ulong
ch)
- The widget is receiving keyboard events and key has
been pressed. mod is a bitmask representing the
state of the current key modifiers. If non-zero, ch
is the matching UCS-4 (or ASCII) character.
key-up
(int
key, int mod, Ulong
ch)
- The widget is receiving keyboard events and key has
been released. mod is a bitmask representing the
state of the current key modifiers. If non-zero, ch
is the matching UCS-4 (or ASCII) character.
For the AG_Widget object:
- Uint flags
- Option flags (see FLAGS section
below).
- int x, y
- Location of the upper-left pixel (relative to the parent widget).
Read-only (set by container).
- int w, h
- Size in pixels. Read-only (set by container).
- AG_Rect r
- Cached rectangle at 0,0. Read-only.
- AG_Rect2 rView
- Cached position & size in display coordinates. Read-only with one
exception: before calling
AG_WidgetDraw(3)
to render a child widget, a container widget may temporarily override its
rView in order to render it at a given offset.
- AG_Rect2 rSens
- Rectangle of sensitivity to mouse events (in display coordinates).
Scrolling containers such as
AG_Scrollview(3)
may adjust this rectangle for partially-visible widgets along its
edges.
- AG_WidgetPalette pal
- Color palette: a 4 x 8 (or
AG_WIDGET_NSTATES
by
AG_WIDGET_NCOLORS
) array of
AG_Color(3).
Entries are set by the current
AG_StyleSheet(3).
Read-only (use AG_SetStyle
() to modify) with one
exception: before calling
AG_WidgetDraw(3)
to render a child widget, a container widget may temporarily override and
restore its palette entries.
- AG_Font *font
- Current font associated with the widget (see
AG_Font(3)).
Read-only (use
AG_SetStyle
() or the
AG_SetFont*
()
family of functions to modify).
- AG_ActionVec *actions
- Dynamic array of AG_Action structures describing
high-level actions (see WIDGET
ACTIONS).
The flags member of the
AG_Widget
structure accepts the following flags:
- AG_WIDGET_HFILL
- Fill any remaining (horizontal) space (hint to vertically-packing
containers).
- AG_WIDGET_VFILL
- Fill any remaining (vertical) space (hint to horizontal-packing
containers).
- AG_WIDGET_EXPAND
- Shorthand for both
AG_WIDGET_HFILL
and
AG_WIDGET_VFILL
.
- AG_WIDGET_HIDE
- Disable rendering of this widget.
- AG_WIDGET_VISIBLE
- This widget and its parent window are both currently visible
(read-only).
- AG_WIDGET_UNDERSIZE
- Disable rendering of this widget because it is too small to draw
(read-only).
- AG_WIDGET_DISABLE_ON_ATTACH
- Make attached widgets start in DISABLED state (without raising
"widget-disabled").
- AG_WIDGET_DISABLED
- Advise that widget is not accepting user input. This state influences
color and styling. The effect of this option is widget-dependent
(read-only; see INPUT STATE
section).
- AG_WIDGET_MOUSEOVER
- A mouse cursor currently intersects the widget's area (read-only; updated
internally if the
AG_WIDGET_USE_MOUSEOVER
flag is
set). This state influences color and styling.
- AG_WIDGET_FOCUSABLE
- The widget is allowed to grab the focus.
- AG_WIDGET_UNFOCUSED_MOTION
- Receive "mouse-motion" events unconditionally (focus is required
by default).
- AG_WIDGET_UNFOCUSED_BUTTONUP
- Receive all
mouse-button-up
() (mouse button
release) events unconditionally.
- AG_WIDGET_UNFOCUSED_BUTTONDOWN
- Receive all
mouse-button-up
() (mouse button press)
events unconditionally.
- AG_WIDGET_UNFOCUSED_KEYDOWN
- Receive
key-down
() (key press) events
unconditionally (focus is required by default).
- AG_WIDGET_UNFOCUSED_KEYUP
- Receive
key-up
() (key release) events
unconditionally (focus is required by default).
- AG_WIDGET_CATCH_TAB
- When the user presses the
TAB
key, generate normal
key-down
() and key-up
()
events. Without this flag, TAB
is used to change
the focus to the next widget.
- AG_WIDGET_NOSPACING
- Advise parent container to disable spacing and padding (per standard box
model), for this widget.
- AG_WIDGET_USE_TEXT
- Allow
draw
(),
size_request
() and
size_allocate
() to use
AG_TextRender(3)
and
AG_TextSize(3).
Agar will automatically save/restore the font engine state according to
the widget's computed style settings. Enables reception of the
"font-changed" event.
- AG_WIDGET_USE_OPENGL
- Establish a separate OpenGL context for the widget. Before the
draw
() routine is invoked, Agar will automatically
save/restore the GL_PROJECTION
,
GL_MODELVIEW
and
GL_TEXTURE
matrices along with GL attributes
GL_TRANSFORM_BIT
,
GL_VIEWPORT_BIT
and
GL_TEXTURE_BIT
. Enables reception of
"widget-reshape", "widget-overlay" and
"widget-underlay" events.
- AG_WIDGET_USE_MOUSEOVER
- Detect cursor motion over the widget's area; update the
AG_WIDGET_MOUSEOVER
flag and generate
"mouse-over" events accordingly.
The AG_Widget
interface first appeared in
Agar 1.0. Widget-level variable bindings have been replaced by generic
AG_Variable(3)
pointers in Agar 1.3.4. Actions were introduced in Agar 1.4.0.
AG_WIDGET_USE_OPENGL
first appeared in Agar 1.5,
replacing
AG_GLView(3).
Agar 1.6.0 first made the actions,
pal and rSens structure members
public. The AG_SetStyleF
(),
AG_PushBlendingMode
() and
AG_PopBlendingMode
() functions appeared in Agar
1.6.0. The "font-changed" and "palette-changed" events
appeared in Agar 1.6.0. AG_PushDisabledState
(),
AG_PopDisabledState
(), the
AG_WIDGET_DISABLE_ON_ATTACH
flag and the
"padding-changed" event appeared in Agar 1.7.0.