542 lines
19 KiB
C
542 lines
19 KiB
C
#ifndef _XPWidgets_h_
|
|
#define _XPWidgets_h_
|
|
|
|
/*
|
|
* Copyright 2005-2012 Sandy Barbour and Ben Supnik
|
|
*
|
|
* All rights reserved. See license.txt for usage.
|
|
*
|
|
* X-Plane SDK Version: 2.1.1
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* WIDGETS - THEORY OF OPERATION AND NOTES
|
|
*
|
|
* Widgets are persistent view 'objects' for X-Plane. A widget is an object
|
|
* referenced by its opaque handle (widget ID) and the APIs in this file. You
|
|
* cannot access the widget's guts directly. Every Widget has the following
|
|
* intrinsic data:
|
|
*
|
|
* - A bounding box defined in global screen coordinates with 0,0 in the
|
|
* bottom left and +y = up, +x = right.
|
|
*
|
|
* - A visible box, which is the intersection of the bounding box with the
|
|
* widget's parents visible box.
|
|
*
|
|
* - Zero or one parent widgets. (Always zero if the widget is a root widget.
|
|
*
|
|
*
|
|
* - Zero or more child widgets.
|
|
*
|
|
* - Whether the widget is a root. Root widgets are the top level plugin
|
|
* windows.
|
|
*
|
|
* - Whether the widget is visible.
|
|
*
|
|
* - A text string descriptor, whose meaning varies from widget to widget.
|
|
*
|
|
* - An arbitrary set of 32 bit integral properties defined by 32-bit integral
|
|
* keys. This is how specific widgets
|
|
*
|
|
* store specific data.
|
|
*
|
|
* - A list of widget callbacks proc that implements the widgets behaviors.
|
|
*
|
|
* The Widgets library sends messages to widgets to request specific behaviors
|
|
* or notify the widget of things.
|
|
*
|
|
* Widgets may have more than one callback function, in which case messages
|
|
* are sent to the most recently added callback function until the message is
|
|
* handled. Messages may also be sent to parents or children; see the
|
|
* XPWidgetDefs.h header file for the different widget message dispatching
|
|
* functions. By adding a callback function to a window you can 'subclass'
|
|
* its behavior.
|
|
*
|
|
* A set of standard widgets are provided that serve common UI purposes. You
|
|
* can also customize or implement entirely custom widgets.
|
|
*
|
|
* Widgets are different than other view hierarchies (most notably Win32,
|
|
* which they bear a striking resemblance to) in the following ways:
|
|
*
|
|
* - Not all behavior can be patched. State that is managed by the XPWidgets
|
|
* DLL and not by individual widgets cannot be customized.
|
|
*
|
|
* - All coordinates are in global screen coordinates. Coordinates are not
|
|
* relative to an enclosing widget, nor are they relative to a display window.
|
|
*
|
|
*
|
|
* - Widget messages are always dispatched synchronously, and there is no
|
|
* concept of scheduling an update or a dirty region. Messages originate from
|
|
* X-Plane as the sim cycle goes by. Since x-plane is constantly redrawing,
|
|
* so are widgets; there is no need to mark a part of a widget as 'needing
|
|
* redrawing' because redrawing happens frequently whether the widget needs it
|
|
* or not.
|
|
*
|
|
* - Any widget may be a 'root' widget, causing it to be drawn; there is no
|
|
* relationship between widget class and rootness. Root widgets are
|
|
* imlemented as XPLMDisply windows.
|
|
*
|
|
*/
|
|
|
|
#include "XPWidgetDefs.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
* WIDGET CREATION AND MANAGEMENT
|
|
***************************************************************************/
|
|
/*
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
/*
|
|
* XPCreateWidget
|
|
*
|
|
* This function creates a new widget and returns the new widget's ID to you.
|
|
* If the widget creation fails for some reason, it returns NULL. Widget
|
|
* creation will fail either if you pass a bad class ID or if there is not
|
|
* adequate memory.
|
|
*
|
|
* Input Parameters:
|
|
*
|
|
* - Top, left, bottom, and right in global screen coordinates defining the
|
|
* widget's location on the screen.
|
|
*
|
|
* - inVisible is 1 if the widget should be drawn, 0 to start the widget as
|
|
* hidden.
|
|
*
|
|
* - inDescriptor is a null terminated string that will become the widget's
|
|
* descriptor.
|
|
*
|
|
* - inIsRoot is 1 if this is going to be a root widget, 0 if it will not be.
|
|
*
|
|
* - inContainer is the ID of this widget's container. It must be 0 for a
|
|
* root widget. for a non-root widget, pass the widget ID of the widget to
|
|
* place this widget within. If this widget is not going to start inside
|
|
* another widget, pass 0; this new widget will then just be floating off in
|
|
* space (and will not be drawn until it is placed in a widget.
|
|
*
|
|
* - inClass is the class of the widget to draw. Use one of the predefined
|
|
* class-IDs to create a standard widget.
|
|
*
|
|
* A note on widget embedding: a widget is only called (and will be drawn,
|
|
* etc.) if it is placed within a widget that will be called. Root widgets
|
|
* are always called. So it is possible to have whole chains of widgets that
|
|
* are simply not called. You can preconstruct widget trees and then place
|
|
* them into root widgets later to activate them if you wish.
|
|
*
|
|
*/
|
|
WIDGET_API XPWidgetID XPCreateWidget(int inLeft,
|
|
int inTop,
|
|
int inRight,
|
|
int inBottom,
|
|
int inVisible,
|
|
const char *inDescriptor,
|
|
int inIsRoot,
|
|
XPWidgetID inContainer,
|
|
XPWidgetClass inClass);
|
|
|
|
/*
|
|
* XPCreateCustomWidget
|
|
*
|
|
* This function is the same as XPCreateWidget except that instead of passing
|
|
* a class ID, you pass your widget callback function pointer defining the
|
|
* widget. Use this function to define a custom widget. All parameters are
|
|
* the same as XPCreateWidget, except that the widget class has been replaced
|
|
* with the widget function.
|
|
*
|
|
*/
|
|
WIDGET_API XPWidgetID XPCreateCustomWidget(int inLeft,
|
|
int inTop,
|
|
int inRight,
|
|
int inBottom,
|
|
int inVisible,
|
|
const char *inDescriptor,
|
|
int inIsRoot,
|
|
XPWidgetID inContainer,
|
|
XPWidgetFunc_t inCallback);
|
|
|
|
/*
|
|
* XPDestroyWidget
|
|
*
|
|
* This class destroys a widget. Pass in the ID of the widget to kill. If
|
|
* you pass 1 for inDestroyChilren, the widget's children will be destroyed
|
|
* first, then this widget will be destroyed. (Furthermore, the widget's
|
|
* children will be destroyed with the inDestroyChildren flag set to 1, so the
|
|
* destruction will recurse down the widget tree.) If you pass 0 for this
|
|
* flag, the child widgets will simply end up with their parent set to 0.
|
|
*
|
|
*/
|
|
WIDGET_API void XPDestroyWidget(XPWidgetID inWidget, int inDestroyChildren);
|
|
|
|
/*
|
|
* XPSendMessageToWidget
|
|
*
|
|
* This sends any message to a widget. You should probably not go around
|
|
* simulating the predefined messages that the widgets library defines for
|
|
* you. You may however define custom messages for your widgets and send them
|
|
* with this method.
|
|
*
|
|
* This method supports several dispatching patterns; see XPDispatchMode for
|
|
* more info. The function returns 1 if the message was handled, 0 if it was
|
|
* not.
|
|
*
|
|
* For each widget that receives the message (see the dispatching modes), each
|
|
* widget function from the most recently installed to the oldest one
|
|
* receives the message in order until it is handled.
|
|
*
|
|
*/
|
|
WIDGET_API int XPSendMessageToWidget(XPWidgetID inWidget,
|
|
XPWidgetMessage inMessage,
|
|
XPDispatchMode inMode,
|
|
intptr_t inParam1,
|
|
intptr_t inParam2);
|
|
|
|
/***************************************************************************
|
|
* WIDGET POSITIONING AND VISIBILITY
|
|
***************************************************************************/
|
|
/*
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
/*
|
|
* XPPlaceWidgetWithin
|
|
*
|
|
* This function changes which container a widget resides in. You may NOT use
|
|
* this function on a root widget! inSubWidget is the widget that will be
|
|
* moved. Pass a widget ID in inContainer to make inSubWidget be a child of
|
|
* inContainer. It will become the last/closest widget in the container.
|
|
* Pass 0 to remove the widget from any container. Any call to this other
|
|
* than passing the widget ID of the old parent of the affected widget will
|
|
* cause the widget to be removed from its old parent. Placing a widget within
|
|
* its own parent simply makes it the last widget.
|
|
*
|
|
* NOTE: this routine does not reposition the sub widget in global
|
|
* coordinates. If the container has layout management code, it will
|
|
* reposition the subwidget for you, otherwise you must do it with
|
|
* SetWidgetGeometry.
|
|
*
|
|
*/
|
|
WIDGET_API void XPPlaceWidgetWithin(XPWidgetID inSubWidget,
|
|
XPWidgetID inContainer);
|
|
|
|
/*
|
|
* XPCountChildWidgets
|
|
*
|
|
* This routine returns the number of widgets another widget contains.
|
|
*
|
|
*/
|
|
WIDGET_API int XPCountChildWidgets(XPWidgetID inWidget);
|
|
|
|
/*
|
|
* XPGetNthChildWidget
|
|
*
|
|
* This routine returns the widget ID of a child widget by index. Indexes are
|
|
* 0 based, from 0 to one minus the number of widgets in the parent,
|
|
* inclusive. If the index is invalid, 0 is returned.
|
|
*
|
|
*/
|
|
WIDGET_API XPWidgetID XPGetNthChildWidget(XPWidgetID inWidget, int inIndex);
|
|
|
|
/*
|
|
* XPGetParentWidget
|
|
*
|
|
* This routine returns the parent of a widget, or 0 if the widget has no
|
|
* parent. Root widgets never have parents and therefore always return 0.
|
|
*
|
|
*/
|
|
WIDGET_API XPWidgetID XPGetParentWidget(XPWidgetID inWidget);
|
|
|
|
/*
|
|
* XPShowWidget
|
|
*
|
|
* This routine makes a widget visible if it is not already. Note that if a
|
|
* widget is not in a rooted widget hierarchy or one of its parents is not
|
|
* visible, it will still not be visible to the user.
|
|
*
|
|
*/
|
|
WIDGET_API void XPShowWidget(XPWidgetID inWidget);
|
|
|
|
/*
|
|
* XPHideWidget
|
|
*
|
|
* Makes a widget invisible. See XPShowWidget for considerations of when a
|
|
* widget might not be visible despite its own visibility state.
|
|
*
|
|
*/
|
|
WIDGET_API void XPHideWidget(XPWidgetID inWidget);
|
|
|
|
/*
|
|
* XPIsWidgetVisible
|
|
*
|
|
* This returns 1 if a widget is visible, 0 if it is not. Note that this
|
|
* routine takes into consideration whether a parent is invisible. Use this
|
|
* routine to tell if the user can see the widget.
|
|
*
|
|
*/
|
|
WIDGET_API int XPIsWidgetVisible(XPWidgetID inWidget);
|
|
|
|
/*
|
|
* XPFindRootWidget
|
|
*
|
|
* XPFindRootWidget returns the Widget ID of the root widget that contains the
|
|
* passed in widget or NULL if the passed in widget is not in a rooted
|
|
* hierarchy.
|
|
*
|
|
*/
|
|
WIDGET_API XPWidgetID XPFindRootWidget(XPWidgetID inWidget);
|
|
|
|
/*
|
|
* XPBringRootWidgetToFront
|
|
*
|
|
* This routine makes the specified widget be in the front most widget
|
|
* hierarchy. If this widget is a root widget, its widget hierarchy comes to
|
|
* front, otherwise the widget's root is brought to the front. If this widget
|
|
* is not in an active widget hiearchy (e.g. there is no root widget at the
|
|
* top of the tree), this routine does nothing.
|
|
*
|
|
*/
|
|
WIDGET_API void XPBringRootWidgetToFront(XPWidgetID inWidget);
|
|
|
|
/*
|
|
* XPIsWidgetInFront
|
|
*
|
|
* This routine returns true if this widget's hierarchy is the front most
|
|
* hierarchy. It returns false if the widget's hierarchy is not in front, or
|
|
* if the widget is not in a rooted hierarchy.
|
|
*
|
|
*/
|
|
WIDGET_API int XPIsWidgetInFront(XPWidgetID inWidget);
|
|
|
|
/*
|
|
* XPGetWidgetGeometry
|
|
*
|
|
* This routine returns the bounding box of a widget in global coordinates.
|
|
* Pass NULL for any parameter you are not interested in.
|
|
*
|
|
*/
|
|
WIDGET_API void XPGetWidgetGeometry(XPWidgetID inWidget,
|
|
int *outLeft, /* Can be NULL */
|
|
int *outTop, /* Can be NULL */
|
|
int *outRight, /* Can be NULL */
|
|
int *outBottom); /* Can be NULL */
|
|
|
|
/*
|
|
* XPSetWidgetGeometry
|
|
*
|
|
* This function changes the bounding box of a widget.
|
|
*
|
|
*/
|
|
WIDGET_API void XPSetWidgetGeometry(XPWidgetID inWidget,
|
|
int inLeft,
|
|
int inTop,
|
|
int inRight,
|
|
int inBottom);
|
|
|
|
/*
|
|
* XPGetWidgetForLocation
|
|
*
|
|
* Given a widget and a location, this routine returns the widget ID of the
|
|
* child of that widget that owns that location. If inRecursive is true then
|
|
* this will return a child of a child of a widget as it tries to find the
|
|
* deepest widget at that location. If inVisibleOnly is true, then only
|
|
* visible widgets are considered, otherwise all widgets are considered. The
|
|
* widget ID passed for inContainer will be returned if the location is in
|
|
* that widget but not in a child widget. 0 is returned if the location is
|
|
* not in the container.
|
|
*
|
|
* NOTE: if a widget's geometry extends outside its parents geometry, it will
|
|
* not be returned by this call for mouse locations outside the parent
|
|
* geometry. The parent geometry limits the child's eligibility for mouse
|
|
* location.
|
|
*
|
|
*/
|
|
WIDGET_API XPWidgetID XPGetWidgetForLocation(XPWidgetID inContainer,
|
|
int inXOffset,
|
|
int inYOffset,
|
|
int inRecursive,
|
|
int inVisibleOnly);
|
|
|
|
/*
|
|
* XPGetWidgetExposedGeometry
|
|
*
|
|
* This routine returns the bounds of the area of a widget that is completely
|
|
* within its parent widgets. Since a widget's bounding box can be outside
|
|
* its parent, part of its area will not be elligible for mouse clicks and
|
|
* should not draw. Use XPGetWidgetGeometry to find out what area defines
|
|
* your widget's shape, but use this routine to find out what area to actually
|
|
* draw into. Note that the widget library does not use OpenGL clipping to
|
|
* keep frame rates up, although you could use it internally.
|
|
*
|
|
*/
|
|
WIDGET_API void XPGetWidgetExposedGeometry(XPWidgetID inWidgetID,
|
|
int *outLeft, /* Can be NULL */
|
|
int *outTop, /* Can be NULL */
|
|
int *outRight, /* Can be NULL */
|
|
int *outBottom); /* Can be NULL */
|
|
|
|
/***************************************************************************
|
|
* ACCESSING WIDGET DATA
|
|
***************************************************************************/
|
|
/*
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
/*
|
|
* XPSetWidgetDescriptor
|
|
*
|
|
* Every widget has a descriptor, which is a text string. What the text
|
|
* string is used for varies from widget to widget; for example, a push
|
|
* button's text is its descriptor, a caption shows its descriptor, and a text
|
|
* field's descriptor is the text being edited. In other words, the usage for
|
|
* the text varies from widget to widget, but this API provides a universal
|
|
* and convenient way to get at it. While not all UI widgets need their
|
|
* descriptor, many do.
|
|
*
|
|
*/
|
|
WIDGET_API void XPSetWidgetDescriptor(XPWidgetID inWidget,
|
|
const char *inDescriptor);
|
|
|
|
/*
|
|
* XPGetWidgetDescriptor
|
|
*
|
|
* This routine returns the widget's descriptor. Pass in the length of the
|
|
* buffer you are going to receive the descriptor in. The descriptor will be
|
|
* null terminated for you. This routine returns the length of the actual
|
|
* descriptor; if you pass NULL for outDescriptor, you can get the
|
|
* descriptor's length without getting its text. If the length of the
|
|
* descriptor exceeds your buffer length, the buffer will not be null
|
|
* terminated (this routine has 'strncpy' semantics).
|
|
*
|
|
*/
|
|
WIDGET_API int XPGetWidgetDescriptor(XPWidgetID inWidget,
|
|
char *outDescriptor,
|
|
int inMaxDescLength);
|
|
|
|
/*
|
|
* XPSetWidgetProperty
|
|
*
|
|
* This function sets a widget's property. Properties are arbitrary values
|
|
* associated by a widget by ID.
|
|
*
|
|
*/
|
|
WIDGET_API void XPSetWidgetProperty(XPWidgetID inWidget,
|
|
XPWidgetPropertyID inProperty,
|
|
intptr_t inValue);
|
|
|
|
/*
|
|
* XPGetWidgetProperty
|
|
*
|
|
* This routine returns the value of a widget's property, or 0 if the property
|
|
* is not defined. If you need to know whether the property is defined, pass
|
|
* a pointer to an int for inExists; the existence of that property will be
|
|
* returned in the int. Pass NULL for inExists if you do not need this
|
|
* information.
|
|
*
|
|
*/
|
|
WIDGET_API intptr_t XPGetWidgetProperty(XPWidgetID inWidget,
|
|
XPWidgetPropertyID inProperty,
|
|
int *inExists); /* Can be NULL */
|
|
|
|
/***************************************************************************
|
|
* KEYBOARD MANAGEMENT
|
|
***************************************************************************/
|
|
/*
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
/*
|
|
* XPSetKeyboardFocus
|
|
*
|
|
* XPSetKeyboardFocus controls which widget will receive keystrokes. Pass the
|
|
* Widget ID of the widget to get the keys. Note that if the widget does not
|
|
* care about keystrokes, they will go to the parent widget, and if no widget
|
|
* cares about them, they go to X-Plane.
|
|
*
|
|
* If you set the keyboard focus to Widget ID 0, X-Plane gets keyboard focus.
|
|
*
|
|
* This routine returns the widget ID that ended up with keyboard focus, or 0
|
|
* for x-plane.
|
|
*
|
|
* Keyboard focus is not changed if the new widget will not accept it. For
|
|
* setting to x-plane, keyboard focus is always accepted.
|
|
*
|
|
* *
|
|
*/
|
|
WIDGET_API XPWidgetID XPSetKeyboardFocus(XPWidgetID inWidget);
|
|
|
|
/*
|
|
* XPLoseKeyboardFocus
|
|
*
|
|
* This causes the specified widget to lose focus; focus is passed to its
|
|
* parent, or the next parent that will accept it. This routine does nothing
|
|
* if this widget does not have focus.
|
|
*
|
|
*/
|
|
WIDGET_API void XPLoseKeyboardFocus(XPWidgetID inWidget);
|
|
|
|
/*
|
|
* XPGetWidgetWithFocus
|
|
*
|
|
* This routine returns the widget that has keyboard focus, or 0 if X-Plane
|
|
* has keyboard focus or some other plugin window that does not have widgets
|
|
* has focus.
|
|
*
|
|
*/
|
|
WIDGET_API XPWidgetID XPGetWidgetWithFocus(void);
|
|
|
|
/***************************************************************************
|
|
* CREATING CUSTOM WIDGETS
|
|
***************************************************************************/
|
|
/*
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
/*
|
|
* XPAddWidgetCallback
|
|
*
|
|
* This function adds a new widget callback to a widget. This widget callback
|
|
* supercedes any existing ones and will receive messages first; if it does
|
|
* not handle messages they will go on to be handled by pre-existing widgets.
|
|
*
|
|
* The widget function will remain on the widget for the life of the widget.
|
|
* The creation message will be sent to the new callback immediately with the
|
|
* widget ID, and the destruction message will be sent before the other widget
|
|
* function receives a destruction message.
|
|
*
|
|
* This provides a way to 'subclass' an existing widget. By providing a
|
|
* second hook that only handles certain widget messages, you can customize or
|
|
* extend widget behavior.
|
|
*
|
|
*/
|
|
WIDGET_API void XPAddWidgetCallback(XPWidgetID inWidget,
|
|
XPWidgetFunc_t inNewCallback);
|
|
|
|
/*
|
|
* XPGetWidgetClassFunc
|
|
*
|
|
* Given a widget class, this function returns the callbacks that power that
|
|
* widget class.
|
|
*
|
|
*/
|
|
WIDGET_API XPWidgetFunc_t XPGetWidgetClassFunc(XPWidgetClass inWidgetClass);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|