ray

Owner: IIIlllIIIllI URL: git@github.com:nyangkosense/ray.git

SDK/CHeaders/Widgets/XPWidgets.h

#ifndef _XPWidgets_h_
#define _XPWidgets_h_

/*
 * Copyright 2005-2022 Laminar Research, Sandy Barbour and Ben Supnik All
 * rights reserved.  See license.txt for usage. X-Plane SDK Version: 4.0.0
 *
 */

/***************************************************************************
 * XPWidgets
 ***************************************************************************/
/*
 * ## 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 callback procedures 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
 *   implemented as XPLMDisplay windows.
 *
 */

#include "XPWidgetDefs.h"
#include "XPLMDisplay.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 be created but will not be drawn
 *   until it is placed inside another 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, direct 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 the number of widgets in the parentone minus one,
 * inclusive. If the index is invalid, 0 is returned.
 *
 */
WIDGET_API XPWidgetID XPGetNthChildWidget(
                         XPWidgetID           inWidget,
                         int                  inIndex);

/*
 * XPGetParentWidget
 * 
 * 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
 * 
 * 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 frontmost 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 frontmost
 * 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 eligible 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);

/*
 * XPGetWidgetUnderlyingWindow
 * 
 * Returns the window (from the XPLMDisplay API) that backs your widget
 * window. If you have opted in to modern windows, via a call to
 * XPLMEnableFeature("XPLM_USE_NATIVE_WIDGET_WINDOWS", 1), you can use the
 * returned window ID for display APIs like XPLMSetWindowPositioningMode(),
 * allowing you to pop the widget window out into a real OS window, or move it
 * into VR.
 *
 */
WIDGET_API XPLMWindowID XPGetWidgetUnderlyingWindow(
                         XPWidgetID           inWidget);

/*
 * 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
 * 
 * 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