.\" Copyright (c) 2002-2007 Hypertriton, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
.\" (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd August 21, 2002
.Dt AG_WINDOW 3
.Os
.ds vT Agar API Reference
.ds oS Agar 1.0
.Sh NAME
.Nm AG_Window
.Nd agar window system
.Sh SYNOPSIS
.Bd -literal
#include
#include
.Ed
.Sh DESCRIPTION
The
.Nm
object implements a mobile, resizable container for widgets; it is
itself derived from the
.Xr AG_Widget 3
structure and attached to an
.Xr AG_View 3 .
Similarly to
.Xr AG_Box 3 ,
.Nm
is a general-purpose widget container.
By default, an
.Xr AG_Titlebar 3
widget is attached to the window when it is created.
.Pp
It not usually necessary to provide explicit dimensions in pixels when
creating new Agar windows.
Widgets are queried for preferred dimensions when the window is first
displayed.
In cases where the "best" widget dimensions cannot be guessed properly at
initialization time, it is customary for Agar widgets to provide one or more
"size hint" routine.
.Pp
Commonly used containers include
.Xr AG_Box 3 ,
.Xr AG_VBox 3
and
.Xr AG_HBox 3
for automatic horizontal and vertical packing,
.Xr AG_Fixed 3
for explicit pixel-precision packing,
.Xr AG_Pane 3
for dual partitions and
.Xr AG_Notebook 3
for notebook-style display.
.Sh INHERITANCE HIERARCHY
.Xr AG_Object 3 ->
.Xr AG_Widget 3 ->
.Nm .
.Sh INTERFACE
.nr nS 1
.Ft "AG_Window *"
.Fn AG_WindowNew "Uint flags"
.Pp
.Ft "AG_Window *"
.Fn AG_WindowNewNamed "Uint flags" "const char *name" "..."
.Pp
.Ft "void"
.Fn AG_WindowSetCaption "AG_Window *win" "const char *fmt" "..."
.Pp
.Ft "void"
.Fn AG_WindowSetIcon "AG_Window *win" "AG_Surface *surface"
.Pp
.Ft "void"
.Fn AG_WindowSetIconNODUP "AG_Window *win" "AG_Surface *surface"
.Pp
.Ft "void"
.Fn AG_WindowSetCloseAction "AG_Window *win" "eum ag_window_close_action action"
.Pp
.Ft "void"
.Fn AG_WindowSetPadding "AG_Window *win" "int paddingLeft" "int paddingRight" "int paddingTop" "int paddingBottom"
.Pp
.Ft "void"
.Fn AG_WindowSetSpacing "AG_Window *win" "int spacing"
.Pp
.Ft "void"
.Fn AG_WindowSetSideBorders "AG_Window *win" "int pixels"
.Pp
.Ft "void"
.Fn AG_WindowSetBottomBorder "AG_Window *win" "int pixels"
.Pp
.Ft "void"
.Fn AG_WindowSetPosition "AG_Window *win, enum ag_window_alignment alignment" "int cascade"
.Pp
.Ft "void"
.Fn AG_WindowSetGeometry "AG_Window *win" "int x" "int y" "int w" "int h"
.Pp
.Ft "void"
.Fn AG_WindowSetGeometryRect "AG_Window *win" "AG_Rect rect" "int bounded"
.Pp
.Ft "void"
.Fn AG_WindowSetGeometryAligned "AG_Window *win" "enum ag_window_alignment alignment" "int w" "int h"
.Pp
.Ft "void"
.Fn AG_WindowSetGeometryAlignedPct "AG_Window *win" "enum ag_window_alignment alignment" "int wPct" "int hPct"
.Pp
.Ft "void"
.Fn AG_WindowSetGeometryBounded "AG_Window *win" "int x" "int y" "int w" "int h"
.Pp
.Ft "void"
.Fn AG_WindowSetGeometryMax "AG_Window *win"
.Pp
.Ft "void"
.Fn AG_WindowSetMinSize "AG_Window *win" "int w" "int h"
.Pp
.Ft "void"
.Fn AG_WindowSetMinSizePct "AG_Window *win" "int pct"
.Pp
.Ft "void"
.Fn AG_WindowMaximize "AG_Window *win"
.Pp
.Ft "void"
.Fn AG_WindowUnmaximize "AG_Window *win"
.Pp
.Ft "void"
.Fn AG_WindowMinimize "AG_Window *win"
.Pp
.Ft "void"
.Fn AG_WindowUnminimize "AG_Window *win"
.Pp
.Ft void
.Fn AG_WindowAttach "AG_Window *win" "AG_Window *subwin"
.Pp
.Ft void
.Fn AG_WindowDetach "AG_Window *win" "AG_Window *subwin"
.Pp
.Ft void
.Fn AG_WindowUpdate "AG_Window *win"
.Pp
.Ft void
.Fn AG_WindowDraw "AG_Window *win"
.Pp
.nr nS 0
The
.Fn AG_WindowNew
allocates, initializes and attach a new window.
.Pp
The
.Fn AG_WindowNewNamed
variant creates a new named window.
If a window of the same name exists,
.Fn AG_WindowNewNamed
only moves the focus to that window, and returns NULL.
.Pp
See
.Dq FLAGS
for available
.Fa flags
options.
.Pp
The
.Fn AG_WindowSetCaption
function sets the text displayed by the titlebar (if there is one).
The string is truncated if its length exceeds
.Dv AG_LABEL_MAX
- 1 bytes.
.Pp
The
.Fn AG_WindowSetIcon
function configures an alternate icon for the window.
This icon will be used by Agar's internal window manager whenever the window
is minimized.
The given surface will be duplicated and can be of any size, but the recommended
default size is given by
.Va agWindowIconWidth
and
.Va agWindowIconHeight .
The
.Fn AG_WindowSetIconNODUP
variant does not duplicate the provided surface, which must remain valid until
the window is destroyed.
.Pp
The
.Fn AG_WindowSetCloseAction
function specifies the action that should be performed when the user clicks on
the
.Em close
control of
.Xr AG_Titlebar 3 .
.Pp
.Bl -tag -width "AG_WINDOW_DETACH "
.It AG_WINDOW_HIDE
Window is only hidden.
This is the default action for windows created with
.Fn AG_WindowNewNamed .
.It AG_WINDOW_DETACH
Window is detached from the view and all resources allocated by it (and
its attached widgets) are released.
This is the default action for windows created with
.Fn AG_WindowNew .
.El
.Pp
To set an arbitrary callback routine, simply configure an
.Sq window-close
event handler (see
.Dq EVENTS ) .
.Pp
The
.Fn AG_WindowSetPadding
function defines the space in pixels separating the widgets from the edges
of the window.
.Pp
The
.Fn AG_WindowSetSpacing
function defines the space separating the widgets from each other.
The default is 2 pixels.
.Pp
Note that
.fn AG_WindowSetSpacing
only affects the widgets which are directly attached to the window.
For widgets that are attached to container widgets, it is the container
widgets that define spacing, as well as other aspects of widget
organization.
For instance, the
.Xr AG_Box 3
container widget provides a
.Fn AG_BoxSetSpacing
function .
.Pp
.Fn AG_WindowSetSideBorders
sets the thickness of the left and right window borders in pixels.
.Fn AG_WindowSetBottomBorder
sets the thickness of the bottom border.
The exact interpretation of this setting is theme-specific.
The default for side borders is 0 (no side borders).
If the
.Fa win
argument is NULL, the defaults are set.
.Pp
The
.Fn AG_WindowSetPosition
specifies the method used to compute the initial window position.
Acceptable values include:
.Bd -literal
AG_WINDOW_TL AG_WINDOW_TC AG_WINDOW_TR
AG_WINDOW_ML AG_WINDOW_MC AG_WINDOW_MR
AG_WINDOW_BL AG_WINDOW_BC AG_WINDOW_BR
.Ed
.Pp
If the
.Fa cascade
argument is 1, the window position is slightly incremented or decremented at
each call (depending on the preferred alignment).
.Pp
The
.Fn AG_WindowSetGeometry
assigns a specific position and geometry in pixels to a window, overriding
the default automatically-computed values.
If either
.Fa w
or
.Fa h
is specified as -1, the current width / height is preserved.
.Pp
The
.Fn AG_WindowSetGeometryRect
variants accepts an
.Ft AG_Rect
argument.
The
.Fa bounded
flag limits the window to the view area.
.Pp
The
.Fn AG_WindowSetGeometryAligned
variant assigns the window a specific size in pixels and positions it
according to the specified window alignment (see description of
.Fn AG_WindowSetPosition
for the possible values).
The parameters of
.Fn AG_WindowSetGeometryAlignedPct
are given in percentage of current view area instead of pixels.
.Pp
The
.Fn AG_WindowSetGeometryBounded
variant limits the window to the view area (by default, windows can lie
outside of the visible area).
.Pp
The
.Fn AG_WindowSetGeometryMax
variant sets the geometry to the size of the display (without setting the
.Dv AG_WINDOW_MAXIMIZED
flag).
.Pp
The
.Fn AG_WindowSetMinSize
routine sets the minimum window size in pixels.
.Fn AG_WindowSetMinSizePct
sets the minimum window size in percentage of the requested (computed)
size.
.Pp
.Fn AG_WindowMaximize
and
.Fn AG_WindowMinimize
maximizes and minimizes the window, respectively.
.Fn AG_WindowUnmaximize
and
.Fn AG_WindowUnminimize
does the opposite.
.Pp
The
.Fn AG_WindowAttach
function arranges for
.Fa pwin
to be the parent window of
.Fa win ,
such that
.Fa win
is automatically destroyed when
.Fa pwin
is detached (through
.Xr AG_ViewDetach 3 ) .
.Pp
The
.Fn AG_WindowDetach
function removes
.Fa win
from its parent window
.Fa pwin .
.Pp
Widgets are allowed to modify the
.Va x ,
.Va y ,
.Va w
and
.Va h
members of their structures directly.
The
.Fn AG_WindowUpdate
function commits all such changes previously made to any widget attached to
.Fa win .
.Pp
.Fn AG_WindowDraw
renders the window to the display.
Calls to
.Fn AG_WindowDraw
must be made in GUI rendering context (i.e., enclosed between calls to
.Xr AG_BeginRendering 3
and
.Xr AG_EndRendering 3 ) .
Typically, this happens in an event loop routine (such as the stock
.Xr AG_EventLoop 3 ) .
.Sh VISIBILITY
.nr nS 1
.Ft void
.Fn AG_WindowShow "AG_Window *win"
.Pp
.Ft void
.Fn AG_WindowHide "AG_Window *win"
.Pp
.Ft int
.Fn AG_WindowIsVisible "AG_Window *win"
.Pp
.Ft int
.Fn AG_WindowSelectedWM "AG_Window *win" "enum ag_wm_operation op"
.Pp
.Ft int
.Fn AG_WindowSetVisibility "AG_Window *win" "int flag"
.Pp
.nr nS 0
The
.Fn AG_WindowShow
and
.Fn AG_WindowHide
functions control the visibility of a window.
.Pp
.Fn AG_WindowIsVisible
returns the current visibility status of a window (0 = invisible, 1 = visible).
With threads, the return value is only valid as long as the
.Fa win
object is locked.
.Pp
.Fn AG_WindowSelectedWM
returns 1 if Agar's internal window manager is currently performing the
specified operation on the window.
Accepted values for
.Fa op
include:
.Pp
.Bl -tag -compact -width "AG_WINOP_LRESIZE "
.It AG_WINOP_NONE
No operation
.It AG_WINOP_LRESIZE
Being resized via left-side resize control.
.It AG_WINOP_RRESIZE
Being resized via right-side resize control.
.It AG_WINOP_HRESIZE
Being resized via horizontal resize control.
.El
.Pp
.Fn AG_WindowSetVisibility
sets the visibility state of
.Fa win .
.Sh FOCUS
.nr nS 1
.Ft void
.Fn AG_WindowFocus "AG_Window *win"
.Pp
.Ft int
.Fn AG_WindowFocusNamed "const char *name"
.Pp
.Ft "AG_Window *"
.Fn AG_WindowFindFocused "void"
.Pp
.Ft "int"
.Fn AG_WindowIsFocused "void"
.Pp
.Ft "void"
.Fn AG_WindowCycleFocus "AG_Window *win" "int reverse"
.Pp
.nr nS 0
The
.Fn AG_WindowFocus
function sets the focus on the given window.
If the currently focused window has the
.Dv AG_WINDOW_KEEPABOVE
flag set, this function becomes a no-op.
.Fn AG_WindowFocusNamed
sets the focus on the window of the given name and returns 0 on success
or -1 if the window was not found.
.Pp
.Fn AG_WindowFindFocused
returns a pointer to the window currently holding focus, or NULL if there
are currently no windows at all.
.Pp
.Fn AG_WindowIsFocused
returns 1 if the window is currently holding focus, otherwise 0.
.Pp
.Fn AG_WindowCycleFocus
places the focus over the widget following (or preceeding if
.Fa reverse
is 1) the widget currently holding focus inside of
.Fa win .
By default, Agar maps the "TAB" key to this function.
.Sh GENERIC EVENT HANDLERS
.nr nS 1
.Ft void
.Fn AG_WindowDetachGenEv "int argc" "union evarg *argv"
.Pp
.Ft void
.Fn AG_WindowHideGenEv "int argc" "union evarg *argv"
.Pp
.Ft void
.Fn AG_WindowShowGenEv "int argc" "union evarg *argv"
.Pp
.Ft void
.Fn AG_WindowCloseGenEv "int argc" "union evarg *argv"
.Pp
.nr nS 0
The
.Fn AG_WindowDetachGenEv
event handler detaches the given window, freeing associated resources.
.Fn AG_WindowHideGenEv
hides the given window, if it is currently visible.
.Fn AG_WindowShowGenEv
invokes
.Fn AG_WindowShow
on the given window.
.Fn AG_WindowCloseGenEv
sends an
.Sq window-close
event to the given window.
A pointer to the window is passed as argument 1 to those event handlers.
.Pp
The
.Fn AG_WindowSetCloseAction
function is an alternative to assigning these event handlers manually.
.Sh FLAGS
For the
.Ft AG_Window
object:
.Pp
.Bl -tag -width "AG_WINDOW_NOUPDATERECT "
.It AG_WINDOW_MAXIMIZED
Window is currently maximized (read-only).
.It AG_WINDOW_MINIMIZED
Window is currently minimized (read-only).
.It AG_WINDOW_KEEPABOVE
Stay on top of other windows.
.It AG_WINDOW_KEEPBELOW
Stay below other windows.
.It AG_WINDOW_DENYFOCUS
Don't automatically grab focus in response to a
.Sq window-mousebuttondown
event in the window area.
.It AG_WINDOW_MODAL
Place window in foreground and prevent all other windows from catching events.
Multiple modal windows are organized in a stack and the effective modal window
is the one that was shown
(with
.Fn AG_WindowShow )
the last.
Implies
.Dv AG_WINDOW_NOMAXIMIZE
and
.Dv AG_WINDOW_NOMINIMIZE .
.It AG_WINDOW_NOBACKGROUND
Don't fill the window background prior to rendering its contents.
.It AG_WINDOW_NOUPDATERECT
Disable automatic updating of the video region corresponding to the
window area (applicable to framebuffer-based graphics drivers only)
.It AG_WINDOW_NOTITLE
Don't automatically create an
.Xr AG_Titlebar 3
widget.
.It AG_WINDOW_NOBORDERS
Don't draw decorative window borders.
.It AG_WINDOW_PLAIN
Alias for
.Dv AG_WINDOW_NOTITLE
and
.Dv AG_WINDOW_NOBORDERS .
.It AG_WINDOW_NOHRESIZE
Disable horizontal window resize control.
.It AG_WINDOW_NOVRESIZE
Disable vertical window resize control.
.It AG_WINDOW_NORESIZE
Alias for
.Dv AG_WINDOW_NOHRESIZE
and
.Dv AG_WINDOW_NOVRESIZE .
.It AG_WINDOW_NOCLOSE
Disable window close button in titelbar.
.It AG_WINDOW_NOMINIMIZE
Disable minimize button in titlebar.
.It AG_WINDOW_NOMAXIMIZE
Disable maximize button in titlebar.
.It AG_WINDOW_NOBUTTONS
Alias for
.Dv AG_WINDOW_NOCLOSE ,
.Dv AG_WINDOW_NOMINIMIZE
and
.Dv AG_WINDOW_NOMAXIMIZE .
.It AG_WINDOW_HMAXIMIZE
Keep window scaled to the display width.
.It AG_WINDOW_VMAXIMIZE
Keep window scaled to the display height.
.It AG_WINDOW_NOMOVE
User is not allowed to move the window.
.It AG_WINDOW_NOCLIPPING
Disable the clipping rectangle over the window area (enabled by default).
.El
.Sh EVENTS
The
.Nm
widget delivers the following events to its child widgets:
.Pp
.\"
.\" EVENTS AS SENDER
.\"
.Bl -tag -width 2n
.It Fn window-mousemotion "int x" "int y" "int xrel" "int yrel" "int state"
The mouse cursor has moved to widget-relative coordinates
.Fa x
and
.Fa y
(which may be negative).
The
.Fa xrel
and
.Fa yrel
arguments represent the displacement relative to the last position of the
mouse cursor.
.Fa state
holds the present button state, as returned by
.Xr SDL_GetMouseState 3 .
Regardless of the mouse position, this event is posted to widgets that either
hold focus inside the focused window, or have the
.Dv AG_WIDGET_UNFOCUSED_MOTION
flag set.
.It Fn window-mousebuttonup "int button" "int x" "int y"
The mouse button indexed by
.Fa button
was released at widget-relative
.Fa x ,
.Fa y
coordinates.
Regardless of the mouse position, this event is posted to the widget that
holds focus inside the focused window.
.It Fn window-mousebuttondown "int button" "int x" "int y"
The mouse button indexed by
.Fa button
was pressed at widget-relative
.Fa x ,
.Fa y
coordinates, which must be inside the widget area.
.It Fn window-keyup "int keysym" "int keymod"
The key identified by
.Fa keysym
was released, and the widget holds the focus.
.It Fn window-keydown "int keysym" "int keymod" "int unicode"
The key identified by
.Fa keysym
was pressed, and the widget holds the focus.
.El
.\"
.\" EVENTS AS WINDOW RECEIVER
.\"
.Pp
The
.Nm
object itself receives the following events:
.Bl -tag -width 2n
.It Fn window-close "void"
The window's titlebar close button was pressed.
Generated after the window is no longer visible.
This event is configurable via the
.Fn AG_WindowSetCloseAction
utility function.
.It Fn window-shown "void"
The window is now visible.
.It Fn window-hidden "void"
The window is no longer visible.
.It Fn window-modal-close "void"
The
.Dv AG_WINDOW_MODAL
flag is set and the user has clicked outside of the window area.
.It Fn window-user-resize "int w" "int h"
The window has been resized by the user.
Calls to
.Fn AG_WindowSetGeometry
will not raise this event.
.It Fn window-user-move "int x" "int y"
The window has been displaced by the user.
Calls to
.Fn AG_WindowSetGeometry
will not raise this event.
.El
.Sh SEE ALSO
.Xr AG_Intro 3 ,
.Xr AG_Icon 3 ,
.Xr AG_Cursor 3 ,
.Xr AG_View 3 ,
.Xr AG_Widget 3
.Sh HISTORY
The
.Nm
system first appeared in Agar 1.0.