diff options
Diffstat (limited to 'NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx')
-rw-r--r-- | NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx | 641 |
1 files changed, 641 insertions, 0 deletions
diff --git a/NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx b/NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx new file mode 100644 index 000000000..9fedd4618 --- /dev/null +++ b/NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx @@ -0,0 +1,641 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/include/cwidgetcontrol.hxx + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * 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. + * 3. Neither the name NuttX, NxWidgets, nor the names of its contributors + * me be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 + * COPYRIGHT OWNER OR CONTRIBUTORS 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. + * + ****************************************************************************/ + +#ifndef __INCLUDE_CWIDGETCONTROLT_HXX +#define __INCLUDE_CWIDGETCONTROLT_HXX + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> +#include <semaphore.h> +#include <time.h> + +#include "nxconfig.hxx" +#include "cgraphicsport.hxx" +#include "cnxwidget.hxx" +#include "crect.hxx" +#include "cwidgetstyle.hxx" +#include "tnxarray.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Implementation Classes + ****************************************************************************/ + +#if defined(__cplusplus) + +namespace NXWidgets +{ + class INxWindow; + class CNxWidget; + + /** + * Class providing a top-level widget and an interface to the CWidgetControl + * widget hierarchy. + * + * There are three instances that represent an NX window from the + * perspective of NXWidgets. + * + * - There is one widget control instance per NX window, + * - One CCallback instance per window, + * - One window instance. + * + * There a various kinds of of window instances, but each inherits + * (1) CCallback and dispatches the Windows callbacks and (2) INxWindow + * that describes the common window behavior. + */ + + class CWidgetControl + { + protected: + /** + * Structure holding the status of the Mouse or Touchscreen. There must + * be one instance of this structure per window instance. The + * content of this structure is update by the CGraphicsPort on each + * NX mouse callback + */ + + struct SMouse + { +#if 0 // Center and right buttons are not used + uint16_t leftPressed : 1; /**< Left button pressed (or + touchscreen contact) */ + uint16_t centerPressed : 1; /**< Center button pressed (not + used with touchscreen) */ + uint16_t rightPressed : 1; /**< Right button pressed (not + used with touchscreen) */ + uint16_t leftHeld : 1; /**< Left button held down (or + touchscreen contact) */ + uint16_t centerHeld : 1; /**< Center button held down + (not used with touchscreen) */ + uint16_t rightHeld : 1; /**< Right button held down + (not used with touchscreen) */ + uint16_t leftDrag : 1; /**< Left button held down (or + touchscreen contact) */ + uint16_t centerDrag : 1; /**< Center button held down (or + touchscreen contact) */ + uint16_t rightDrag : 1; /**< Right button held down (or + touchscreen contact) */ + uint16_t leftReleased : 1; /**< Left button release (or + loss of touchscreen contact) */ + uint16_t centerReleased : 1; /**< Center button release (or + loss of touchscreen contact) */ + uint16_t rightReleased : 1; /**< Right button release (or + loss of touchscreen contact) */ + uint16_t doubleClick : 1; /**< Left button double click */ + uint16_t unused : 3; /**< Padding bits */ +#else + uint8_t leftPressed : 1; /**< Left button pressed (or + touchscreen contact) */ + uint8_t leftHeld : 1; /**< Left button held down (or + touchscreen contact) */ + uint8_t leftDrag : 1; /**< Left button held down (or + touchscreen contact) */ + uint8_t leftReleased : 1; /**< Left button release (or + loss of touchscreen contact) */ + uint8_t doubleClick : 1; /**< Left button double click */ + uint8_t unused : 3; /**< Padding bits */ +#endif + nxgl_coord_t x; /**< Current X coordinate of + the mouse/touch */ + nxgl_coord_t y; /**< Current Y coordinate of + the mouse/touch */ + nxgl_coord_t lastX; /**< X coordinate of the mouse + at the previous poll */ + nxgl_coord_t lastY; /**< Y coordinate of the mouse + at the previous poll */ + struct timespec leftPressTime; /**< Time the left button was + pressed */ + struct timespec leftReleaseTime; /**< Time the left button was + released */ + }; + + /** + * State data + */ + + CGraphicsPort *m_port; /**< The graphics port + that is used for + drawing on this window */ + TNxArray<CNxWidget*> m_deleteQueue; /**< Array of widgets + awaiting deletion. */ + TNxArray<CNxWidget*> m_widgets; /**< List of controlled + widgets. */ + bool m_modal; /**< True: in modal loop */ + sem_t m_modalsem; /**< Modal loops waits for + events on this semaphore */ + /** + * I/O + */ + + struct SMouse m_mouse; /**< Current pointer + device state */ + CNxWidget *m_clickedWidget; /**< Pointer to the widget + that is clicked. */ + CNxWidget *m_focusedWidget; /**< Pointer to the widget + that received keyboard + input. */ + uint8_t m_kbdbuf[CONFIG_NXWIDGETS_KBDBUFFER_SIZE]; + uint8_t m_nCh; /**< Number of buffered + keyboard characters */ + uint8_t m_controls[CONFIG_NXWIDGETS_CURSORCONTROL_SIZE]; + uint8_t m_nCc; /**< Number of buffered + cursor controls */ + /** + * The following were picked off from the position callback. + */ + + NXHANDLE m_hWindow; /**< Handle to the NX window */ + struct nxgl_size_s m_size; /**< Size of the window */ + struct nxgl_point_s m_pos; /**< Position in display space */ + struct nxgl_rect_s m_bounds; /**< Size of the display */ + + /** + * Style + */ + + CWidgetStyle m_style; /**< Default style used by all + widgets in the window. */ + + /** + * Copy a widget style + * + * @param dest The destination style + * @param src The source to use + */ + + void copyWidgetStyle(CWidgetStyle *dest, const CWidgetStyle *src); + + /** + * Return the elapsed time in millisconds + * + * @param startTime A time in the past from which to compute the elapsed time. + * @return The elapsed time since startTime + */ + + uint32_t elapsedTime(FAR const struct timespec *startTime); + + /** + * Pass clicks to the widget hierarchy. Closes the context menu if + * the clicked widget is not the context menu. If a single widget + * is supplied, only that widget is sent the click. That widget + * should be running modally. + * + * @param x Click xcoordinate. + * @param y Click ycoordinate. + * @param widget Pointer to a modally-running widget or NULL. + */ + + void handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, CNxWidget* widget); + + /** + * Get the index of the specified controlled widget. + * + * @param widget The widget to get the index of. + * @return The index of the widget. -1 if the widget is not found. + */ + + const int getWidgetIndex(const CNxWidget *widget) const; + + /** + * Delete any widgets in the deletion queue. + */ + + void processDeleteQueue(void); + + /** + * Process mouse/touchscreen events and send throughout the hierarchy. + * + * @param widget to process, used for modal widgets; omit this parameter + * to run the whole system. + * @return True means a mouse event occurred + */ + + bool pollMouseEvents(CNxWidget* widget); + + /** + * Process keypad events and send throughout the hierarchy. + * + * @return True means a keyboard event occurred + */ + + bool pollKeyboardEvents(void); + + /** + * Process cursor control events and send throughout the hierarchy. + * + * @return True means a cursor control event was processes + */ + + bool pollCursorControlEvents(void); + + /** + * Wake up the modal loop + */ + + void wakeupModalLoop(void); + + /** + * Clear all mouse events + */ + + void clearMouseEvents(void); + + public: + + /** + * Constructor + * + * @param style The default style that all widgets on this display + * should use. If this is not specified, the widget will use the + * values stored in the defaultCWidgetStyle object. + */ + + CWidgetControl(FAR const CWidgetStyle *style = (const CWidgetStyle *)NULL); + + /** + * Destructor. + */ + + ~CWidgetControl(void); + + /** + * Run the widget modally. This will run the CWidgetControl + * application until stopModal() is called. + */ + + void goModal(void); + + /** + * Wait for an interesting modal event to occur (like a mouse or keyboard event) + */ + + void waitForModalEvent(void); + + /** + * Is the widget modal? Only true if the Widget singleton is also modal. + * + * @return True if the widget is modal. + */ + + inline const bool isModal(void) const + { + return m_modal; + } + + /** + * Stop the widget running modally. + */ + + void stopModal(void); + + /** + * Run all code that needs to take place on a periodic basis. + * This is normally called from and is the main body of goModal() + * with widget == NULL. + * + * @param widget Sub-widget to run, used for modal widgets; omit + * this parameter to run the whole system. + * @return True means some interesting event occurred + */ + + bool pollEvents(CNxWidget *widget = (CNxWidget *)NULL); + + /** + * Swaps the depth of the supplied widget. + * This function presumes that all child widgets are screens. + * + * @param widget The widget to be depth-swapped. + * @return True if the depth swap occurred. + */ + + bool swapWidgetDepth(CNxWidget *widget); + + /** + * Redraws any dirty regions within the supplied region. + * + * @param rect The region to redraw + */ + + void eraseRect(CRect rect); + + /** + * Add another widget to be managed by this control instance + * + * @param widget The widget to be controlled. + */ + + inline void addControlledWidget(CNxWidget* widget) + { + m_widgets.push_back(widget); + } + + /** + * Remove a controlled widget + * + * @param widget The widget to be removed + */ + + void removeControlledWidget(CNxWidget* widget); + + /** + * Get the number of controlled widgets. + * + * @return The number of child widgets belonging to this widget. + */ + + inline const int getControlledWidgetCount(void) const + { + return m_widgets.size(); + } + + /** + * Add a widget to the list of widgets to be deleted. + * Must never be called by anything other than the framework itself. + * + * @param widget The widget to add to the delete queue. + */ + + void addToDeleteQueue(CNxWidget *widget); + + /** + * Set the clicked widget pointer. Note that this should not be + * called by code other than within the CWidgetControl library itself. + * + * @param widget The new clicked widget. + */ + + void setClickedWidget(CNxWidget *widget); + + /** + * Get the clicked widget pointer. + * + * @return Pointer to the clicked widget. + */ + + inline CNxWidget *getClickedWidget(void) + { + return m_clickedWidget; + } + + /** + * Set the focused widget that will receive keyboard input. + * + * @param widget The new focused widget. + */ + + void setFocusedWidget(CNxWidget *widget); + + /** + * Reset the focused widget so that it will no longer receive keyboard input. + * + * @param widget The new focused widget. + */ + + void clearFocusedWidget(CNxWidget *widget) + { + if (widget == m_focusedWidget) + { + m_focusedWidget = (CNxWidget *)NULL; + } + } + + /** + * Get the focused widget pointer. + * + * @return Pointer to the focused widget. + */ + + inline CNxWidget *getFocusedWidget(void) + { + return m_focusedWidget; + } + + /** + * Check for the occurrence of a double click. + * + * @return Pointer to the clicked widget. + */ + + inline bool doubleClick(void) + { + return (bool)m_mouse.doubleClick; + } + + /** + * Get the default widget style for this window. + * + * @return Pointer to the clicked widget. + */ + + inline void getWidgetStyle(CWidgetStyle *style) + { + copyWidgetStyle(style, &m_style); + } + + /** + * These remaining methods are used by the CCallback instance to + * provide notifications of certain events. + */ + + /** + * This event will occur when the position or size of the underlying + * window occurs. + * + * @param hWindow The window handle that should be used to communicate + * with the window + * @param pos The position of the window in the physical device space. + * @param size The size of the window. + * @param bounds The size of the underlying display (pixels x rows) + */ + + void geometryEvent(NXHANDLE hWindow, + const struct nxgl_size_s *size, + const struct nxgl_point_s *pos, + const struct nxgl_rect_s *bounds); + + /** + * This event will occur when the a portion of the window that was + * previously obscured is now exposed. + * + * @param nxRect The region in the window that must be redrawn. + * @param more True means that more re-draw requests will follow + */ + + void redrawEvent(FAR const struct nxgl_rect_s *nxRect, bool more); + + /** + * This event means that new mouse data is available for the window. + * + * @param pPos The (x,y) position of the mouse. + * @param buttons See NX_MOUSE_* definitions. + */ + + void newMouseEvent(FAR const struct nxgl_point_s *pPos, uint8_t buttons); + + /** + * This event means that keyboard/keypad data is available for the window. + * + * @param nCh The number of characters that are available in pStr[]. + * @param pStr The array of characters. + */ + + void newKeyboardEvent(uint8_t nCh, FAR const uint8_t *pStr); + + /** + * This event means that cursor control data is available for the window. + * + * @param cursorControl The cursor control code received. + */ + + void newCursorControlEvent(ECursorControl cursorControl); + + /** + * Get the window handle reported on the first position callback. + * + * @return This function returns the window handle. + */ + + inline NXHANDLE getWindowHandle(void) + { + return m_hWindow; + } + + /** + * Get the window bounding box in physical display coordinated. + * + * @return This function returns the window handle. + */ + + inline CRect getWindowBoundingBox(void) + { + return CRect(&m_bounds); + } + + /** + * Get the position of the window (as reported by the last NX callback). + * + * @return The position. + */ + + inline bool getWindowPosition(FAR struct nxgl_point_s *pPos) + { + pPos->x = m_pos.x; + pPos->x = m_pos.y; + return true; + } + + /** + * Get the size of the window (as reported by the last NX callback). + * + * @return The size. + */ + + inline bool getWindowSize(FAR struct nxgl_size_s *pSize) + { + pSize->h = m_size.h; + pSize->w = m_size.w; + return true; + } + + /** + * Get the width of the window (as reported by the last NX callback). + * + * @return The size. + */ + + inline nxgl_coord_t getWindowWidth(void) + { + return m_size.w; + } + + /** + * Get the height of the window (as reported by the last NX callback). + * + * @return The size. + */ + + inline nxgl_coord_t getWindowHeight(void) + { + return m_size.h; + } + + /** + * The creation sequence is: + * + * 1) Create a dumb CWigetControl instance + * 2) Pass the dumb CWidgetControl instance to the window constructor + * that inherits from INxWindow. + * 3) The call this method with the static_cast to INxWindow to, + * finally, create the CGraphicsPort for this window. + * 4) After that, the fully smartend CWidgetControl instance can + * be used to generate additional widgets. + * + * @param window The instance of INxWindow needed to construct the + * CGraphicsPort instance + */ + + inline bool createGraphicsPort(INxWindow *window) + { + m_port = new CGraphicsPort(window); + return m_port != (CGraphicsPort *)NULL; + } + + /** + * Get the CGraphicsPort instance for drawing on this window + */ + + inline CGraphicsPort *getGraphicsPort(void) + { + return m_port; + } + }; +} + +#endif // __cplusplus + +#endif // __INCLUDE_CWIDGETCONTROLT_HXX |