2022-01-01 23:50:23 +01:00

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