diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-03-22 21:22:59 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-03-22 21:22:59 +0000 |
commit | 4dedf494c242b2c4b52707441eefe2a36fbacf0f (patch) | |
tree | 36728130c995053f18637c019829f492f0c3b3fe /NxWidgets/libnxwidgets/src | |
parent | af2319a52f4b11df952a5a1060c76cc0cdff0b98 (diff) | |
download | px4-nuttx-4dedf494c242b2c4b52707441eefe2a36fbacf0f.tar.gz px4-nuttx-4dedf494c242b2c4b52707441eefe2a36fbacf0f.tar.bz2 px4-nuttx-4dedf494c242b2c4b52707441eefe2a36fbacf0f.zip |
First check-in of NxWidgets
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4505 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'NxWidgets/libnxwidgets/src')
75 files changed, 29575 insertions, 0 deletions
diff --git a/NxWidgets/libnxwidgets/src/cbgwindow.cxx b/NxWidgets/libnxwidgets/src/cbgwindow.cxx new file mode 100644 index 000000000..08ae584b8 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cbgwindow.cxx @@ -0,0 +1,364 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cbgwindow.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cwidgetcontrol.hxx" +#include "cbgwindow.hxx" +#include "cbitmap.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. Obtains the background window from server and wraps + * the window as CBgWindow. + * + * @param hNxServer Handle to the NX server. + * @param widgetControl Controlling widget for this window. + */ + +CBgWindow::CBgWindow(NXHANDLE hNxServer, CWidgetControl *pWidgetControl) + : CCallback(pWidgetControl), m_hNxServer(hNxServer), m_hWindow(0), + m_widgetControl(pWidgetControl) +{ + // Create the CGraphicsPort instance for this window + + m_widgetControl->createGraphicsPort(static_cast<INxWindow*>(this)); +} + +/** + * Destructor. Returns the background window to the server. + */ + +CBgWindow::~CBgWindow(void) +{ + // Release the background. We do not release the widget control + // instance. The lifetime of that instance is owned by he-who- + // constructed-us. + + (void)nx_releasebkgd(m_hWindow); +} + +/** + * Creates a new window. Window creation is separate from + * object instantiation so that failures can be reported. + * + * @return True if the window was successfully opened. + */ + +bool CBgWindow::open(void) +{ + // Get the C-callable callback vtable + + FAR struct nx_callback_s *vtable = getCallbackVTable(); + + // Request the background the window + + int ret = nx_requestbkgd(m_hNxServer, vtable, (FAR void *)m_widgetControl); + if (ret < 0) + { + return false; + } + + // Window handle (picked off by the callback logic) + + m_hWindow = m_widgetControl->getWindowHandle(); + return true; +} + +/** + * Request the position and size information of the window. The values + * will be returned asynchronously through the client callback method. + * The GetPosition() method may than be called to obtain the positional + * data as provided by the callback. + * + * @return Always returns true. + */ + +bool CBgWindow::requestPosition(void) +{ + // The background window is always at {0,0} and the size never changes. + + return true; +} + +/** + * Get the position of the window (as reported by the NX callback). NOTE: + * The background window is always positioned at {0,0} + * + * @return The position. + */ + +bool CBgWindow::getPosition(FAR struct nxgl_point_s *pPos) +{ + // The background window is always at {0,0} + + pPos->x = 0; + pPos->y = 0; + return true; +} + +/** + * Get the size of the window (as reported by the NX callback). NOTE: + * The size of the background window is always the entire display. + * + * @return The size. + */ + +bool CBgWindow::getSize(FAR struct nxgl_size_s *pSize) +{ + // The size is always the full size of the display + + return m_widgetControl->getWindowSize(pSize); +} + +/** + * Set the position and size of the window. + * + * @param pPos The new position of the window. + * @return Always returns false. + */ + +bool CBgWindow::setPosition(FAR const struct nxgl_point_s *pPos) +{ + // The position of the background cannot be changed + + return false; +} + +/** + * Set the size of the selected window. NOTE: The size of the + * background window is always the entire display and cannot be + * changed. + * + * @param pSize The new size of the window. + * @return Always returns false. + */ + +bool CBgWindow::setSize(FAR const struct nxgl_size_s *pSize) +{ + // The position of the background cannot be changed + + return false; +} + +/** + * Bring the window to the top of the display. NOTE: The background + * window cannot be raised. + * + * @return Always returns false. + */ + +bool CBgWindow::raise(void) +{ + // The background cannot be raised + + return false; +} + +/** + * Lower the window to the bottom of the display. NOTE: The background + * window is always at the bottom of the window hierarchy. + * + * @return Always returns false. + */ + +bool CBgWindow::lower(void) +{ + // The background cannot be lowered + + return false; +} + +/** + * Set an individual pixel in the window with the specified color. + * + * @param pPos The location of the pixel to be filled. + * @param color The color to use in the fill. + * + * @return True on success; false on failure. + */ + +bool CBgWindow::setPixel(FAR const struct nxgl_point_s *pPos, + nxgl_mxpixel_t color) +{ + // Set an individual pixel to the specified color + + return nx_setpixel(m_hWindow, pPos, &color) == OK; +} + +/** + * Fill the specified rectangle in the window with the specified color. + * + * @param pRect The location to be filled. + * @param color The color to use in the fill. + * + * @return True on success; false on failure. + */ + +bool CBgWindow::fill(FAR const struct nxgl_rect_s *pRect, + nxgl_mxpixel_t color) +{ + // Fill a rectangular region with a solid color + + return nx_fill(m_hWindow, pRect, &color) == OK; +} + +/** + * Get the raw contents of graphic memory within a rectangular region. NOTE: + * Since raw graphic memory is returned, the returned memory content may be + * the memory of windows above this one and may not necessarily belong to + * this window unless you assure that this is the top window. + * + * @param rect The location to be copied + * @param dest - The describes the destination bitmap to receive the + * graphics data. + */ + +void CBgWindow::getRectangle(FAR const struct nxgl_rect_s *rect, struct SBitmap *dest) +{ + // Get a rectangule region from the window + + (void)nx_getrectangle(m_hWindow, rect, 0, (FAR uint8_t*)dest->data, dest->stride); +} + +/** + * Fill the specified trapezoidal region in the window with the specified + * color. + * + * @param pClip Clipping rectangle relative to window (may be null). + * @param pTrap The trapezoidal region to be filled. + * @param color The color to use in the fill. + * + * @return True on success; false on failure. + */ + +bool CBgWindow::fillTrapezoid(FAR const struct nxgl_rect_s *pClip, + FAR const struct nxgl_trapezoid_s *pTrap, + nxgl_mxpixel_t color) +{ + // Fill a trapezoidal region with a solid color + + return nx_filltrapezoid(m_hWindow, pClip, pTrap, &color) == OK; +} + +/** + * Fill the specified line in the window with the specified color. + * + * @param vector - Describes the line to be drawn + * @param width - The width of the line + * @param color - The color to use to fill the line + * + * @return True on success; false on failure. + */ + +bool CBgWindow::drawLine(FAR struct nxgl_vector_s *vector, + nxgl_coord_t width, nxgl_mxpixel_t color) +{ + // Draw a line with the specified color + + return nx_drawline(m_hWindow, vector, width, &color) == OK; +} + +/** + * Draw a filled circle at the specified position, size, and color. + * + * @param center The window-relative coordinates of the circle center. + * @param radius The radius of the rectangle in pixels. + * @param color The color of the rectangle. + */ + +bool CBgWindow::drawFilledCircle(struct nxgl_point_s *center, nxgl_coord_t radius, + nxgl_mxpixel_t color) +{ + return nx_fillcircle(m_hWindow, center, radius, &color) == OK; +} + +/** + * Move a rectangular region within the window. + * + * @param pRect Describes the rectangular region to move. + * @param pOffset The offset to move the region. + * + * @return True on success; false on failure. + */ + +bool CBgWindow::move(FAR const struct nxgl_rect_s *pRect, + FAR const struct nxgl_point_s *pOffset) +{ + // Move a rectangular region of the display + + return nx_move(m_hWindow, pRect, pOffset) == OK; +} + +/** + * Copy a rectangular region of a larger image into the rectangle in the + * specified window. The source image is treated as an opaque image. + * + * @param pDest Describes the rectangular on the display that will receive + * the bitmap. + * @param pSrc The start of the source image. + * @param pOrigin the pOrigin of the upper, left-most corner of the full + * bitmap. Both pDest and pOrigin are in window coordinates, however, + * pOrigin may lie outside of the display. + * @param stride The width of the full source image in bytes. + * + * @return True on success; false on failure. + */ + +bool CBgWindow::bitmap(FAR const struct nxgl_rect_s *pDest, + FAR const void *pSrc, + FAR const struct nxgl_point_s *pOrigin, + unsigned int stride) +{ + // Copy a rectangular bitmap image in a region on the display + + return nx_bitmap(m_hWindow, pDest, &pSrc, pOrigin, stride) == OK; +} diff --git a/NxWidgets/libnxwidgets/src/cbitmap.cxx b/NxWidgets/libnxwidgets/src/cbitmap.cxx new file mode 100644 index 000000000..875e6daaa --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cbitmap.cxx @@ -0,0 +1,197 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cbitmap.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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> +#include <cstring> + +#include <nuttx/nx/nxglib.h> + +#include "cbitmap.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param bitmap The bitmap structure being wrapped. + */ + +CBitmap::CBitmap(const struct SBitmap *bitmap) : m_bitmap(bitmap) {} + +/** + * Get the bitmap's color format. + * + * @return The bitmap's width. + */ + +const uint8_t CBitmap::getColorFormat(void) const +{ + return m_bitmap->fmt; +} + +/** + * Get the bitmap's color format. + * + * @return The bitmap's color format. + */ + +const uint8_t CBitmap::getBitsPerPixel(void) const +{ + return m_bitmap->bpp; +} + +/** + * Get the bitmap's width (in pixels/columns). + * + * @return The bitmap's pixel depth. + */ + +const nxgl_coord_t CBitmap::getWidth(void) const +{ + return m_bitmap->width; +} + +/** + * Get the bitmap's height (in rows). + * + * @return The bitmap's height. + */ + +const nxgl_coord_t CBitmap::getHeight(void) const +{ + return m_bitmap->height; +} + +/** + * Get the bitmap's width (in bytes). + * + * @return The bitmap's width. + */ + +const nxgl_coord_t CBitmap::getStride(void) const +{ + return m_bitmap->stride; +} + +/** + * Get one row from the bit map image. + * + * @param x The offset into the row to get + * @param y The row number to get + * @param width The number of pixels to get from the row + * @param data The memory location provided by the caller + * in which to return the data. This should be at least + * (getWidth()*getBitsPerPixl() + 7)/8 bytes in length + * and properly aligned for the pixel color format. + * @param True if the run was returned successfully. + */ + +bool CBitmap::getRun(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, + FAR void *data) +{ + // Check ranges. Casts to unsigned int are ugly but permit one-sided comparisons + + if (((unsigned int)x < (unsigned int)width) && + ((unsigned int)(x + width) <= (unsigned int)m_bitmap->width) && + ((unsigned int)y < (unsigned int)m_bitmap->height)) + { + // Get starting position of the copy (this will only work if bpp + // is an even multiple of bytes). + + FAR uint8_t *start = (FAR uint8_t*)m_bitmap->data + + y * m_bitmap->stride + + ((x * m_bitmap->bpp) >> 3); + + // Get the number of bytes to copy. + + unsigned int length = (width * m_bitmap->bpp) >> 3; + + // And do the copy + + memcpy(data, start, length); + return true; + } + + return false; +} diff --git a/NxWidgets/libnxwidgets/src/cbutton.cxx b/NxWidgets/libnxwidgets/src/cbutton.cxx new file mode 100644 index 000000000..66ad3f2c7 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cbutton.cxx @@ -0,0 +1,300 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cbutton.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "cbutton.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CButton Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor for buttons that display a string. + * + * @param pWidgetControl The controlling widget for the display. + * @param x The x coordinate of the button, relative to its parent. + * @param y The y coordinate of the button, relative to its parent. + * @param width The width of the button. + * @param height The height of the button. + * @param text The text for the button to display. + * @param style The style that the button should use. If this is not + * specified, the button will use the values stored in the global + * g_defaultWidgetStyle object. The button will copy the properties of + * the style into its own internal style object. + */ + +CButton::CButton(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, + nxgl_coord_t height, const CNxString &text, CWidgetStyle *style) +: CLabel(pWidgetControl, x, y, width, height, text, style) +{ +} + +/** + * Draws the outline of the button. + * + * @param port Graphics port to draw to. + */ + +void CButton::drawOutline(CGraphicsPort *port) +{ + drawOutline(port, isClicked()); +} + +/** + * Draws the outline of the button. + * + * @param port Graphics port to draw to. + * @param useClicked Present outline using the 'clicked' style + */ + +void CButton::drawOutline(CGraphicsPort *port, bool useClicked) +{ + // Stop drawing if the widget indicates it should not have an outline + + if (isBorderless()) + { + return; + } + + // Work out which colors to use + + nxgl_coord_t color1; + nxgl_coord_t color2; + + if (useClicked) + { + // Bevelled into the screen + + color1 = getShadowEdgeColor(); + color2 = getShineEdgeColor(); + } + else + { + // Bevelled out of the screen + + color1 = getShineEdgeColor(); + color2 = getShadowEdgeColor(); + } + + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), color1, color2); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CButton::drawContents(CGraphicsPort *port) +{ + drawContents(port, isClicked()); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @param useClicked Present contents using the 'clicked' style + * @see redraw() + */ + +void CButton::drawContents(CGraphicsPort *port, bool useClicked) + +{ + // Get the draw region (excluding any borders) + + CRect rect; + getRect(rect); + + // Get the X/Y position of the text within the button + + struct nxgl_point_s pos; + pos.x = rect.getX() + m_align.x; + pos.y = rect.getY() + m_align.y; + + // Pick the text color + + nxgl_mxpixel_t textColor; + if (!isEnabled()) + { + textColor = getDisabledTextColor(); + } + else if (useClicked) + { + textColor = getSelectedTextColor(); + } + else + { + textColor = getEnabledTextColor(); + } + + // And draw the button text + + port->drawText(&pos, &rect, getFont(), m_text, 0, m_text.getLength(), textColor); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CButton::drawBorder(CGraphicsPort *port) +{ + drawBorder(port, isClicked()); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @param useClicked Present border using the 'clicked' style + * @see redraw() + */ + +void CButton::drawBorder(CGraphicsPort *port, bool useClicked) +{ + // Determine the background color + + nxgl_mxpixel_t backColor; + + if (useClicked || m_highlighted) + { + backColor = getSelectedBackgroundColor(); + } + else + { + backColor = getBackgroundColor(); + } + + port->drawFilledRect(getX(), getY(), getWidth(), getHeight(), backColor); + drawOutline(port); +} + +/** + * Redraws the button. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CButton::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + redraw(); +} + +/** + * Raises an action event and redraws the button. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + */ + +void CButton::onRelease(nxgl_coord_t x, nxgl_coord_t y) +{ + m_widgetEventHandlers->raiseActionEvent(); + redraw(); +} + +/** + * Redraws the button. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + */ + +void CButton::onReleaseOutside(nxgl_coord_t x, nxgl_coord_t y) +{ + redraw(); +} diff --git a/NxWidgets/libnxwidgets/src/cbuttonarray.cxx b/NxWidgets/libnxwidgets/src/cbuttonarray.cxx new file mode 100644 index 000000000..263a16ce4 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cbuttonarray.cxx @@ -0,0 +1,608 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/include/cbuttonarray.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "cbuttonarray.hxx" +#include "cgraphicsport.hxx" +#include "cwidgetstyle.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CButtonArray Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor for an array of buttons. + * + * @param pWidgetControl The widget control for the display. + * @param x The x coordinate of the button array, relative to its parent. + * @param y The y coordinate of the button array, relative to its parent. + * @param buttonColumns The number of buttons in one row of the button array + * @param buttonRows The number of buttons in one column of the button array + * @param buttonWidth The width of one button + * @param buttonHeight The height of one button + * @param style The style that the button should use. If this is not + * specified, the button will use the global default widget + * style. + */ + +CButtonArray::CButtonArray(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + uint8_t buttonColumns, uint8_t buttonRows, + nxgl_coord_t buttonWidth, nxgl_coord_t buttonHeight, + CWidgetStyle *style) +: CNxWidget(pWidgetControl, x, y, + buttonColumns * buttonWidth + 2, buttonRows * buttonHeight + 2, + 0, style) +{ + // Save configuration + + m_buttonRows = buttonRows; + m_buttonColumns = buttonColumns; + m_buttonWidth = buttonWidth; + m_buttonHeight = buttonHeight; + + // Make sure the the positional data is valid. + + m_clickX = x; + m_clickY = y; + m_cursorColumn = 0; + m_cursorRow = 0; + + // Default behavior is to redraw the entire button array + + m_redrawButton = false; + + // No hightlighted buttons + + m_cursorOn = false; + m_cursorChange = false; + + // At present, There is no border on the array itself + + m_flags.borderless = true; + + // Make sure that the full size of the text array is allocated + + m_buttonText = new CNxString[m_buttonRows * m_buttonColumns]; +} + +/** + * CButtonArray Destructor. + */ + +CButtonArray::~CButtonArray(void) +{ + // Delete the array of CNxString instances + + delete [] m_buttonText; +} + +/** + * Returns the string shown in the label. + * + * @param column The column index of the button of interest +* @param row The row index of the button of interest + * @return The label's text. + */ + +const CNxString &CButtonArray::getText(int column, int row) const +{ + return m_buttonText[row * m_buttonColumns + column]; +} + +/** + * Set the text displayed in the label. + * + * @param column The column index of the button to set + * @param row The row index of the button to set + * @param text String to display. + */ + +void CButtonArray::setText(int column, int row, const CNxString &text) +{ + m_buttonText[row * m_buttonColumns + column] = text; + onTextChange(); +} + +/** + * Return the position of the last clicked button (0,0 will be returned + * the no button has every been clicked). The button at this position + * is currently clicked then, in addition, return true. + * + * @param column The location to return the column index of the button + * of interest + * @param row The location to return the row index of the button of + * interest + * @return True if a button in the array is clicked + */ + +bool CButtonArray::isButtonClicked(int &column, int &row) const +{ + // Return the last clicked position + + column = (m_clickX - getX()) / m_buttonWidth; + + // Calculate and return the button row index + + row = (m_clickY - getY()) / m_buttonHeight; + + // Return true if the button is currently clicked + + return isClicked(); +} + +/** + * Check if this specific button in the array is clicked + * + * @param column The column of the button to check. + * @param row The row of the button to check. + * @return True if this button is clicked + */ + +bool CButtonArray::isThisButtonClicked(int column, int row) const +{ + // The upper left X/Y position of the button at these indices + + nxgl_coord_t x = getX() + column * m_buttonWidth; + nxgl_coord_t y = getY() + row * m_buttonHeight; + + // Was the last click on this button? + + if ((m_clickX >= x && m_clickX < x + m_buttonWidth) && + (m_clickY >= y && m_clickY < y + m_buttonHeight)) + { + // Yes.. return true if the button is clicked + + return isClicked(); + } + else + { + // No.. then it can't be clicked + + return false; + } +} + +/** + * Control the cursor state. + * + * @param cursorOn True(1), the current cursor position will be highlighted + */ + +void CButtonArray::cursor(bool cursorOn) +{ + if (cursorOn != m_cursorOn) + { + // Set the state cursor state + + m_cursorOn = cursorOn; + + // Update only the effected button + + m_cursorChange = true; + redraw(); + m_cursorChange = false; + } +} + +/** + * Return the current cursor position (button indices) and an indication + * if the button at the cursor is currently hightlighted. + * + * @param column The location to return the column index of the button + * of interest + * @param row The location to return the row index of the button of + * interest + * @return True if the cursor is enabled and the button is highlighted + */ + +bool CButtonArray::getCursorPosition(int &column, int &row) const +{ + column = m_cursorColumn; + row = m_cursorRow; + return m_cursorOn; +} + +/** + * Set the cursor position (button indices). Note that the cursor + * does not have to be enabled to set the position. + * + * @param column The column index of the button of interest + * @param row The row index of the button of interest + * @return True if the cursor position is valid + */ + +bool CButtonArray::setCursorPosition(int column, int row) +{ + // Verify that the cursor position is within range + + if ((unsigned)column < m_buttonColumns && (unsigned)row < m_buttonRows) + { + // Verify that the now position is different from the old position + + if (column != m_cursorColumn || row != m_cursorRow) + { + m_cursorChange = true; + + // Is the cursor on now? + + bool redrawCursor = m_cursorOn; + if (redrawCursor) + { + // Yes.. clear the old cursor highlight + + m_cursorOn = false; + redraw(); + } + + // Set the new cursor position + + m_cursorColumn = column; + m_cursorRow = row; + + // Do we need to turn the cursor back on? + + if (redrawCursor) + { + // Yes.. Set the new cursor hightlight + + m_cursorOn = true; + redraw(); + } + + m_cursorChange = false; + } + + return true; + } + + return false; +} + +/** + * Check if this specific button in the array is at the cursor position + * and highlighted. + * + * @param column The column of the button to check. + * @param row The row of the button to check. + * @return True if this button is at the cursor postion and highlighted. + */ + +bool CButtonArray::isCursorPosition(int column, int row) const +{ + if (column == m_cursorColumn && row == m_cursorRow) + { + return m_cursorOn; + } + + return false; +} + +/** + * Insert the dimensions that this widget wants to have into the rect + * passed in as a parameter. All coordinates are relative to the + * widget's parent. + * + * @param rect Reference to a rect to populate with data. + */ + +void CButtonArray::getPreferredDimensions(CRect &rect) const +{ + return getRect(rect); +} + +/** + * Sets the font. + * + * @param font A pointer to the font to use. + */ + +void CButtonArray::setFont(CNxFont *font) +{ + m_style.font = font; + redraw(); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CButtonArray::drawContents(CGraphicsPort *port) +{ + // Do we draw just the clicked/unclicked button? + + if (m_redrawButton) + { + int column; + int row; + + // Just one. Get the row/column indices from the last click + + (void)posToButton(m_clickX, m_clickY, column, row); + + // And draw that button + + drawButton(port, column, row, isClicked()); + } + + // Do we just draw the hightlighted button? + + else if (m_cursorChange) + { + // Do nothing if the highlighted button is also the clicked button + + if (!isThisButtonClicked(m_cursorColumn, m_cursorRow)) + { + drawButton(port, m_cursorColumn, m_cursorRow, false); + } + } + + // Draw all buttons + + else + { + // Visit each column + + for (int column = 0; column < m_buttonColumns; column++) + { + // Visit each row + + for (int row = 0; row < m_buttonRows; row++) + { + // Draw each button + + drawButton(port, column, row, isThisButtonClicked(column, row)); + } + } + } +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CButtonArray::drawBorder(CGraphicsPort *port) +{ + // This doesn't do anything anymore +} + +/** + * Redraw only one button + * + * @param port The CGraphicsPort to draw to. + * @param column The button column index + * @param row The button row index + * @param useClicked Draw the button using the 'clicked' button style, + * regardless of the actual button state. + * @see onClick() and onRelease() + */ + +void CButtonArray::drawButton(CGraphicsPort *port, int column, int row, bool useClicked) +{ + // The X/Y position of the button + + nxgl_coord_t x = getX() + column * m_buttonWidth; + nxgl_coord_t y = getY() + row * m_buttonHeight; + + // Determine which colors to use + + nxwidget_pixel_t borderColor1; + nxwidget_pixel_t borderColor2; + nxwidget_pixel_t backColor; + nxwidget_pixel_t textColor; + + // Pick the background and test colors. Should we use the 'clicked' backgound style? + + if (useClicked || isCursorPosition(column, row)) + { + // "Selected" text color on unique "Selected" background color + + backColor = getSelectedBackgroundColor(); + textColor = getSelectedTextColor(); + } + else + { + // Normal background color and "Enabled" text color + + backColor = getBackgroundColor(); + textColor = getEnabledTextColor(); + } + + // Pick the border colors. Should we use the 'clicked' button style? + + if (useClicked) + { + // Yes.. Bevelled into the screen + + borderColor1 = getShadowEdgeColor(); + borderColor2 = getShineEdgeColor(); + } + else + { + // No.. Bevelled out of the screen + + borderColor1 = getShineEdgeColor(); + borderColor2 = getShadowEdgeColor(); + } + + // Use a special text color if the widget is not enabled + + if (!isEnabled()) + { + textColor = getDisabledTextColor(); + } + + // Draw the background + + port->drawFilledRect(x, y, m_buttonWidth, m_buttonHeight, backColor); + + // Draw the button outline + + port->drawBevelledRect(x, y, m_buttonWidth, m_buttonHeight, borderColor1, borderColor2); + + // Get the text for this button + + CNxString *text = &m_buttonText[row * m_buttonColumns + column]; + + // Get the text drawing region + + CRect rect; + rect.setX(x + 1); + rect.setY(y + 1); + rect.setWidth(m_buttonWidth - 2); + rect.setHeight(m_buttonHeight - 2); + + // Get the centered text alignment + + nxgl_coord_t alignY = (m_buttonHeight - getFont()->getHeight() - 2) >> 1; + nxgl_coord_t alignX = (m_buttonWidth - getFont()->getStringWidth(*text) - 2) >> 1; + + // Get the text display position + + struct nxgl_point_s pos; + pos.x = x + alignX; + pos.y = y + alignY; + + // And draw the button text + + port->drawText(&pos, &rect, getFont(), *text, 0, text->getLength(), textColor); +} + +/** + * Redraws the button. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CButtonArray::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + // Click X,Y is in raw window coordinates + + m_clickX = x; + m_clickY = y; + + // Redraw only the button that was clicked + + m_redrawButton = true; + redraw(); + m_redrawButton = false; +} + +/** + * Raises an action event and redraws the button. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + */ + +void CButtonArray::onRelease(nxgl_coord_t x, nxgl_coord_t y) +{ + m_widgetEventHandlers->raiseActionEvent(); + + // Redraw only the button that was released + + m_redrawButton = true; + redraw(); + m_redrawButton = false; +} + +/** + * Redraws the button. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + */ + +void CButtonArray::onReleaseOutside(nxgl_coord_t x, nxgl_coord_t y) +{ + redraw(); +} + +/** + * Convert an X/Y position to a button column/row index + * + * @param x The x position + * @param y The y position + * @param column The location to return the column index of the button + * of interest + * @param row The location to return the row index of the button of + * interest + * @return false is the position is invalid + */ + +bool CButtonArray::posToButton(nxgl_coord_t x, nxgl_coord_t y, int &column, int &row) +{ + // Get the row/column indices matching the x/y position + + column = (x - getX()) / m_buttonWidth; + row = (y - getY()) / m_buttonHeight; + return ((unsigned)column < m_buttonColumns && (unsigned)row < m_buttonRows); +} + +/** + * Updates the GUI after the text has changed. + */ + +void CButtonArray::onTextChange(void) +{ + redraw(); + m_widgetEventHandlers->raiseValueChangeEvent(); +} + diff --git a/NxWidgets/libnxwidgets/src/ccallback.cxx b/NxWidgets/libnxwidgets/src/ccallback.cxx new file mode 100644 index 000000000..25cb228b3 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/ccallback.cxx @@ -0,0 +1,195 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/ccallback.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <debug.h> + +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + + /** + * Constructor. + * + * @param pWidgetControl Control object associated with this window + */ + +CCallback::CCallback(CWidgetControl *pWidgetControl) +{ + // Initialize the callback vtable + + m_callbacks.redraw = redraw; + m_callbacks.position = position; + m_callbacks.mousein = newMouseEvent; + m_callbacks.kbdin = newKeyboardEvent; +} + + /** + * ReDraw Callback. The redraw action is handled by CWidgetControl:redrawEvent. + * + * @param hWindow Handle to a specific NX window. + * @param pRect The rectangle that needs to be re-drawn (in window + * relative coordinates). + * @param bMore true: More re-draw requests will follow. + * @param pvArg User provided argument (see nx_openwindow, nx_requestbg, + * nxtk_openwindow, or nxtk_opentoolbar). + */ + +void CCallback::redraw(NXHANDLE hWindow, + FAR const struct nxgl_rect_s *pRect, + bool bMore, FAR void *pvArg) +{ + gvdbg("hWindow=%p pRect={(%d,%d),(%d,%d)} bMore=%s\n", + hWindow, + pRect->pt1.x, pRect->pt1.y, pRect->pt2.x, pRect->pt2.y, + bMore ? "true" : "false"); + + // The argument must be the CWidgetControl instance + + CWidgetControl *This = (CWidgetControl *)pvArg; + + // Just forward the callback to the CWidgetControl::redrawEvent method + + This->redrawEvent(pRect, bMore); +} + + /** + * Position Callback. The new positional data is handled by + * CWidgetControl::geometryEvent. + * + * @param hWindow Handle to a specific NX window. + * @param pSize The size of the window. + * @param pPos The position of the upper left hand corner of the window on + * the overall display. + * @param pBounds The bounding rectangle that describes the entire display. + * @param pvArg User provided argument (see nx_openwindow, nx_requestbg, + * nxtk_openwindow, or nxtk_opentoolbar). + */ + +void CCallback::position(NXHANDLE hWindow, + FAR const struct nxgl_size_s *pSize, + FAR const struct nxgl_point_s *pPos, + FAR const struct nxgl_rect_s *pBounds, + FAR void *pvArg) +{ + gvdbg("hWindow=%p pSize=(%d,%d) pPos=(%d,%d) pBounds={(%d,%d),(%d,%d)} pvArg=%p\n", + hWindow, pSize->w, pSize->h, pPos->x, pPos->y, + pBounds->pt1.x, pBounds->pt1.y, pBounds->pt2.x, pBounds->pt2.y, + pvArg); + + + // The argument must be the CWidgetControl instance + + CWidgetControl *This = (CWidgetControl *)pvArg; + + // Just forward the callback to the CWidgetControl::geometry method + + This->geometryEvent(hWindow, pSize, pPos, pBounds); +} + + /** + * New mouse data is available for the window. The new mouse data is + * handled by CWidgetControl::newMouseEvent. + * + * @param hWindow Handle to a specific NX window. + * @param pPos The (x,y) position of the mouse. + * @param buttons See NX_MOUSE_* definitions. + * @param pvArg User provided argument (see nx_openwindow, nx_requestbg, + * nxtk_openwindow, or nxtk_opentoolbar). + */ + +#ifdef CONFIG_NX_MOUSE +void CCallback::newMouseEvent(NXHANDLE hWindow, + FAR const struct nxgl_point_s *pPos, + uint8_t buttons, FAR void *pvArg) +{ + gvdbg("hWindow=%p pPos=(%d,%d) buttons=%02x pvArg=%p\n", + hWindow, pPos->x, pPos->y, buttons, pvArg); + + // The argument must be the CWidgetControl instance + + CWidgetControl *This = (CWidgetControl *)pvArg; + + // Just forward the callback to the CWidgetControl::newMouseEvent method + + This->newMouseEvent(pPos, buttons); +} +#endif /* CONFIG_NX_MOUSE */ + +/** + * New keyboard/keypad data is available for the window. The new keyboard + * data is handled by CWidgetControl::newKeyboardEvent. + * + * @param hWindow Handle to a specific NX window. + * @param nCh The number of characters that are available in pStr[]. + * @param pStr The array of characters. + * @param pvArg User provided argument (see nx_openwindow, nx_requestbg, + * nxtk_openwindow, or nxtk_opentoolbar). + */ + +#ifdef CONFIG_NX_KBD +void CCallback::newKeyboardEvent(NXHANDLE hWindow, uint8_t nCh, + FAR const uint8_t *pStr, + FAR void *pvArg) +{ + gvdbg("hWindow=%p nCh=%d pvArg=%p\n", + hWindow, nCh, pvArg); + + // The argument must be the CWidgetControl instance + + CWidgetControl *This = (CWidgetControl *)pvArg; + + // Just forward the callback to the CWidgetControl::newKeyboardEvent method + + This->newKeyboardEvent(nCh, pStr); +} +#endif // CONFIG_NX_KBD diff --git a/NxWidgets/libnxwidgets/src/ccheckbox.cxx b/NxWidgets/libnxwidgets/src/ccheckbox.cxx new file mode 100644 index 000000000..a6cc9400a --- /dev/null +++ b/NxWidgets/libnxwidgets/src/ccheckbox.cxx @@ -0,0 +1,265 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/ccheckbox.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccheckbox.hxx" +#include "cgraphicsport.hxx" +#include "cbitmap.hxx" +#include "singletons.hxx" +#include "glyphs.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The widget control for the display. + * @param x The x coordinate of the checkbox, relative to its parent. + * @param y The y coordinate of the checkbox, relative to its parent. + * @param width The width of the checkbox. + * @param height The height of the checkbox. + * @param style The style that the widget should use. If this is not + * specified, the widget will use the values stored in the global + * g_defaultWidgetStyle object. The widget will copy the properties of + * the style into its own internal style object. + */ + +CCheckBox::CCheckBox(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + CWidgetStyle *style) +: CButton(pWidgetControl, x, y, width, height, *NXWidgets::g_nullString, style) +{ + m_state = CHECK_BOX_STATE_OFF; + m_flags.borderless = false; + + // Border width is one line + + m_borderSize.top = 1; + m_borderSize.right = 1; + m_borderSize.bottom = 1; + m_borderSize.left = 1; +} + +/** + * Set the state of the checkbox. + * + * @param state The new checkbox state. + */ + +void CCheckBox::setState(CCheckBox::CheckBoxState state) +{ + if (m_state != state) + { + m_state = state; + m_widgetEventHandlers->raiseValueChangeEvent(); + redraw(); + } +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CCheckBox::drawContents(CGraphicsPort *port) +{ + // Get the X/Y position of the drawable region within the CheckBox + + nxgl_coord_t x = getX(); + nxgl_coord_t y = getY(); + + nxgl_coord_t width = getWidth(); + nxgl_coord_t height = getHeight(); + + // Include and offset for the border + + if (!m_flags.borderless) + { + x += m_borderSize.left; + y += m_borderSize.top; + + width -= (m_borderSize.left + m_borderSize.right); + height -= (m_borderSize.top + m_borderSize.bottom); + } + + // Decide which glyph to draw + + const struct SBitmap *glyph; + + switch (m_state) + { + default: + case CHECK_BOX_STATE_ON: + glyph = &g_checkBoxOn; + break; + + case CHECK_BOX_STATE_OFF: + glyph = &g_checkBoxOff; + break; + + case CHECK_BOX_STATE_MU: + glyph = &g_checkBoxMu; + break; + } + + // Don't exceed the size of the glyph + + if (width > glyph->width) + { + width = glyph->width; + } + + if (height > glyph->height) + { + height = glyph->height; + } + + // Draw the checkbox + + port->drawBitmap(x, y, width, height, glyph, 0, 0, + CONFIG_NXWIDGETS_TRANSPARENT_COLOR); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CCheckBox::drawBorder(CGraphicsPort *port) +{ + // Determine the background color + + nxgl_mxpixel_t backColor; + + if (m_highlighted) + { + backColor = getSelectedBackgroundColor(); + } + else + { + backColor = getBackgroundColor(); + } + + // Draw the background (excluding the border) + + port->drawFilledRect(getX(), getY(), getWidth(), getHeight(), + backColor); + + // Stop drawing if the widget indicates it should not have an outline + + if (!isBorderless()) + { + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), + getShineEdgeColor(), getShadowEdgeColor()); + } +} + +/** + * Toggles the state of the checkbox. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CCheckBox::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + if (m_state == CHECK_BOX_STATE_ON) + { + setState(CHECK_BOX_STATE_OFF); + } + else + { + setState(CHECK_BOX_STATE_ON); + } +} diff --git a/NxWidgets/libnxwidgets/src/ccyclebutton.cxx b/NxWidgets/libnxwidgets/src/ccyclebutton.cxx new file mode 100644 index 000000000..b5f96683d --- /dev/null +++ b/NxWidgets/libnxwidgets/src/ccyclebutton.cxx @@ -0,0 +1,482 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/ccyclebutton.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "ccyclebutton.hxx" +#include "cgraphicsport.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CButton Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor for cycle buttons. + * + * @param pWidgetControl The widget control for the display. + * @param x The x coordinate of the button, relative to its parent. + * @param y The y coordinate of the button, relative to its parent. + * @param width The width of the button. + * @param height The height of the button. + * @param style The style that the button should use. If this is not + * specified, the button will use the values stored in the global + * g_defaultWidgetStyle object. The button will copy the properties of + * the style into its own internal style object. + */ + +CCycleButton::CCycleButton(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + CWidgetStyle *style) +: CButton(pWidgetControl, x, y, width, height, "", style) +{ + // Force text to align left + + nxgl_coord_t glyphSpace = m_borderSize.left - 1; + + // Text x coordinate is width of cycle glyph plus a space plus width + // of the spacer line (2px) plus a space + + m_align.x = g_cycle.width + 2 + (glyphSpace << 1); + + m_options.addListDataEventHandler(this); + m_options.setAllowMultipleSelections(false); +} + +/** + * Add a new option to the widget. + * + * @param text The text of the option. + * @param value The value of the option. + */ + +void CCycleButton::addOption(const CNxString &text, const uint32_t value) +{ + m_options.addItem(new CListDataItem(text, value)); + + // Select the option if this is the first option added + + if (m_options.getItemCount() == 1) + { + selectOption(0); + } +} + +/** + * Remove an option from the widget by its index. + * + * @param index The index of the option to remove. + */ + +void CCycleButton::removeOption(const int index) +{ + m_options.removeItem(index); +} + +/** + * Remove all options from the widget. + */ + +void CCycleButton::removeAllOptions(void) +{ + m_options.removeAllItems(); +} + +/** + * Select an option by its index. + * Redraws the widget and raises a value changed event. + * + * @param index The index of the option to select. + */ + +void CCycleButton::selectOption(const int index) +{ + m_options.setItemSelected(index, true); +} + +/** + * Get the selected index. Returns -1 if nothing is selected. If more than one + * option is selected, the index of the first selected option is returned. + * + * @return The selected index. + */ + +const int CCycleButton::getSelectedIndex(void) const +{ + return m_options.getSelectedIndex(); +} + +/** + * Sets the selected index. Specify -1 to select nothing. Resets any + * other selected options to deselected. + * Redraws the widget and raises a value changed event. + * + * @param index The selected index. + */ + +void CCycleButton::setSelectedIndex(const int index) +{ + m_options.setItemSelected(index, true); +} + +/** + * Get the selected option. Returns NULL if nothing is selected. + * + * @return The selected option. + */ + +const CListDataItem *CCycleButton::getSelectedOption(void) const +{ + return m_options.getSelectedItem(); +} + +/** + * Sort the options alphabetically by the text of the options. + */ + +void CCycleButton::sort(void) +{ + m_options.sort(); +} + +/** + * Handles list data changed events. + * + * @param e Event arguments. + */ + +void CCycleButton::handleListDataChangedEvent(const CListDataEventArgs &e) +{ + redraw(); +} + +/** + * Handles list selection changed events. + * + * @param e Event arguments. + */ + +void CCycleButton::handleListDataSelectionChangedEvent(const CListDataEventArgs &e) +{ + redraw(); + m_widgetEventHandlers->raiseValueChangeEvent(); +} + +/** + * Insert the dimensions that this widget wants to have into the rect + * passed in as a parameter. All coordinates are relative to the widget's + * parent. Value is based on the length of the largest string in the + * set of options. + * + * @param rect Reference to a rect to populate with data. + */ + +void CCycleButton::getPreferredDimensions(CRect &rect) const +{ + nxgl_coord_t width = 0; + nxgl_coord_t height = getFont()->getHeight(); + + // Locate longest string in options + + for (int i = 0; i < m_options.getItemCount(); ++i) + { + nxgl_coord_t optionWidth = + getFont()->getStringWidth(m_options.getItem(i)->getText()); + + if (optionWidth > width) + { + width = optionWidth; + } + } + + // Add the border width + + if (!m_flags.borderless) + { + width += (m_borderSize.left + m_borderSize.right); + height += (m_borderSize.top + m_borderSize.bottom); + } + + // Add text alignment + + width += m_align.x; + height += m_align.y; + + // And returned this preferred size + + rect.setX(m_rect.getX()); + rect.setY(m_rect.getY()); + rect.setWidth(width); + rect.setHeight(height); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CCycleButton::drawContents(CGraphicsPort *port) +{ + // Get the drawing region (excluding any border) + + CRect rect; + getRect(rect); + + nxgl_coord_t glyphSpace = m_borderSize.left - 1; + nxgl_coord_t glyphYOffset = (rect.getHeight() - g_cycle.height) >> 1; + + nxwidget_pixel_t textColor; + nxwidget_pixel_t separatorLeftColor; + nxwidget_pixel_t separatorRightColor; + + if (!isEnabled()) + { + textColor = getDisabledTextColor(); + separatorLeftColor = getShadowEdgeColor(); + separatorRightColor = getShineEdgeColor(); + } + else if (!isClicked()) + { + textColor = getEnabledTextColor(); + separatorLeftColor = getShadowEdgeColor(); + separatorRightColor = getShineEdgeColor(); + } + else + { + textColor = getSelectedTextColor(); + separatorLeftColor = getShineEdgeColor(); + separatorRightColor = getShadowEdgeColor(); + } + + // Draw cycle glyph + + port->drawBitmap(rect.getX(), rect.getY() + glyphYOffset, + g_cycle.width, g_cycle.height, &g_cycle, + 0, 0, CONFIG_NXWIDGETS_TRANSPARENT_COLOR); + + // Draw separator + + nxgl_coord_t x = getX() + glyphSpace + g_cycle.width; + nxgl_coord_t y = getY(); + nxgl_coord_t w = glyphSpace + g_cycle.width; + nxgl_coord_t h = rect.getHeight() - 1; + + port->drawLine(x, y, w, h, separatorLeftColor); + port->drawLine(x+1, y, w+1, h, separatorRightColor); + + // Only draw text if option is selected + + if (m_options.getSelectedItem() != NULL) + { + struct nxgl_point_s pos; + pos.x = getX() + m_align.x; + pos.y = getY() + m_align.y; + + port->drawText(&pos, &rect, getFont(), + m_options.getSelectedItem()->getText(), 0, + m_options.getSelectedItem()->getText().getLength(), + textColor); + } +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CCycleButton::drawBorder(CGraphicsPort *port) +{ + // Determine the background color + + nxwidget_pixel_t backColor; + + if (isClicked() || m_highlighted) + { + backColor = getSelectedBackgroundColor(); + } + else + { + backColor = getBackgroundColor(); + } + + // Draw the background (excluding the border) + + port->drawFilledRect(getX(), getY(), getWidth(), getHeight(), backColor); + + // Then add the border. + + drawOutline(port); +} + +/** + * Draws the outline of the button. + * + * @param port Graphics port to draw to. + */ + +void CCycleButton::drawOutline(CGraphicsPort *port) +{ + // Stop drawing if the widget indicates it should not have an outline + + if (isBorderless()) + { + return; + } + + // Work out which colors to use + + nxgl_coord_t color1; + nxgl_coord_t color2; + + if (isClicked()) + { + // Bevelled into the screen + + color1 = getShadowEdgeColor(); + color2 = getShineEdgeColor(); + } + else + { + // Bevelled out of the screen + + color1 = getShineEdgeColor(); + color2 = getShadowEdgeColor(); + } + + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), color1, color2); +} + +/** + * Selects the next option in the list and redraws the button. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + */ + +void CCycleButton::onRelease(nxgl_coord_t x, nxgl_coord_t y) +{ + // Choose next option + + if (m_options.getItemCount() > 1) + { + int selectedIndex = m_options.getSelectedIndex(); + + if (selectedIndex < m_options.getItemCount() - 1) + { + // Move to next option + + selectOption(selectedIndex + 1); + } + else + { + // Wrap around as there are no more options + + selectOption(0); + } + } + + redraw(); +} + +/** + * Redraws the button. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + */ + +void CCycleButton::onReleaseOutside(nxgl_coord_t x, nxgl_coord_t y) +{ + redraw(); +} + diff --git a/NxWidgets/libnxwidgets/src/cglyphbutton.cxx b/NxWidgets/libnxwidgets/src/cglyphbutton.cxx new file mode 100644 index 000000000..f24b5c943 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cglyphbutton.cxx @@ -0,0 +1,297 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cglyphbutton.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "nxconfig.hxx" +#include "cglyphbutton.hxx" +#include "cgraphicsport.hxx" +#include "cbitmap.hxx" +#include "singletons.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CButton Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The widget control for the display. + * @param x The x coordinate of the button. + * @param y The y coordinate of the button. + * @param width The width of the button. + * @param height The height of the button. + * @param normalGlyph Glyph to display when unclicked. + * @param clickedGlyph Glyph to display when clicked. + * @param bitmapX The x coordinate at which the bitmaps will be drawn. + * @param bitmapY The y coordinate at which the bitmaps will be drawn. + * @param style The style that the button should use. If this is not + * specified, the button will use the values stored in the global + * g_defaultWidgetStyle object. The button will copy the properties of + * the style into its own internal style object. + */ + +CGlyphButton::CGlyphButton(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + nxgl_coord_t bitmapX, nxgl_coord_t bitmapY, + FAR const struct SBitmap *normalGlyph, + FAR const struct SBitmap *clickedGlyph, + CWidgetStyle *style) +: CNxWidget(pWidgetControl, x, y, width, height, 0, style) +{ + // The border should be set to the minimum so that the bitmap + // image can extend all the way to the border. + + m_borderSize.top = 1; + m_borderSize.right = 1; + m_borderSize.bottom = 1; + m_borderSize.left = 1; + + // Save the bitmap state data + + m_bitmapX = bitmapX; + m_bitmapY = bitmapY; + m_bitmapNormal = normalGlyph; + m_bitmapClicked = clickedGlyph; +} + +/** + * Insert the dimensions that this widget wants to have into the rect + * passed in as a parameter. All coordinates are relative to the widget's + * parent. + * @param rect Reference to a rect to populate with data. + */ + +void CGlyphButton::getPreferredDimensions(CRect &rect) const +{ + nxgl_coord_t width = m_bitmapNormal->width; + nxgl_coord_t height = m_bitmapNormal->height; + + if (!m_flags.borderless) + { + width = m_borderSize.left + m_borderSize.right; + height = m_borderSize.top + m_borderSize.bottom; + } + + rect.setX(m_rect.getX()); + rect.setY(m_rect.getY()); + rect.setWidth(width); + rect.setHeight(height); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CGlyphButton::drawContents(CGraphicsPort *port) +{ + // Get the drawable region within the Label + + CRect rect; + getRect(rect); + + // Pick the glyph to show + + FAR const struct SBitmap *bitmap; + if (m_flags.clicked) + { + bitmap = m_bitmapClicked; + } + else + { + bitmap = m_bitmapNormal; + } + + // Then draw it -- in greyscale if not enabled + + if (isEnabled()) + { + port->drawBitmap(rect.getX(), rect.getY(), + rect.getWidth(), rect.getHeight(), + bitmap, m_bitmapX, m_bitmapY, + CONFIG_NXWIDGETS_TRANSPARENT_COLOR); + } + else + { + port->drawBitmapGreyScale(rect.getX(), rect.getY(), + rect.getWidth(), rect.getHeight(), + bitmap, m_bitmapX, m_bitmapY); + } +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CGlyphButton::drawBorder(CGraphicsPort *port) +{ + port->drawFilledRect(getX(), getY(), getWidth(), + getHeight(), getBackgroundColor()); + drawOutline(port); +} + +/** + * Draws the outline of the button. + * + * @param port Graphics port to draw to. + */ + +void CGlyphButton::drawOutline(CGraphicsPort *port) +{ + // Don't draw if the widget indicates it should not have an outline + + if (!isBorderless()) + { + // Determine which colors to use + + nxgl_coord_t color1; + nxgl_coord_t color2; + + if (isClicked()) + { + // Bevelled into the screen + + color1 = getShadowEdgeColor(); + color2 = getShineEdgeColor(); + } + else + { + // Bevelled out of the screen + + color1 = getShineEdgeColor(); + color2 = getShadowEdgeColor(); + } + + port->drawBevelledRect(getX(), getY(), + getWidth(), getHeight(), + color1, color2); + } +} + +/** + * Redraws the button. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CGlyphButton::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + redraw(); +} + +/** + * Raises an action event and redraws the button. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + */ + +void CGlyphButton::onRelease(nxgl_coord_t x, nxgl_coord_t y) +{ + m_widgetEventHandlers->raiseReleaseEvent(x, y); + redraw(); +} + +/** + * Redraws the button. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + */ + +void CGlyphButton::onReleaseOutside(nxgl_coord_t x, nxgl_coord_t y) +{ + redraw(); +} diff --git a/NxWidgets/libnxwidgets/src/cgraphicsport.cxx b/NxWidgets/libnxwidgets/src/cgraphicsport.cxx new file mode 100644 index 000000000..43076e240 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cgraphicsport.cxx @@ -0,0 +1,988 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cgraphicsport.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "inxwindow.hxx" +#include "cnxstring.hxx" +#include "crect.hxx" +#include "cnxfont.hxx" +#include "cgraphicsport.hxx" +#include "cwidgetstyle.hxx" +#include "cbitmap.hxx" +#include "singletons.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pNxWnd An instance of the underlying window type. + */ + +CGraphicsPort::CGraphicsPort(INxWindow *pNxWnd) +{ + m_pNxWnd = pNxWnd; +} + +/** + * Destructor. + */ + +CGraphicsPort::~CGraphicsPort(void) +{ + // m_pNxWnd is not deleted. This is an abstract base class and + // the caller of the CGraphicsPort instance is responsible for + // the window destruction. +}; + +/** + * Return the absolute x coordinate of the upper left hand corner of the + * underlying window. + * + * @return The x coordinate of the underlying window. + */ + +const nxgl_coord_t CGraphicsPort::getX(void) const +{ + struct nxgl_point_s pos; + (void)m_pNxWnd->getPosition(&pos); + return pos.x; +}; + +/** + * Return the absolute y coordinate of the upper left hand corner of the + * underlying window. + * + * @return The y coordinate of the underlying window. + */ + +const nxgl_coord_t CGraphicsPort::getY(void) const +{ + struct nxgl_point_s pos; + (void)m_pNxWnd->getPosition(&pos); + return pos.y; +}; + +/** + * Draw a pixel into the window. + * + * @param x The window-relative x coordinate of the pixel. + * @param y The window-relative y coordinate of the pixel. + * @param color The color of the pixel. + */ + +void CGraphicsPort::drawPixel(nxgl_coord_t x, nxgl_coord_t y, + nxgl_mxpixel_t color) +{ + struct nxgl_point_s pos; + pos.x = x; + pos.y = y; + m_pNxWnd->setPixel(&pos, color); +} + +/** + * Draw a horizontal line of the specified start position, width, and color. + * + * @param x The x coordinate of the line. + * @param y The y coordinate of the top-most end of the line. + * @param width The width of the line in pixels. + * @param color The color of the line. + */ + +void CGraphicsPort::drawHorizLine(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_mxpixel_t color) +{ + FAR struct nxgl_rect_s dest; + nxgl_coord_t halfwidth; + + // Express the line as a rectangle + + halfwidth = width >> 1; + + dest.pt1.x = x; + dest.pt1.y = y; + dest.pt2.x = x + width - 1; + dest.pt2.y = y; + + // Draw the line + + if (!m_pNxWnd->fill(&dest, color)) + { + gdbg("INxWindow::fill failed\n"); + } +} + +/** + * Draw a vertical line of the specified start position, width, and + * color. + * + * @param x The x coordinate of the left-most end of the line. + * @param y The y coordinate of the line. + * @param height The height of the line in rows. + * @param color The color of the line. + */ + +void CGraphicsPort::drawVertLine(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t height, nxgl_mxpixel_t color) +{ + FAR struct nxgl_rect_s dest; + + // Express the line as a rectangle + + dest.pt1.x = x; + dest.pt1.y = y; + dest.pt2.x = x; + dest.pt2.y = y + height - 1; + + // Draw the line + + if (!m_pNxWnd->fill(&dest, color)) + { + gdbg("INxWindow::fill failed\n"); + } +} + +/** + * Draw a line of a fixed color in the window. + * + * @param x1 The x coordinate of the start point of the line. + * @param y1 The y coordinate of the start point of the line. + * @param x2 The x coordinate of the end point of the line. + * @param y2 The y coordinate of the end point of the line. + * @param color The color of the line. + */ + +void CGraphicsPort::drawLine(nxgl_coord_t x1, nxgl_coord_t y1, + nxgl_coord_t x2, nxgl_coord_t y2, + nxgl_mxpixel_t color) +{ + struct nxgl_vector_s vector; + + vector.pt1.x = x1; + vector.pt1.y = y1; + vector.pt2.x = x2; + vector.pt2.y = y2; + + if (!m_pNxWnd->drawLine(&vector, 1, color)) + { + gdbg("INxWindow::drawLine failed\n"); + } +} + +/** + * Draw a filled rectangle to the bitmap. + * + * @param x The window-relative x coordinate of the rectangle. + * @param y The window-relative y coordinate of the rectangle. + * @param width The width of the rectangle in pixels. + * @param height The height of the rectangle in rows. + * @param color The color of the rectangle. + */ + +void CGraphicsPort::drawFilledRect(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + nxgl_mxpixel_t color) +{ + struct nxgl_rect_s rect; + rect.pt1.x = x; + rect.pt1.y = y; + rect.pt2.x = x + width - 1; + rect.pt2.y = y + height - 1; + m_pNxWnd->fill(&rect, color); +} + +/** + * Draw an unfilled rectangle to the window + * + * @param x The window-relative x coordinate of the rectangle. + * @param y The window-relative y coordinate of the rectangle. + * @param width The width of the rectangle. + * @param height The height of the rectangle. + * @param color The color of the rectangle outline. + */ + +void CGraphicsPort::drawRect(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + nxgl_mxpixel_t color) +{ + drawHorizLine(x, y, width, color); + drawHorizLine(x, y + height - 1, width, color); + drawVertLine(x, y, height, color); + drawVertLine(x + width -1, y, height, color); +} + +/** + * Draw a bevelled rectangle to the window. + * + * @param x The x coordinate of the rectangle. + * @param y The y coordinate of the rectangle. + * @param width The width of the rectangle. + * @param height The height of the rectangle. + * @param shineColor The color of the top/left sides. + * @param shadowColor The color of the bottom/right sides. + */ + +void CGraphicsPort::drawBevelledRect(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + nxgl_mxpixel_t shineColor, + nxgl_mxpixel_t shadowColor) +{ + drawHorizLine(x, y, width, shineColor); // Top + drawHorizLine(x, y + height - 1, width, shadowColor); // Bottom + drawVertLine(x, y + 1, height - 2, shineColor); // Left + drawVertLine(x + width - 1, y + 1, height - 2, shadowColor); // Right +} + +/** + * Draw an opaque bitmap to the window. + * + * @param x The window-relative x coordinate to draw the bitmap to. + * @param y The window-relative y coordinate to draw the bitmap to. + * @param width The width of the bitmap to draw. + * @param height The height of the bitmap to draw. + * @param bitmap Pointer to the bitmap to draw. + * @param bitmapX The window-relative x coordinate within the supplied + * bitmap to use as the origin. + * @param bitmapY The window-relative y coordinate within the supplied + * bitmap to use as the origin. + */ + +void CGraphicsPort::drawBitmap(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + const struct SBitmap *bitmap, + int bitmapX, int bitmapY) +{ + // origin - The origin of the upper, left-most corner of the full bitmap. + // Both dest and origin are in window coordinates, however, origin + // may lie outside of the display. + + struct nxgl_point_s origin; + origin.x = x - bitmapX; + origin.y = y - bitmapY; + + // dest - Describes the rectangular on the display that will receive the + // the bit map. + + struct nxgl_rect_s dest; + dest.pt1.x = x; + dest.pt1.y = y; + dest.pt2.x = x + width - 1; + dest.pt2.y = y + height - 1; + + // Blit the bitmap + + (void)m_pNxWnd->bitmap(&dest, (FAR const void *)bitmap->data, &origin, bitmap->stride); +} + +/** + * Draw a bitmap to the window, using the supplied transparent + * color as an invisible color. + * + * @param x The window-relative x coordinate to draw the bitmap to. + * @param y The window-relative y coordinate to draw the bitmap to. + * @param width The width of the bitmap to draw. + * @param height The height of the bitmap to draw. + * @param bitmap Pointer to the bitmap to draw. + * @param bitmapX The window-relative x coordinate within the supplied bitmap to use as + * the origin. + * @param bitmapY The window-relative y coordinate within the supplied bitmap to use as + * the origin. + * @param transparentColor The transparent color used in the bitmap. + */ + +void CGraphicsPort::drawBitmap(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + const struct SBitmap *bitmap, + int bitmapX, int bitmapY, + nxgl_mxpixel_t transparentColor) +{ + // Get the starting position in the image, offset by bitmapX and bitmapY into the image. + + FAR uint8_t *srcLine = (uint8_t *)bitmap->data + + bitmapY * bitmap->stride + + ((bitmapX * bitmap->bpp + 7) >> 3); + FAR nxwidget_pixel_t *srcPtr = (nxwidget_pixel_t *)srcLine; + + // Loop until all rows have been displayed + + nxgl_coord_t firstX = x; + nxgl_coord_t lastX = x + width; + nxgl_coord_t lastY = y + height; + + while (y < lastY) + { + // Search for the next non-transparent pixel in the source image + + while (*srcPtr == transparentColor) + { + // The pixel is transparent. Move to the next column + + if (++x >= lastX) + { + // We are at the end of the row. Reset to the next row + + x = firstX; + y++; + + // Was that the last row: + + if (y >= lastY) + { + // Yes, then we are finished + + return; + } + + // Update the source data pointers to the beginning of the next + // row + + srcLine += bitmap->stride; + srcPtr = (nxwidget_pixel_t *)srcLine; + } + else + { + // This is another transparent pixel on the same row + + srcPtr++; + } + } + + // srcPtr points to the next non-transparent color. Save this + // as the start of a run that has length of at least one + + FAR nxwidget_pixel_t *runPtr = srcPtr; + nxgl_coord_t runX = x; + nxgl_coord_t runWidth = 0; + + // Now search for the next transparent pixel on the same row. + // This will determine the length of the run + + do + { + // This is another non-transparent pixel on the same row + + runWidth++; + srcPtr++; + + // Move to the next column + + if (++x >= lastX) + { + // We are at the end of the row. Reset to the next row + + x = firstX; + y++; + + // Update the source data pointers to the beginning of the next + // row + + srcLine += bitmap->stride; + srcPtr = (nxwidget_pixel_t *)srcLine; + + // And break out of this loop + + break; + } + } + while (*srcPtr != transparentColor); + + // When we come out of the above loop, either (1) srcPtr points to the + // next transparent pixel on the same row, or (2) srcPtr points to the + // first pixel in the next row. + + // origin - The origin of the upper, left-most corner of the full bitmap. + // Both dest and origin are in window coordinates, however, origin + // may lie outside of the display. + + struct nxgl_point_s origin; + origin.x = runX; + origin.y = y; + + // dest - Describes the rectangular on the display that will receive the + // the bit map. + + struct nxgl_rect_s dest; + dest.pt1.x = runX; + dest.pt1.y = y; + dest.pt2.x = runX + runWidth - 1; + dest.pt2.y = y; + + // Blit the bitmap + + (void)m_pNxWnd->bitmap(&dest, (FAR const void *)runPtr, &origin, bitmap->stride); + } +} + +/** + * Draw a bitmap to the port in greyscale. + * + * @param x The window-relative x coordinate to draw the bitmap to. + * @param y The window-relative y coordinate to draw the bitmap to. + * @param width The width of the bitmap to draw. + * @param height The height of the bitmap to draw. + * @param bitmap Pointer to the bitmap to draw. + * @param bitmapX The window-relative x coordinate within the supplied bitmap to use as + * the origin. + * @param bitmapY The window-relative y coordinate within the supplied bitmap to use as + * the origin. + */ + +void CGraphicsPort::drawBitmapGreyScale(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + const struct SBitmap *bitmap, + int bitmapX, int bitmapY) +{ + // Working buffer. Holds one converted row from the bitmap + + FAR nxwidget_pixel_t *run = new nxwidget_pixel_t[width]; + + // Pointer to the beginning of the first source row + + FAR uint8_t *src = (FAR uint8_t *)bitmap->data + bitmapY * bitmap->stride + bitmapX; + + // Setup non-changing blit parameters + + struct nxgl_point_s origin; + origin.x = 0; + origin.y = 0; + + struct nxgl_rect_s dest; + dest.pt1.x = x; + dest.pt1.y = y; + dest.pt2.x = x + width - 1; + dest.pt2.y = y; + + // Convert each row to greyscale and send it to the display + + for (int row = 0; row < height; row++) + { + // Convert the next row + + FAR nxwidget_pixel_t *runSrc = (FAR nxwidget_pixel_t *)src; + FAR nxwidget_pixel_t *runDest = run; + + for (int col = 0; col < width; col++) + { + // Get the next RGB pixel and break out the individual components + + nxwidget_pixel_t rgb = *runSrc++; + nxwidget_pixel_t r = RGB2RED(rgb); + nxwidget_pixel_t g = RGB2GREEN(rgb); + nxwidget_pixel_t b = RGB2BLUE(rgb); + + // A truly accurate greyscale conversion would be complex. Let's + // just average. + + nxwidget_pixel_t avg = (r + g + b) / 3; + *runDest++ = MKRGB(avg, avg, avg); + } + + // Now blit the single row + + (void)m_pNxWnd->bitmap(&dest, (FAR void *)bitmap->data, &origin, bitmap->stride); + + // Setup for the next source row + + y++; + dest.pt1.y = y; + dest.pt2.y = y; + + src += bitmap->stride; + } + + delete run; +} + +/** + * Draw a string to the window. + * + * @param pos The window-relative x/y coordinate of the string. + * @param bound The window-relative bounds of the string. + * @param font The font to draw with. + * @param string The string to output. + */ + +void CGraphicsPort::drawText(struct nxgl_point_s *pos, CRect *bound, + CNxFont *font, const CNxString &string) +{ + drawText(pos, bound, font, string, 0, string.getLength()); +} + +/** + * Draw a particular length of a string to the window in a secific color. + * + * @param pos The window-relative x/y coordinate of the string. + * @param bound The window-relative bounds of the string. + * @param font The font to draw with. + * @param string The string to output. + * @param startIndex The start index within the string from which + * drawing will commence. + * @param length The number of characters to draw. + * @param color The color of the string. + */ + +void CGraphicsPort::drawText(struct nxgl_point_s *pos, CRect *bound, + CNxFont *font, const CNxString &string, + int startIndex, int length, + nxgl_mxpixel_t color) +{ + // Temporarily change the font color + + nxgl_mxpixel_t savedColor = font->getColor(); + font->setColor(color); + + // Draw the string with this new color + + drawText(pos, bound, font, string, startIndex, length); + + // Restore the font color + + font->setColor(savedColor); +} + +/** + * Draw a portion of a string to the window. + * @param pos The window-relative x/y coordinate of the string. + * @param bound The window-relative bounds of the string. + * @param font The font to draw with. + * @param string The string to output. + * @param startIndex The start index within the string from which + * drawing will commence. + * @param length The number of characters to draw. + */ + +void CGraphicsPort::drawText(struct nxgl_point_s *pos, CRect *bound, + CNxFont *font, const CNxString &string, + int startIndex, int length) +{ + // Verify index and length + + int stringLength = string.getLength(); + if (startIndex >= stringLength) + { + return; + } + + int endIndex = startIndex + length; + if (endIndex > stringLength) + { + endIndex = stringLength; + } + + // Allocate a bit of memory to hold the largest rendered font + + unsigned int bmWidth = ((unsigned int)font->getMaxWidth() * CONFIG_NXWIDGETS_BPP + 7) >> 3; + unsigned int bmHeight = (unsigned int)font->getHeight(); + + unsigned int glyphSize = bmWidth * bmHeight; + FAR uint8_t *glyph = new uint8_t[glyphSize]; + + // Get the bounding rectangle in NX form + + struct nxgl_rect_s boundingBox; + bound->getNxRect(&boundingBox); + + // Loop setup + +#if 0 + nxwidget_pixel_t backcolor = g_defaultWidgetStyle->colors.back; +#endif + + struct SBitmap bitmap; + bitmap.bpp = CONFIG_NXWIDGETS_BPP; + bitmap.fmt = CONFIG_NXWIDGETS_FMT; + bitmap.data = (FAR const nxgl_mxpixel_t*)glyph; + + // Loop for each letter in the sub-string + + for (int i = startIndex; i < endIndex; i++) + { + // Get the next letter in the string + + const nxwidget_char_t letter = string.getCharAt(i); + + // Get the font metrics for this letter + + struct nx_fontmetric_s metrics; + font->getCharMetrics(letter, &metrics); + + // Get the width of the font (in pixels) + + nxgl_coord_t fontWidth = (nxgl_coord_t)(metrics.width + metrics.xoffset); + + // Does the letter have height? Spaces have width, but no height + + if (metrics.height > 0) + { + // Get the height of the font + + nxgl_coord_t fontHeight = (nxgl_coord_t)(metrics.height + metrics.yoffset); + + // Set the current, effective size of the bitmap + + bitmap.width = fontWidth; + bitmap.height = fontHeight; + bitmap.stride = (fontWidth * bitmap.bpp + 7) >> 3; + + // Describe the destination of the font as a bounding box + + struct nxgl_rect_s dest; + dest.pt1.x = pos->x; + dest.pt1.y = pos->y; + dest.pt2.x = pos->x + fontWidth - 1; + dest.pt2.y = pos->y + fontHeight - 1; + + // Get the interection of the font box and the bounding box + + struct nxgl_rect_s intersection; + nxgl_rectintersect(&intersection, &dest, &boundingBox); + + // Skip to the next character if this one is completely outside + // the bounding box. + + if (!nxgl_nullrect(&intersection)) + { + // Initialize the bitmap memory by reading from the display. The + // font renderer always renders the fonts on a transparent background. + // Sometimes a solid background works, sometimes not. But reading + // from graphics memory always works. + +#if 0 + // Set the glyph memory to the background color + + nxwidget_pixel_t *bmPtr = (nxwidget_pixel_t *)bitmap.data; + unsigned int npixels = fontWidth * fontHeight; + for (unsigned int j = 0; j < npixels; j++) + { + *bmPtr++ = backcolor; + } +#else + // Read the current contents of the destination into the glyph memory + + m_pNxWnd->getRectangle(&dest, &bitmap); +#endif + // Render the font into the initialized bitmap + + font->drawChar(&bitmap, letter); + + // Then put the font on the display + + if (!m_pNxWnd->bitmap(&intersection, (FAR const void *)bitmap.data, + pos, bitmap.stride)) + { + gvdbg("nx_bitmapwindow failed: %d\n", errno); + } + } + } + + // Adjust the X position for the next character in the string + + pos->x += fontWidth; + } + + delete glyph; +} + +/** + * Copy a rectangular region from the source coordinates to the + * destination coordinates. + * + * @param sourceX Source x coordinate. + * @param sourceY Source y coordinate. + * @param destX Destination x coordinate. + * @param destY Destination y coordinate. + * @param width Width of the rectangle to copy. + * @param height Height of the rectangle to copy. + */ + +void CGraphicsPort::copy(nxgl_coord_t sourceX, nxgl_coord_t sourceY, + nxgl_coord_t destX, nxgl_coord_t destY, + nxgl_coord_t width, nxgl_coord_t height) +{ + struct nxgl_rect_s rect; + struct nxgl_point_s offset; + + rect.pt1.x = sourceX; + rect.pt1.y = sourceY; + rect.pt1.x = sourceX + width - 1; + rect.pt1.y = sourceY + height - 1; + + offset.x = destX - sourceX; + offset.y = destY - sourceY; + + (void)m_pNxWnd->move(&rect, &offset); +} + +/** + * Move a region by a specified distance in two dimensions. + * + * @param x X coordinate of the source area to move. + * @param y Y coordinate of the source area to move. + * @param deltaX Horizontal distance to move. + * @param deltaY Vertical distance to move. + * @param width Width of the area to move. + * @param height Height of the area to move. + */ + +void CGraphicsPort::move(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t deltaX, nxgl_coord_t deltaY, + nxgl_coord_t width, nxgl_coord_t height) +{ + struct nxgl_rect_s rect; + rect.pt1.x = x; + rect.pt1.y = y; + rect.pt2.x = x + width - 1; + rect.pt2.y = y = height -1; + + struct nxgl_point_s offset; + offset.x = deltaX; + offset.y = deltaY; + + (void)m_pNxWnd->move(&rect, &offset); +} + +/** + * Convert the region to greyscale. + * + * @param x X coordinate of the region to change. + * @param y Y coordinate of the region to change. + * @param width Width of the region to change. + * @param height Height of the region to change. + */ + +void CGraphicsPort::greyScale(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height) +{ + // Allocate memory to hold one row of graphics data + + unsigned int stride = ((unsigned int)width * CONFIG_NXWIDGETS_BPP + 7) >> 3; + FAR uint8_t *rowBuffer = new uint8_t[height * stride]; + if (!rowBuffer) + { + return; + } + + // Describe the receiving bitmap memory + + SBitmap rowBitmap; + rowBitmap.bpp = CONFIG_NXWIDGETS_BPP; + rowBitmap.fmt = CONFIG_NXWIDGETS_FMT; + rowBitmap.width = width; + rowBitmap.height = 1; + rowBitmap.stride = stride; + rowBitmap.data = (FAR const nxgl_mxpixel_t *)rowBuffer; + + // Partially describe the source rectangle + + struct nxgl_rect_s rect; + rect.pt1.x = x; + rect.pt2.x = x + width - 1; + + // Partially setup the graphics origin + + struct nxgl_point_s origin; + origin.x = x; + + // Loop for each row in the region to be inverted + + for (int row = 0; row < height; row++) + { + // Read the graphic memory corresponding to the row + + rect.pt1.y = rect.pt2.y = y + row; + m_pNxWnd->getRectangle(&rect, &rowBitmap); + + // Convert each bit to each bit + + nxwidget_pixel_t *ptr = (nxwidget_pixel_t *)rowBuffer; + for (int col = 0; col < width; col++) + { + // Get the next RGB pixel and break out the individual components + + nxwidget_pixel_t color = *ptr; + uint8_t red = RGB2RED(color); + uint8_t green = RGB2GREEN(color); + uint8_t blue = RGB2BLUE(color); + + // A truly accurate greyscale conversion would be complex. Let's + // just average. + + nxwidget_pixel_t avg = (red + green + blue) / 3; + *ptr++ = MKRGB(avg, avg, avg); + } + + // Then write the row back to graphics memory + + origin.y = rect.pt1.y; + m_pNxWnd->bitmap(&rect, (FAR const void *)rowBitmap.data, + &origin, rowBitmap.stride) ; + } + + delete rowBuffer; +} + +/** + * Invert colors in a region. NOTE: This allocates an in-memory + * buffer the size of one row in graphic memory. So it may only be + * useful for inverting small regions and its only current use of for + * the inverted cursor text. + * + * @param x X coordinate of the region to change. + * @param y Y coordinate of the region to change. + * @param width Width of the region to change. + * @param height Height of the region to change. + */ + +void CGraphicsPort::invert(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height) +{ + // Allocate memory to hold one row of graphics data + + unsigned int stride = ((unsigned int)width * CONFIG_NXWIDGETS_BPP + 7) >> 3; + FAR uint8_t *rowBuffer = new uint8_t[height * stride]; + if (!rowBuffer) + { + return; + } + + // Describe the receiving bitmap memory + + SBitmap rowBitmap; + rowBitmap.bpp = CONFIG_NXWIDGETS_BPP; + rowBitmap.fmt = CONFIG_NXWIDGETS_FMT; + rowBitmap.width = width; + rowBitmap.height = 1; + rowBitmap.stride = stride; + rowBitmap.data = (FAR const nxgl_mxpixel_t *)rowBuffer; + + // Partially describe the source rectangle + + struct nxgl_rect_s rect; + rect.pt1.x = x; + rect.pt2.x = x + width - 1; + + // Partially setup the graphics origin + + struct nxgl_point_s origin; + origin.x = x; + + // Loop for each row in the region to be inverted + + for (int row = 0; row < height; row++) + { + // Read the graphic memory corresponding to the row + + rect.pt1.y = rect.pt2.y = y + row; + m_pNxWnd->getRectangle(&rect, &rowBitmap); + + // Invert each bit + + nxwidget_pixel_t *ptr = (nxwidget_pixel_t *)rowBuffer; + for (int col = 0; col < width; col++) + { + nxwidget_pixel_t color = *ptr; + uint8_t red = RGB2RED(color); + uint8_t green = RGB2GREEN(color); + uint8_t blue = RGB2BLUE(color); + *ptr++ = MKRGB(~red, ~green, ~blue); + } + + // Then write the row back to graphics memory + + origin.y = rect.pt1.y; + m_pNxWnd->bitmap(&rect, (FAR const void *)rowBitmap.data, + &origin, rowBitmap.stride) ; + } + + delete rowBuffer; +}; + diff --git a/NxWidgets/libnxwidgets/src/cimage.cxx b/NxWidgets/libnxwidgets/src/cimage.cxx new file mode 100644 index 000000000..b57857e66 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cimage.cxx @@ -0,0 +1,343 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/include/cimage.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> +#include <debug.h> + +#include <nuttx/nx/nxglib.h> + +#include "nxconfig.hxx" +#include "cgraphicsport.hxx" +#include "ibitmap.hxx" +#include "cbitmap.hxx" +#include "cimage.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor for a label containing a string. + * + * @param pWidgetControl The controlling widget for the display + * @param x The x coordinate of the image box, relative to its parent. + * @param y The y coordinate of the image box, relative to its parent. + * @param width The width of the textbox. + * @param height The height of the textbox. + * @param bitmap The source bitmap image. + * @param style The style that the widget should use. If this is not + * specified, the button will use the global default widget + * style. + */ + +CImage::CImage(CWidgetControl *pWidgetControl, nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, FAR IBitmap *bitmap, + CWidgetStyle *style) + : CNxWidget(pWidgetControl, x, y, width, height, 0, style) +{ + // Save the IBitmap instance + + m_bitmap = bitmap; + + // Position the top/lef corner of the bitmap in the top/left corner of the display + + m_origin.x = 0; + m_origin.y = 0; +} + +/** + * Insert the dimensions that this widget wants to have into the rect + * passed in as a parameter. All coordinates are relative to the + * widget's parent. + * + * @param rect Reference to a rect to populate with data. + */ + +void CImage::getPreferredDimensions(CRect &rect) const +{ + nxgl_coord_t width = m_bitmap->getWidth(); + nxgl_coord_t height = m_bitmap->getHeight(); + + if (!m_flags.borderless) + { + width += (m_borderSize.left + m_borderSize.right); + height += (m_borderSize.top + m_borderSize.bottom); + } + + rect.setX(m_rect.getX()); + rect.setY(m_rect.getY()); + rect.setWidth(width); + rect.setHeight(height); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CImage::drawContents(CGraphicsPort *port) +{ + // Get the the drawable region + + CRect rect; + getRect(rect); + + // Allocate a working buffer that will hold one row of the bitmap + + FAR nxwidget_pixel_t *buffer = new nxwidget_pixel_t[rect.getWidth()]; + + // Set up a simple bitmap structure to describe on row + + struct SBitmap bitmap; + bitmap.bpp = m_bitmap->getBitsPerPixel(); + bitmap.fmt = m_bitmap->getColorFormat(); + bitmap.width = rect.getWidth(); + bitmap.height = 1; + bitmap.stride = (rect.getWidth() * m_bitmap->getBitsPerPixel()) >> 3; + bitmap.data = buffer; + + // This is the number of rows that we can draw at the top of the display + + nxgl_coord_t nTopRows = m_bitmap->getHeight() - m_origin.y; + if (nTopRows > rect.getHeight()) + { + nTopRows = rect.getHeight(); + } + else if (nTopRows < 0) + { + nTopRows = 0; + } + + // This the starting row in the bitmap image where we will begin drawing. + + nxgl_coord_t imageRow = m_origin.y; + + // This the starting row in the display image where we will begin drawing. + + nxgl_coord_t displayRow = rect.getY(); + + // Are we going to draw any rows at the top of the display? + + if (nTopRows > 0) + { + // This is the number of columns that we can draw on the left side of + // the display + + nxgl_coord_t nLeftPixels = m_bitmap->getWidth() - m_origin.x; + + // This is the number of rows that we have to pad on the right if the display + // width is wider than the image width + + nxgl_coord_t nRightPad; + if (nLeftPixels >= rect.getWidth()) + { + nRightPad = 0; + } + else + { + nRightPad = rect.getWidth() - nLeftPixels; + } + + // Apply the padding to the right hand side + + FAR nxwidget_pixel_t *ptr = &buffer[nLeftPixels]; + nxwidget_pixel_t backColor = getBackgroundColor(); + + for (int column = nLeftPixels; column < rect.getWidth(); column++) + { + *ptr++ = backColor; + } + + // The is the row number of the first row that we cannot draw into + + nxgl_coord_t lastTopRow = nTopRows + m_origin.y; + + // Now draw the rows from the offset position + + for (; imageRow < lastTopRow; imageRow++, displayRow++) + { + // Get the graphics data for the right hand side of this row + + if (!m_bitmap->getRun(m_origin.x, imageRow, nLeftPixels, buffer)) + { + gvdbg("IBitmap::getRun failed at image row\n", imageRow); + delete buffer; + return; + } + + // Replace any transparent pixels with the background color. + // Then we can use the faster opaque drawBitmap() function. + + ptr = buffer; + for (int i = 0; i < nLeftPixels; i++, ptr++) + { + if (*ptr == CONFIG_NXWIDGETS_TRANSPARENT_COLOR) + { + *ptr = backColor; + } + } + + // And put these on the display + + port->drawBitmap(rect.getX(), displayRow, rect.getWidth(), 1, + &bitmap, 0, 0); + } + } + + // Are we going to draw any rows at the top of the display? + + if (nTopRows < rect.getHeight()) + { + // Pad the entire row + + FAR nxwidget_pixel_t *ptr = buffer; + nxwidget_pixel_t backColor = getBackgroundColor(); + + for (int column = 0; column < rect.getWidth(); column++) + { + *ptr++ = backColor; + } + + // Now draw the rows from the offset position + + for (; displayRow < rect.getHeight(); displayRow++) + { + // Put the padded row on the display + + port->drawBitmap(rect.getX(), displayRow, rect.getWidth(), 1, + &bitmap, 0, 0); + } + } + + delete buffer; +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CImage::drawBorder(CGraphicsPort *port) +{ + if (!isBorderless()) + { + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), + getShadowEdgeColor(), getShineEdgeColor()); + } +} + +/** + * Set the horizontal position of the bitmap. Zero is the left edge + * of the bitmap and values >0 will move the bit map to the right. + * This method is useful for horizontal scrolling a large bitmap + * within a smaller window + */ + +void CImage::setImageLeft(nxgl_coord_t column) +{ + if (column > 0 && column <= m_bitmap->getWidth()) + { + m_origin.x = column; + } +} + +/** + * Set the vertical position of the bitmap. Zero is the top edge + * of the bitmap and values >0 will move the bit map down. + * This method is useful for vertical scrolling a large bitmap + * within a smaller window + */ + +void CImage::setImageTop(nxgl_coord_t row) +{ + if (row > 0 && row <= m_bitmap->getHeight()) + { + m_origin.x = row; + } +} + diff --git a/NxWidgets/libnxwidgets/src/ckeypad.cxx b/NxWidgets/libnxwidgets/src/ckeypad.cxx new file mode 100644 index 000000000..898885c62 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/ckeypad.cxx @@ -0,0 +1,214 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/ckeypad.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxglib.h> + +#include "cwidgetcontrol.hxx" +#include "cwidgetstyle.hxx" +#include "ckeypad.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +// The geometry of the button array + +#define BUTTONARRAY_NCOLUMNS 4 +#define BUTTONARRAY_NROWS 7 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +using namespace NXWidgets; + +static FAR const char *g_alphaLabels[BUTTONARRAY_NCOLUMNS*BUTTONARRAY_NROWS] = { + "=>", "A", "B", "<DEL", + "C", "D", "E", "F", + "G", "H", "I", "J", + "K", "L", "M", "N", + "O", "P", "Q", "R", + "S", "T", "U", "V", + "W", "X", "Y", "Z" +}; + +static FAR const char *g_numLabels[BUTTONARRAY_NCOLUMNS*BUTTONARRAY_NROWS] = { + "=>", "0", "1", "<DEL", + "2", "3", "4", "5", + "6", "7", "8", "9", + "-", "#", "*", "&", + "?", "!", "@", "%", + ":", ",", ".", "/", + "\"", "'", "(", ")" +}; + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +/** + * Constructor for buttons that display a string. + * + * @param pWidgetControl The widget control for the display. + * @param hNxServer The NX server that will receive the keyboard input + * @param x The x coordinate of the keypad, relative to its parent. + * @param y The y coordinate of the keypad, relative to its parent. + * @param width The width of the keypad + * @param height The height of the keypad + * @param style The style that the button should use. If this is not + * specified, the button will use the global default widget + * style. + */ + +CKeypad::CKeypad(CWidgetControl *pWidgetControl, NXHANDLE hNxServer, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + CWidgetStyle *style) +: CButtonArray(pWidgetControl, x, y, 4, 7, width / BUTTONARRAY_NCOLUMNS, + height / BUTTONARRAY_NROWS, style) +{ + m_hNxServer = hNxServer; + + // Force the height and width to be an exact multiple of the button height and width + + resize(m_buttonWidth * m_buttonColumns, m_buttonHeight * m_buttonRows); + + // Start in alphabetic mode + + setKeypadMode(false); +} + +/** + * Catch button clicks. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CKeypad::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + // Perform the redraw + + CButtonArray::onClick(x, y); + + // The button should now be clicked + + int column; + int row; + + if (isButtonClicked(column, row)) + { + // The left arrow at (0,0) is a special case + + char ch; + if (column == 0 && row == 0) + { + m_widgetControl->newCursorControlEvent(CURSOR_RIGHT); + return; + } + + // The backspace at (3,0) is a special case + + else if (column == 3 && row == 0) + { + ch = KEY_CODE_BACKSPACE; + } + + // Otherwise, just grab the character for the arrays + + else + { + int index = row * BUTTONARRAY_NCOLUMNS + column; + FAR const char *ptr; + if (m_numeric) + { + ptr = g_numLabels[index]; + } + else + { + ptr = g_alphaLabels[index]; + } + + ch = ptr[0]; + } + + // Then inject the keyboard input into the NX server. The NX + // server will determine which window receives the input. + // The ultimate recipient will be the widget in the top window + // that has focus. + + (void)nx_kbdchin(m_hNxServer, (uint8_t)ch); + } +} + +/** + * Configure the keypad for the currenly selected display mode. + */ + +void CKeypad::configureKeypadMode(void) +{ + // Add the labels to each button. Each call to setText would + // cause a text change event and, hence, redrawing of the + + FAR const char **ptr = m_numeric ? g_numLabels : g_alphaLabels; + for (int j = 0; j < BUTTONARRAY_NROWS; j++) + { + for (int i = 0; i < BUTTONARRAY_NCOLUMNS; i++) + { + // setText does this. But each call to setText would + // cause a text change even and, hence, redrawing of + // the whole keypad. So we access the protected data + // directly and redraw only once. + + CNxString string = *ptr++; + m_buttonText[j * m_buttonColumns + i] = string; + } + } + + // Then redraw the display + + onTextChange(); +} + diff --git a/NxWidgets/libnxwidgets/src/clabel.cxx b/NxWidgets/libnxwidgets/src/clabel.cxx new file mode 100644 index 000000000..4c7ea3554 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/clabel.cxx @@ -0,0 +1,426 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/clabel.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "nxconfig.hxx" +#include "clabel.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CLabel Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor for a label containing a string. + * + * @param pWidgetControl The controlling widget for the display + * @param x The x coordinate of the text box, relative to its parent. + * @param y The y coordinate of the text box, relative to its parent. + * @param width The width of the textbox. + * @param height The height of the textbox. + * @param text Pointer to a string to display in the textbox. + * @param style The style that the button should use. If this is not + * specified, the button will use the global default widget + * style. + */ + +CLabel::CLabel(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + const CNxString &text, CWidgetStyle *style) + : CNxWidget(pWidgetControl, x, y, width, height, 0, style) +{ + // Default is centered text + + m_hAlignment = TEXT_ALIGNMENT_HORIZ_CENTER; + m_vAlignment = TEXT_ALIGNMENT_VERT_CENTER; + + // The border thickness is 1 pixel + + m_borderSize.top = 1; + m_borderSize.right = 1; + m_borderSize.bottom = 1; + m_borderSize.left = 1; + + m_align.x = 0; + m_align.y = 0; + + m_textChange = false; + m_highlighted = false; + setText(text); + + calculateTextPositionHorizontal(); + calculateTextPositionVertical(); +} + +/** + * Set the horizontal alignment of text within the label. + * + * @param alignment The horizontal position of the text. + */ + +void CLabel::setTextAlignmentHoriz(TextAlignmentHoriz alignment) +{ + m_hAlignment = alignment; + calculateTextPositionHorizontal(); + redraw(); +} + +/** + * Set the vertical alignment of text within the label. + * + * @param alignment The vertical position of the text. + */ + +void CLabel::setTextAlignmentVert(TextAlignmentVert alignment) +{ + m_vAlignment = alignment; + calculateTextPositionVertical(); + redraw(); +} + +/** + * Set the text displayed in the label. + * + * @param text String to display. + */ + +void CLabel::setText(const CNxString &text) +{ + m_text = text; + onTextChange(); +} + +/** + * Append new text to the end of the current text displayed in the + * label. + * + * @param text String to append. + */ + +void CLabel::appendText(const CNxString &text) +{ + m_text.append(text); + onTextChange(); +} + +/** + * Insert text at the specified index. + * + * @param text The text to insert. + * @param index Index at which to insert the text. + */ + +void CLabel::insertText(const CNxString &text, const int index) +{ + m_text.insert(text, index); + onTextChange(); +} + +/** + * Control the highlight state. + * + * @param highlightOn True(1), the label will be highlighted + */ + +void CLabel::highlight(bool highlightOn) +{ + if (highlightOn != m_highlighted) + { + m_highlighted = highlightOn; + redraw(); + } +} + +/** + * Insert the dimensions that this widget wants to have into the rect + * passed in as a parameter. All coordinates are relative to the + * widget's parent. + * + * @param rect Reference to a rect to populate with data. + */ + +void CLabel::getPreferredDimensions(CRect &rect) const +{ + nxgl_coord_t width; + nxgl_coord_t height; + + if (!m_flags.borderless) + { + width = m_borderSize.left + m_borderSize.right; + height = m_borderSize.top + m_borderSize.bottom; + } + else + { + width = 0; + height = 0; + } + + width += getFont()->getStringWidth(m_text); + height += getFont()->getHeight(); + + rect.setX(m_rect.getX()); + rect.setY(m_rect.getY()); + rect.setWidth(width); + rect.setHeight(height); +} + +/** + * Sets the font. + * + * @param font A pointer to the font to use. + */ + +void CLabel::setFont(CNxFont *font) +{ + m_style.font = font; + + // Need to recalculate the text position as the font may have changed size + + calculateTextPositionHorizontal(); + calculateTextPositionVertical(); + redraw(); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * @param port The CGraphicsPort to draw to. + * + * @see redraw() + */ + +void CLabel::drawContents(CGraphicsPort *port) +{ + // Get the drawing area (excluding the border) + + CRect rect; + getRect(rect); + + // Pick the text and background colors + + nxgl_mxpixel_t textColor; + nxgl_mxpixel_t backColor; + + if (!isEnabled()) + { + textColor = getDisabledTextColor(); + backColor = getBackgroundColor(); + } + else if (m_highlighted) + { + textColor = getSelectedTextColor(); + backColor = getSelectedBackgroundColor(); + } + else + { + textColor = getEnabledTextColor(); + backColor = getBackgroundColor(); + } + + // Draw the background (excluding the border) + + port->drawFilledRect(rect.getX(), rect.getY(), + rect.getWidth(), rect.getHeight(), backColor); + + // Get the X/Y position of the text within the Label + + struct nxgl_point_s pos; + pos.x = rect.getX() + m_align.x; + pos.y = rect.getY() + m_align.y; + + // Add the text using the selected color + + port->drawText(&pos, &rect, getFont(), m_text, 0, m_text.getLength(), + textColor); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CLabel::drawBorder(CGraphicsPort *port) +{ + // Check if the widget indicates it should have an outline: That + // the outline is enabled and the this is not just a text-only + // redraw + + if (!isBorderless() && !isTextChange()) + { + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), + getShadowEdgeColor(), getShineEdgeColor()); + } +} + +/** + * Resize the widget to the new dimensions. + * + * @param width The new width. + * @param height The new height. + */ + +void CLabel::onResize(nxgl_coord_t width, nxgl_coord_t height) +{ + calculateTextPositionHorizontal(); + calculateTextPositionVertical(); +} + +/** + * Calculate the vertical position of the string based on the font + * + * height and the alignment options. + */ + +void CLabel::calculateTextPositionVertical(void) +{ + CRect rect; + getClientRect(rect); + + nxgl_coord_t height = rect.getHeight(); + + switch (m_vAlignment) + { + case TEXT_ALIGNMENT_VERT_CENTER: + m_align.y = (height - getFont()->getHeight()) >> 1; + break; + + case TEXT_ALIGNMENT_VERT_TOP: + m_align.y = 0; + break; + + case TEXT_ALIGNMENT_VERT_BOTTOM: + m_align.y = height - getFont()->getHeight(); + break; + } +} + +/** + * Calculate the position of the string based on its length and the + * alignment options. + */ + +void CLabel::calculateTextPositionHorizontal(void) +{ + CRect rect; + getClientRect(rect); + + nxgl_coord_t width = rect.getWidth(); + + switch (m_hAlignment) + { + case TEXT_ALIGNMENT_HORIZ_CENTER: + m_align.x = (width - getFont()->getStringWidth(m_text)) >> 1; + break; + + case TEXT_ALIGNMENT_HORIZ_LEFT: + m_align.x = 0; + break; + + case TEXT_ALIGNMENT_HORIZ_RIGHT: + m_align.x = width - getFont()->getStringWidth(m_text); + break; + } +} + +/** + * Updates the GUI after the text has changed. + */ + +void CLabel::onTextChange(void) +{ + calculateTextPositionHorizontal(); + calculateTextPositionVertical(); + m_textChange = true; + redraw(); + m_textChange = false; + m_widgetEventHandlers->raiseValueChangeEvent(); +} + + diff --git a/NxWidgets/libnxwidgets/src/clatchbutton.cxx b/NxWidgets/libnxwidgets/src/clatchbutton.cxx new file mode 100644 index 000000000..673d50319 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/clatchbutton.cxx @@ -0,0 +1,131 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/clatchbutton.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "cstickybutton.hxx" +#include "clatchbutton.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CButton Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor for buttons that display a string. + * + * @param pWidgetControl The controlling widget for the display. + * @param x The x coordinate of the button, relative to its parent. + * @param y The y coordinate of the button, relative to its parent. + * @param width The width of the button. + * @param height The height of the button. + * @param text The text for the button to display. + * @param style The style that the button should use. If this is not + * specified, the button will use the global default widget + * style. + */ + +CLatchButton::CLatchButton(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + const CNxString &text, + CWidgetStyle *style) +: CStickyButton(pWidgetControl, x, y, width, height, text, style) +{ +} + +/** + * Handles button click events + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CLatchButton::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + /* On each press event, toggle the button stuck down state */ + + toggleStuckDown(); +} diff --git a/NxWidgets/libnxwidgets/src/clatchbuttonarray.cxx b/NxWidgets/libnxwidgets/src/clatchbuttonarray.cxx new file mode 100644 index 000000000..d8292941b --- /dev/null +++ b/NxWidgets/libnxwidgets/src/clatchbuttonarray.cxx @@ -0,0 +1,116 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/clatchbuttonarray.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "cstickybuttonarray.hxx" +#include "clatchbuttonarray.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CButton Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor for an array of latch buttons. + * + * @param pWidgetControl The widget control for the display. + * @param x The x coordinate of the button array, relative to its parent. + * @param y The y coordinate of the button array, relative to its parent. + * @param buttonColumns The number of buttons in one row of the button array + * @param buttonRows The number of buttons in one column of the button array + * @param buttonWidth The width of one button + * @param buttonHeight The height of one button + * @param style The style that the button should use. If this is not + * specified, the button will use the global default widget + * style. + */ + +CLatchButtonArray::CLatchButtonArray(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + uint8_t buttonColumns, uint8_t buttonRows, + nxgl_coord_t buttonWidth, nxgl_coord_t buttonHeight, + CWidgetStyle *style) +: CStickyButtonArray(pWidgetControl, x, y, buttonColumns, buttonRows, buttonWidth, buttonHeight, style) +{ +} + +/** + * Handles button click events + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CLatchButtonArray::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + // We need to save the button position so that when CButtonArray + // gets the release, it will have the correct position. This would + // look nicer if we just called CButtonArray::onClock() but that + // would cause duplicate redraw() + + m_clickX = x; + m_clickY = y; + + // Convert the new key press to row/columin indices + + int column; + int row; + + if (posToButton(x, y, column, row)) + { + // Change the stuck down button on each in-range button press + // NOTE that normally button click events are not processed (but + // button release events will be processed). + + stickDown(column, row); + } +} diff --git a/NxWidgets/libnxwidgets/src/clistbox.cxx b/NxWidgets/libnxwidgets/src/clistbox.cxx new file mode 100644 index 000000000..a8d3db0a6 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/clistbox.cxx @@ -0,0 +1,661 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/clistbox.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cwidgetcontrol.hxx" +#include "clistbox.hxx" +#include "cgraphicsport.hxx" +#include "cnxfont.hxx" +#include "singletons.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The controlling widget for the display. + * @param x The x coordinate of the widget. + * @param y The y coordinate of the widget. + * @param width The width of the widget. + * @param height The height of the widget. + * @param style The style that the widget should use. If this is not + * specified, the widget will use the values stored in the global + * g_defaultWidgetStyle object. The widget will copy the properties of + * the style into its own internal style object. + */ + +CListBox::CListBox(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + CWidgetStyle *style) +: CScrollingPanel(pWidgetControl, x, y, width, height, 0, style) +{ + m_flags.draggable = true; + m_flags.doubleClickable = true; + m_optionPadding = 2; + m_options.addListDataEventHandler(this); + m_lastSelectedIndex = -1; + + // Disallow horizontal scrolling + + setAllowsHorizontalScroll(false); +} + +/** + * Destructor. + */ + +CListBox::~CListBox(void) +{ + m_options.removeListDataEventHandler(this); +} + + +/** + * Add a new option to the widget using default colors. + * + * @param text Text to show in the option. + * @param value The value of the option. + */ + +void CListBox::addOption(const CNxString &text, const uint32_t value) +{ + addOption(text, value, + getShadowEdgeColor(), getBackgroundColor(), + getShadowEdgeColor(), getHighlightColor()); +} + +/** + * Add an option to the widget. + * + * @param option The option to add. + */ + +void CListBox::addOption(CListBoxDataItem *option) +{ + m_options.addItem(option); +} + +/** + * Remove an option from the widget by its index. + * + * @param index The index of the option to remove. + */ + +void CListBox::removeOption(const int index) +{ + m_options.removeItem(index); +} + +/** + * Remove all options from the widget. + */ + +void CListBox::removeAllOptions(void) +{ + m_options.removeAllItems(); +} + +/** + * Add a new option to the widget. + * + * @param text Text to show in the option. + * @param value The value of the option. + * @param normalTextColor Color to draw the text with when not selected. + * @param normalBackColor Color to draw the background with when not selected. + * @param selectedTextColor Color to draw the text with when selected. + * @param selectedBackColor Color to draw the background with when selected. + */ + +void CListBox::addOption(const CNxString &text, const uint32_t value, + const nxwidget_pixel_t normalTextColor, + const nxwidget_pixel_t normalBackColor, + const nxwidget_pixel_t selectedTextColor, + const nxwidget_pixel_t selectedBackColor) +{ + addOption(new CListBoxDataItem(text, value, + normalTextColor, normalBackColor, + selectedTextColor, selectedBackColor)); +} + +/** + * Select an option by its index. + * Redraws the widget and raises a value changed event. + * + * @param index The index of the option to select. + */ + +void CListBox::selectOption(const int index) +{ + setOptionSelected(index, true); +} + +/** + * Select an option by its index. + * Redraws the widget and raises a value changed event. + * + * @param index The index of the option to select. + */ + +void CListBox::deselectOption(const int index) +{ + setOptionSelected(index, false); +} + +/** + * Select all options. Does nothing if the listbox does not allow + * multiple selections. Redraws the widget and raises a value changed + * event. + */ + +void CListBox::selectAllOptions(void) +{ + m_options.selectAllItems(); +} + +/** + * Deselect all options. + * Redraws the widget and raises a value changed event. + */ + +void CListBox::deselectAllOptions(void) +{ + m_options.deselectAllItems(); +} + +/** + * Get the selected index. Returns -1 if nothing is selected. If + * more than one option is selected, the index of the first selected + * option is returned. + * + * @return The selected index. + */ + +const int CListBox::getSelectedIndex(void) const +{ + return m_options.getSelectedIndex(); +} + +/** + * Sets the selected index. Specify -1 to select nothing. Resets any + * other selected options to deselected. Redraws the widget and raises + * a value changed event. + * + * @param index The selected index. + */ + +void CListBox::setSelectedIndex(const int index) +{ + setOptionSelected(index, true); +} + +/** + * Get the selected option. Returns NULL if nothing is selected. + * + * @return The selected option. + */ + +const CListBoxDataItem *CListBox::getSelectedOption(void) const +{ + return (const CListBoxDataItem*)m_options.getSelectedItem(); +} + +/** + * Resize the scrolling canvas to encompass all options. + */ + +void CListBox::resizeCanvas(void) +{ + // Get client area + + CRect rect; + getClientRect(rect); + + int oldCanvasHeight = m_canvasHeight; + + // Resize the canvas + + m_canvasHeight = (m_options.getItemCount() * getOptionHeight()); + + // Ensure canvas is at least as tall as the widget + + m_canvasHeight = m_canvasHeight < rect.getHeight() ? rect.getHeight() : m_canvasHeight; + + // If resize has left scroll position beyond end of canvas, adjust + // to compensate + + if (m_canvasY + (m_canvasHeight - getHeight()) < 0) + { + scroll(0, -(oldCanvasHeight - (m_canvasHeight - getHeight()))); + } +} + +/** + * Sort the options alphabetically by the text of the options. + */ + +void CListBox::sort(void) +{ + m_options.sort(); +} + +/** + * Get the height of a single option. + * + * @return The height of an option. + */ + +const nxgl_coord_t CListBox::getOptionHeight(void) const +{ + return getFont()->getHeight() + (m_optionPadding << 1); +} + +/** + * Handles list data changed events. + * + * @param e Event arguments. + */ + +void CListBox::handleListDataChangedEvent(const CListDataEventArgs &e) +{ + // Forget the last selected item as it may have changed + + m_lastSelectedIndex = -1; + resizeCanvas(); + redraw(); +} + +/** + * Handles list selection changed events. + * + * @param e Event arguments. + */ + +void CListBox::handleListDataSelectionChangedEvent(const CListDataEventArgs &e) +{ + redraw(); + m_widgetEventHandlers->raiseValueChangeEvent(); +} + +/** + * Insert the dimensions that this widget wants to have into the rect + * passed in as a parameter. All coordinates are relative to the widget's + * parent. Value is based on the length of the largest string in the + * set of options. + * + * @param rect Reference to a rect to populate with data. + */ + +void CListBox::getPreferredDimensions(CRect &rect) const +{ + nxgl_coord_t width; + nxgl_coord_t height; + + if (!m_flags.borderless) + { + width = m_borderSize.left + m_borderSize.right; + height = m_borderSize.top + m_borderSize.bottom; + } + else + { + width = 0; + height = 0; + } + + nxgl_coord_t maxWidth = 0; + nxgl_coord_t optionWidth = 0; + + // Locate longest string in options + + for (int i = 0; i < m_options.getItemCount(); ++i) + { + optionWidth = getFont()->getStringWidth(m_options.getItem(i)->getText()); + + if (optionWidth > maxWidth) + { + maxWidth = optionWidth; + } + } + + rect.setX(m_rect.getX()); + rect.setY(m_rect.getY()); + rect.setWidth(width + (m_optionPadding << 1) + maxWidth); + rect.setHeight(height + getOptionHeight() * 3); +} + +/** + * Check if the click is a double-click. + * + * @param x X coordinate of the click. + * @param y Y coordinate of the click. + * @return True if the click is a double-click. + */ + +bool CListBox::isDoubleClick(nxgl_coord_t x, nxgl_coord_t y) +{ + if (CNxWidget::isDoubleClick(x, y)) + { + // Calculate which option was clicked + + int selectedIndex = (-m_canvasY + (y - getY())) / getOptionHeight(); + + // Has the same option been clicked twice? Ignore double-clicks that + // occur on different items + + if (selectedIndex == m_lastSelectedIndex) + { + // Process click as a double-click + + return true; + } + } + + return false; +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CListBox::drawContents(CGraphicsPort *port) +{ + // Get the drawing region (excluding the borders) + + CRect rect; + getRect(rect); + + // Draw background + + port->drawFilledRect(rect.getX(), rect.getY(), + rect.getWidth(), rect.getHeight(), + getBackgroundColor()); + + // Calculate clipping values + + nxgl_coord_t clipX = rect.getX(); + nxgl_coord_t clipY = rect.getY(); + nxgl_coord_t clipHeight = rect.getHeight(); + + // Precalc values for option draw loop + + nxgl_coord_t optionHeight = getOptionHeight(); + + // Ensure that we subtract 1 from topOption to ensure that the option + // above is drawn if it is partially visible + + int topOption = ((clipY - m_canvasY) / optionHeight) - 1; + + // Ensure that we add 2 to the bottom option to ensure that the option + // below is draw if it is partially visible - subbing 1 from topOption + // means we need to add an additional 1 to compensate + + int bottomOption = topOption + (clipHeight / optionHeight) + 2; + + // Ensure top options is not negative + + if (topOption < 0) + { + topOption = 0; + } + + // Ensure bottom option does not exceed number of options + + if (bottomOption >= m_options.getItemCount()) + { + bottomOption = m_options.getItemCount() - 1; + } + + // Calculate values for loop + + int y = m_canvasY + (topOption * optionHeight); + int i = topOption; + + const CListBoxDataItem *item = (CListBoxDataItem *)NULL; + + // Loop through all options drawing each ones + + while (i <= bottomOption) + { + item = (const CListBoxDataItem*)m_options.getItem(i); + + // Is the option selected? + + if (item->isSelected()) + { + // Draw background + + if (item->getSelectedBackColor() != getBackgroundColor()) + { + port->drawFilledRect(rect.getX(), rect.getY() + y, + rect.getWidth(), optionHeight, + item->getSelectedBackColor()); + } + + // Draw text + + struct nxgl_point_s pos; + pos.x = rect.getX() + m_optionPadding; + pos.y = rect.getY() + y + m_optionPadding; + + if (isEnabled()) + { + port->drawText(&pos, &rect, getFont(), item->getText(), 0, + item->getText().getLength(), + item->getSelectedTextColor()); + } + else + { + port->drawText(&pos, &rect, getFont(), item->getText(), 0, + item->getText().getLength(), + getDisabledTextColor()); + } + } + else + { + // Draw background + + if (item->getNormalBackColor() != getBackgroundColor()) + { + port->drawFilledRect(clipX, y, getWidth(), optionHeight, + item->getNormalBackColor()); + } + + // Draw text + + struct nxgl_point_s pos; + pos.x = rect.getX() + m_optionPadding; + pos.y = rect.getY() + y + m_optionPadding; + + if (isEnabled()) + { + port->drawText(&pos, &rect, getFont(), item->getText(), 0, + item->getText().getLength(), + item->getNormalTextColor()); + } + else + { + port->drawText(&pos, &rect, getFont(), item->getText(), 0, + item->getText().getLength(), + getDisabledTextColor()); + } + } + + i++; + y += optionHeight; + } +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CListBox::drawBorder(CGraphicsPort *port) +{ + // Stop drawing if the widget indicates it should not have an outline + + if (!isBorderless()) + { + port->drawBevelledRect(0, 0, getWidth(), getHeight(), + getShadowEdgeColor(), getShineEdgeColor()); + } +} + +/** + * Determines which item was clicked and selects or deselects it as + * appropriate. Also starts the dragging system. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CListBox::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + // Calculate which option was clicked + + m_lastSelectedIndex = (-m_canvasY + (y - getY())) / getOptionHeight(); + + const CListBoxDataItem *item = + (const CListBoxDataItem*)m_options.getItem(m_lastSelectedIndex); + + // Are we setting or unsetting? + + if (item->isSelected()) + { + // Deselecting + + m_options.deselectItem(m_lastSelectedIndex); + } + else + { + // Selecting + + m_options.selectItem(m_lastSelectedIndex); + } + + startDragging(x, y); + redraw(); +} + +/** + * Selects the clicked item and deselects all others. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CListBox::onDoubleClick(nxgl_coord_t x, nxgl_coord_t y) +{ + // Calculate which option was clicked + + int newSelectedIndex = (-m_canvasY + (y - getY())) / getOptionHeight(); + + // Double-click - select the item exclusively + + deselectAllOptions(); + setSelectedIndex(newSelectedIndex); + m_widgetEventHandlers->raiseActionEvent(); +} + +/** + * Select or deselect an option by its index. Does not deselect any other selected options. + * Set index to -1 to select nothing. + * Redraws the widget and raises a value changed event. + * + * @param index The index of the option to select. + * @param selected True to select the option, false to deselect it. + */ + +void CListBox::setOptionSelected(const int index, bool selected) +{ + m_options.setItemSelected(index, selected); +} diff --git a/NxWidgets/libnxwidgets/src/clistboxdataitem.cxx b/NxWidgets/libnxwidgets/src/clistboxdataitem.cxx new file mode 100644 index 000000000..0ef1b2d25 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/clistboxdataitem.cxx @@ -0,0 +1,114 @@ +/****************************************************************************
+ * NxWidgets/libnxwidgets/src/clistboxdataitem.cxx
+ *
+ * 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.
+ *
+ ****************************************************************************
+ *
+ * Portions of this package derive from Woopsi (http://woopsi.org/) and
+ * portions are original efforts. It is difficult to determine at this
+ * point what parts are original efforts and which parts derive from Woopsi.
+ * However, in any event, the work of Antony Dzeryn will be acknowledged
+ * in most NxWidget files. Thanks Antony!
+ *
+ * Copyright (c) 2007-2011, Antony Dzeryn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the names "Woopsi", "Simian Zombie" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "cwidgetcontrol.hxx"
+#include "clistboxdataitem.hxx"
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Method Implementations
+ ****************************************************************************/
+
+using namespace NXWidgets;
+
+/**
+ * Constructor.
+ *
+ * @param text The text to display in the item.
+ * @param value The value of the item.
+ * @param normalTextColor Color to draw the text with when not selected.
+ * @param normalBackColor Color to draw the background with when not selected.
+ * @param selectedTextColor Color to draw the text with when selected.
+ * @param selectedBackColor Color to draw the background with when selected.
+ */
+
+CListBoxDataItem::CListBoxDataItem(const CNxString& text, const uint32_t value,
+ const nxwidget_pixel_t normalTextColor,
+ const nxwidget_pixel_t normalBackColor,
+ const nxwidget_pixel_t selectedTextColor,
+ const nxwidget_pixel_t selectedBackColor)
+: CListDataItem(text, value)
+{
+ m_normalTextColor = normalTextColor;
+ m_normalBackColor = normalBackColor;
+ m_selectedTextColor = selectedTextColor;
+ m_selectedBackColor = selectedBackColor;
+}
diff --git a/NxWidgets/libnxwidgets/src/clistdata.cxx b/NxWidgets/libnxwidgets/src/clistdata.cxx new file mode 100644 index 000000000..3b9601fc0 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/clistdata.cxx @@ -0,0 +1,462 @@ +/****************************************************************************
+ * NxWidgets/libnxwidgets/src/clistdata.cxx
+ *
+ * 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.
+ *
+ ****************************************************************************
+ *
+ * Portions of this package derive from Woopsi (http://woopsi.org/) and
+ * portions are original efforts. It is difficult to determine at this
+ * point what parts are original efforts and which parts derive from Woopsi.
+ * However, in any event, the work of Antony Dzeryn will be acknowledged
+ * in most NxWidget files. Thanks Antony!
+ *
+ * Copyright (c) 2007-2011, Antony Dzeryn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the names "Woopsi", "Simian Zombie" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <cstring>
+
+#include "clistdata.hxx"
+#include "ilistdataeventhandler.hxx"
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Method Implementations
+ ****************************************************************************/
+
+using namespace NXWidgets;
+
+/**
+ * Constructor.
+ */
+
+CListData::CListData(void)
+{
+ m_allowMultipleSelections = true;
+ m_sortInsertedItems = false;
+}
+
+/**
+ * Destructor.
+ */
+
+CListData::~CListData(void)
+{
+ removeAllItems();
+}
+
+/**
+ * Add a new item.
+ *
+ * @param text Text to show in the option.
+ * @param value The value of the option.
+ */
+
+void CListData::addItem(const CNxString &text, const uint32_t value)
+{
+ // Create new option
+
+ addItem(new CListDataItem(text, value));
+}
+
+/**
+ * Add an existing item. CListData becomes the owner of the option and will delete it
+ * when the list is deleted.
+ *
+ * @param item The item to add.
+ */
+
+void CListData::addItem(CListDataItem *item)
+{
+ // Determine insert type
+
+ if (m_sortInsertedItems)
+ {
+ // Sorted insert
+
+ m_items.insert(getSortedInsertionIndex(item), item);
+ }
+ else
+ {
+ // Append
+
+ m_items.push_back(item);
+ }
+
+ raiseDataChangedEvent();
+}
+
+/**
+ * Remove an item by its index.
+ *
+ * @param index The index of the option to remove.
+ */
+
+void CListData::removeItem(const int index)
+{
+ // Bounds check
+
+ if (index < m_items.size())
+ {
+ // Delete the option
+
+ delete m_items[index];
+
+ // Erase the option from the list
+
+ m_items.erase(index);
+ raiseDataChangedEvent();
+ }
+}
+
+/**
+ * Select an item by its index.
+ *
+ * @param index The index of the item to select.
+ */
+
+void CListData::selectItem(const int index)
+{
+ setItemSelected(index, true);
+}
+
+/**
+ * Deselect an item by its index.
+ *
+ * @param index The index of the item to select.
+ */
+
+void CListData::deselectItem(const int index)
+{
+ setItemSelected(index, false);
+}
+
+/**
+ * Remove all items.
+ */
+
+void CListData::removeAllItems(void)
+{
+ // Delete all option data
+
+ for (int i = 0; i < m_items.size(); i++)
+ {
+ delete m_items[i];
+ }
+
+ m_items.clear();
+ raiseDataChangedEvent();
+}
+
+/**
+ * Get the selected index. Returns -1 if nothing is selected. If more than one
+ * item is selected, the index of the first selected item is returned.
+ *
+ * @return The selected index.
+ */
+
+const int CListData::getSelectedIndex(void) const
+{
+ // Get the first selected index
+
+ for (int i = 0; i < m_items.size(); i++)
+ {
+ if (m_items[i]->isSelected())
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+/**
+ * Sets the selected index. Specify -1 to select nothing. Resets any
+ * other selected items to deselected.
+ *
+ * @param index The selected index.
+ */
+
+void CListData::setSelectedIndex(const int index)
+{
+ setItemSelected(index, true);
+}
+
+/**
+ * Get the selected item. Returns NULL if nothing is selected.
+ *
+ * @return The selected option.
+ */
+
+const CListDataItem *CListData::getSelectedItem(void) const
+{
+ // Get the first selected option
+
+ int index = getSelectedIndex();
+ if (index > -1)
+ {
+ return m_items[index];
+ }
+ return (CListDataItem *)NULL;
+}
+
+/**
+ * Sort the items using their compareTo() methods.
+ */
+
+void CListData::sort(void)
+{
+ quickSort(0, m_items.size() - 1);
+ raiseDataChangedEvent();
+}
+
+/**
+ * Select all items. Does nothing if the list does not allow
+ * multiple selections.
+ */
+
+void CListData::selectAllItems(void)
+{
+ if (m_allowMultipleSelections)
+ {
+ for (int i = 0; i < m_items.size(); i++)
+ {
+ m_items[i]->setSelected(true);
+ }
+
+ raiseSelectionChangedEvent();
+ }
+}
+
+/**
+ * Deselect all items.
+ */
+
+void CListData::deselectAllItems(void)
+{
+ for (int i = 0; i < m_items.size(); i++)
+ {
+ m_items[i]->setSelected(false);
+ }
+
+ raiseSelectionChangedEvent();
+}
+
+/**
+ * Select or deselect an item by its index. Does not deselect any
+ * other selected items. Set index to -1 to select nothing.
+ *
+ * @param index The index of the item to select.
+ * @param selected True to select the item, false to deselect it.
+ */
+
+void CListData::setItemSelected(const int index, bool selected)
+{
+ // Deselect old options if we're making an option selected and
+ // we're not a multiple list
+
+ if (((!m_allowMultipleSelections) || (index == -1)) && (selected))
+ {
+ for (int i = 0; i < m_items.size(); i++)
+ {
+ m_items[i]->setSelected(false);
+ }
+ }
+
+ // Select or deselect the new option
+
+ if ((index > -1) && (index < m_items.size()))
+ {
+ m_items[index]->setSelected(selected);
+ }
+
+ raiseSelectionChangedEvent();
+}
+
+/**
+ * Remove an event handler.
+ *
+ * @param eventHandler The event handler to remove.
+ */
+
+void CListData::removeListDataEventHandler(IListDataEventHandler *eventHandler)
+{
+ for (int i = 0; i < m_listDataEventhandlers.size(); ++i)
+ {
+ if (m_listDataEventhandlers.at(i) == eventHandler)
+ {
+ m_listDataEventhandlers.erase(i);
+ return;
+ }
+ }
+}
+
+/**
+ * Quick sort the items using their compareTo() methods.
+ *
+ * @param start The index to start sorting at.
+ * @param end The index to stop sorting at.
+ */
+
+void CListData::quickSort(const int start, const int end)
+{
+ if (end > start)
+ {
+ int left = start;
+ int right = end;
+
+ CListDataItem *pivot = m_items[(start + end) >> 1];
+
+ do
+ {
+ while ((pivot->compareTo(m_items[left]) > 0) && (left < end))
+ {
+ left++;
+ }
+
+ while ((pivot->compareTo(m_items[right]) < 0) && (right > start))
+ {
+ right--;
+ }
+
+ if (left > right)
+ {
+ break;
+ }
+
+ swapItems(left, right);
+ left++;
+ right--;
+ }
+ while (left <= right);
+
+ quickSort(start, right);
+ quickSort(left, end);
+ }
+}
+
+/**
+ * Swap the locations of two items in the array.
+ *
+ * @param index1 The index of the first item to swap.
+ * @param index2 The index of the second item to swap.
+ */
+
+void CListData::swapItems(const int index1, const int index2)
+{
+ CListDataItem *tmp = m_items[index1];
+ m_items[index1] = m_items[index2];
+ m_items[index2] = tmp;
+}
+
+/**
+ * Return the index that an item should be inserted at to maintain a sorted list of data.
+ *
+ * @param item The item to insert.
+ * @return The index that the item should be imserted into at.
+ */
+
+const int CListData::getSortedInsertionIndex(const CListDataItem *item) const
+{
+ int i = 0;
+
+ // Locate slot where new option should go
+
+ while ((i < m_items.size()) && (item->compareTo(m_items[i]) > 0))
+ {
+ i++;
+ }
+ return i;
+}
+
+/**
+ * Raise a data changed event.
+ */
+
+void CListData::raiseDataChangedEvent(void)
+{
+ CListDataEventArgs eventArgs(this);
+
+ for (int i = 0; i < m_listDataEventhandlers.size(); ++i)
+ {
+ m_listDataEventhandlers.at(i)->handleListDataChangedEvent(eventArgs);
+ }
+}
+
+/**
+ * Raise a selection changed event.
+ */
+
+void CListData::raiseSelectionChangedEvent(void)
+{
+ CListDataEventArgs eventArgs(this);
+
+ for (int i = 0; i < m_listDataEventhandlers.size(); ++i)
+ {
+ m_listDataEventhandlers.at(i)->handleListDataSelectionChangedEvent(eventArgs);
+ }
+}
diff --git a/NxWidgets/libnxwidgets/src/clistdataitem.cxx b/NxWidgets/libnxwidgets/src/clistdataitem.cxx new file mode 100644 index 000000000..036cea61e --- /dev/null +++ b/NxWidgets/libnxwidgets/src/clistdataitem.cxx @@ -0,0 +1,128 @@ +/****************************************************************************
+ * NxWidgets/libnxwidgets/src/clistdataitem.cxx
+ *
+ * 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.
+ *
+ ****************************************************************************
+ *
+ * Portions of this package derive from Woopsi (http://woopsi.org/) and
+ * portions are original efforts. It is difficult to determine at this
+ * point what parts are original efforts and which parts derive from Woopsi.
+ * However, in any event, the work of Antony Dzeryn will be acknowledged
+ * in most NxWidget files. Thanks Antony!
+ *
+ * Copyright (c) 2007-2011, Antony Dzeryn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the names "Woopsi", "Simian Zombie" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "cwidgetcontrol.hxx"
+#include "clistdataitem.hxx"
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Method Implementations
+ ****************************************************************************/
+
+using namespace NXWidgets;
+/**
+ * Constructor.
+ *
+ * @param text The text to display in the item.
+ * @param value The value of the item.
+ */
+
+CListDataItem::CListDataItem(const CNxString &text, const uint32_t value)
+{
+ m_text = text;
+ m_value = value;
+ m_isSelected = false;
+}
+
+/**
+ * Destructor.
+ */
+
+CListDataItem::~CListDataItem(void)
+{
+}
+
+/**
+ * Compare the item with another. Comparison is based on the text of
+ * the item. Returns 0 if the text in the two items is the same,
+ * a value less than 0 if this item is less than the argument, and
+ * a value greater than 0 if this item is greater than the argument.
+ *
+ * @param item An item to compare this object with.
+ * @return 0 if the text in the two items is the same,
+ * a value less than 0 if this item is less than the argument, and
+ * a value greater than 0 if this item is greater than the argument.
+ */
+
+int CListDataItem::compareTo(const CListDataItem *item) const
+{
+ return m_text.compareTo(item->getText());
+}
diff --git a/NxWidgets/libnxwidgets/src/cmultilinetextbox.cxx b/NxWidgets/libnxwidgets/src/cmultilinetextbox.cxx new file mode 100644 index 000000000..94caac5fd --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cmultilinetextbox.cxx @@ -0,0 +1,1284 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cmultilinetextbox.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cwidgetcontrol.hxx" +#include "cnxfont.hxx" +#include "ctext.hxx" +#include "cgraphicsport.hxx" +#include "singletons.hxx" +#include "cstringiterator.hxx" +#include "cnxtimer.hxx" +#include "cmultilinetextbox.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The widget control for the display. + * @param x The x coordinate of the text box, relative to its parent. + * @param y The y coordinate of the text box, relative to its parent. + * @param width The width of the textbox. + * @param height The height of the textbox. + * @param text Pointer to a string to display in the textbox. + * @param flags Standard widget flag options. + * @param maxRows The maximum number of rows the textbox can track. Adding + * text beyond this number will cause rows at the start of the text to be + * forgotten; text is essentially stored as a queue, and adding to the back + * of a full queue causes the front items to be popped off. Setting this to + * 0 will make the textbox track only the visible rows. + * @param style The style that the widget should use. If this is not + * specified, the widget will use the values stored in the global + * g_defaultWidgetStyle object. The widget will copy the properties of + * the style into its own internal style object. + */ + +CMultiLineTextBox::CMultiLineTextBox(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + const CNxString &text, uint32_t flags, + nxgl_coord_t maxRows, CWidgetStyle *style) +: CScrollingPanel(pWidgetControl, x, y, width, height, flags, style) +{ + m_hAlignment = TEXT_ALIGNMENT_HORIZ_CENTER; + m_vAlignment = TEXT_ALIGNMENT_VERT_CENTER; + m_topRow = 0; + + // The border is one line thick + + m_borderSize.top = 1; + m_borderSize.right = 1; + m_borderSize.bottom = 1; + m_borderSize.left = 1; + + CRect rect; + getClientRect(rect); + m_text = new CText(getFont(), "", rect.getWidth()); + m_canvasWidth = rect.getWidth(); + + m_flags.draggable = true; + m_flags.doubleClickable = true; + m_maxRows = maxRows; + + calculateVisibleRows(); + + // Set maximum rows if value not set + + if (m_maxRows == 0) + { + m_maxRows = m_visibleRows + 1; + } + + m_cursorPos = 0; + m_showCursor = SHOW_CURSOR_NEVER; + m_wrapCursor = false; + + setText(text); +} + +/** + * Set the horizontal alignment of text within the textbox. + * + * @param alignment The horizontal position of the text. + */ + +void CMultiLineTextBox::setTextAlignmentHoriz(TextAlignmentHoriz alignment) +{ + m_hAlignment = alignment; + redraw(); +} + +/** + * Set the vertical alignment of text within the textbox. + * + * @param alignment The vertical position of the text. + */ + +void CMultiLineTextBox::setTextAlignmentVert(TextAlignmentVert alignment) +{ + m_vAlignment = alignment; + redraw(); +} + +/** + * Returns the number of "pages" that the text spans. A page + * is defined as the amount of text that can be displayed within + * the textbox at one time. + * + * @return The page count. + */ + +const int CMultiLineTextBox::getPageCount(void) const +{ + if (m_visibleRows > 0) + { + return (m_text->getLineCount() / m_visibleRows) + 1; + } + else + { + return 1; + } +} + +/** + * Returns the current page. + * + * @return The current page. + * @see getPageCount(). + */ + +const int CMultiLineTextBox::getCurrentPage(void) const +{ + // Calculate the top line of text + + int topRow = -m_canvasY / m_text->getLineHeight(); + + // Return the page on which the top row falls + + if (m_visibleRows > 0) + { + return topRow / m_visibleRows; + } + else + { + return 1; + } +} + +/** + * Set the text displayed in the textbox. + * + * @param text String to display. + */ + +void CMultiLineTextBox::setText(const CNxString &text) +{ + bool drawingEnabled = m_flags.drawingEnabled; + disableDrawing(); + + m_text->setText(text); + + cullTopLines(); + limitCanvasHeight(); + jumpToTextBottom(); + + if (drawingEnabled) + { + enableDrawing(); + } + redraw(); + + m_widgetEventHandlers->raiseValueChangeEvent(); +} + +/** + * Append new text to the end of the current text + * displayed in the textbox. + * + * @param text String to append. + */ + +void CMultiLineTextBox::appendText(const CNxString &text) +{ + bool drawingEnabled = m_flags.drawingEnabled; + disableDrawing(); + + m_text->append(text); + + cullTopLines(); + limitCanvasHeight(); + jumpToTextBottom(); + + if (drawingEnabled) + { + enableDrawing(); + } + redraw(); + + m_widgetEventHandlers->raiseValueChangeEvent(); +} + +/** + * Remove all characters from the string from the start index onwards. + * + * @param startIndex Index to remove from. + */ + +void CMultiLineTextBox::removeText(const unsigned int startIndex) +{ + removeText(startIndex, m_text->getLength() - startIndex); +} + +/** + * Remove specified number of characters from the string from the + * start index onwards. + * + * @param startIndex Index to remove from. + * @param count Number of characters to remove. + */ + +void CMultiLineTextBox::removeText(const unsigned int startIndex, + const unsigned int count) +{ + bool drawingEnabled = m_flags.drawingEnabled; + disableDrawing(); + + m_text->remove(startIndex, count); + + limitCanvasHeight(); + limitCanvasY(); + + moveCursorToPosition(startIndex); + + if (drawingEnabled) + { + enableDrawing(); + } + redraw(); + + m_widgetEventHandlers->raiseValueChangeEvent(); +} + +/** + * Set the font used in the textbox. + * + * @param font Pointer to the new font. + */ + +void CMultiLineTextBox::setFont(CNxFont *font) +{ + bool drawingEnabled = m_flags.drawingEnabled; + disableDrawing(); + + m_style.font = font; + m_text->setFont(font); + + cullTopLines(); + limitCanvasHeight(); + limitCanvasY(); + + if (drawingEnabled) + { + enableDrawing(); + } + redraw(); + + m_widgetEventHandlers->raiseValueChangeEvent(); +} + +/** + * Get the length of the text string. + * + * @return The length of the text string. + */ + +const int CMultiLineTextBox::getTextLength(void) const +{ + return m_text->getLength(); +} + +/** + * Sets the cursor display mode. + * + * @param cursorMode Determines cursor display mode + */ + +void CMultiLineTextBox::showCursor(EShowCursor cursorMode) +{ + if (m_showCursor != cursorMode) + { + m_showCursor = (uint8_t)cursorMode; + redraw(); + } +} + +/** + * Move the cursor to the text position specified. 0 indicates the start + * of the string. If position is greater than the length of the string, + * the cursor is moved to the end of the string. + * + * @param position The new cursor position. + */ + +void CMultiLineTextBox::moveCursorToPosition(const int position) +{ + CGraphicsPort *port = m_widgetControl->getGraphicsPort(); + + // Erase existing cursor + + drawCursor(port); + + // Force position to within confines of string + + if (position < 0) + { + m_cursorPos = 0; + } + else + { + int len = (int)m_text->getLength(); + m_cursorPos = len > position ? position : len; + } + + // Draw cursor in new position + + drawCursor(port); +} + +/** + * Insert text at the specified index. + * + * @param text The text to insert. + * @param index Index at which to insert the text. + */ + +void CMultiLineTextBox::insertText(const CNxString &text, + const unsigned int index) +{ + bool drawingEnabled = m_flags.drawingEnabled; + disableDrawing(); + + m_text->insert(text, index); + + cullTopLines(); + limitCanvasHeight(); + + moveCursorToPosition(index + text.getLength()); + + if (drawingEnabled) + { + enableDrawing(); + } + redraw(); + + m_widgetEventHandlers->raiseValueChangeEvent(); +} + +/** + * Insert text at the current cursor position. + * + * @param text The text to insert. + */ + +void CMultiLineTextBox::insertTextAtCursor(const CNxString &text) +{ + insertText(text, getCursorPosition()); +} + +/** + * Handle a keyboard press event. + * + * @param e The event data. + */ + +void CMultiLineTextBox::handleKeyPressEvent(const CWidgetEventArgs &e) +{ + nxwidget_char_t key = e.getKey(); + + if (key == KEY_CODE_BACKSPACE) + { + // Delete character in front of cursor + + if (m_cursorPos > 0) + { + removeText(m_cursorPos - 1, 1); + } + } + else if (key != KEY_CODE_NONE) + { + // Not modifier; append value + + insertTextAtCursor(key); + } +} + +/** + * Get the coordinates of the cursor relative to the text. + * + * @param x Will be populated with the x coordinate of the cursor. + * @param y Will be populated with the y coordinate of the cursor. + */ + +void CMultiLineTextBox::getCursorCoordinates(nxgl_coord_t &x, nxgl_coord_t &y) const +{ + unsigned int cursorRow = 0; + + x = 0; + y = 0; + + // Only calculate the cursor position if the cursor isn't at the start + // of the text + + if (m_cursorPos > 0) + { + // Calculate the row in which the cursor appears + + cursorRow = m_text->getLineContainingCharIndex(m_cursorPos); + + // Cursor line offset gives us the distance of the cursor from the + // start of the line + + uint8_t cursorLineOffset = m_cursorPos - m_text->getLineStartIndex(cursorRow); + + CStringIterator *iterator = m_text->newStringIterator(); + iterator->moveTo(m_text->getLineStartIndex(cursorRow)); + + // Sum the width of each char in the row to find the x coordinate + + for (int i = 0; i < cursorLineOffset; ++i) + { + x += getFont()->getCharWidth(iterator->getChar()); + iterator->moveToNext(); + } + + delete iterator; + } + + // Add offset of row to calculated value + + x += getRowX(cursorRow); + + // Calculate y coordinate of the cursor + + y = getRowY(cursorRow); +} + +/** + * Gets the index of the character at the specified x coordinate in the + * specified row. + * + * @param x X coordinate of the character. + * @param rowIndex Index of the row containing the character. + * @return The index of the character at the specified coordinate. + */ + +int CMultiLineTextBox::getCharIndexAtCoordinate(nxgl_coord_t x, int rowIndex) const +{ + // Locate the character within the row + + int startIndex = m_text->getLineStartIndex(rowIndex); + int stopIndex = m_text->getLineLength(rowIndex); + int width = getRowX(rowIndex); + int index = -1; + + CStringIterator *iterator = m_text->newStringIterator(); + iterator->moveTo(startIndex); + + width += m_text->getFont()->getCharWidth(iterator->getChar()); + + for (int i = 0; i < stopIndex; ++i) + { + if (width > x) + { + if (i == 0) + { + // If the coordinate is on the left of the text, we add nothing + // to the index + + index = startIndex; + } + else + { + // Character within the row. + // This is the character that contains the coordinate. + + index = startIndex + i; + } + break; + } + + iterator->moveToNext(); + width += m_text->getFont()->getCharWidth(iterator->getChar()); + } + + delete iterator; + + // If the coordinate is past the last character, index will still be -1. + // We need to set it to the last character + + if (index == -1) + { + if (rowIndex == m_text->getLineCount() - 1) + { + // Index past the end point of the text, so return an index + // just past the text + + index = startIndex + stopIndex; + } + else + { + // Index at the end of a row, so return the last index of the + // row + + index = startIndex + stopIndex - 1; + } + } + + return index; +} + +/** + * Get the index of the character at the specified coordinates. + * + * @param x X coordinate of the character. + * @param y Y coordinate of the character. + * @return The index of the character at the specified coordinates. + */ + +unsigned int +CMultiLineTextBox::getCharIndexAtCoordinates(nxgl_coord_t x, nxgl_coord_t y) const +{ + int rowIndex = getRowContainingCoordinate(y); + return getCharIndexAtCoordinate(x, rowIndex); +} + +/** + * Get the row containing the specified Y coordinate. + * + * @param y Y coordinate to locate. + * @return The index of the row containing the specified Y coordinate. + */ + +int CMultiLineTextBox::getRowContainingCoordinate(nxgl_coord_t y) const +{ + int row = -1; + + // Locate the row containing the character + + for (int i = 0; i < m_text->getLineCount(); ++i) + { + // Abort search if we've found the row below the y coordinate + + if (getRowY(i) > y) + { + if (i == 0) + { + // If the coordinate is above the text, we return the top + // row + + row = 0; + } + else + { + // Row within the text, so return the previous row - this is + // the row that contains the coordinate. + + row = i - 1; + } + + break; + } + } + + // If the coordinate is below the text, row will still be -1. + // We need to set it to the last row + + if (row == -1) + { + row = m_text->getLineCount() - 1; + } + + return row; +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CMultiLineTextBox::drawContents(CGraphicsPort *port) +{ + drawText(port); + + // Draw the cursor + + drawCursor(port); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CMultiLineTextBox::drawBorder(CGraphicsPort *port) +{ + port->drawFilledRect(0, 0, getWidth(), getHeight(), getBackgroundColor()); + + // Stop drawing if the widget indicates it should not have an outline + + if (!isBorderless()) + { + port->drawBevelledRect(0, 0, getWidth(), getHeight(), + getShadowEdgeColor(), getShineEdgeColor()); + } +} + +/** + * Move cursor one character to the left. + */ + +void CMultiLineTextBox::moveCursorLeft(void) +{ + if (m_cursorPos > 0) + { + moveCursorToPosition(m_cursorPos - 1); + } + + jumpToCursor(); +} + +/** + * Move cursor one character to the right. + */ + +void CMultiLineTextBox::moveCursorRight(void) +{ + if (m_cursorPos < (int)m_text->getLength()) + { + moveCursorToPosition(m_cursorPos + 1); + } + + jumpToCursor(); +} + +/** + * Move cursor one row upwards. + */ + +void CMultiLineTextBox::moveCursorUp(void) +{ + nxgl_coord_t cursorX = 0; + nxgl_coord_t cursorY = 0; + + getCursorCoordinates(cursorX, cursorY); + + // Get the midpoint of the cursor. We use the midpoint to ensure that + // the cursor does not drift off to the left as it moves up the text, which + // is a problem when we use the left edge as the reference point when the + // font is proportional + + cursorX += m_text->getFont()->getCharWidth(m_text->getCharAt(m_cursorPos)) >> 1; + + // Locate the character above the midpoint + + int index = getCharIndexAtCoordinates(cursorX, cursorY + m_text->getLineHeight()); + moveCursorToPosition(index); + jumpToCursor(); +} + +/** + * Move cursor one row downwards. + */ + +void CMultiLineTextBox::moveCursorDown(void) +{ + nxgl_coord_t cursorX = 0; + nxgl_coord_t cursorY = 0; + + getCursorCoordinates(cursorX, cursorY); + + // Get the midpoint of the cursor. We use the midpoint to ensure that + // the cursor does not drift off to the left as it moves up the text, which + // is a problem when we use the left edge as the reference point when the + // font is proportional + + cursorX += m_text->getFont()->getCharWidth(m_text->getCharAt(m_cursorPos)) >> 1; + + // Locate the character above the midpoint + + int index = getCharIndexAtCoordinates(cursorX, cursorY - m_text->getLineHeight()); + moveCursorToPosition(index); + jumpToCursor(); +} + +/** + * Ensures that the textbox only contains the maximum allowed + * number of rows by culling any excess rows from the top of + * the text. + * + * @return True if lines were removed from the text; false if not. + */ + +bool CMultiLineTextBox::cullTopLines(void) +{ + // Ensure that we have the correct number of rows + + if (m_text->getLineCount() > m_maxRows) + { + m_text->stripTopLines(m_text->getLineCount() - m_maxRows); + return true; + } + + return false; +} + +/** + * Ensures that the canvas height is the height of the widget, + * if the widget exceeds the size of the text, or the height of + * the text if the text exceeds the size of the widget. + */ + +void CMultiLineTextBox::limitCanvasHeight(void) +{ + m_canvasHeight = m_text->getPixelHeight(); + + CRect rect; + getClientRect(rect); + if (m_canvasHeight < rect.getHeight()) + { + m_canvasHeight = rect.getHeight(); + } +} + +/** + * Ensures that the canvas cannot scroll beyond its height. + */ + +void CMultiLineTextBox::limitCanvasY(void) +{ + CRect rect; + getClientRect(rect); + + // Ensure that the visible portion of the canvas is not less than the + // height of the viewer window + + if (m_canvasY + m_canvasHeight < rect.getHeight()) + { + jumpToTextBottom(); + } +} + +/** + * Jumps to the cursor coordinates of the text. + */ + +void CMultiLineTextBox::jumpToCursor(void) +{ + // Get the co-odinates of the cursor + + nxgl_coord_t cursorX; + nxgl_coord_t cursorY; + + getCursorCoordinates(cursorX, cursorY); + + // Work out which row the cursor falls within + + int cursorRow = m_text->getLineContainingCharIndex(m_cursorPos); + nxgl_coord_t rowY = getRowY(cursorRow); + + // If the cursor is outside the visible portion of the canvas, jump to it + + CRect rect; + getClientRect(rect); + + if (rowY + m_text->getLineHeight() + m_canvasY > rect.getHeight()) + { + // Cursor is below the visible portion of the canvas, so + // jump down so that the cursor's row is the bottom row of + // text + + jump(0, -(rowY + m_text->getLineHeight() - rect.getHeight())); + } + else if (rowY + m_canvasY < 0) + { + // Cursor is above the visible portion of the canvas, so + // jump up so that the cursor's row is the top row of text + + jump(0, -cursorY); + } +} + +/** + * Jumps to the bottom of the text. + */ + +void CMultiLineTextBox::jumpToTextBottom(void) +{ + CRect rect; + getClientRect(rect); + jump(0, -(m_canvasHeight - rect.getHeight())); +} + +/** + * Resize the textbox to the new dimensions. + * + * @param width The new width. + * @param height The new height. + */ + +void CMultiLineTextBox::onResize(nxgl_coord_t width, nxgl_coord_t height) +{ + // Ensure the base class resize method is called + + CScrollingPanel::onResize(width, height); + + // Resize the canvas' width + + CRect rect; + getClientRect(rect); + + m_canvasWidth = rect.getWidth(); + m_canvasHeight = rect.getHeight(); + m_canvasX = 0; + m_canvasY = 0; + + calculateVisibleRows(); + + // Re-wrap the text + + m_text->setWidth(getWidth()); + m_text->wrap(); + + bool raiseEvent = cullTopLines(); + limitCanvasHeight(); + limitCanvasY(); + + if (raiseEvent) + { + m_widgetEventHandlers->raiseValueChangeEvent(); + } +} + +/** + * Starts the dragging system. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CMultiLineTextBox::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + startDragging(x, y); + + // Move cursor to clicked coordinates + + CRect rect; + getClientRect(rect); + + // Adjust x and y from screen coordinates to canvas coordinates + + nxgl_coord_t canvasRelativeX = x - getX() - rect.getX() - m_canvasX; + nxgl_coord_t canvasRelativeY = y - getY() - rect.getY() - m_canvasY; + + moveCursorToPosition(getCharIndexAtCoordinates(canvasRelativeX, canvasRelativeY)); +} + +/** + * Opens the keyboard on the bottom display. + * + * @param x The x coordinates of the click. + * @param y The y coordinates of the click. + */ + +void CMultiLineTextBox::onDoubleClick(nxgl_coord_t x, nxgl_coord_t y) +{ +} + +/** + * Handles cursor control events. Moves the cursor + * in the direction selected. + * + * @param key The key that was pressed. + */ + +void CMultiLineTextBox::handleCursorControlEvent(const CWidgetEventArgs &e) +{ + ECursorControl control = e.getCursorControl(); + + switch (control) + { + case CURSOR_LEFT: + moveCursorLeft(); + break; + + case CURSOR_RIGHT: + moveCursorRight(); + break; + + case CURSOR_UP: + moveCursorDown(); + break; + + case CURSOR_DOWN: + moveCursorUp(); + break; + + default: + // Not interested in other controls + + break; + } +} + +/** + * Handle a keyboard press event. + * + * @param e The event data. + */ + + void handleKeyPressEvent(const CWidgetEventArgs &e); + +/** + * Gets the x position of a row of text based on the width of the row and the + * type of horizontal alignment currently set. + * + * @param row The index of the row. + * @return The x coordinate of the row. + */ + +nxgl_coord_t CMultiLineTextBox::getRowX(int row) const +{ + CRect rect; + getClientRect(rect); + + uint8_t rowLength = m_text->getLineTrimmedLength(row); + uint8_t rowPixelWidth = m_text->getFont()->getStringWidth(*m_text, m_text->getLineStartIndex(row), rowLength); + + // Calculate horizontal position + + switch (m_hAlignment) + { + case TEXT_ALIGNMENT_HORIZ_CENTER: + return (rect.getWidth() - rowPixelWidth) >> 1; + + case TEXT_ALIGNMENT_HORIZ_LEFT: + return 0; + + case TEXT_ALIGNMENT_HORIZ_RIGHT: + return rect.getWidth() - rowPixelWidth; + } + + // Will never be reached + + return 0; +} + +/** + * Gets the y position of the specified row of text based on the type of + * vertical alignment currently set. + * + * @param row The row number to find the y coordinate of. + * @return The y coordinate of the specified row of text. + */ + +nxgl_coord_t CMultiLineTextBox::getRowY(int row) const +{ + // If the amount of text exceeds the size of the widget, force + // the text to be top-aligned + + if (m_visibleRows <= m_text->getLineCount()) + { + return row * m_text->getLineHeight(); + } + + // All text falls within the textbox, so obey the alignment + // options + + nxgl_coord_t textY = 0; + nxgl_coord_t startPos = 0; + + int canvasRows = 0; + int textRows = 0; + + CRect rect; + getClientRect(rect); + + // Calculate vertical position + + switch (m_vAlignment) + { + case TEXT_ALIGNMENT_VERT_CENTER: + + // Calculate the maximum number of rows + + canvasRows = m_canvasHeight / m_text->getLineHeight(); + textY = row * m_text->getLineHeight(); + + // Get the number of rows of text + + textRows = m_text->getLineCount(); + + // Ensure there's always one row + + if (textRows == 0) + { + textRows = 1; + } + + // Calculate the start position of the block of text + + startPos = ((canvasRows - textRows) * m_text->getLineHeight()) >> 1; + + // Calculate the row Y coordinate + + textY = startPos + textY; + break; + + case TEXT_ALIGNMENT_VERT_TOP: + textY = row * m_text->getLineHeight(); + break; + + case TEXT_ALIGNMENT_VERT_BOTTOM: + textY = rect.getHeight() - (((m_text->getLineCount() - row) * m_text->getLineHeight())); + break; + } + + return textY; +} + +/** + * Return true if the cursor is visible + */ + +bool CMultiLineTextBox::isCursorVisible(void) const +{ + return (m_showCursor == SHOW_CURSOR_ALWAYS || + (m_showCursor == SHOW_CURSOR_ONFOCUS && hasFocus())); +} + +/** + * Gets the character under the cursor. + * + * @return The character under the cursor. + */ + +nxwidget_char_t CMultiLineTextBox::getCursorChar(void) const +{ + if (m_cursorPos < m_text->getLength()) + { + return m_text->getCharAt(m_cursorPos); + } + else + { + return ' '; + } +} + +/** + * Works out the number of visible rows within the textbox. + */ + +void CMultiLineTextBox::calculateVisibleRows(void) +{ + CRect rect; + getClientRect(rect); + + m_visibleRows = rect.getHeight() / m_text->getLineHeight(); +} + +/** + * Draws text. + * + * @param port The CGraphicsPort to draw to. + */ + +void CMultiLineTextBox::drawText(CGraphicsPort *port) +{ + // Early exit if there is no text to display + + if (m_text->getLineCount() == 0) + { + return; + } + + // Determine the top and bottom rows within the graphicsport's clip rect. + // We only draw these rows in order to increase the speed of the routine. + + int regionY = -m_canvasY + m_rect.getY(); // Y coord of canvas visible region + int topRow = getRowContainingCoordinate(regionY); + int bottomRow = getRowContainingCoordinate(regionY + m_rect.getHeight()); + + // Early exit checks + + if ((topRow < 0) && (bottomRow < 0)) + { + return; + } + + if ((bottomRow >= m_text->getLineCount()) && (topRow >= m_text->getLineCount())) + { + return; + } + + // Prevent overflows + + if (topRow < 0) + { + topRow = 0; + } + + if (bottomRow >= m_text->getLineCount()) + { + bottomRow = m_text->getLineCount() - 1; + } + + // Draw lines of text + + int currentRow = topRow; + + // Draw all rows in this region + + while (currentRow <= bottomRow) + { + drawRow(port, currentRow); + currentRow++; + } +} + +/** + * Draws the cursor. + * + * @param port The CGraphicsPort to draw to. + */ + +void CMultiLineTextBox::drawCursor(CGraphicsPort *port) +{ + // Get the cursor coordinates + + if (isCursorVisible()) + { + nxgl_coord_t cursorX = 0; + nxgl_coord_t cursorY = 0; + + getCursorCoordinates(cursorX, cursorY); + + // Adjust for canvas offsets + + cursorX += m_canvasX; + cursorY += m_canvasY; + + // Draw cursor + + port->invert(cursorX, cursorY, + m_text->getFont()->getCharWidth( getCursorChar()), + m_text->getFont()->getHeight()); + } +} + +/** + * Draws a single line of text. + * + * @param port The CGraphicsPort to draw to. + * @param row The index of the row to draw. + */ + +void CMultiLineTextBox::drawRow(CGraphicsPort *port, int row) +{ + // Get the drawing region + + CRect rect; + getRect(rect); + + uint8_t rowLength = m_text->getLineTrimmedLength(row); + + struct nxgl_point_s pos; + pos.x = getRowX(row) + m_canvasX; + pos.y = getRowY(row) + m_canvasY; + + // Determine the background and text color + + nxgl_mxpixel_t textColor; + + if (!isEnabled()) + { + textColor = getDisabledTextColor(); + } + else + { + textColor = getEnabledTextColor(); + } + + // And draw the text using the selected color + + port->drawText(&pos, &rect, m_text->getFont(), *m_text, + m_text->getLineStartIndex(row), rowLength, textColor); +} diff --git a/NxWidgets/libnxwidgets/src/cnxfont.cxx b/NxWidgets/libnxwidgets/src/cnxfont.cxx new file mode 100644 index 000000000..189cfb9e0 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cnxfont.cxx @@ -0,0 +1,276 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cnxfont.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <cstring> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "cnxstring.hxx" +#include "cstringiterator.hxx" +#include "cnxfont.hxx" +#include "cbitmap.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CNxFont Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * CNxFont Constructor. + * + * @param fontid The font ID to use. + * @param fontColor The font color to use. + * @param transparentColor The color in the font bitmap used as the + * background color. + */ + +CNxFont::CNxFont(enum nx_fontid_e fontid, nxgl_mxpixel_t fontColor, + nxgl_mxpixel_t transparentColor) +{ + m_fontId = fontid; + m_fontHandle = nxf_getfonthandle(fontid); + m_pFontSet = nxf_getfontset(m_fontHandle); + m_fontColor = fontColor; + m_transparentColor = transparentColor; +} + +/** + * Checks if supplied character is blank in the current font. + * + * @param letter The character to check. + * @return True if the glyph contains any pixels to be drawn. False if + * the glyph is blank. + */ + +const bool CNxFont::isCharBlank(const nxwidget_char_t letter) const +{ + FAR const struct nx_fontbitmap_s *fbm; + + /* Get the bitmap associated with the character */ + + fbm = nxf_getbitmap(m_fontHandle, (uint16_t)letter); + return (fbm == NULL); +} + +/** + * Draw an individual character of the font to the specified bitmap. + * + * @param bitmap The bitmap to draw use. The caller should use + * the getFontMetrics method to assure that the buffer will hold + * the font. + * @param letter The character to output. + * + * @return The width of the string in pixels. + */ + +void CNxFont::drawChar(FAR SBitmap *bitmap, nxwidget_char_t letter) +{ + // Get the NX bitmap associated with the font + + FAR const struct nx_fontbitmap_s *fbm; + fbm = nxf_getbitmap(m_fontHandle, letter); + if (fbm) + { + // Get information about the font bitmap + + uint8_t fwidth = fbm->metric.width + fbm->metric.xoffset; + uint8_t fheight = fbm->metric.height + fbm->metric.yoffset; + uint8_t fstride = (fwidth * bitmap->bpp + 7) >> 3; + + // Then render the glyph into the bitmap memory + + (void)FONT_RENDERER((FAR nxgl_mxpixel_t*)bitmap->data, fheight, + fwidth, fstride, fbm, m_fontColor); + } +} + +/** + * Get the width of a string in pixels when drawn with this font. + * + * @param text The string to check. + * @return The width of the string in pixels. + */ + +nxgl_coord_t CNxFont::getStringWidth(const CNxString &text) const +{ + CStringIterator *iter = text.newStringIterator(); + + // Get the width of the string of characters + // Move to the first character + + unsigned int width = 0; + if (iter->moveToFirst()) + { + // moveToFirst returns true if there is at least one character + + do + { + // Add the width of the font bitmap for this character and + // move the the next character + + nxwidget_char_t ch = iter->getChar(); + + width += getCharWidth(ch); + } + while (iter->moveToNext()); + } + + // Return the total width + + delete iter; + return width; +} + +/** + * Get the width of a portion of a string in pixels when drawn with this + * font. + * + * @param text The string to check. + * @param startIndex The start point of the substring within the string. + * @param length The length of the substring in chars. + * @return The width of the substring in pixels. + */ + +nxgl_coord_t CNxFont::getStringWidth(const CNxString &text, + int startIndex, int length) const +{ + CStringIterator *iter = text.newStringIterator(); + + // Get the width of the string of characters + + iter->moveTo(startIndex); + unsigned int width = 0; + + while (length-- > 0) + { + // Add the width of the font bitmap for this character + + nxwidget_char_t ch = iter->getChar(); + width += getCharWidth(ch); + + // Position to the next character in the string + + if (!iter->moveToNext()) + { + break; + } + } + + // Return the total width + + delete iter; + return width; +} + +/** + * Gets font metrics for a particular character + * + * @param letter The character to get the width of. + * @param metrics The location to return the font metrics + */ + +void CNxFont::getCharMetrics(nxwidget_char_t letter, + FAR struct nx_fontmetric_s *metrics) const +{ + FAR const struct nx_fontbitmap_s *fbm; + + // Get the font bitmap for this character + + fbm = nxf_getbitmap(m_fontHandle, letter); + if (fbm) + { + // Return the metrics of the font + + memcpy(metrics, &fbm->metric, sizeof(struct nx_fontmetric_s)); + } + else + { + // Use the metrics of a space which has no width and no height + // but an xoffset equal to the standard width of a space. + + metrics->stride = (m_pFontSet->spwidth * CONFIG_NXWIDGETS_BPP + 7) >> 3; + metrics->width = 0; + metrics->height = 0; + metrics->xoffset = m_pFontSet->spwidth; + metrics->yoffset = 0; + } +} + +/** + * Get the width of an individual character. + * + * @param letter The character to get the width of. + * @return The width of the character in pixels. + */ + +nxgl_coord_t CNxFont::getCharWidth(nxwidget_char_t letter) const +{ + FAR const struct nx_fontbitmap_s *fbm; + nxgl_coord_t width; + + /* Get the font bitmap for this character */ + + fbm = nxf_getbitmap(m_fontHandle, letter); + if (fbm) + { + /* Return the width of the font -- including the X offset */ + + width = fbm->metric.width + fbm->metric.xoffset; + } + else + { + /* Use the width of a space */ + + width = m_pFontSet->spwidth; + } + + return width; +} diff --git a/NxWidgets/libnxwidgets/src/cnxserver.cxx b/NxWidgets/libnxwidgets/src/cnxserver.cxx new file mode 100644 index 000000000..2f36b0f2d --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cnxserver.cxx @@ -0,0 +1,386 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cnxserver.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <cerrno> +#include <debug.h> + +#ifdef CONFIG_NX_MULTIUSER +# include <sched.h> +# include <pthread.h> +#endif + +#include "nxconfig.hxx" +#include "singletons.hxx" +#include "cnxserver.hxx" + +/**************************************************************************** + * Static Data Members + ****************************************************************************/ + +using namespace NXWidgets; + +uint8_t CNxServer::m_nServers; /**< The number of NX server instances */ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +/** + * CNXServer constructor + */ + +CNxServer::CNxServer(void) +{ + // Initialize server instance state data + + m_hDevice = (FAR NX_DRIVERTYPE *)NULL; // LCD/Framebuffer device handle + m_hNxServer = (NXHANDLE)NULL; // NX server handle +#ifdef CONFIG_NX_MULTIUSER + m_connected = false; // True: Connected to the server + sem_init(&m_connsem, 0, 0); // Wait for server connection +#endif + + // Increment the global count of NX servers. Normally there is only one + // but we don't want to preclude the case where there might be multiple + // displays, each with its own NX server instance + + m_nServers++; + + // Create miscellaneous singleton instances. Why is this done here? + // Because this needs to be done once before any widgets are created and we + // don't want to rely on static constructors. + + instantiateSingletons(); +} + +/** + * CNXServer destructor + */ + +CNxServer::~CNxServer(void) +{ + // Disconnect from the server + + disconnect(); + + // Decrement the count of NX servers. When that count goes to zero, + // delete all of the fake static instances + + if (--m_nServers == 0) + { + freeSingletons(); + } +} + +/** + * Connect to the NX Server -- Single user version + */ + +#ifndef CONFIG_NX_MULTIUSER +bool CNxServer::connect(void) +{ +#if defined(SCREENS_EXTERNINIT) + // Use external graphics driver initialization + + m_hDevice = up_nxdrvinit(CONFIG_NXWIDGETS_DEVNO); + if (!m_hDevice) + { + gdbg("up_nxdrvinit failed, devno=%d\n", CONFIG_NXWIDGETS_DEVNO); + return false; + } + +#elif defined(CONFIG_NX_LCDDRIVER) + int ret; + + // Initialize the LCD device + + ret = up_lcdinitialize(); + if (ret < 0) + { + gdbg("up_lcdinitialize failed: %d\n", -ret); + return false; + } + + // Get the device instance + + m_hDevice = up_lcdgetdev(CONFIG_NXWIDGETS_DEVNO); + if (!m_hDevice) + { + gdbg("up_lcdgetdev failed, devno=%d\n", CONFIG_NXWIDGETS_DEVNO); + return false; + } + + // Turn the LCD on at 75% power + + (void)m_hDevice->setpower(m_hDevice, ((3*CONFIG_LCD_MAXPOWER + 3)/4)); +#else + int ret; + + // Initialize the frame buffer device + + ret = up_fbinitialize(); + if (ret < 0) + { + gdbg("up_fbinitialize failed: %d\n", -ret); + return false; + } + + m_hDevice = up_fbgetvplane(CONFIG_NXWIDGETS_VPLANE); + if (!m_hDevice) + { + gdbg("CNxServer::connect: up_fbgetvplane failed, vplane=%d\n", + CONFIG_NXWIDGETS_VPLANE); + return false; + } +#endif + + // Then open NX + + m_hNxServer = nx_open(m_hDevice); + if (!m_hNxServer) + { + gdbg("CNxServer::connect: nx_open failed: %d\n", errno); + return false; + } + + return true; +} +#endif + +/** + * Connect to the NX Server -- Multi user version + */ + +#ifdef CONFIG_NX_MULTIUSER +bool CNxServer::connect(void) +{ + struct sched_param param; + pthread_t thread; + pid_t serverId; + int ret; + + // Set the client task priority + + param.sched_priority = CONFIG_NXWIDGETS_CLIENTPRIO; + ret = sched_setparam(0, ¶m); + if (ret < 0) + { + gdbg("CNxServer::connect: sched_setparam failed: %d\n" , ret); + return false; + } + + // Start the server task + + message("NxServer::connect: Starting nx_servertask task\n"); + serverId = task_create("NX Server", CONFIG_NXWIDGETS_SERVERPRIO, + CONFIG_NXWIDGETS_STACKSIZE, nx_servertask, NULL); + if (serverId < 0) + { + message("NxServer::connect: Failed to create nx_servertask task: %d\n", errno); + return false; + } + + // Wait a bit to let the server get started + + sleep(1); + + // Connect to the server + + m_hNxServer = nx_connect(); + if (m_hNxServer) + { + pthread_attr_t attr; + + // Start a separate thread to listen for server events. This is probably + // the least efficient way to do this, but it makes this logic flow more + // smoothly. + + (void)pthread_attr_init(&attr); + param.sched_priority = CONFIG_NXWIDGETS_LISTENERPRIO; + (void)pthread_attr_setschedparam(&attr, ¶m); + (void)pthread_attr_setstacksize(&attr, CONFIG_NXWIDGETS_STACKSIZE); + + m_stop = false; + m_running = true; + + ret = pthread_create(&thread, &attr, listener, (FAR void *)this); + if (ret != 0) + { + printf("NxServer::connect: pthread_create failed: %d\n", ret); + m_running = false; + disconnect(); + return false; + } + + // Don't return until we are connected to the server + + while (!m_connected && m_running) + { + // Wait for the listener thread to wake us up when we really + // are connected. + + (void)sem_wait(&m_connsem); + } + + // In the successful case, the listener is still running (m_running) + // and the server is connected (m_connected). Anything else is a failure. + + if (!m_connected !! !m_running) + { + disconnect(); + return false; + } + } + else + { + gdbg("NxServer::connect: nx_connect failed: %d\n", errno); + return false; + } + + return true; +} +#endif + +/** + * Disconnect to the NX Server -- Single user version + */ + +#ifndef CONFIG_NX_MULTIUSER +void CNxServer::disconnect(void) +{ + /* Close the server */ + + if (m_hNxServer) + { + nx_close(m_hNxServer); + m_hNxServer = NULL; + } +} +#endif + +/** + * Disconnect to the NX Server -- Single user version + */ + +#ifdef CONFIG_NX_MULTIUSER +void CNxServer::disconnect(void) +{ + // Is the listener running? + // Hmm.. won't this hang is the listener is in a blocking call? + + while (m_running) + { + // Yes.. stop the listener thread + + m_stop = true; + while (m_running) + { + // Wait for the listener thread to stop + + (void)sem_wait(&m_connsem); + } + } + + /* Disconnect from the server */ + + if (m_hNxServer) + { + nx_disconnect(m_hNxServer); + m_hNxServer = NULL; + } +} +#endif + +/** + * This is the entry point of a thread that listeners for and dispatches + * events from the NX server. + */ + +#ifdef CONFIG_NX_MULTIUSER +FAR void *CNxServer::listener(FAR void *arg) +{ + // The argument must be the CNxServer instance + + CNxServer *This = (CNxServer*)pvArg; + + // Process events forever + + while (!This->m_stop) + { + // Handle the next event. If we were configured blocking, then + // we will stay right here until the next event is received. Since + // we have dedicated a while thread to servicing events, it would + // be most natural to also select CONFIG_NX_BLOCKING -- if not, the + // following would be a tight infinite loop (unless we added addition + // logic with nx_eventnotify and sigwait to pace it). + + int ret = nx_eventhandler(This->m_hNxServer); + if (ret < 0) + { + // An error occurred... assume that we have lost connection with + // the server. + + gdbg("CNxServer::listener: Lost server connection: %d\n", errno); + break; + } + + /* If we received a message, we must be connected */ + + if (!This->m_connected) + { + This->m_connected = true; + sem_post(&This->m_connsem); + gdbg("CNxServer::listener: Connected\n"); + } + } + + // We fall out of the loop when either (1) the server has died or + // we have been requested to stop + + This->m_running = false; + This->m_connected = false; + sem_post(&This->m_connsem); + return NULL; +} +#endif diff --git a/NxWidgets/libnxwidgets/src/cnxstring.cxx b/NxWidgets/libnxwidgets/src/cnxstring.cxx new file mode 100644 index 000000000..3ad3855b9 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cnxstring.cxx @@ -0,0 +1,799 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cnxstring.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <string.h> + +#include "cnxstring.hxx" +#include "cstringiterator.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CNxString Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor to create an empty string object. + */ + +CNxString::CNxString() +{ + m_text = (FAR nxwidget_char_t *)NULL; + m_stringLength = 0; + m_allocatedSize = 0; + m_growAmount = 16; +} + +/** + * Constructor to create a string from a C character array. + * + * @param text Pointer to a char array to use as the basis of the + * string. + */ + +CNxString::CNxString(FAR const char *text) +{ + m_text = (FAR nxwidget_char_t *)NULL; + m_stringLength = 0; + m_allocatedSize = 0; + m_growAmount = 16; + + setText(text); +} + +/** + * Constructor to create a string from a single character. + * @param letter Single character to use as the basis of the string. + */ + +CNxString::CNxString(const nxwidget_char_t text) +{ + m_text = (FAR nxwidget_char_t *)NULL; + m_stringLength = 0; + m_allocatedSize = 0; + m_growAmount = 16; + + setText(text); +} + +CNxString::CNxString(const CNxString &string) +{ + m_text = (FAR nxwidget_char_t *)NULL; + m_stringLength = 0; + m_allocatedSize = 0; + m_growAmount = 16; + + setText(string); +} + +/** + * Creates and returns a new CCStringIterator object that will iterate + * over this string. The object must be manually deleted once it is + * no longer needed. + * + * @return A new CCStringIterator object. + */ + +CStringIterator *CNxString::newStringIterator() const +{ + return new CStringIterator(this); +} + +/** + * Copy the internal array to the supplied buffer. The buffer must be + * large enough to contain the full text in the string. The + * getByteCount() method can be used to obtain the length of the string. + * Unlike the CNxString class, the char array is null-terminated. + * The buffer must be (getByteCount() + 2) bytes long, in order to + * accommodate the terminator. + * + * @param buffer Buffer to copy the internal char array to. + */ + +void CNxString::copyToCharArray(FAR nxwidget_char_t *buffer) const +{ + unsigned int dataLength = sizeof(nxwidget_char_t) * m_stringLength; + memcpy(buffer, m_text, dataLength); + buffer[dataLength] = '\0'; +} + +/** + * Set the text in the string. + * + * @param text CNxString containing the new data for this string. + */ + +void CNxString::setText(const CNxString &text) +{ + // Ensure we've got enough memory available + + allocateMemory(text.getLength(), false); + + // Copy the text into the internal array + + memcpy(m_text, text.getCharArray(), sizeof(nxwidget_char_t) * text.getLength()); + + // Save size (in characters) of the string + + m_stringLength = text.getLength(); +} + +/** + * Set the 8-bit C-string text in the string. + * + * @param text Char array to use as the new data for this string. + */ + +void CNxString::setText(FAR const char *text) +{ + int length = strlen(text); + + // Ensure we've got enough memory available + + allocateMemory(length, false); + + // Copy characters into m_text, converting from 8- to 16-bit characters + // (if necessary) and cache the length + + for (int i = 0; i < length; i++) + { + m_text[i] = (nxwidget_char_t)text[i]; + } + + m_stringLength = length; +} + +/** + * Set the text in the string. + * + * @param text Char array to use as the new data for this string. + */ + +void CNxString::setText(FAR const nxwidget_char_t *text, int nchars) +{ + // Ensure we've got enough memory available + + allocateMemory(nchars, false); + + // Copy characters into m_text and cache the length + + m_stringLength = nchars; + memcpy(m_text, text, sizeof(nxwidget_char_t) * nchars); +} + +/** + * Set the text in the string. + * + * @param text Character to to use as the new data for this string. + */ + +void CNxString::setText(const nxwidget_char_t letter) +{ + // Ensure we've got enough memory available + + allocateMemory(1, false); + + // Copy the valid character into m_text and cache the length + + *m_text = letter; + m_stringLength = 1; +} + +/** + * Append text to the end of the string. + * + * @param text String to append. + */ + +void CNxString::append(const CNxString &text) +{ + // Ensure we've got enough memory available + + allocateMemory(m_stringLength + text.getLength(), true); + + // Append the new string to the end of the array + + FAR nxwidget_char_t *dest = &m_text[m_stringLength]; + FAR const nxwidget_char_t *src = text.getCharArray(); + for (int i = 0; i < text.getLength(); i++) + { + *dest++ = *src++; + } + + // Update the size in characters and the size in bytes + + m_stringLength += text.getLength(); +} + +/** + * Insert text at the specified character index. + * + * @param text The text to insert. + * @param index The index at which to insert the text. + */ + +void CNxString::insert(const CNxString &text, int index) +{ + // Early exit if the string is empty + + if (!hasData()) + { + CNxString::setText(text); + return; + } + + // Early exit if we're just appending + + if (index >= m_stringLength) + { + CNxString::append(text); + return; + } + + // Get the total size of the string that we need + + int newLength = m_stringLength + text.getLength(); + int newSize = newLength * sizeof(nxwidget_char_t); + + // Reallocate memory if the existing memory isn't large enough + + if (m_allocatedSize < newSize) + { + int allocLength = newLength + m_growAmount; + + // Allocate new string large enough to contain additional data + + FAR nxwidget_char_t *newText = new nxwidget_char_t[allocLength]; + + // Copy the start of the existing text to the newly allocated string + + FAR nxwidget_char_t *dest = newText; + FAR const nxwidget_char_t *src = m_text; + for (int i = 0; i < index; i++) + { + *dest++ = *src++; + } + + // Insert the additional text into the new string + + src = text.getCharArray(); + for (int i = 0; i < text.getLength(); i++) + { + *dest++ = *src++; + } + + // Copy the end of the existing text the the newly allocated string + + src = &m_text[index]; + for (int i = index; i < m_stringLength; i++) + { + *dest++ = *src++; + } + + m_allocatedSize = allocLength * sizeof(nxwidget_char_t); + + // Delete existing string + + delete[] m_text; + + // Swap pointers + + m_stringLength = newLength; + m_text = newText; + } + else + { + // Existing size is large enough, so make space in string for insert + + FAR nxwidget_char_t *dest = &m_text[newLength - 1]; + FAR const nxwidget_char_t *src = &m_text[m_stringLength - 1]; + for (int i = 0; i < m_stringLength - index; i++) + { + *dest-- = *src--; + } + + // Insert the additional text into the new string + + dest = &m_text[index]; + src = text.getCharArray(); + for (int i = 0; i < text.getLength(); i++) + { + *dest++ = *src++; + } + + m_stringLength = newLength; + } +} + +/** + * Remove all characters from the string from the start index onwards. + * + * @param startIndex Index to remove from. + */ + +void CNxString::remove(const int startIndex) +{ + // Reject if requested operation makes no sense + + if (!hasData() || startIndex >= m_stringLength) + { + return; + } + + // Removing characters from the end of the string is trivial - simply + // decrease the length + + m_stringLength = startIndex; +} + +/** + * Remove specified number of characters from the string from the + * start index onwards. + * + * @param startIndex Index to remove from. + * @param count Number of characters to remove. + */ + +void CNxString::remove(const int startIndex, const int count) +{ + // Reject if requested operation makes no sense + + if (!hasData() || startIndex >= m_stringLength) + { + return; + } + + // Don't remove in this way if the count includes the end of the string + + int endIndex = startIndex + count; + if (endIndex > m_stringLength) + { + remove(startIndex); + return; + } + + // Copy characters from a point after the area to be deleted into the space created + // by the deletion + + FAR nxwidget_char_t *dest = &m_text[startIndex]; + FAR const nxwidget_char_t *src = &m_text[endIndex]; + for (int i = m_stringLength - endIndex; i > 0; i--) + { + *dest++ = *src++; + } + + // Decrease length + + m_stringLength -= count; + +} + +/** + * Get the character at the specified index. This function is useful + * for finding the occasional character at an index, but for iterating + * over strings it is exceptionally slow. The newStringIterator() + * method should be used to retrieve an iterator object that can iterate + * over the string efficiently. + * + * @param index The index of the character to retrieve. + * @return The character at the specified index. + */ + +const nxwidget_char_t CNxString::getCharAt(int index) const +{ + return *getCharPointer(index); +} + +/** + * Returns the first index of the specified letter within the string. + * Will return -1 if the letter is not found. + * + * @param letter Letter to find. + * @return The index of the letter. + */ + +const int CNxString::indexOf(nxwidget_char_t letter) const +{ + return indexOf(letter, 0, getLength()); +} + +/** + * Returns the first index of the specified letter within the string. + * Will return -1 if the letter is not found. Scans through the string + * from "startIndex" until it has examined all subsequent letters. + * + * @param letter Letter to find. + * @param startIndex The index to start searching from. + * @return The index of the letter. + */ + +const int CNxString::indexOf(nxwidget_char_t letter, int startIndex) const +{ + return indexOf(letter, startIndex, getLength() - startIndex); +} + +/** + * Returns the first index of the specified letter within the string. + * Will return -1 if the letter is not found. Scans through the string + * from "startIndex" until it has examined all letters within the + * range "count". + * + * @param letter Letter to find. + * @param startIndex The index to start searching from. + * @param count The number of characters to examine. + * @return The index of the letter. + */ + +const int CNxString::indexOf(nxwidget_char_t letter, int startIndex, int count) const +{ + // Exit if no data available + + if (!hasData()) + { + return -1; + } + + int index = -1; + int charsExamined = 0; + + CStringIterator *iterator = new CStringIterator(this); + if (!iterator->moveTo(startIndex)) + { + delete iterator; + return -1; + } + + do + { + if (iterator->getChar() == letter) + { + index = iterator->getIndex(); + break; + } + + charsExamined++; + } + while (iterator->moveToNext() && (charsExamined < count)); + + delete iterator; + return index; +} + +/** + * Returns the last index of the specified letter within the string. + * Will return -1 if the letter is not found. + * + * @param letter Letter to find. + * @return The index of the letter. + */ + +const int CNxString::lastIndexOf(nxwidget_char_t letter) const +{ + return lastIndexOf(letter, getLength() - 1, getLength()); +} + +/** + * Returns the last index of the specified letter within the string. + * Will return -1 if the letter is not found. Scans through the string + * backwards from "startIndex" until it has examined all preceding + * letters within the string. + * + * @param letter Letter to find. + * @param startIndex The index to start searching from. + * @return The index of the letter. + */ + +const int CNxString::lastIndexOf(nxwidget_char_t letter, int startIndex) const +{ + return lastIndexOf(letter, startIndex, getLength() - (getLength() - startIndex)); +} + +/** + * Returns the last index of the specified letter within the string. + * Will return -1 if the letter is not found. Scans through the string + * backwards from "startIndex" until it has examined all letters within + * the range "count". + * @param letter Letter to find. + * @param startIndex The index to start searching from. + * @param count The number of characters to examine. + * @return The index of the letter. + */ + +const int CNxString::lastIndexOf(nxwidget_char_t letter, int startIndex, int count) const +{ + // Exit if no data available + + if (!hasData()) + { + return -1; + } + + int index = -1; + int charsExamined = 0; + + CStringIterator *iterator = new CStringIterator(this); + if (!iterator->moveTo(startIndex)) + { + delete iterator; + return -1; + } + + do + { + if (iterator->getChar() == letter) + { + index = iterator->getIndex(); + break; + } + + charsExamined++; + } + while (iterator->moveToPrevious() && (charsExamined <= count)); + + delete iterator; + return index; +} + +/** + * Get a substring from this string. It is the responsibility of the + * caller to delete the substring when it is no longer required. + * + * @param startIndex The starting point of the substring. + * @return A pointer to a new CNxString object containing the + * substring. + */ + +CNxString* CNxString::subString(int startIndex) const +{ + return subString(startIndex, getLength() - startIndex); +} + +/** + * Get a substring from this string. It is the responsibility of the + * caller to delete the substring when it is no longer required. + * + * @param startIndex The starting point of the substring. + * @param length The length of the substring. + * @return A pointer to a new CNxString object containing the + * substring. +*/ + +CNxString *CNxString::subString(int startIndex, int length) const +{ + CNxString *newString = new CNxString(); + CStringIterator *iterator = new CStringIterator(this); + + if (!iterator->moveTo(startIndex)) + { + delete iterator; + return (CNxString *)0; + } + + // Build up the string character by character. We could do a memcpy + // here and improve performance. + + int count = 0; + while (count < length) + { + newString->append(iterator->getChar()); + iterator->moveToNext(); + count++; + } + + delete iterator; + return newString; +} + +/** + * Overloaded assignment operator. Copies the data within the argument + * string to this string. + * + * @param string The string to copy. + * @return This string. + */ + +CNxString& CNxString::operator=(const CNxString &string) +{ + if (&string != this) + { + setText(string); + } + return *this; +} + +/** + * Overloaded assignment operator. Copies the data within the argument + * char array to this string. + * + * @param string The string to copy. + * @return This string. + */ + +CNxString& CNxString::operator=(const char *string) +{ + setText(string); + return *this; +} + +/** + * Overloaded assignment operator. Copies the data from the argument + * char to this string. + * + * @param letter The char to copy. + * @return This string. + */ + +CNxString& CNxString::operator=(const nxwidget_char_t letter) +{ + setText(letter); + return *this; +} + +/** + * Compares this string to the argument. + * + * @param string String to compare to. + * @return Zero if both strings are equal. A value greater than zero + * indicates that this string is greater than the argument string. A + * value less than zero indicates the opposite. Note that the return + * value indicates the *byte* that does not match, not the *character*. + */ + +int CNxString::compareTo(const CNxString &string) const +{ + return memcmp((FAR const char*)m_text, + (FAR const char*)string.getCharArray(), + getLength()); +} + +/** + * Allocate memory for the string. + * + * @param chars Number nxwidget_char_t size characters to allocate. + * @param preserve If true, the data in the existing memory will be + * preserved if new memory must be allocated + */ + +void CNxString::allocateMemory(int nChars, bool preserve) +{ + // This is the size of the allocation that we need + + int nBytesNeeded = nChars * sizeof(nxwidget_char_t); + + // Do we already have enough memory allocated to contain this new size? + // If so, we can avoid deallocating and allocating new memory by re-using the old + + if (nBytesNeeded > m_allocatedSize) + { + // Not enough space in existing memory; allocate new memory + + int allocChars = nChars + m_growAmount; + nxwidget_char_t *newText = new nxwidget_char_t[allocChars]; + + // Free old memory if necessary + + if (m_text != NULL) + { + // Preserve existing data if required + + if (preserve) + { + memcpy(newText, m_text, sizeof(nxwidget_char_t) * m_stringLength); + } + + delete[] m_text; + } + + // Set pointer to new memory + + m_text = newText; + + // Remember how much memory we've allocated. + + m_allocatedSize = allocChars * sizeof(nxwidget_char_t); + } +} + +/** + * Return a pointer to the specified characters. + * + * @param index Index of the character to retrieve. + */ + +FAR nxwidget_char_t *CNxString::getCharPointer(const int index) const +{ + // Early exit if the string is empty + + if (!hasData()) + { + return (FAR nxwidget_char_t*)NULL; + } + + // Early exit if the index is greater than the length of the string + + if (index >= m_stringLength) + { + return (FAR nxwidget_char_t*)NULL; + } + + return &m_text[index]; +} diff --git a/NxWidgets/libnxwidgets/src/cnxtimer.cxx b/NxWidgets/libnxwidgets/src/cnxtimer.cxx new file mode 100644 index 000000000..e351d2357 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cnxtimer.cxx @@ -0,0 +1,382 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cnxtimer.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> +#include <cstring> +#include <ctime> +#include <csignal> +#include <debug.h> + +#include "cnxtimer.hxx" +#include "singletons.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Static Data Members + ****************************************************************************/ + +using namespace NXWidgets; + +/**************************************************************************** + * Implementation Classes + ****************************************************************************/ + +/** + * Constructor. + * + * @param pWidgetControl The controlling widget for the display. + * @param timeout Time, in milliseconds, before the timer fires an + * EVENT_ACTION event. + * @param repeat If true, the timer will fire multiple events. If false, + * the timer will fire just once and stop. + */ + +CNxTimer::CNxTimer(CWidgetControl *pWidgetControl, uint32_t timeout, bool repeat) +: CNxWidget(pWidgetControl, 0, 0, 0, 0, 0, 0) +{ + // Remember the timer configuration + + m_timeout = timeout; + m_isRepeater = repeat; + m_isRunning = false; + + // Create a POSIX timer (We can't do anything about failures here) + + int ret = timer_create(CLOCK_REALTIME, (FAR struct sigevent *)NULL, &m_timerid); + if (ret < 0) + { + gdbg("timer_create() failed\n"); + return; + } + + // If we are the first timer created in the whole system, then create + // the timer list and attach the SIGALRM timer handler. + + if (!g_nxTimers) + { + if (!g_nxTimers) + { + gdbg("Failed to create the timer list\n"); + return; + } + + // Attach the SIGALM signal handler (no harm if this is done multiple times) + + struct sigaction sigact; + sigact.sa_handler = signalHandler; + sigact.sa_flags = 0; + sigemptyset(&sigact.sa_mask); + + ret = sigaction(SIGALRM, &sigact, (FAR struct sigaction *)NULL); + if (ret < 0) + { + gdbg("sigaction() failed\n"); + return; + } + } + + // Add ourself onto the array of timers +#warning "Need to disable SIGALRM here" + g_nxTimers->push_back(this); +} + +/** + * Destructor. + */ + +CNxTimer::~CNxTimer(void) +{ + // Locate ourself in the list of timers and remove ourselves + +#warning "Need to disable SIGALRM here" + for (int i = 0; i < g_nxTimers->size(); i++) + { + CNxTimer *timer = g_nxTimers->at(i); + if (timer == this) + { + g_nxTimers->erase(i); + break; + } + } + + // Destroy the timer + + (void)timer_delete(m_timerid); +} + +/** + * Return the timeout of this timer. + * + * @return The number of milliseconds that this timer will run before firing + * an event. + */ + +const uint32_t CNxTimer::getTimeout(void) +{ + // If the timer is not running, then just return the timeout value + + if (!m_isRunning) + { + return m_timeout; + } + else + { + // Get the time remaining on the POSIX timer. Of course, there + // are race conditions here.. the timer could expire at anytime + + struct itimerspec remaining; + int ret = timer_gettime(m_timerid, &remaining); + if (ret < 0) + { + gdbg("timer_gettime() failed\n"); + return 0; + } + + return timespecToMilliseconds(&remaining.it_value); + } +} + +/** + * Resets the millisecond timer. + */ + +void CNxTimer::reset(void) +{ + // It does not make sense to reset the timer if the timer is not running + + if (m_isRunning) + { + // If the specified timer was already armed when timer_settime() is + // called, this call will reset the time until next expiration to the + // value specified. + + m_isRunning = false; + start(); + } +} + +/** + * Starts the timer. + */ + +void CNxTimer::start(void) +{ + // If the timer is running, reset should be used to restart it + + if (!m_isRunning) + { + // If the specified timer was already armed when timer_settime() is + // called, this call will reset the time until next expiration to the + // value specified. + + struct itimerspec timerspec; + millisecondsToTimespec(m_timeout, &timerspec.it_value); + timerspec.it_interval.tv_sec = 0; + timerspec.it_interval.tv_nsec = 0; + + int ret = timer_settime(m_timerid, 0, &timerspec, + (FAR struct itimerspec *)NULL); + if (ret < 0) + { + gdbg("timer_settime() failed\n"); + } + + // The timer is now running + + m_isRunning = true; + } +} + +/** + * Stops the timer + */ + +void CNxTimer::stop(void) +{ + if (m_isRunning) + { + // If the it_value member of value is zero, the timer will be disarmed. + // The effect of disarming or resetting a timer with pending expiration + // notifications is unspecified. + + struct itimerspec nullTime; + memset(&nullTime, 0, sizeof(struct itimerspec)); + + int ret = timer_settime(m_timerid, 0, &nullTime, + (FAR struct itimerspec *)NULL); + if (ret < 0) + { + gdbg("timer_settime failed\n"); + } + + // The time is no longer running + + m_isRunning = false; + } +} + +/** + * The SIGALM signal handler that will be called when the timer goes off + * + * @param signo The signal number call caused the handler to run (SIGALM) + */ + +void CNxTimer::signalHandler(int signo) +{ + // Call handlerTimerExpiration on every timer instance + + for (int i = 0; i < g_nxTimers->size(); i++) + { + CNxTimer *timer = g_nxTimers->at(i); + timer->handleTimerExpiration(); + } +} + +/** + * Handle an expired timer + */ + +void CNxTimer::handleTimerExpiration(void) +{ + // Do we think our timer is running? + + if (m_isRunning) + { + // Is it running? It the timer is not running, it will return an + // it_value of zero. + + struct itimerspec status; + int ret = timer_gettime(m_timerid, &status); + if (ret < 0) + { + gdbg("timer_gettime() failed\n"); + return; + } + + // it_value == 0 means that timer is not running + + if (status.it_value.tv_sec == 0 && status.it_value.tv_nsec == 0) + { + // It has expired + + m_isRunning = false; + + // Raise the action event. Hmmm.. are there any issues with + // doing this from a signal handler? We'll find out + + m_widgetEventHandlers->raiseActionEvent(); + + // Restart the timer if this is a repeating timer + + if (m_isRepeater) + { + start(); + } + } + } +} + +/** + * Convert a timespec to milliseconds + * + * @param tp The pointer to the timespec to convert + * @return The corresponding time in milliseconds + */ + +uint32_t CNxTimer::timespecToMilliseconds(FAR const struct timespec *tp) +{ + return (uint32_t)tp->tv_sec * 1000 + (uint32_t)tp->tv_nsec / 10000000; +} + +/** + * Convert milliseconds to a timespec + * + * @param milliseconds The milliseconds to be converted + * @param tp The pointer to the location to store the converted timespec + */ + + void CNxTimer::millisecondsToTimespec(uint32_t milliseconds, + FAR struct timespec *tp) + { + tp->tv_sec = milliseconds / 1000; + uint32_t remainder = milliseconds - (uint32_t)tp->tv_sec * 1000; + tp->tv_nsec = remainder * 1000000; + } + + diff --git a/NxWidgets/libnxwidgets/src/cnxtkwindow.cxx b/NxWidgets/libnxwidgets/src/cnxtkwindow.cxx new file mode 100644 index 000000000..36b07dce5 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cnxtkwindow.cxx @@ -0,0 +1,387 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cnxtkwindow.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> +#include <cassert> + +#include "cwidgetcontrol.hxx" +#include "cnxtkwindow.hxx" +#include "cnxtoolbar.hxx" +#include "cbitmap.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param hNxServer Handle to the NX server. + * @param widgetControl Controlling widget for this window. + */ + +CNxTkWindow::CNxTkWindow(NXHANDLE hNxServer, CWidgetControl *pWidgetControl) + : CCallback(pWidgetControl), m_hNxServer(hNxServer), m_hNxTkWindow(0), + m_widgetControl(pWidgetControl) +{ + // Create the CGraphicsPort instance for this window + + m_widgetControl->createGraphicsPort(static_cast<INxWindow*>(this)); +} + +/** + * Destructor. + */ + +CNxTkWindow::~CNxTkWindow(void) +{ + // It would be a disaster if toolbar instance persists beyond + // the window! + + DEBUGASSERT(!m_toolbar); + + // Release the window. We do not release the widget control + // instance. The lifetime of that instance is owned by he-who- + // constructed-us. + + (void)nxtk_closewindow(m_hNxTkWindow); +} + +/** + * Creates a new framed window. Window creation is separate from + * object instantiation so that failures can be reported. + * + * @return True if the framed window was successfully created. + */ + +bool CNxTkWindow::open(void) +{ + // Get the C-callable callback vtable + + FAR struct nx_callback_s *vtable = getCallbackVTable(); + + // Create the window + + m_hNxTkWindow = nxtk_openwindow(m_hNxServer, vtable, (FAR void *)m_widgetControl); + return m_hNxTkWindow != NULL; +} + +/** + * Open a toolbar on the framed window + * + * @param height Height of the toolbar + */ + +CNxToolbar *CNxTkWindow::openToolbar(nxgl_coord_t height) +{ + if (m_hNxTkWindow && !m_toolbar) + { + // Get current window style from the widget control + + CWidgetStyle style; + m_widgetControl->getWidgetStyle(&style); + + // Create a new controlling widget for the window + + CWidgetControl *widgetControl = new CWidgetControl(&style); + + // And create the toolcar + + m_toolbar = new CNxToolbar(this, m_hNxTkWindow, + widgetControl, height); + if (!m_toolbar) + { + delete widgetControl; + } + } + return m_toolbar; +} + +/** + * Request the position and size information of the window. The values + * will be returned asynchronously through the client callback method. + * The GetPosition() method may than be called to obtain the positional + * data as provided by the callback. + * + * @return True on success, false on any failure. + */ + +bool CNxTkWindow::requestPosition(void) +{ + // Request the window position + + return nxtk_getposition(m_hNxTkWindow) == OK; +} + +/** + * Get the position of the window in the physical display coordinates + * (as reported by the NX callback). + * + * @return The position. + */ + +bool CNxTkWindow::getPosition(FAR struct nxgl_point_s *pPos) +{ + return m_widgetControl->getWindowPosition(pPos); +} + +/** + * Get the size of the window (as reported by the NX callback). + * + * @return The size. + */ + +bool CNxTkWindow::getSize(FAR struct nxgl_size_s *pSize) +{ + return m_widgetControl->getWindowSize(pSize); +} + +/** + * Set the position and size of the window. + * + * @param pPos The new position of the window. + * @return True on success, false on any failure. + */ + +bool CNxTkWindow::setPosition(FAR const struct nxgl_point_s *pPos) +{ + // Set the window size and position + + return nxtk_setposition(m_hNxTkWindow, pPos) == OK; +} + +/** + * Set the size of the selected window. + * + * @param pSize The new size of the window. + * @return True on success, false on any failure. + */ + +bool CNxTkWindow::setSize(FAR const struct nxgl_size_s *pSize) +{ + // Set the window size + + return nxtk_setsize(m_hNxTkWindow, pSize) == OK; +} + +/** + * Bring the window to the top of the display. + * + * @return True on success, false on any failure. + */ + +bool CNxTkWindow::raise(void) +{ + // Raise the window to the top of the display + + return nxtk_raise(m_hNxTkWindow) == OK; +} + +/** + * Lower the window to the bottom of the display. + * + * @return True on success, false on any failure. + */ + +bool CNxTkWindow::lower(void) +{ + // Lower the window to the bottom of the display + + return nxtk_lower(m_hNxTkWindow) == OK; +} + +/** + * Set an individual pixel in the window with the specified color. + * + * @param pPos The location of the pixel to be filled. + * @param color The color to use in the fill. + * + * @return True on success; false on failure. + */ + +bool CNxTkWindow::setPixel(FAR const struct nxgl_point_s *pPos, + nxgl_mxpixel_t color) +{ +#if 0 + // Set an individual pixel to the specified color + + return nxtk_setpixel(m_hNxTkWindow, pPos, &color) == OK; +#else +# warning "Revisit" + return false; +#endif +} + +/** + * Fill the specified rectangle in the window with the specified color. + * + * @param pRect The location to be filled. + * @param color The color to use in the fill. + * + * @return True on success; false on failure. + */ + +bool CNxTkWindow::fill(FAR const struct nxgl_rect_s *pRect, + nxgl_mxpixel_t color) +{ + // Fill a rectangular region with a solid color + + return nxtk_fillwindow(m_hNxTkWindow, pRect, &color) == OK; +} + +/** + * Get the raw contents of graphic memory within a rectangular region. NOTE: + * Since raw graphic memory is returned, the returned memory content may be + * the memory of windows above this one and may not necessarily belong to + * this window unless you assure that this is the top window. + * + * @param rect The location to be copied + * @param dest - The describes the destination bitmap to receive the + * graphics data. + */ + +void CNxTkWindow::getRectangle(FAR const struct nxgl_rect_s *rect, struct SBitmap *dest) +{ + // Get a rectangule region from the window + + (void)nxtk_getwindow(m_hNxTkWindow, rect, 0, (FAR uint8_t*)dest->data, dest->stride); +} + +/** + * Fill the specified trapezoidal region in the window with the specified + * color. + * + * @param pClip Clipping rectangle relative to window (may be null). + * @param pTrap The trapezoidal region to be filled. + * @param color The color to use in the fill. + * + * @return True on success; false on failure. + */ + +bool CNxTkWindow::fillTrapezoid(FAR const struct nxgl_rect_s *pClip, + FAR const struct nxgl_trapezoid_s *pTrap, + nxgl_mxpixel_t color) +{ + // Fill a trapezoidal region with a solid color + + return nxtk_filltrapwindow(m_hNxTkWindow, pTrap, &color) == OK; +} + +/** + * Fill the specified line in the window with the specified color. + * + * @param vector - Describes the line to be drawn + * @param width - The width of the line + * @param color - The color to use to fill the line + * + * @return True on success; false on failure. + */ + +bool CNxTkWindow::drawLine(FAR struct nxgl_vector_s *vector, + nxgl_coord_t width, nxgl_mxpixel_t color) +{ + // Draw a line with the specified color + + return nxtk_drawlinewindow(m_hNxTkWindow, vector, width, &color) == OK; +} + +/** + * Draw a filled circle at the specified position, size, and color. + * + * @param center The window-relative coordinates of the circle center. + * @param radius The radius of the rectangle in pixels. + * @param color The color of the rectangle. + */ + +bool CNxTkWindow::drawFilledCircle(struct nxgl_point_s *center, nxgl_coord_t radius, + nxgl_mxpixel_t color) +{ + return nxtk_fillcirclewindow(m_hNxTkWindow, center, radius, &color) == OK; +} + +/** + * Move a rectangular region within the window. + * + * @param pRect Describes the rectangular region to move. + * @param pOffset The offset to move the region. + * + * @return True on success; false on failure. + */ + +bool CNxTkWindow::move(FAR const struct nxgl_rect_s *pRect, + FAR const struct nxgl_point_s *pOffset) +{ + // Move a rectangular region of the display + + return nxtk_movewindow(m_hNxTkWindow, pRect, pOffset) == OK; +} + +/** + * Copy a rectangular region of a larger image into the rectangle in the + * specified window. The source image is treated as an opaque image. + * + * @param pDest Describes the rectangular on the display that will receive + * the bitmap. + * @param pSrc The start of the source image. + * @param pOrigin the pOrigin of the upper, left-most corner of the full + * bitmap. Both pDest and pOrigin are in window coordinates, however, + * pOrigin may lie outside of the display. + * @param stride The width of the full source image in bytes. + * + * @return True on success; false on failure. + */ + +bool CNxTkWindow::bitmap(FAR const struct nxgl_rect_s *pDest, + FAR const void *pSrc, + FAR const struct nxgl_point_s *pOrigin, + unsigned int stride) +{ + // Copy a rectangular bitmap image in a region on the display + + return nxtk_bitmapwindow(m_hNxTkWindow, pDest, &pSrc, pOrigin, stride) == OK; +} diff --git a/NxWidgets/libnxwidgets/src/cnxtoolbar.cxx b/NxWidgets/libnxwidgets/src/cnxtoolbar.cxx new file mode 100644 index 000000000..5911c731d --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cnxtoolbar.cxx @@ -0,0 +1,364 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cnxtoolbar.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cwidgetcontrol.hxx" +#include "cnxtoolbar.hxx" +#include "cbitmap.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pNxTkWindow Parent framed window instance + * @param hNxTkWindow Parent framed window NX handler + * @param widgetControl Controlling widget for this toolbar. + * @param height The height of the toolbar. + */ + +CNxToolbar::CNxToolbar(CNxTkWindow *pNxTkWindow, NXTKWINDOW hNxTkWindow, + CWidgetControl *pWidgetControl, nxgl_coord_t height) + : CCallback(pWidgetControl) +{ + m_nxTkWindow = pNxTkWindow; + m_hNxTkWindow = hNxTkWindow; + m_widgetControl = pWidgetControl; + m_height = height; +} + +/** + * Destructor. + */ + +CNxToolbar::~CNxToolbar(void) +{ + // Inform the parent window instance that the toolbar is gone + + m_nxTkWindow->detachToolbar(); + + // Release the widget control instance. Normally the lifetime + // of the widget control instance is managed by logic outside + // of the window instance. But here, as in the real world, + // our parent expects us to clean up after ourselves. + + delete m_widgetControl; + + // Release the toolbar. + + (void)nxtk_closetoolbar(m_hNxTkWindow); +} + +/** + * Creates a new toolbar. Toolbar creation is separate from + * object instantiation so that failures can be reported. + * + * @return True if the toolbar was successfully created. + */ + +bool CNxToolbar::open(void) +{ + // Get the C-callable callback vtable + + FAR struct nx_callback_s *vtable = getCallbackVTable(); + + // Create the toolbar + + int ret = nxtk_opentoolbar(m_hNxTkWindow, m_height, vtable, + (FAR void *)m_widgetControl); + return ret == OK; +} + +/** + * Request the position and size information of the toolbar. The values + * will be returned asynchronously through the client callback method. + * The GetPosition() method may than be called to obtain the positional + * data as provided by the callback. + * + * @return True on success, false on any failure. + */ + +bool CNxToolbar::requestPosition(void) +{ + // Request the position of the entire framed window containing the + // toolbar. The NXTK callback will route toolbar specific + // information back to us. + + nxtk_getposition(m_hNxTkWindow); + return false; +} + +/** + * Get the position of the toolbar in the physical display coordinates + * (as reported by the NX callback). + * + * @return The position. + */ + +bool CNxToolbar::getPosition(FAR struct nxgl_point_s *pPos) +{ + return m_widgetControl->getWindowPosition(pPos); +} + +/** + * Get the size of the toolbar (as reported by the NX callback). + * + * @return The size. + */ + +bool CNxToolbar::getSize(FAR struct nxgl_size_s *pSize) +{ + return m_widgetControl->getWindowSize(pSize); +} + +/** + * Set the position and size of the toolbar. The position of + * the toolbar is fixed at the top of the parent framed window. + * + * @param pPos The new position of the toolbar. + * @return Always returns false. + */ + +bool CNxToolbar::setPosition(FAR const struct nxgl_point_s *pPos) +{ + return false; +} + +/** + * Set the size of the selected toolbar. The only variable dimension + * is the height of the toolbar, but that cannot be changed once + * it is created. + * + * @param pSize The new size of the toolbar. + * @return Always returns false. + */ + +bool CNxToolbar::setSize(FAR const struct nxgl_size_s *pSize) +{ + return false; +} + +/** + * Bring the toolbar to the top of the display. The toolbar is + * a component of the containing, parent, framed window. It + * cannot be raised separately. + * + * @return Always returns false. + */ + +bool CNxToolbar::raise(void) +{ + return false; +} + +/** + * Lower the toolbar to the bottom of the display. The toolbar is + * a component of the containing, parent, framed window. It + * cannot be raised separately. + * + * @return Always returns false. + */ + +bool CNxToolbar::lower(void) +{ + return false; +} + +/** + * Set an individual pixel in the toolbar with the specified color. + * + * @param pPos The location of the pixel to be filled. + * @param color The color to use in the fill. + * + * @return True on success; false on failure. + */ + +bool CNxToolbar::setPixel(FAR const struct nxgl_point_s *pPos, + nxgl_mxpixel_t color) +{ +#if 0 + // Set an individual pixel to the specified color + + return nxtk_setpixel(m_hNxTkWindow, pPos, &color) == OK; +#else +# warning "Revisit" + return false; +#endif +} + +/** + * Fill the specified rectangle in the toolbar with the specified color. + * + * @param pRect The location to be filled. + * @param color The color to use in the fill. + * + * @return True on success; false on failure. + */ + +bool CNxToolbar::fill(FAR const struct nxgl_rect_s *pRect, + nxgl_mxpixel_t color) +{ + // Fill a rectangular region with a solid color + + return nxtk_filltoolbar(m_hNxTkWindow, pRect, &color) == OK; +} + +/** + * Get the raw contents of graphic memory within a rectangular region. NOTE: + * Since raw graphic memory is returned, the returned memory content may be + * the memory of windows above this one and may not necessarily belong to + * this window unless you assure that this is the top window. + * + * @param rect The location to be copied + * @param dest - The describes the destination bitmap to receive the + * graphics data. + */ + +void CNxToolbar::getRectangle(FAR const struct nxgl_rect_s *rect, struct SBitmap *dest) +{ + // Get a rectangule region from the toolbar + + (void)nxtk_gettoolbar(m_hNxTkWindow, rect, 0, (FAR uint8_t*)dest->data, dest->stride); +} + +/** + * Fill the specified trapezoidal region in the toolbar with the specified + * color. + * + * @param pClip Clipping rectangle relative to toolbar (may be null). + * @param pTrap The trapezoidal region to be filled. + * @param color The color to use in the fill. + * + * @return True on success; false on failure. + */ + +bool CNxToolbar::fillTrapezoid(FAR const struct nxgl_rect_s *pClip, + FAR const struct nxgl_trapezoid_s *pTrap, + nxgl_mxpixel_t color) +{ + // Fill a trapezoidal region with a solid color + + return nxtk_filltraptoolbar(m_hNxTkWindow, pTrap, &color) == OK; +} + +/** + * Fill the specified line in the toolbar with the specified color. + * + * @param vector - Describes the line to be drawn + * @param width - The width of the line + * @param color - The color to use to fill the line + * + * @return True on success; false on failure. + */ + +bool CNxToolbar::drawLine(FAR struct nxgl_vector_s *vector, + nxgl_coord_t width, nxgl_mxpixel_t color) +{ + // Draw a line with the specified color + + return nxtk_drawlinetoolbar(m_hNxTkWindow, vector, width, &color) == OK; +} + +/** + * Draw a filled circle at the specified position, size, and color. + * + * @param center The window-relative coordinates of the circle center. + * @param radius The radius of the rectangle in pixels. + * @param color The color of the rectangle. + */ + +bool CNxToolbar::drawFilledCircle(struct nxgl_point_s *center, nxgl_coord_t radius, + nxgl_mxpixel_t color) +{ + return nxtk_fillcircletoolbar(m_hNxTkWindow, center, radius, &color) == OK; +} + +/** + * Move a rectangular region within the toolbar. + * + * @param pRect Describes the rectangular region to move. + * @param pOffset The offset to move the region. + * + * @return True on success; false on failure. + */ + +bool CNxToolbar::move(FAR const struct nxgl_rect_s *pRect, + FAR const struct nxgl_point_s *pOffset) +{ + // Move a rectangular region of the display + + return nxtk_movetoolbar(m_hNxTkWindow, pRect, pOffset) == OK; +} + +/** + * Copy a rectangular region of a larger image into the rectangle in the + * specified toolbar. The source image is treated as an opaque image. + * + * @param pDest Describes the rectangular on the display that will receive + * the bitmap. + * @param pSrc The start of the source image. + * @param pOrigin the pOrigin of the upper, left-most corner of the full + * bitmap. Both pDest and pOrigin are in toolbar coordinates, however, + * pOrigin may lie outside of the display. + * @param stride The width of the full source image in bytes. + * + * @return True on success; false on failure. + */ + +bool CNxToolbar::bitmap(FAR const struct nxgl_rect_s *pDest, + FAR const void *pSrc, + FAR const struct nxgl_point_s *pOrigin, + unsigned int stride) +{ + // Copy a rectangular bitmap image in a region on the display + + return nxtk_bitmaptoolbar(m_hNxTkWindow, pDest, &pSrc, pOrigin, stride) == OK; +} diff --git a/NxWidgets/libnxwidgets/src/cnxwidget.cxx b/NxWidgets/libnxwidgets/src/cnxwidget.cxx new file mode 100644 index 000000000..de84f1393 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cnxwidget.cxx @@ -0,0 +1,2424 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cnxwidget.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cnxwidget.hxx" +#include "cgraphicsport.hxx" +#include "cwidgeteventhandler.hxx" +#include "cnxfont.hxx" +#include "cwidgetstyle.hxx" +#include "cwidgeteventargs.hxx" +#include "crectcache.hxx" +#include "cwidgetcontrol.hxx" +#include "singletons.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +#define DOUBLE_CLICK_BOUNDS 10 + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The controllwing widget for the display + * @param x The x coordinate of the widget. + * @param y The y coordinate of the widget. + * @param width The width of the widget. + * @param height The height of the widget. + * @param flags Bitmask specifying some set-up values for the widget. + * @param style The style that the button should use. If this is not + * specified, the button will use the global default widget + * style. + * @see WidgetFlagType. + */ + +CNxWidget::CNxWidget(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + uint32_t flags, const CWidgetStyle *style) +{ + // Save the controlling widget + + m_widgetControl = pWidgetControl; + + // Set properties from parameters. If this is a child widget, then + // this coordinates are relative to the parent widget. + + m_rect.setX(x); + m_rect.setY(y); + m_rect.setWidth(width); + m_rect.setHeight(height); + + // Do we need to fetch the default style? + + if (style == (CWidgetStyle *)NULL) + { + // Get the style from the controlling widget. This allows different + // widgets within a window to have the same style, unique to the window. + + pWidgetControl->getWidgetStyle(&m_style); + } + else + { + // Use specified style + + useWidgetStyle(style); + } + + // Add ourself to the list of controlled widgets + + pWidgetControl->addControlledWidget(this); + + // Mask flags against bitmasks and logical NOT twice to obtain boolean values + + m_flags.borderless = (!(!(flags & WIDGET_BORDERLESS))); + m_flags.draggable = (!(!(flags & WIDGET_DRAGGABLE))); + m_flags.permeable = (!(!(flags & WIDGET_PERMEABLE))); + m_flags.doubleClickable = (!(!(flags & WIDGET_DOUBLE_CLICKABLE))); + + // Dragging values + + m_grabPointX = 0; + m_grabPointY = 0; + m_newX = 0; + m_newY = 0; + + // Set initial flag values + + m_flags.clicked = false; + m_flags.dragging = false; + m_flags.hasFocus = false; + m_flags.deleted = false; + m_flags.drawingEnabled = false; + m_flags.enabled = true; + m_flags.erased = true; + m_flags.shelved = false; + m_flags.visibleRegionCacheInvalid = true; + m_flags.hidden = false; + m_flags.modal = false; + + // Set hierarchy pointers + + m_parent = (CNxWidget *)NULL; + m_focusedChild = (CNxWidget *)NULL; + + // Double-click + + clock_gettime(CLOCK_REALTIME, &m_lastClickTime); + m_lastClickX = 0; + m_lastClickY = 0; + m_doubleClickBounds = DOUBLE_CLICK_BOUNDS; + + // Set other default values + + m_refcon = 0; + + // Set border size to 1 line + + m_borderSize.top = 1; + m_borderSize.right = 1; + m_borderSize.bottom = 1; + m_borderSize.left = 1; + + m_closeType = CLOSE_TYPE_CLOSE; + m_rectCache = new CRectCache(this); + m_widgetEventHandlers = new CWidgetEventHandlerList(this); +} + +/** + * Destructor. + */ + +CNxWidget::~CNxWidget(void) +{ + if (!m_flags.deleted) + { + m_flags.deleted = true; + + // Unset the clicked pointer if necessary + + if (m_widgetControl->getClickedWidget() == this) + { + m_widgetControl->setClickedWidget((CNxWidget *)NULL); + } + } + + if (m_parent != (CNxWidget *)NULL) + { + m_parent->removeChild(this); + } + + // Delete children + + while (m_children.size() > 0) + { + m_children[0]->destroy(); + } + + // Delete shelved children + + while (m_shelvedWidgets.size() > 0) + { + m_shelvedWidgets[0]->destroy(); + } + + // Remove ourselve from the controlled widget list + + m_widgetControl->removeControlledWidget(this); + + // Delete instances. NOTE that we do not delete the controlling + // widget. It persists until the window is closed. + + delete m_rectCache; + delete m_widgetEventHandlers; +} + +/** + * Get the x coordinate of the widget in "Widget space". + * + * @return Widget space x coordinate. + */ + +const nxgl_coord_t CNxWidget::getX(void) const +{ + if (m_parent != (CNxWidget *)NULL) + { + return m_parent->getX() + m_rect.getX(); + } + + return m_rect.getX(); +} + +/** + * Get the y coordinate of the widget in "Widget space". + * + * @return Widget space y coordinate. + */ + +const nxgl_coord_t CNxWidget::getY(void) const +{ + if (m_parent != (CNxWidget *)NULL) + { + return m_parent->getY() + m_rect.getY(); + } + + return m_rect.getY(); +} + +/** + * Get the x coordinate of the widget relative to its parent. + * + * @return Parent-space x coordinate. + */ + +const nxgl_coord_t CNxWidget::getRelativeX(void) const +{ + return m_rect.getX(); +} + +/** + * Get the y coordinate of the widget relative to its parent. + * + * @return Parent-space y coordinate. + */ + +const nxgl_coord_t CNxWidget::getRelativeY(void) const +{ + return m_rect.getY(); +} + +/** + * Has the widget been marked for deletion? This function recurses up the widget + * hierarchy and only returns true if all of the widgets in the ancestor + * chain are not deleted. + * + * Widgets marked for deletion are automatically deleted and should not be + * interacted with. + * + * @return True if marked for deletion. + */ + +const bool CNxWidget::isDeleted(void) const +{ + if (m_parent != (CNxWidget *)NULL) + { + if (m_parent->isDeleted()) + { + return true; + } + } + + return m_flags.deleted; +} + +/** + * Is the widget allowed to draw? This function recurses up the widget + * hierarchy and only returns true if all of the widgets in the ancestor + * chain are visible. + * + * @return True if drawing is enabled. + */ + +const bool CNxWidget::isDrawingEnabled(void) const +{ + if (m_parent != (CNxWidget *)NULL) + { + if (m_parent->isDrawingEnabled()) + { + // Drawing is enabled if the widget is drawable, not deleted, and not shelved + + return (m_flags.drawingEnabled && (!m_flags.deleted) && (!m_flags.shelved) && (!m_flags.hidden)); + } + } + else + { + return (m_flags.drawingEnabled && (!m_flags.deleted) && (!m_flags.shelved) && (!m_flags.hidden)); + } + + return false; +} + +/** + * Is the widget hidden? This function recurses up the widget + * hierarchy and returns true if any of the widgets in the ancestor + * chain are hidden. + * + * @return True if hidden. + */ + +const bool CNxWidget::isHidden(void) const +{ + if (m_parent != (CNxWidget *)NULL) + { + if (!m_parent->isHidden()) + { + // Hidden if the widget is deleted, shelved or hidden + + return (m_flags.deleted || m_flags.shelved || m_flags.hidden); + } + } + else + { + return (m_flags.deleted || m_flags.shelved || m_flags.hidden); + } + + return true; +} + +/** + * Is the widget enabled? This function recurses up the widget + * hierarchy and only returns true if all of the widgets in the ancestor + * chain are enabled. + * + * @return True if enabled. + */ + +const bool CNxWidget::isEnabled() const +{ + if (m_parent != (CNxWidget *)NULL) + { + if (m_parent->isEnabled()) + { + // Enabled if the widget is enabled, not deleted, not shelved and not hidden + + return (m_flags.enabled && (!m_flags.deleted) && (!m_flags.shelved) && (!m_flags.hidden)); + } + } + else + { + return (m_flags.enabled && (!m_flags.deleted) && (!m_flags.shelved) && (!m_flags.hidden)); + } + + return false; +} + +/** + * Is the widget modal? Only true if the Widget singleton is also modal. + * + * @return True if the widget is modal. + */ + +const bool CNxWidget::isModal(void) const +{ + return m_widgetControl->isModal() & m_flags.modal; +} + +/** + * Insert the dimensions that this widget wants to have into the rect + * passed in as a parameter. All coordinates are relative to the widget's + * parent. + * + * @param rect Reference to a rect to populate with data. + */ + +void CNxWidget::getPreferredDimensions(CRect &rect) const +{ + rect = m_rect; +} + +/** + * Insert the properties of the space within this widget that is available + * for children into the rect passed in as a parameter. + * All coordinates are relative to this widget. + * + * @param rect Reference to a rect to populate with data. + */ + +void CNxWidget::getClientRect(CRect &rect) const +{ + if (m_flags.borderless) + { + rect.setX(0); + rect.setY(0); + rect.setWidth(getWidth()); + rect.setHeight(getHeight()); + } + else + { + rect.setX(m_borderSize.left); + rect.setY(m_borderSize.top); + rect.setWidth(getWidth() - (m_borderSize.left + m_borderSize.right)); + rect.setHeight(getHeight() - (m_borderSize.top + m_borderSize.bottom)); + } +} + +/** + * Insert the properties of the space within this widget that is + * available for children into the rect passed in as a parameter. + * Identical to getClientRect() except that all coordinates are + * absolute positions within the window. + * + * @param rect Reference to a rect to populate with data. + */ + +void CNxWidget::getRect(CRect &rect) const +{ + getClientRect(rect); + rect.setX(rect.getX() + getX()); + rect.setY(rect.getY() + getY()); +} + +/** + * Clips the supplied rect to the boundaries defined by this widget and + * this widget's parents. + * + * @param rect Reference to a rect to populate with data. + */ + +void CNxWidget::getRectClippedToHierarchy(CRect &rect) const +{ + // Copy the widget's properties into the rect. NOTE that if this is + // a child widget, getX() and getY() will return the actual X and Y + // positions (and not the parent-relative X and Y positions). + + rect.setX(getX()); + rect.setY(getY()); + rect.setWidth(getWidth()); + rect.setHeight(getHeight()); + + // And clip it + + clipRectToHierarchy(rect); +} + +/** + * Gets a pointer to the vector of all of the visible regions of this widget, + * including any covered by children. + * + * @return A pointer to a vector of all visible regions. + */ + +TNxArray<CRect> *CNxWidget::getForegroundRegions(void) +{ + return m_rectCache->getForegroundRegions(); +} + +/** + * Sets this widget's reference constant. This should be unique, + * at least amongst this widget's siblings. + * + * @param refcon The reference constant. + */ + +uint32_t CNxWidget::setRefcon(uint32_t refcon) +{ + uint32_t old = m_refcon; + m_refcon = refcon; + return old; +} + +/** + * Sets this widget's border state. + * + * @param isBorderless The border state. + */ + +void CNxWidget::setBorderless(bool borderless) +{ + m_flags.borderless = borderless; + invalidateVisibleRectCache(); +} + +/** + * Sets the font. + * + * @param font A pointer to the font to use. + */ + +void CNxWidget::setFont(CNxFont *font) +{ + m_style.font = font; +} + +/** + * Draws the visible regions of the widget and the widget's child widgets. + */ + +void CNxWidget::redraw(void) +{ + if (isDrawingEnabled()) + { + cacheVisibleRects(); + + if (m_rectCache->getBackgroundRegions()->size() > 0) + { + // Get the graphics port for drawing in this window + + CGraphicsPort *port = m_widgetControl->getGraphicsPort(); + + // Draw all visible rectangles + + for (int i = 0; i < m_rectCache->getBackgroundRegions()->size(); i++) + { + drawBorder(port); + drawContents(port); + } + } + + // Remember that the widget is no longer erased + + m_flags.erased = false; + drawChildren(); + } +} + +/** + * Erases the visible regions of the widget by redrawing the widgets + * behind it. + */ + +void CNxWidget::erase(void) +{ + if (!m_flags.erased) + { + cacheVisibleRects(); + + if (m_parent != (CNxWidget *)NULL) + { + m_parent->eraseWidget(this); + } + + // Remember that the widget has been erased + + m_flags.erased = true; + invalidateVisibleRectCache(); + } +} + +/** + * Enables the widget. + * + * @return True if the widget was enabled. + */ + +bool CNxWidget::enable(void) +{ + if (!m_flags.enabled) + { + m_flags.enabled = true; + onEnable(); + redraw(); + m_widgetEventHandlers->raiseEnableEvent(); + return true; + } + + return false; +} + +/** + * Disabled the widget. + * + * @return True if the widget was disabled. + */ + +bool CNxWidget::disable(void) +{ + if (m_flags.enabled) + { + m_flags.enabled = false; + onDisable(); + redraw(); + m_widgetEventHandlers->raiseDisableEvent(); + return true; + } + + return false; +} + +/** + * Erases the widget, marks it as deleted, and moves it to the CNxWidget + * deletion queue. Widgets are automatically deleted by the framework and + * should not be deleted externally. + */ + +void CNxWidget::close(void) +{ + if (!m_flags.deleted) + { + m_widgetEventHandlers->raiseCloseEvent(); + m_widgetEventHandlers->disable(); + + m_flags.deleted = true; + m_flags.drawingEnabled = false; + + // Unset clicked widget if necessary + + CNxWidget *clickedWidget = m_widgetControl->getClickedWidget(); + if (clickedWidget == this) + { + release(clickedWidget->getX(), clickedWidget->getY()); + } + + // Ensure the widget isn't running modally + + stopModal(); + erase(); + + if (m_parent != (CNxWidget *)NULL) + { + m_parent->closeChild(this); + } + } +} + +/** + * Erases the widget, removes it from the main hierarchy and sets it to + * invisible. Widgets hidden in this way will be partioned off from + * other widgets and will no longer be processed. + * + * @return True if the widget was shelved. + * @see unshelve() + */ + +bool CNxWidget::shelve(void) +{ + if (!m_flags.shelved) + { + m_widgetEventHandlers->raiseShelveEvent(); + m_widgetEventHandlers->disable(); + + m_flags.shelved = true; + m_flags.drawingEnabled = false; + + // Unset clicked widget if necessary + + CNxWidget *clickedWidget = m_widgetControl->getClickedWidget(); + if (clickedWidget == this) + { + release(clickedWidget->getX(), clickedWidget->getY()); + } + + // Ensure the widget isn't running modally + + stopModal(); + erase(); + + if (m_parent != (CNxWidget *)NULL) + { + m_parent->shelveChild(this); + } + return true; + } + + return false; +} + +/** + * Moves the widget back into the hierarchy and redraws it. Widgets shown + * in this way will be unpartioned and will be processed again. + * + * @return True if the widget was unshelved. + * @see shelve() + */ + +bool CNxWidget::unshelve(void) +{ + if (m_flags.shelved) + { + m_widgetEventHandlers->enable(); + m_widgetEventHandlers->raiseUnshelveEvent(); + + m_flags.drawingEnabled = true; + m_flags.shelved = false; + + if (m_parent != (CNxWidget *)NULL) + { + m_parent->moveShelvedToChildList(this); + m_parent->invalidateVisibleRectCache(); + } + + redraw(); + return true; + } + + return false; +} + +/** + * Draws the widget and makes it visible. + * Does not steal focus from other widgets. + * + * @return True if the widget was shown. + * @see hide() + */ + +bool CNxWidget::show(void) +{ + if (m_flags.hidden) + { + m_flags.hidden = false; + + // Ensure that widgets behind this do not draw over the + // top of the newly-visible widget + + m_parent->invalidateLowerWidgetsVisibleRectCache(this); + m_widgetEventHandlers->raiseShowEvent(); + redraw(); + return true; + } + + return false; +} + +/** + * Erases the widget and makes it invisible. + * Does not re-assign focus to another widget. + * + * @return True if the widget was hidden. + * @see show() + */ + +bool CNxWidget::hide(void) +{ + if (!m_flags.hidden) + { + m_flags.hidden = true; + + // Ensure the widget isn't running modally + + stopModal(); + m_widgetEventHandlers->raiseHideEvent(); + erase(); + return true; + } + + return false; +} + +/** + * Click this widget at the supplied coordinates. This should only be + * overridden in subclasses if the default click behaviour needs to be changed. + * If the subclassed widget should just respond to a standard click, + * the onClick() method should be overridden instead. + * + * @param x X coordinate of the click. + * @param y Y coordinate of the click. + * @return True if the click was successful. + */ + +bool CNxWidget::click(nxgl_coord_t x, nxgl_coord_t y) +{ + if (!isEnabled() || !checkCollision(x, y)) + { + return false; + } + + // Check for a double-click + + if (isDoubleClick(x, y)) + { + return doubleClick(x, y); + } + + // Work out which child was clicked + + for (int i = m_children.size() - 1; i > -1; i--) + { + if (m_children[i]->click(x, y)) + { + return true; + } + } + + // Ensure that the click has occurred on a region of this widget + // not obscured by its siblings + + if (!checkCollisionWithForegroundRects(x, y)) + { + return false; + } + + // Handle clicks on this + + m_flags.clicked = true; + + // Record data for double-click + + clock_gettime(CLOCK_REALTIME, &m_lastClickTime); + m_lastClickX = x; + m_lastClickY = y; + + // Take focus away from child widgets + + setFocusedWidget((CNxWidget *)NULL); + + // Tell controlling widget that the clicked widget has changed + + m_widgetControl->setClickedWidget(this); + + // Run any code in the inherited class + + onClick(x, y); + m_widgetEventHandlers->raiseClickEvent(x, y); + return true; +} + +/** + * Check if the click is a double-click. + * + * @param x X coordinate of the click. + * @param y Y coordinate of the click. + * @return True if the click is a double-click. + */ + +bool CNxWidget::isDoubleClick(nxgl_coord_t x, nxgl_coord_t y) +{ + // Check for a double-click + + if (m_flags.doubleClickable && hasFocus() && m_widgetControl->doubleClick()) + { + // Within the allowed region? + + if ((m_lastClickX > x - m_doubleClickBounds) && (m_lastClickX < x + m_doubleClickBounds)) + { + if ((m_lastClickY > y - m_doubleClickBounds) && (m_lastClickY < y + m_doubleClickBounds)) + { + return true; + } + } + } + + return false; +} + +/** + * Double-click this widget at the supplied coordinates. This + * should only be overridden in subclasses if the default + * double-click behaviour needs to be changed. If the subclassed + * widget should just respond to a standard double-click, the + * onDoubleClick() method should be overridden instead. + * + * @param x X coordinate of the click. + * @param y Y coordinate of the click. + * @return True if the click was successful. + */ + +bool CNxWidget::doubleClick(nxgl_coord_t x, nxgl_coord_t y) +{ + if (!isEnabled() || !checkCollision(x, y)) + { + return false; + } + + // Work out which child was clicked. Allow the + // child to determine if it has been double-clicked or not + // in case the second click has fallen on a different + // child to the first. + + for (int i = m_children.size() - 1; i > -1; i--) + { + if (m_children[i]->click(x, y)) + { + return true; + } + } + + // Ensure that the click has occurred on a region of this widget + // not obscured by its siblings + + if (!checkCollisionWithForegroundRects(x, y)) + { + return false; + } + + m_flags.clicked = true; + + // Record data for double-click + + clock_gettime(CLOCK_REALTIME, &m_lastClickTime); + m_lastClickX = x; + m_lastClickY = y; + + // Take focus away from child widgets + + setFocusedWidget((CNxWidget *)NULL); + + // Tell controlling widget that the clicked widget has changed + + m_widgetControl->setClickedWidget(this); + + onDoubleClick(x, y); + m_widgetEventHandlers->raiseDoubleClickEvent(x, y); + return true; +} + +/** + * Release this widget at the supplied coordinates. This should only be + * overridden in subclasses if the default release behaviour needs to be + * changed. If the subclassed widget should just respond to a standard + * release, the onRelease() method should be overridden instead. + * + * @param x X coordinate of the release. + * @param y Y coordinate of the release. + * @return True if the release was successful. + */ + +bool CNxWidget::release(nxgl_coord_t x, nxgl_coord_t y) +{ + if (!m_flags.clicked) + { + return false; + } + + m_flags.clicked = false; + stopDragging(x, y); + + if (m_widgetControl->getClickedWidget() == this) + { + m_widgetControl->setClickedWidget((CNxWidget *)NULL); + } + + // Determine which release event to fire + + if (checkCollision(x, y)) + { + onRelease(x, y); + + // Release occurred within widget; raise release + + m_widgetEventHandlers->raiseReleaseEvent(x, y); + } + else + { + onReleaseOutside(x, y); + + // Release occurred outside widget; raise release + + m_widgetEventHandlers->raiseReleaseOutsideEvent(x, y); + } + + return true; +} + +/** + * Drag the widget to the supplied coordinates. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + * @param vX The horizontal distance that the mouse was dragged. + * @param vY The vertical distance that the mouse was dragged. + * @return True if the drag was successful. + */ + +bool CNxWidget::drag(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t vX, nxgl_coord_t vY) +{ + if ((isEnabled()) && (m_flags.dragging)) + { + if ((vX != 0) || (vY != 0)) + { + onDrag(x, y, vX, vY); + m_widgetEventHandlers->raiseDragEvent(x, y, vX, vY); + } + + return true; + } + + return false; +} + +/** + * Send a keypress to the widget. + * + * @param key The keycode to send to the widget. + * @return True if the keypress was processed. + */ + +bool CNxWidget::keyPress(nxwidget_char_t key) +{ + if (!isEnabled()) + { + return false; + } + + // Raise keypress for this widget + + m_widgetEventHandlers->raiseKeyPressEvent(key); + + // Handle active child + + if (m_focusedChild != NULL) + { + m_focusedChild->keyPress(key); + } + + return true; +} + +/** + * Send a cursor control event to the widget. + * + * @param cursorControl The cursor control code o send to the widget. + * @return True if the cursor control was processed. + */ + +bool CNxWidget::cursorControl(ECursorControl control) +{ + if (!isEnabled()) + { + return false; + } + + // Raise cursor control for this widget + + m_widgetEventHandlers->raiseCursorControlEvent(control); + + // Handle active child + + if (m_focusedChild != NULL) + { + m_focusedChild->cursorControl(control); + } + + return true; +} + +/** + * Give the widget focus. + * + * @return True if the widget received focus correctly. + */ + +bool CNxWidget::focus(void) +{ + if (!isEnabled()) + { + return false; + } + + // Remember if the widget has focus + + bool hadFocus = m_flags.hasFocus; + m_flags.hasFocus = true; + + // Notify parent that this widget has focus + + if (m_parent != (CNxWidget *)NULL) + { + m_parent->setFocusedWidget(this); + } + + // Raise an event only if the widget did not have focus + + if (!hadFocus) + { + onFocus(); + + m_widgetEventHandlers->raiseFocusEvent(); + return true; + } + + return false; +} + +/** + * Remove focus from the widget. + * + * @return True if the widget lost focus correctly. + */ + +bool CNxWidget::blur(void) +{ + // Remember if the widget had focus + + bool hadFocus = m_flags.hasFocus; + + m_flags.hasFocus = false; + + // Take focus away from child widgets + + if (m_focusedChild != (CNxWidget *)NULL) + { + m_focusedChild->blur(); + m_focusedChild = (CNxWidget *)NULL; + m_widgetControl->clearFocusedWidget(this); + } + + // Raise an event only if the widget had focus + + if (hadFocus) + { + onBlur(); + + m_widgetEventHandlers->raiseBlurEvent(); + return true; + } + + return false; +} + +/** + * Move the widget to the new coordinates. + * Co-ordinates are relative to the parent widget. + * + * @param x The new x coordinate. + * @param y The new y coordinate. + * @return True if the move was successful. + */ + +bool CNxWidget::moveTo(nxgl_coord_t x, nxgl_coord_t y) +{ + // Enforce widget to stay within parent confines if necessary + + if (m_parent != (CNxWidget *)NULL) + { + if (!m_parent->isPermeable()) + { + CRect parentRect; + m_parent->getClientRect(parentRect); + + // Check x coordinate + + if (x < parentRect.getX()) + { + x = parentRect.getX(); + + // Check width against new value + + if (x + getWidth() > parentRect.getX2() + 1) + { + return false; + } + } + else if (x + getWidth() > parentRect.getX2() + 1) + { + x = (parentRect.getX() + parentRect.getX()) - getWidth(); + + // Check new x value + + if (x < parentRect.getX()) + { + return false; + } + } + + // Check y coordinate + + if (y < parentRect.getY()) + { + y = parentRect.getY(); + + // Check height against new value + + if (y + getHeight() > parentRect.getY2() + 1) + { + return false; + } + } + else if (y + getHeight() > parentRect.getY2() + 1) + { + y = (parentRect.getY() + parentRect.getY()) - getHeight(); + + // Check new y value + + if (y < parentRect.getY()) + { + return false; + } + } + } + } + + // Perform move if necessary + + if ((m_rect.getX() != x) || (m_rect.getY() != y)) + { + erase(); + + nxgl_coord_t oldX = m_rect.getX(); + nxgl_coord_t oldY = m_rect.getY(); + + m_rect.setX(x); + m_rect.setY(y); + + redraw(); + m_widgetEventHandlers->raiseMoveEvent(x, y, x - oldX, y - oldY); + return true; + } + + return false; +} + +/** + * Resize the widget to the new dimensions. + * + * @param width The new width. + * @param height The new height. + * @return True if the resize was successful. + */ + +bool CNxWidget::resize(nxgl_coord_t width, nxgl_coord_t height) +{ + // Enforce widget to stay within parent confines if necessary + + if (m_parent != (CNxWidget *)NULL) + { + if (!m_parent->isPermeable()) + { + CRect parentRect; + m_parent->getClientRect(parentRect); + + // Check width + + if (m_rect.getX() + width > parentRect.getX2() + 1) + { + width = parentRect.getX2() + 1 - m_rect.getX(); + } + + // Check height + + if (m_rect.getY() + height > parentRect.getY2() + 1) + { + height = parentRect.getY2() + 1 - m_rect.getY(); + } + } + } + + if (getWidth() != width || getHeight() != height) + { + // Remember if the widget is permeable + + bool wasPermeable = m_flags.permeable; + + // Remember if widget was drawing + + bool wasDrawEnabled = m_flags.drawingEnabled; + + m_flags.permeable = true; + erase(); + disableDrawing(); + + m_rect.setWidth(width); + m_rect.setHeight(height); + + // Handle visible region caching + + if (m_parent != (CNxWidget *)NULL) + { + m_parent->invalidateLowerWidgetsVisibleRectCache(this); + } + + onResize(width, height); + + // Reset the permeable value + + m_flags.permeable = wasPermeable; + + // Reset drawing value + + m_flags.drawingEnabled = wasDrawEnabled; + redraw(); + m_widgetEventHandlers->raiseResizeEvent(width, height); + return true; + } + + return false; +} + +/** + * Resize and move the widget in one operation. + * Only performs one redraw so it is faster than calling the + * two separate functions. + * + * @param x The new x coordinate. + * @param y The new y coordinate. + * @param width The new width. + * @param height The new height. + * @return True if the widget was adjusted successfully. + */ + +bool CNxWidget::changeDimensions(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height) +{ + bool wasDrawing = m_flags.drawingEnabled; + m_flags.drawingEnabled = false; + bool moved = moveTo(x, y); + m_flags.drawingEnabled = wasDrawing; + return (resize(width, height) | moved); +} + +/** + * Raises the widget to the top of its parent's widget stack. + * + * @return True if the raise was successful. + */ + +bool CNxWidget::raiseToTop(void) +{ + if (m_parent != (CNxWidget *)NULL) + { + if (m_parent->raiseWidgetToTop(this)) + { + m_widgetEventHandlers->raiseMoveForwardEvent(); + return true; + } + } + + return false; +} + +/** + * Lowers the widget to the bottom of its parent's widget stack. + * + * @return True if the lower was successful. + */ + +bool CNxWidget::lowerToBottom(void) +{ + if (m_parent != (CNxWidget *)NULL) + { + if (m_parent->lowerWidgetToBottom(this)) + { + m_widgetEventHandlers->raiseMoveBackwardEvent(); + return true; + } + } + + return false; +} + +/** + * Raises the supplied widget to the top of this widget's child stack. + * The supplied widget pointer must be a child of this widget. + * + * @param widget A pointer to the child widget to raise. + * @return True if the raise was successful. + */ + +bool CNxWidget::raiseWidgetToTop(CNxWidget *widget) +{ + // Locate widget in the stack + + int index = getWidgetIndex(widget); + + if ((index > -1) && (index < m_children.size() - 1)) + { + m_children.erase(index); + m_children.push_back(widget); + + widget->invalidateVisibleRectCache(); + + // Invalidate all widgets that collide with the depth-swapped widget + + for (int i = 0; i < m_children.size(); i++) + { + if (m_children[i]->checkCollision(widget)) + { + m_children[i]->invalidateVisibleRectCache(); + } + } + + widget->redraw(); + return true; + } + + return false; +} + +/** + * Lowers the supplied widget to the bottom of this widget's child stack. + * The supplied widget pointer must be a child of this widget. + * + * @param widget A pointer to the child widget to lower. + * @return True if the lower was successful. + */ + +bool CNxWidget::lowerWidgetToBottom(CNxWidget *widget) +{ + // Locate widget in the stack + + int index = getWidgetIndex(widget); + + if (index > 0) + { + widget->erase(); + + // Handle visible region caching + + widget->invalidateVisibleRectCache(); + invalidateLowerWidgetsVisibleRectCache(widget); + + m_children.erase(index); + m_children.insert(0, widget); + + widget->redraw(); + return true; + } + + return false; +} + +/** + * Moves the supplied child widget to the deletion queue. + * For framework use only. + * + * @param widget A pointer to the child widget. + */ + +void CNxWidget::moveChildToDeleteQueue(CNxWidget *widget) +{ + // Locate widget in main vector + + for (int i = 0; i < m_children.size(); i++) + { + if (m_children[i] == widget) + { + // Add widget to controlling widget's delete vector + + m_widgetControl->addToDeleteQueue(widget); + + // Remove widget from main vector + + m_children.erase(i); + break; + } + } +} + +/** + * Moves the supplied child widget to the shelved widget list. + * For framework use only. + * + * @param widget A pointer to the child widget. + * @return True if the widget was moved successfully. + * @see moveShelvedToChildList() + * @see hide() + */ + +bool CNxWidget::moveChildToShelvedList(CNxWidget *widget) +{ + // Locate widget in main vector + + for (int i = 0; i < m_children.size(); i++) + { + if (m_children[i] == widget) + { + // Add widget to shelved vector + + m_shelvedWidgets.push_back(widget); + + // Remove widget from main vector + + m_children.erase(i); + return true; + } + } + + return false; +} + +/** + * Moves the supplied child widget from the shelved list back + * to the child widget list. + * For framework use only. + * + * @param widget A pointer to the shelved widget. + * @return True if the widget was moved successfully. + * @see moveChildtoShelvedList() + * @see show() + */ + +bool CNxWidget::moveShelvedToChildList(CNxWidget *widget) +{ + // Locate widget in shelved vector + + for (int i = 0; i < m_shelvedWidgets.size(); i++) + { + if (m_shelvedWidgets[i] == widget) + { + // Add widget to end of main vector + + m_children.push_back(widget); + + // Remove widget from shelved vector + + m_shelvedWidgets.erase(i); + return true; + } + } + + return false; +} + +/** + * Sets the supplied widget as the focused child. The widget must + * be a child of this widget. + * + * @param widget A pointer to the child widget. + * @see getFocusedWidget() + */ + +void CNxWidget::setFocusedWidget(CNxWidget *widget) +{ + if (m_focusedChild != widget) + { + if (m_focusedChild != NULL) + { + // Blur the current active widget + + m_focusedChild->blur(); + } + } + + // Remember the new active widget + + m_focusedChild = widget; + + // Make this widget active too + + focus(); + + // Route keyboard input to the focused widget + + m_widgetControl->setFocusedWidget(this); +} + +/** + * Checks if the supplied coordinates collide with this widget. + * + * @param x The x coordinate to check. + * @param y The y coordinate to check. + * @return True if a collision occurred. + */ + +bool CNxWidget::checkCollision(nxgl_coord_t x, nxgl_coord_t y) const +{ + if (isHidden()) + { + return false; + } + + // Get the clipped rect + + CRect rect; + getRectClippedToHierarchy(rect); + return rect.contains(x, y); +} + +/** + * Checks if the supplied rectangle definition collides with this widget. + * + * @param x The x coordinate of the rectangle to check. + * @param y The y coordinate of the rectangle to check. + * @param width The width of the rectangle to check. + * @param height The height of the rectangle to check. + * @return True if a collision occurred. + */ + +bool CNxWidget::checkCollision(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height) const +{ + if (isHidden()) + { + return false; + } + + // Get the clipped rect + + CRect rect; + getRectClippedToHierarchy(rect); + return rect.intersects(CRect(x, y, width, height)); +} + +/** + * Checks if the supplied widget collides with this widget. + * + * @param widget A pointer to another widget to check for collisions with. + * @return True if a collision occurred. + */ + +bool CNxWidget::checkCollision(CNxWidget *widget) const +{ + // Get the clipped rect + + CRect rect; + widget->getRectClippedToHierarchy(rect); + return rect.intersects(m_rect); +} + +/** + * Invalidate the visible region cache for all widgets below the supplied + * widget in this widget's child stack. This will cause those widgets to + * + * recalculate their visible regions next time they try to draw themselves. + * @param widget A pointer to a child widget. + */ + +void CNxWidget::invalidateLowerWidgetsVisibleRectCache(CNxWidget *widget) +{ + // Find the widget + + int widgetIndex = getWidgetIndex(widget); + + // Invalidate lower widgets + + for (int i = widgetIndex - 1; i > -1; i--) + { + if (m_children[i]->checkCollision(widget)) + { + m_children[i]->invalidateVisibleRectCache(); + } + } +} + +/** + * Adds a widget to this widget's child stack. The widget is added to the + * top of the stack. Note that the widget can only be added if it is not + * already a child of another widget. + * + * @param widget A pointer to the widget to add to the child list. + * @see insertWidget() + */ + +void CNxWidget::addWidget(CNxWidget *widget) +{ + if (widget->getParent() == NULL) + { + widget->setParent(this); + m_children.push_back(widget); + + // Should the widget steal the focus? + + if (widget->hasFocus()) + { + setFocusedWidget(widget); + } + + widget->enableDrawing(); + invalidateVisibleRectCache(); + widget->redraw(); + } +} + +/** + * Inserts a widget into this widget's child stack at the bottom of the + * stack. Note that the widget can only be added if it is not already + * a child of another widget. + * + * @param widget A pointer to the widget to add to the child list. + * @see addWidget() + */ + +void CNxWidget::insertWidget(CNxWidget *widget) +{ + if (widget->getParent() == NULL) + { + widget->setParent(this); + m_children.insert(0, widget); + + widget->enableDrawing(); + invalidateVisibleRectCache(); + widget->redraw(); + } +} + +/** + * Rebuild the list of this widget's visible regions + */ + +void CNxWidget::cacheVisibleRects(void) const +{ + m_rectCache->cache(); +} + +/** + * Mark this widget's visible region cache as invalid, and do the same + * to its child widgets. + */ + +void CNxWidget::invalidateVisibleRectCache(void) +{ + m_rectCache->invalidate(); + + // Invalidate child cache + + for (int i = 0; i < m_children.size(); i++) + { + m_children[i]->invalidateVisibleRectCache(); + } +} + +/** + * Erase a child widget by drawing the widgets behind it. + * + * @param widget The child widget to erase. + */ + +void CNxWidget::eraseWidget(CNxWidget *widget) +{ + // Locate the widget + + int widgetIndex = getWidgetIndex(widget); + + // Ensure rect cache is up to date + + widget->cacheVisibleRects(); + + // Order all lower widgets to redraw themselves based on the erased widget's + // visible rect cache + + for (int i = widgetIndex - 1; i > -1; i--) + { + m_children[i]->redrawDirty(widget->getForegroundRegions(), widget); + } + + // Order this widget to redraw itself based on any remaining rectangles + // in the erased widget's rect cache + + redrawDirty(widget->getForegroundRegions(), widget); + invalidateVisibleRectCache(); +} + +/** + * Redraw any visible regions of this widget that have become corrupted. + * + * @param invalidRects A list of corrupt regions. + * @param sender A pointer to the widget that corrupted the regions. + */ + +void CNxWidget::redrawDirty(TNxArray<CRect> *invalidRects, CNxWidget *sender) +{ + if (isDrawingEnabled()) + { + // Draw any children first + + redrawDirtyChildren(invalidRects, sender); + + // Create an array that will contain all of the rects from the + // original array that overlap this widget + + TNxArray<CRect> *overlappingRects = new TNxArray<CRect>(); + + // Remove any non-overlapping rectangles from dirty vector and add to + // overlapping vector + + m_rectCache->splitRectangles(invalidRects, overlappingRects, sender); + + // Create an array that will contain all of the rects that overlap this + // widget clipped to its parent + + TNxArray<CRect> *rectsToDraw = new TNxArray<CRect>(); + + // Split from overlappingRects into rectsToDraw, giving us an array + // of rects that overlap only the visible portions of this widget + + m_rectCache->splitRectangles(overlappingRects, rectsToDraw, sender); + + // Get the graphics port for drawing in this window + + CGraphicsPort *port = m_widgetControl->getGraphicsPort(); + + // Draw the dirty rects + + if (rectsToDraw->size() > 0) + { + for (int i = 0; i < rectsToDraw->size(); i++) + { + drawBorder(port); + drawContents(port); + } + } + + // Copy all of the overlapping rects we didn't draw back to the main + // array of rects that need to be drawn by another widget + + for (int i = 0; i < overlappingRects->size(); i++) + { + invalidRects->push_back(overlappingRects->at(i)); + } + + // Clean up + + delete overlappingRects; + delete rectsToDraw; + } +} + +/** + * Clips a rectangular region to the dimensions of this widget and its ancestors. + * + * @param rect The region that needs to be clipped. + */ + +void CNxWidget::clipRectToHierarchy(CRect &rect) const { + + const CNxWidget *parent = m_parent; + const CNxWidget *widget = this; + CRect thisRect; + + while (parent != NULL) + { + // Standard widgets can draw into client space + + parent->getClientRect(thisRect); + + // Adjust rect to screen space + + thisRect.offset(parent->getX(), parent->getY()); + rect.clipToIntersect(thisRect); + + // Send up to parent + + widget = parent; + parent = parent->getParent(); + } +} + + /** + * Swaps the depth of the supplied child widget. + * + * @param widget A pointer to the child widget that needs to swap depths. + * @return True if the swap was successful. + */ + +bool CNxWidget::swapWidgetDepth(CNxWidget *widget) +{ + // Can we swap? + + if (m_children.size() > 1) + { + int widgetSource = 0; + int widgetDest = 0; + + // Locate the widget in the vector + + widgetSource = getWidgetIndex(widget); + + // Attempt to raise up + + int i = getHigherVisibleWidget(widgetSource); + if (i > -1) + { + // Raise + + widgetDest = i; + } + else + { + // Lower to bottom of stack + + widgetDest = 0; + } + + // Erase the widget from the screen + + eraseWidget(widget); + + // Swap + + CNxWidget *tmp = m_children[widgetSource]; + m_children[widgetSource] = m_children[widgetDest]; + m_children[widgetDest] = tmp; + + // Invalidate the widgets below the top affected widget + + if (widgetSource < widgetDest) + { + // Source lower; invalidate from dest down + + m_children[widgetDest]->invalidateVisibleRectCache(); + invalidateLowerWidgetsVisibleRectCache(m_children[widgetDest]); + } + else + { + // Dest lower; invalidate from source down + + m_children[widgetSource]->invalidateVisibleRectCache(); + invalidateLowerWidgetsVisibleRectCache(m_children[widgetSource]); + } + + // Redraw the widget + + widget->redraw(); + return true; + } + + return false; +} + +/** + * Swap the depth of this widget. + * + * @return True if the swap was successful. + */ + +bool CNxWidget::swapDepth(void) +{ + if (m_parent != (CNxWidget *)NULL) + { + return m_parent->swapWidgetDepth(this); + } + + return false; +} + +/** + * Remove this widget from the widget hierarchy. Returns + * responsibility for deleting the widget back to the developer. + * Does not unregister the widget from the VBL system. + * Does not erase the widget from the display. + * + * @return True if the widget was successfully removed. + */ + +bool CNxWidget::remove(void) +{ + if (m_parent != (CNxWidget *)NULL) + { + return m_parent->removeChild(this); + } + + return false; +} + +/** + * Remove a child widget from the widget hierarchy. Returns + * responsibility for deleting the widget back to the developer. + * Does not unregister the widget from the VBL system. + * Does not erase the widget from the display. + * + * @param widget Pointer to the widget to remove from the hierarchy. + * @return True if the widget was succesfully removed. + */ + +bool CNxWidget::removeChild(CNxWidget *widget) +{ + // Do we need to make another widget active? + + if (m_focusedChild == widget) + { + m_focusedChild = (CNxWidget *)NULL; + m_widgetControl->clearFocusedWidget(this); + } + + // Unset clicked widget if necessary + + CNxWidget *clickedWidget = m_widgetControl->getClickedWidget(); + if (clickedWidget == widget) + { + clickedWidget->release(clickedWidget->getX(), clickedWidget->getY()); + } + + // Divorce child from parent + + widget->setParent((CNxWidget *)NULL); + widget->disableDrawing(); + + // Locate widget in main vector + + for (int i = 0; i < m_children.size(); i++) + { + if (m_children[i] == widget) + { + // Remove widget from main vector + + m_children.erase(i); + return true; + } + } + + // Try to locate in shelved vector + + for (int i = 0; i < m_shelvedWidgets.size(); i++) + { + if (m_shelvedWidgets[i] == widget) + { + // Divorce child from parent + + m_shelvedWidgets[i]->setParent((CNxWidget *)NULL); + + // Remove widget from shelved vector + + m_shelvedWidgets.erase(i); + widget->disableDrawing(); + return true; + } + } + + return false; +} + +/** + * Run the widget modally. + */ + +void CNxWidget::goModal(void) +{ + // Remember that we're running modally + + m_flags.modal = true; + + // Steal focus + + focus(); + + // Loop until no longer modal + + while (isModal()) + { + // Process pending events + + bool interestingEvent = m_widgetControl->pollEvents(this); + + // Did any interesting events occur? + + if (!interestingEvent) + { + // No, give up the CPU until something interesting happens. + + m_widgetControl->waitForModalEvent(); + } + } +} + +/** + * Get the index of the specified child 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 CNxWidget::getWidgetIndex(const CNxWidget *widget) const +{ + for (int i = 0; i < m_children.size(); i++) + { + if (m_children[i] == widget) + { + return i; + } + } + + return -1; +} + +/** + * Get the child widget at the specified index. + * + * @param index Index of the child to retrieve. + * @return Pointer to the child at the specified index. + */ + +const CNxWidget *CNxWidget::getChild(const int index) const +{ + if (index < (int)m_children.size()) + { + return m_children[index]; + } + return (CNxWidget *)NULL; +} + +/** + * Sets the border size. The border cannot be drawn over in the + * drawContents() method. + * + * @param borderSize The new border size. + */ + +void CNxWidget::setBorderSize(const WidgetBorderSize &borderSize) +{ + m_borderSize.top = borderSize.top; + m_borderSize.right = borderSize.right; + m_borderSize.bottom = borderSize.bottom; + m_borderSize.left = borderSize.left; +} + +/** + * Use the provided widget style + */ + +void CNxWidget::useWidgetStyle(const CWidgetStyle *style) +{ + m_style.colors.background = style->colors.background; + m_style.colors.selectedBackground = style->colors.selectedBackground; + m_style.colors.shineEdge = style->colors.shineEdge; + m_style.colors.shadowEdge = style->colors.shadowEdge; + m_style.colors.highlight = style->colors.highlight; + m_style.colors.disabledText = style->colors.disabledText; + m_style.colors.enabledText = style->colors.enabledText; + m_style.colors.selectedText = style->colors.selectedText; + m_style.font = style->font; +} + +/** + * Checks if the supplied coordinates collide with a portion of this widget + * that is not obscured by its siblings, but that may be obscured by + * its children. + * + * @param x X coordinate of the click. + * @param y Y coordinate of the click. + * @return True if a collision occurred; false if not. + */ + +bool CNxWidget::checkCollisionWithForegroundRects(nxgl_coord_t x, nxgl_coord_t y) const +{ + if (isHidden()) + { + return false; + } + + cacheVisibleRects(); + + CRect *rect; + for (int i = 0; i < m_rectCache->getForegroundRegions()->size(); ++i) + { + rect = &(m_rectCache->getForegroundRegions()->at(i)); + if (rect->contains(x, y)) + { + return true; + } + } + + return false; +} + +/** + * Draw all visible regions of this widget's children. + */ + +void CNxWidget::drawChildren(void) +{ + for (int i = 0; i < m_children.size(); i++) + { + m_children[i]->redraw(); + } +} + +/** + * Erase and remove the supplied child widget from this widget and + * send it to the deletion queue. + * + * @param widget The widget to close. + * @see close(). + */ + +void CNxWidget::closeChild(CNxWidget *widget) +{ + if (widget == NULL) + { + return; + } + + // Ensure widget knows it is being closed + + widget->close(); + + // Do we need to make another widget active? + + if (m_focusedChild == widget) + { + m_focusedChild = (CNxWidget *)NULL; + m_widgetControl->clearFocusedWidget(this); + + // Try to choose highest widget + + for (int i = m_children.size() - 1; i > -1; i--) + { + if ((m_children[i] != widget) && (!m_children[i]->isHidden())) + { + m_focusedChild = m_children[i]; + } + } + + // Where should the focus go? + + if (m_focusedChild != NULL) + { + // Send focus to the new active widget + + m_focusedChild->focus(); + + // Route keyboard input to the focused widget + + m_widgetControl->setFocusedWidget(this); + } + else + { + // Give focus to this + + setFocusedWidget((CNxWidget *)NULL); + } + } + + moveChildToDeleteQueue(widget); +} + +/** + * Erase the supplied child widget and move it out of the main child + * list into the shelved list. The widget remains in memory and can + * be restored by calling "unshelve()" on the widget. + * + * @param widget The widget to hide. + */ + +void CNxWidget::shelveChild(CNxWidget *widget) +{ + if (widget == NULL) + { + return; + } + + // Ensure widget knows it is being shelved + + widget->shelve(); + + // Do we need to give another widget focus? + + if (m_focusedChild == widget) + { + m_focusedChild = (CNxWidget *)NULL; + m_widgetControl->clearFocusedWidget(this); + + // Try to choose highest widget + + for (int i = m_children.size() - 1; i > -1; i--) + { + if ((m_children[i] != widget) && (!m_children[i]->isHidden())) + { + m_focusedChild = m_children[i]; + } + } + + // Where should the focus go? + + if (m_focusedChild != NULL) + { + // Send focus to the new active widget + + m_focusedChild->focus(); + + // Route keyboard input to the focused widget + + m_widgetControl->setFocusedWidget(this); + } + else + { + // Give focus to this + + setFocusedWidget((CNxWidget *)NULL); + } + } + + moveChildToShelvedList(widget); +} + + /** + * Redraws all regions of child widgets that fall within the invalidRects + * regions. + * + * @param invalidRects List of invalid regions that need to be redrawn. + * @param sender Pointer to the widget that initiated the redraw. + */ + +void CNxWidget::redrawDirtyChildren(TNxArray<CRect> *invalidRects, CNxWidget *sender) +{ + for (int i = m_children.size() - 1; i > -1 ; i--) + { + if (invalidRects->size() > 0) + { + if (m_children.at(i) != sender) + { + m_children[i]->redrawDirty(invalidRects, sender); + } + } + else + { + break; + } + } +} + +/** + * Get the index of the next visible widget higher up the z-order. + * + * @param startIndex The starting index. + * @return The index of the next highest visible widget. + */ + +const int CNxWidget::getHigherVisibleWidget(const int startIndex) const +{ + for (int i = startIndex; i < m_children.size(); i++) + { + if (!m_children[i]->isHidden()) + { + return i; + } + } + + return -1; +} + +/** + * Get the index of the next visible widget lower down the z-order. + * + * @param startIndex The starting index. + * @return The index of the next lowest visible widget. + */ + +const int CNxWidget::getLowerVisibleWidget(const int startIndex) const +{ + for (int i = startIndex; i > -1; i--) + { + if (!m_children[i]->isHidden()) + { + return i; + } + } + + return -1; +} + +/** + * Notify this widget that it is being dragged, and set its drag point. + * + * @param x The x coordinate of the drag position relative to this widget. + * @param y The y coordinate of the drag position relative to this widget. + */ + +void CNxWidget::startDragging(nxgl_coord_t x, nxgl_coord_t y) +{ + if (m_flags.draggable) + { + m_flags.dragging = true; + m_flags.clicked = true; + m_grabPointX = x - getX(); + m_grabPointY = y - getY(); + m_newX = m_rect.getX(); + m_newY = m_rect.getY(); + + onDragStart(); + } +} + +/** + * Notify this widget that it is no longer being dragged. + */ + +void CNxWidget::stopDragging(nxgl_coord_t x, nxgl_coord_t y) +{ + if (m_flags.dragging) + { + onDragStop(); + m_flags.dragging = false; + m_widgetEventHandlers->raiseDropEvent(x, y); + } +} diff --git a/NxWidgets/libnxwidgets/src/cnxwindow.cxx b/NxWidgets/libnxwidgets/src/cnxwindow.cxx new file mode 100644 index 000000000..fd4cc6ef2 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cnxwindow.cxx @@ -0,0 +1,342 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cnxwindow.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cwidgetcontrol.hxx" +#include "cnxwindow.hxx" +#include "cbitmap.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param hNxServer Handle to the NX server. + */ + +CNxWindow::CNxWindow(NXHANDLE hNxServer, CWidgetControl *pWidgetControl) + : CCallback(pWidgetControl), m_hNxServer(hNxServer), m_hNxWindow(0), + m_widgetControl(pWidgetControl) +{ + // Create the CGraphicsPort instance for this window + + m_widgetControl->createGraphicsPort(static_cast<INxWindow*>(this)); +} + +/** + * Destructor. + */ + +CNxWindow::~CNxWindow(void) +{ + // Release the window. We do not release the widget control + // instance. The lifetime of that instance is owned by he-who- + // constructed-us. + + (void)nx_closewindow(m_hNxWindow); +} + +/** + * Creates a new window. Window creation is separate from + * object instantiation so that failures can be reported. + * + * @return True if the window was successfully opened. + */ + +bool CNxWindow::open(void) +{ + // Get the C-callable callback vtable + + FAR struct nx_callback_s *vtable = getCallbackVTable(); + + // Create the window + + m_hNxWindow = nx_openwindow(m_hNxServer, vtable, (FAR void *)m_widgetControl); + return m_hNxWindow != NULL; +} + +/** + * Request the position and size information of the window. The values + * will be returned asynchronously through the client callback method. + * The GetPosition() method may than be called to obtain the positional + * data as provided by the callback. + * + * @return True on success, false on any failure. + */ + +bool CNxWindow::requestPosition(void) +{ + // Request the window position + + return nx_getposition(m_hNxWindow) == OK; +} + +/** + * Get the position of the window in the physical display coordinates + * (as reported by the NX callback). + * + * @return The position. + */ + +bool CNxWindow::getPosition(FAR struct nxgl_point_s *pPos) +{ + return m_widgetControl->getWindowPosition(pPos); +} + +/** + * Get the size of the window (as reported by the NX callback). + * + * @return The size. + */ + +bool CNxWindow::getSize(FAR struct nxgl_size_s *pSize) +{ + return m_widgetControl->getWindowSize(pSize); +} + +/** + * Set the position and size of the window. + * + * @param pPos The new position of the window. + * @return True on success, false on any failure. + */ + +bool CNxWindow::setPosition(FAR const struct nxgl_point_s *pPos) +{ + // Set the window size and position + + return nx_setposition(m_hNxWindow, pPos) == OK; +} + +/** + * Set the size of the selected window. + * + * @param pSize The new size of the window. + * @return True on success, false on any failure. + */ + +bool CNxWindow::setSize(FAR const struct nxgl_size_s *pSize) +{ + // Set the window size + + return nx_setsize(m_hNxWindow, pSize) == OK; +} + +/** + * Bring the window to the top of the display. + * + * @return True on success, false on any failure. + */ + +bool CNxWindow::raise(void) +{ + // Raise the window to the top of the display + + return nx_raise(m_hNxWindow) == OK; +} + +/** + * Lower the window to the bottom of the display. + * + * @return True on success, false on any failure. + */ + +bool CNxWindow::lower(void) +{ + // Lower the window to the bottom of the display + + return nx_lower(m_hNxWindow) == OK; +} + +/** + * Set an individual pixel in the window with the specified color. + * + * @param pPos The location of the pixel to be filled. + * @param color The color to use in the fill. + * + * @return True on success; false on failure. + */ + +bool CNxWindow::setPixel(FAR const struct nxgl_point_s *pPos, + nxgl_mxpixel_t color) +{ + // Set an individual pixel to the specified color + + return nx_setpixel(m_hNxWindow, pPos, &color) == OK; +} + +/** + * Fill the specified rectangle in the window with the specified color. + * + * @param pRect The location to be filled. + * @param color The color to use in the fill. + * + * @return True on success; false on failure. + */ + +bool CNxWindow::fill(FAR const struct nxgl_rect_s *pRect, + nxgl_mxpixel_t color) +{ + // Fill a rectangular region with a solid color + + return nx_fill(m_hNxWindow, pRect, &color) == OK; +} + +/** + * Get the raw contents of graphic memory within a rectangular region. NOTE: + * Since raw graphic memory is returned, the returned memory content may be + * the memory of windows above this one and may not necessarily belong to + * this window unless you assure that this is the top window. + * + * @param rect The location to be copied + * @param dest - The describes the destination bitmap to receive the + * graphics data. + */ + +void CNxWindow::getRectangle(FAR const struct nxgl_rect_s *rect, struct SBitmap *dest) +{ + // Get a rectangule region from the window + + (void)nx_getrectangle(m_hNxWindow, rect, 0, (FAR uint8_t*)dest->data, dest->stride); +} +/** + * Fill the specified trapezoidal region in the window with the specified + * color. + * + * @param pClip Clipping rectangle relative to window (may be null). + * @param pTrap The trapezoidal region to be filled. + * @param color The color to use in the fill. + * + * @return True on success; false on failure. + */ + +bool CNxWindow::fillTrapezoid(FAR const struct nxgl_rect_s *pClip, + FAR const struct nxgl_trapezoid_s *pTrap, + nxgl_mxpixel_t color) +{ + // Fill a trapezoidal region with a solid color + + return nx_filltrapezoid(m_hNxWindow, pClip, pTrap, &color) == OK; +} + +/** + * Fill the specified line in the window with the specified color. + * + * @param vector - Describes the line to be drawn + * @param width - The width of the line + * @param color - The color to use to fill the line + * + * @return True on success; false on failure. + */ + +bool CNxWindow::drawLine(FAR struct nxgl_vector_s *vector, + nxgl_coord_t width, nxgl_mxpixel_t color) +{ + // Draw a line with the specified color + + return nx_drawline(m_hNxWindow, vector, width, &color) == OK; +} + +/** + * Draw a filled circle at the specified position, size, and color. + * + * @param center The window-relative coordinates of the circle center. + * @param radius The radius of the rectangle in pixels. + * @param color The color of the rectangle. + */ + +bool CNxWindow::drawFilledCircle(struct nxgl_point_s *center, nxgl_coord_t radius, + nxgl_mxpixel_t color) +{ + return nx_fillcircle(m_hNxWindow, center, radius, &color) == OK; +} + +/** + * Move a rectangular region within the window. + * + * @param pRect Describes the rectangular region to move. + * @param pOffset The offset to move the region. + * + * @return True on success; false on failure. + */ + +bool CNxWindow::move(FAR const struct nxgl_rect_s *pRect, + FAR const struct nxgl_point_s *pOffset) +{ + // Move a rectangular region of the display + + return nx_move(m_hNxWindow, pRect, pOffset) == OK; +} + +/** + * Copy a rectangular region of a larger image into the rectangle in the + * specified window. The source image is treated as an opaque image. + * + * @param pDest Describes the rectangular on the display that will receive + * the bitmap. + * @param pSrc The start of the source image. + * @param pOrigin the pOrigin of the upper, left-most corner of the full + * bitmap. Both pDest and pOrigin are in window coordinates, however, + * pOrigin may lie outside of the display. + * @param stride The width of the full source image in bytes. + * + * @return True on success; false on failure. + */ + +bool CNxWindow::bitmap(FAR const struct nxgl_rect_s *pDest, + FAR const void *pSrc, + FAR const struct nxgl_point_s *pOrigin, + unsigned int stride) +{ + // Copy a rectangular bitmap image in a region on the display + + return nx_bitmap(m_hNxWindow, pDest, &pSrc, pOrigin, stride) == OK; +} diff --git a/NxWidgets/libnxwidgets/src/cprogressbar.cxx b/NxWidgets/libnxwidgets/src/cprogressbar.cxx new file mode 100644 index 000000000..5f29a3f7e --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cprogressbar.cxx @@ -0,0 +1,230 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cprogressbar.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <cstdio> +#include <cstring> + +#include <nuttx/nx/nxglib.h> + +#include "cprogressbar.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CButton Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The widget control for the display. + * @param x The x coordinate of the progress bar, relative to its parent. + * @param y The y coordinate of the progress bar, relative to its parent. + * @param width The width of the progress bar. + * @param height The height of the progress bar. + */ + +CProgressBar::CProgressBar(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height) +: CNxWidget(pWidgetControl, x, y, width, height, 0) +{ + m_minimumValue = 0; + m_maximumValue = 0; + m_value = 0; + m_showPercentageText = true; + m_flags.borderless = false; +} + +/** + * Set the value that of the progress bar. + * + * @param value The new value. + */ + +void CProgressBar::setValue(const int16_t value) +{ + m_value = value; + + // Limit to max/min values + + if (m_value > m_maximumValue) + { + m_value = m_maximumValue; + } + + if (m_value < m_minimumValue) + { + m_value = m_minimumValue; + } + + redraw(); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CProgressBar::drawContents(CGraphicsPort *port) +{ + // Get the drawing window, accounting for the presence of any border + + CRect rect; + getRect(rect); + + // Calculate ratio of pixels to value range (max fractional value of 255) + + uint32_t ratio = ((uint32_t)rect.getWidth() << 8) / (uint32_t)(m_maximumValue - m_minimumValue); + + // Convert value using ratio, rounding up and shifting down + + int16_t barWidth = ((m_value * ratio) + 128) >> 8; + + // Draw filled region + + port->drawFilledRect(rect.getX(), rect.getY(), barWidth, rect.getHeight(), getHighlightColor()); + + // Draw unfilled background + + if (barWidth < rect.getWidth()) + { + port->drawFilledRect(rect.getX() + barWidth, rect.getY(), + rect.getWidth() - barWidth, rect.getHeight(), + getBackgroundColor()); + } + + // Draw completion percentage text + + if (m_showPercentageText) + { + char text[6]; + sprintf(text, "%d%%", (100 * m_value) / (m_maximumValue - m_minimumValue)); + + struct nxgl_point_s pos; + pos.x = rect.getX() + + ((rect.getWidth() - getFont()->getStringWidth(text)) >> 1); + pos.y = rect.getY() + + ((rect.getHeight() - getFont()->getHeight()) >> 1); + + // Determine the background and text color + + nxgl_mxpixel_t textColor; + + if (!isEnabled()) + { + textColor = getDisabledTextColor(); + } + else + { + textColor = getEnabledTextColor(); + } + + // And draw the text using the selected color + + port->drawText(&pos, &rect, getFont(), text, 0, strlen(text), + textColor); + } +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CProgressBar::drawBorder(CGraphicsPort *port) +{ + // Stop drawing if the widget indicates it should not have an outline + + if (!isBorderless()) + { + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), + getShadowEdgeColor(), getShineEdgeColor()); + } +} diff --git a/NxWidgets/libnxwidgets/src/cradiobutton.cxx b/NxWidgets/libnxwidgets/src/cradiobutton.cxx new file mode 100644 index 000000000..86ad4118f --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cradiobutton.cxx @@ -0,0 +1,225 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cradiobutton.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "cwidgetcontrol.hxx" +#include "cradiobutton.hxx" +#include "cradiobuttongroup.hxx" +#include "cgraphicsport.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" +#include "singletons.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CLabel Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The controlling widget for the display. + * @param x The x coordinate of the radio button, relative to its + * parent. + * @param y The y coordinate of the radio button, relative to its + * parent. + * @param width The width of the radio button. + * @param height The height of the radio button. + * @param style The style that the widget should use. If this is not + * specified, the widget will use the values stored in the global + * defaultCWidgetStyle object. The widget will copy the properties of + * the style into its own internal style object. + */ + +CRadioButton::CRadioButton(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + CWidgetStyle *style) +: CButton(pWidgetControl, x, y, width, height, *NXWidgets::g_nullString, style) +{ + m_state = RADIO_BUTTON_STATE_OFF; + m_flags.borderless = true; +} + +/** + * Set the state of the radio button. + * + * @param state The new radio button state. + */ + +void CRadioButton::setState(CRadioButton::RadioButtonState state) +{ + if (m_state != state) + { + m_state = state; + + if (m_state != RADIO_BUTTON_STATE_OFF) + { + ((CRadioButtonGroup*)m_parent)->setSelectedWidget(this); + } + + m_widgetEventHandlers->raiseValueChangeEvent(); + redraw(); + } +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CRadioButton::drawContents(CGraphicsPort *port) +{ + // Get the X/Y position of the drawable region within the Label + + nxgl_coord_t x = getX(); + nxgl_coord_t y = getY(); + + nxgl_coord_t width = getWidth(); + nxgl_coord_t height = getHeight(); + + // Include and offset for the border + + if (!m_flags.borderless) + { + x += m_borderSize.left; + y += m_borderSize.top; + + width -= (m_borderSize.left + m_borderSize.right); + height -= (m_borderSize.top + m_borderSize.bottom); + } + + // Decide which glyph to draw + + const struct SBitmap *glyph; + + switch (m_state) + { + default: + case RADIO_BUTTON_STATE_ON: + glyph = &g_radioButtonOn; + break; + + case RADIO_BUTTON_STATE_OFF: + glyph = &g_radioButtonOff; + break; + + case RADIO_BUTTON_STATE_MU: + glyph = &g_radioButtonMu; + break; + } + + // Don't exceed the size of the glyph + + if (width > glyph->width) + { + width = glyph->width; + } + + if (height > glyph->height) + { + height = glyph->height; + } + + // Draw button + + port->drawBitmap(x, y, width, height, glyph, 0, 0, + CONFIG_NXWIDGETS_TRANSPARENT_COLOR); +} + +/** + * Sets the radiobutton's state to "on". + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CRadioButton::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + setState(RADIO_BUTTON_STATE_ON); +} diff --git a/NxWidgets/libnxwidgets/src/cradiobuttongroup.cxx b/NxWidgets/libnxwidgets/src/cradiobuttongroup.cxx new file mode 100644 index 000000000..b1d75f625 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cradiobuttongroup.cxx @@ -0,0 +1,344 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cradiobutton.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "cradiobuttongroup.hxx" +#include "cradiobutton.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CLabel Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. Note that the group determines its width and height + * from the position and dimensions of its children. + * + * @param pWidgetControl The controlling widget for the display. + * @param x The x coordinate of the group. + * @param y The y coordinate of the group. + * @param style The style that the button should use. If this is not + * specified, the button will use the global default widget + * style. + */ + +CRadioButtonGroup::CRadioButtonGroup(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + CWidgetStyle *style) +: CNxWidget(pWidgetControl, x, y, 0, 0, WIDGET_BORDERLESS, style) +{ + m_widgetControl = pWidgetControl; + m_selectedWidget = (CRadioButton *)NULL; +} + +/** + * Simple method for adding a new radio button to the group. + * This should be used in preference to the usual addWidget() method, + * as this method automatically resizes the group. + * + * @param x The x coordinate of the new button, relative to this + * widget. + * @param y The y coordinate of the new button, relative to this + * widget. + * @param width The width of the new button. + * @param height The height of the new button. + */ + +CRadioButton *CRadioButtonGroup::newRadioButton(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height) +{ + CRadioButton *newButton = new CRadioButton(m_widgetControl, x, y, width, height, &m_style); + newButton->addWidgetEventHandler(this); + addWidget(newButton); + + // Do we need to resize? + + nxgl_coord_t newWidth = getWidth(); + nxgl_coord_t newHeight = getHeight(); + + if (newWidth < x + width) + { + newWidth = x + width; + } + + if (newHeight < y + height) + { + newHeight = y + height; + } + + resize(newWidth, newHeight); + return newButton; +} + +/** + * Gets a pointer to the selected widget. + * + * @return Pointer to the selected widget. + */ + +const CRadioButton *CRadioButtonGroup::getSelectedWidget(void) const +{ + return (CRadioButton *)m_selectedWidget; +} + +/** + * Gets the index of the selected widget. + * + * @return The index of the selected widget. + */ + +const int CRadioButtonGroup::getSelectedIndex(void) const +{ + for (int i = 0; i < m_children.size(); i++) + { + if (((CRadioButton*)m_children[i]) == m_selectedWidget) + { + return i; + } + } + + // Nothing selected + + return -1; +} + +/** + * Sets the selected radio button to the supplied widget. + * + * @param widget The radio button to select. + */ + +void CRadioButtonGroup::setSelectedWidget(CRadioButton* widget) +{ + if (m_selectedWidget != widget) + { + if (m_selectedWidget != NULL) + { + m_selectedWidget->setState(CRadioButton::RADIO_BUTTON_STATE_OFF); + } + + m_selectedWidget = widget; + + if (m_selectedWidget != NULL) + { + m_selectedWidget->setState(CRadioButton::RADIO_BUTTON_STATE_ON); + } + + m_widgetEventHandlers->raiseValueChangeEvent(); + } +} + +/** + * Selects the widget at the specified index. + * + * @param index The index of the widget to select. + */ + +void CRadioButtonGroup::setSelectedIndex(int index) +{ + if (index < m_children.size()) + { + setSelectedWidget((CRadioButton*)m_children[index]); + m_widgetEventHandlers->raiseValueChangeEvent(); + } +} + +/** + * Insert the dimensions that this widget wants to have into the rect + * passed in as a parameter. All coordinates are relative to the + * widget's parent. Value is based on the length of the largest string + * in the set of options. + * + * @param rect Reference to a rect to populate with data. + */ + +void CRadioButtonGroup::getPreferredDimensions(CRect& rect) const +{ + nxgl_coord_t width = 0; + nxgl_coord_t height = 0; + + if (!m_flags.borderless) + { + width = m_borderSize.left + m_borderSize.right; + height = m_borderSize.top + m_borderSize.bottom; + } + + nxgl_coord_t widgetX = 0; + nxgl_coord_t widgetY = 0; + + nxgl_coord_t maxX = 0; + nxgl_coord_t maxY = 0; + + // Locate largest x and y coords within children + + for (int i = 0; i < m_children.size(); ++i) + { + widgetX = m_children[i]->getX() + m_children[i]->getWidth(); + widgetY = m_children[i]->getY() + m_children[i]->getHeight(); + + if (widgetX > maxX) + { + maxX = widgetX; + } + + if (widgetY > maxY) + { + maxY = widgetY; + } + } + + rect.setX(m_rect.getX()); + rect.setY(m_rect.getY()); + rect.setWidth(width + maxX - getX()); + rect.setHeight(height + maxY - getY()); +} + +/** + * Handle a mouse click event. + * + * @param e The event data. + */ + +void CRadioButtonGroup::handleClickEvent(const CWidgetEventArgs &e) +{ + m_widgetEventHandlers->raiseClickEvent(e.getX(), e.getY()); +} + +/** + * Handle a mouse double-click event. + * + * @param e The event data. + */ + +void CRadioButtonGroup::handleDoubleClickEvent(const CWidgetEventArgs &e) +{ + m_widgetEventHandlers->raiseDoubleClickEvent(e.getX(), e.getY()); +} + +/** + * Handle a mouse button release event that occurred within the bounds of + * the source widget. + * @param e The event data. + */ + +void CRadioButtonGroup::handleReleaseEvent(const CWidgetEventArgs &e) +{ + m_widgetEventHandlers->raiseReleaseEvent(e.getX(), e.getY()); +} + +/** + * Handle a mouse button release event that occurred outside the bounds of + * the source widget. + * + * @param e The event data. + */ + +void CRadioButtonGroup::handleReleaseOutsideEvent(const CWidgetEventArgs &e) +{ + // Child raised a release outside event, but we need to raise a different + // event if the release occurred within the bounds of this parent widget + + if (checkCollision(e.getX(), e.getY())) + { + m_widgetEventHandlers->raiseReleaseEvent(e.getX(), e.getY()); + } + else + { + m_widgetEventHandlers->raiseReleaseOutsideEvent(e.getX(), e.getY()); + } +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CRadioButtonGroup::drawContents(CGraphicsPort *port) +{ + port->drawFilledRect(getX(), getY(), getWidth(), getHeight(), getBackgroundColor()); +} diff --git a/NxWidgets/libnxwidgets/src/crect.cxx b/NxWidgets/libnxwidgets/src/crect.cxx new file mode 100644 index 000000000..8e0ed2cd4 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/crect.cxx @@ -0,0 +1,380 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cbgwindow.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "crect.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + */ + +CRect::CRect(void) +{ + m_pos.x = 0; + m_pos.y = 0; + m_size.w = 0; + m_size.h = 0; +} + +/** + * Constructor. + * + * @param x The x coordinate of the rect. + * @param y The y coordinate of the rect. + * @param width The width of the rect. + * @param height The height of the rect. + */ + +CRect::CRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height) +{ + m_pos.x = x; + m_pos.y = y; + m_size.w = width; + m_size.h = height; +} + +/** + * Constructor. + * + * @param rect Pointer to an NX rectangle + */ + +CRect::CRect(FAR const nxgl_rect_s *rect) +{ + setNxRect(rect); +} + +/** + * Copy constructor. + * + * @param rect CRect to copy. + */ + +CRect::CRect(const CRect &rect) +{ + m_pos.x = rect.getX(); + m_pos.y = rect.getY(); + m_size.w = rect.getWidth(); + m_size.h = rect.getHeight(); +} + +/** + * Create a rect object from the supplied coordinates. + * + * @param x1 The x coordinate of the rect's top-left corner. + * @param y1 The y coordinate of the rect's top-left corner. + * @param x2 The x coordinate of the rect's bottom-right corner. + * @param y2 The y coordinate of the rect's bottom-right corner. + * @return A new rect. + */ + +CRect fromCoordinates(nxgl_coord_t x1, nxgl_coord_t y1, + nxgl_coord_t x2, nxgl_coord_t y2) +{ + // Ensure x2 is the larger value + + if (x2 < x1) + { + nxgl_coord_t swap = x1; + x1 = x2; + x2 = swap; + } + nxgl_coord_t width = x2 - x1 + 1; + + // Ensure y2 is the larger value + + if (y2 < y1) + { + nxgl_coord_t swap = y1; + y1 = y2; + y2 = swap; + } + nxgl_coord_t height = y2 - y1 + 1; + + // Create the CRect instance + + return CRect(x1, y1, width, height); +} + +/** + * Set the x coordinate of the rect's bottom-right corner. If x2 is less + * than the rect's current x coordinate the method automatically adjusts + * the coordinates so that the rect's width is never negative. Changing this + * property will change the width of the rect. + * + * @param x2 The x coordinate of the rect's bottom-right corner. + */ + +void CRect::setX2(nxgl_coord_t x2) +{ + // Ensure that x contains the smaller value + + if (x2 < m_pos.x) + { + nxgl_coord_t swap = m_pos.x; + m_pos.x = x2; + x2 = swap; + } + + // Then set the width + + m_size.w = x2 - m_pos.x + 1; +} + +/** + * Set the y coordinate of the rect's bottom-right corner. If y2 is less + * than the rect's current y coordinate the method automatically adjusts + * the coordinates so that the rect's height is never negative. Changing this + * property will change the height of the rect. + * + * @param y2 The y coordinate of the rect's bottom-right corner. + */ + +void CRect::setY2(nxgl_coord_t y2) +{ + // Ensure that y contains the smaller value + + if (y2 < m_pos.y) + { + nxgl_coord_t swap = m_pos.y; + m_pos.y = y2; + y2 = swap; + } + + // Then set the height + + m_size.h = y2 - m_pos.y + 1; +} + +/** + * Populates dest with a rectangle representating the intersection + * of this rectangle and rect. + * + * @param rect The rectangle to intersect with this. + * @param dest The destination rectangle. + */ + +void CRect::getIntersect(const CRect &rect, CRect &dest) const +{ + nxgl_coord_t x1 = ngl_max(m_pos.x, rect.getX()); + nxgl_coord_t y1 = ngl_max(m_pos.y, rect.getY()); + nxgl_coord_t x2 = ngl_min(getX2(), rect.getX2()); + nxgl_coord_t y2 = ngl_min(getY2(), rect.getY2()); + + dest.setX(x1); + dest.setY(y1); + dest.setWidth(x2 - x1 + 1); + dest.setHeight(y2 - y1 + 1); +} + +/** + * Populates dest with a rectangle representating the smallest + * rectangle that contains this rectangle and rect. + * + * @param rect The rectangle to add to this. + * @param dest The destination rectangle. + */ + +void CRect::getAddition(const CRect &rect, CRect &dest) const +{ + + nxgl_coord_t x1 = ngl_min(m_pos.x, rect.getX()); + nxgl_coord_t y1 = ngl_min(m_pos.y, rect.getY()); + nxgl_coord_t x2 = ngl_max(getX2(), rect.getX2()); + nxgl_coord_t y2 = ngl_max(getY2(), rect.getY2()); + + dest.setX(x1); + dest.setY(y1); + dest.setWidth(x2 - x1 + 1); + dest.setHeight(y2 - y1 + 1); +} + +/** + * Clips this rect to the region that intersects the supplied rect. + * + * @param rect CRect to intersect. + */ + +void CRect::clipToIntersect(const CRect &rect) +{ + CRect clipped; + getIntersect(rect, clipped); + + setX(clipped.getX()); + setY(clipped.getY()); + setWidth(clipped.getWidth()); + setHeight(clipped.getHeight()); +} + +/** + * Expands this rect so that it includes the area described by the supplied + * rect. + * + * @param rect CRect to include. + */ + +void CRect::expandToInclude(const CRect& rect) +{ + CRect addition; + getAddition(rect, addition); + + setX(addition.getX()); + setY(addition.getY()); + setWidth(addition.getWidth()); + setHeight(addition.getHeight()); +} + +/** + * Check if the supplied rect intersects this. + * + * @param rect CRect to check for intersection with this. + * @return True if the rect intersects this; false if not. + */ + +bool CRect::intersects(const CRect &rect) const +{ + return ((m_pos.x + m_size.w > rect.getX()) && + (m_pos.y + m_size.h > rect.getY()) && + (m_pos.x < rect.getX() + rect.getWidth()) && + (m_pos.y < rect.getY() + rect.getHeight())); +} + +/** + * Check if the rect contains the supplied point. + * + * @param x X coordinate of the point. + * @param y Y coordinate of the point. + * @return True if the rect contains the point; false if not. + */ + +bool CRect::contains(nxgl_coord_t x, nxgl_coord_t y) const +{ + return ((x >= m_pos.x) && (y >= m_pos.y) && + (x < m_pos.x + m_size.w) && (y < m_pos.y + m_size.h)); +} + +/** + * Copy the properties of this rect to the destination rect. + * + * @param dest Destination rect to copy to. + */ + +void CRect::copyTo(CRect &dest) const +{ + dest.setX(m_pos.x); + dest.setY(m_pos.y); + dest.setWidth(m_size.w); + dest.setHeight(m_size.h); +} + +/** + * Overloaded & operator. Returns the intersect of this rectangle and the + * rectangle passed as the "rect" argument". + * + * @param rect The rectangle to intersect with this. + */ + +CRect CRect::operator&(const CRect &rect) +{ + CRect dest; + getIntersect(rect, dest); + return dest; +} + +/** + * Overloaded + operator. Returns the smallest rectangle that can contain + * this rectangle and the rectangle passed as the "rect" argument". + * + * @param rect The rectangle to add to this. + */ + +CRect CRect::operator+(const CRect &rect) +{ + CRect dest; + getAddition(rect, dest); + return dest; +} diff --git a/NxWidgets/libnxwidgets/src/crectcache.cxx b/NxWidgets/libnxwidgets/src/crectcache.cxx new file mode 100644 index 000000000..3f74ee75d --- /dev/null +++ b/NxWidgets/libnxwidgets/src/crectcache.cxx @@ -0,0 +1,521 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/crectcache.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "crectcache.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CNxFont Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param widget Widget that contains the rect cache. + */ + +CRectCache::CRectCache(const CNxWidget* widget) +{ + m_widget = widget; + m_foregroundInvalid = true; + m_backgroundInvalid = true; +} + +/** + * Rebuild the cache if it is invalid. + */ + +void CRectCache::cache(void) +{ + cacheBackgroundRegions(); +} + +/** + * Works out which rectangles in the invalidRects list overlap this + * widget, then cuts the rectangles into smaller pieces. The overlapping + * pieces are pushed into validRects, and the non-overlapping pieces are + * pushed back into the invalidRects vector. + * + * @param invalidRects A vector of regions that need to be tested + * for collisions against this widget; they represent regions that need + * to be redrawn. + * @param validRects A vector of regions that represents areas of the + * display that do not need to be redrawn. + * @param sender Pointer to the widget that initiated the split. + */ + +void CRectCache::splitRectangles(TNxArray<CRect>* invalidRects, + TNxArray<CRect>* validRects, + FAR const CNxWidget *sender) const +{ + // Check for collisions with any rectangles in the vector + + for (int i = 0; i < invalidRects->size(); i++) + { + // Get rectangle to check + + CRect checkRect = invalidRects->at(i); + nxgl_coord_t splitX[4]; + nxgl_coord_t splitY[4]; + unsigned int rectXCount = 0; + unsigned int rectYCount = 0; + unsigned int overlapXRect = 0; + unsigned int overlapYRect = 0; + + nxgl_coord_t width = checkRect.getWidth(); + nxgl_coord_t height = checkRect.getHeight(); + + if (m_widget->checkCollision(checkRect.getX(), checkRect.getY(), width, height)) + { + // Got a collision. We need to split this rectangle + // Get clipped dimensions of widget + + CRect widgetRect; + m_widget->getRectClippedToHierarchy(widgetRect); + + // Vertical split + // Start at left edge of rectangle + + splitX[0] = checkRect.getX(); + + // Check for second split + + if (checkRect.getX() < widgetRect.getX()) + { + // Widget is to the right of the invalid rectangle (or in the centre) + + if (splitX[rectXCount] != widgetRect.getX()) + { + rectXCount++; + splitX[rectXCount] = widgetRect.getX(); + + // The next rectangle is the overlap + + overlapXRect = rectXCount; + } + } + else + { + // Widget rectangle is on the left of the invalid rectangle + + if (splitX[rectXCount] != widgetRect.getX2() + 1) + { + // We've found the start of the overlapping rectangle! + + overlapXRect = rectXCount; + rectXCount++; + + // Split is either the end of the widget or the end of the + // invalid rect, whichever comes first + + if (widgetRect.getX2() <= checkRect.getX2()) + { + splitX[rectXCount] = widgetRect.getX2() + 1; + } + else + { + splitX[rectXCount] = checkRect.getX2() + 1; + } + } + else + { + // Found the start of the overlapping rectangle + + overlapXRect = rectXCount; + } + } + + // Check for third split + + if (widgetRect.getX2() + 1 <= checkRect.getX2() + 1) + { + // Widget ends before the invalid rectangle + + if (splitX[rectXCount] != widgetRect.getX2() + 1) + { + // Record end of overlap + + rectXCount++; + splitX[rectXCount] = widgetRect.getX2() + 1; + } + } + + // Store end of invalid rectangle + + if (splitX[rectXCount] <= checkRect.getX2()) + { + rectXCount++; + splitX[rectXCount] = checkRect.getX2() + 1; + } + + // Horizontal split + // Start at left edge of rectangle + + splitY[0] = checkRect.getY(); + + // Check for second split + + if (checkRect.getY() < widgetRect.getY()) + { + // Widget below the invalid rectangle (or in the centre) + + if (splitY[rectYCount] != widgetRect.getY()) + { + rectYCount++; + splitY[rectYCount] = widgetRect.getY(); + + // The next rectangle is the overlap + + overlapYRect = rectYCount; + } + } + else + { + // Widget rectangle above the invalid rectangle + + if (splitY[rectYCount] != widgetRect.getY2() + 1) + { + // We've found the start of the overlapping rectangle! + + overlapYRect = rectYCount; + rectYCount++; + + // Split is either the end of the widget or the end of the + // invalid rect, whichever comes first + + if (widgetRect.getY2() <= checkRect.getY2()) + { + splitY[rectYCount] = widgetRect.getY2() + 1; + } + else + { + splitY[rectYCount] = checkRect.getY2() + 1; + } + } + else + { + // Found the start of the overlapping rectangle + + overlapYRect = rectYCount; + } + } + + // Check for third split + + if (widgetRect.getY2() < checkRect.getY2()) + { + // Widget ends before the invalid rectangle + + if (splitY[rectYCount] != widgetRect.getY2() + 1) + { + // Record end of overlap + + rectYCount++; + splitY[rectYCount] = widgetRect.getY2() + 1; + } + } + + // Store end of invalid rectangle + + if (splitY[rectYCount] <= checkRect.getY2()) + { + rectYCount++; + splitY[rectYCount] = checkRect.getY() + 1; + } + + // Remove the original rectangle + + invalidRects->erase(i); + + // Force the loop to re-examine the new rectangle at this index + + i--; + + // Add the new rectangles (not the overlap; that's the one we need to draw) + + for (unsigned int xRects = 0; xRects < rectXCount; xRects++) + { + for (unsigned int yRects = 0; yRects < rectYCount; yRects++) + { + // Is this the overlap? + + if ((overlapXRect == xRects) && (overlapYRect == yRects)) + { + // Got the overlap, so set the output values + + CRect overlapRect; + overlapRect.setX(splitX[xRects]); + overlapRect.setY(splitY[yRects]); + overlapRect.setX2(splitX[xRects + 1] - 1); + overlapRect.setY2(splitY[yRects + 1] - 1); + + if (overlapRect.hasDimensions()) + { + validRects->push_back(overlapRect); + } + } + else + { + // Not an overlap; add to vector + + CRect newRect; + newRect.setX(splitX[xRects]); + newRect.setY(splitY[yRects]); + newRect.setX2(splitX[xRects + 1] - 1); + newRect.setY2(splitY[yRects + 1] - 1); + + // Insert the new rectangle at the start so we don't + + if (newRect.hasDimensions()) + { + invalidRects->push_back(newRect); + } + + // Increase iterator to compensate for insertion + + i++; + } + } + } + } + } +} + +/** + * Move any rectangles from the visibleRects list that overlap this widget + * into the invisibleRects list. Used during visible region calculations. + * + * @param visibleRects A vector of regions that are not overlapped. + * @param invisibleRects A vector of regions that are overlapped. + * @param widget The widget that requested the lists. + * @see splitRectangles() + */ + +void CRectCache::removeOverlappedRects(TNxArray<CRect> *visibleRects, + TNxArray<CRect> *invisibleRects, + FAR const CNxWidget* widget) const +{ + const CNxWidget* parent = m_widget; + int widgetIndex = -1; + + while ((widget != NULL) && (parent != NULL)) + { + // Locate widget in the list; we add one to the index to + // ensure that we deal with the next widget up in the z-order + + widgetIndex = parent->getWidgetIndex(widget) + 1; + + // Widget should never be the bottom item on the screen + + if (widgetIndex > 0) + { + // Remove any overlapped rectangles + + for (int i = widgetIndex; i < parent->getChildCount(); i++) + { + if (visibleRects->size() > 0) + { + parent->getChild(i)->getCRectCache()->splitRectangles(visibleRects, invisibleRects, widget); + } + else + { + break; + } + } + } + + if (visibleRects->size() > 0) + { + widget = parent; + + if (parent != NULL) + { + parent = parent->getParent(); + } + } + else + { + return; + } + } +} + +/** + * Cache the foreground regions. + */ + +void CRectCache::cacheForegroundRegions(void) +{ + if (m_foregroundInvalid) + { + // Use internal region cache to store the non-overlapped rectangles + // We will use this to clip the widget + + m_foregroundRegions.clear(); + + // Create pointer to a vector to store the overlapped rectangles + // We can discard this later as we don't need it + + TNxArray<CRect>* invisibleRects = new TNxArray<CRect>(); + + // Copy the clipped widget dimensions into a rect + + CRect rect; + m_widget->getRectClippedToHierarchy(rect); + + // Do we have a visible region left? + + if (rect.hasDimensions()) + { + // Add rect to list + + m_foregroundRegions.push_back(rect); + + // Request refresh + + if (m_widget->getParent() != NULL) + { + m_widget->getParent()->getCRectCache()->removeOverlappedRects(&m_foregroundRegions, invisibleRects, m_widget); + } + } + + // Tidy up + + delete invisibleRects; + m_foregroundInvalid = false; + } +} + +/** + * Cache the background regions. + */ + +void CRectCache::cacheBackgroundRegions(void) +{ + // Ensure that foreground is up to date + + cacheForegroundRegions(); + + if (m_backgroundInvalid) + { + // Cache visible regions not overlapped by children + + m_backgroundRegions.clear(); + + // Create pointer to a vector to store the overlapped rectangles + // We can discard this later as we don't need it + + TNxArray<CRect>* invisibleRects = new TNxArray<CRect>(); + + // Copy all foreground regions into the new vector + + for (int i = 0; i < m_foregroundRegions.size(); i++) + { + m_backgroundRegions.push_back(m_foregroundRegions[i]); + } + + // Remove all child rects from the visible vector + + for (int i = 0; i < m_widget->getChildCount(); i++) + { + if (m_backgroundRegions.size() > 0) + { + m_widget->getChild(i)->getCRectCache()->splitRectangles(&m_backgroundRegions, invisibleRects, m_widget); + } + else + { + break; + } + } + + // Tidy up + + delete invisibleRects; + m_backgroundInvalid = false; + } +} + + diff --git a/NxWidgets/libnxwidgets/src/crlepalettebitmap.cxx b/NxWidgets/libnxwidgets/src/crlepalettebitmap.cxx new file mode 100644 index 000000000..25e9473ed --- /dev/null +++ b/NxWidgets/libnxwidgets/src/crlepalettebitmap.cxx @@ -0,0 +1,414 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/crlepalettebitmap.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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> +#include <cstring> + +#include <nuttx/nx/nxglib.h> + +#include "nxconfig.hxx" +#include "crlepalettebitmap.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param bitmap The bitmap structure being wrapped. + */ + +CRlePaletteBitmap::CRlePaletteBitmap(const struct SRlePaletteBitmap *bitmap) +{ + m_bitmap = bitmap; + startOfImage(); +} + +/** + * Get the bitmap's color format. + * + * @return The bitmap's width. + */ + +const uint8_t CRlePaletteBitmap::getColorFormat(void) const +{ + return m_bitmap->fmt; +} + +/** + * Get the bitmap's color format. + * + * @return The bitmap's color format. + */ + +const uint8_t CRlePaletteBitmap::getBitsPerPixel(void) const +{ + return m_bitmap->bpp; +} + +/** + * Get the bitmap's width (in pixels/columns). + * + * @return The bitmap's pixel depth. + */ + +const nxgl_coord_t CRlePaletteBitmap::getWidth(void) const +{ + return m_bitmap->width; +} + +/** + * Get the bitmap's height (in rows). + * + * @return The bitmap's height. + */ + +const nxgl_coord_t CRlePaletteBitmap::getHeight(void) const +{ + return m_bitmap->height; +} + +/** + * Get the bitmap's width (in bytes). + * + * @return The bitmap's width. + */ + +const nxgl_coord_t CRlePaletteBitmap::getStride(void) const +{ + // This only works if the bpp is an even multiple of 8-bit bytes + + return (m_bitmap->width * m_bitmap->bpp) >> 3; +} + +/** + * Get one row from the bit map image. + * + * @param x The offset into the row to get + * @param y The row number to get + * @param width The number of pixels to get from the row + * @param data The memory location provided by the caller + * in which to return the data. This should be at least + * (getWidth()*getBitsPerPixl() + 7)/8 bytes in length + * and properly aligned for the pixel color format. + * @param True if the run was returned successfully. + */ + +bool CRlePaletteBitmap::getRun(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, + FAR void *data) +{ + // Check ranges. Casts to unsigned int are ugly but permit one-sided comparisons + + if (((unsigned int)x < (unsigned int)width) && + ((unsigned int)(x + width) <= (unsigned int)m_bitmap->width)) + { + // Seek to the requested row + + if (!seekRow(y)) + { + return false; + } + + // Offset to the starting X position + + if (x > 0) + { + if (!skipPixels(x)) + { + return false; + } + } + + // Then copy the requested number of pixels + + return copyPixels(width, data); + } + + return false; +} + +/** + * Reset to the beginning of the image + */ + +void CRlePaletteBitmap::startOfImage(void) +{ + m_row = 0; + m_col = 0; + m_rle = &m_bitmap->data[0]; + m_remaining = m_rle->npixels; +} + +/** + * Advance position data ahead. Called after npixels have + * have been consume. + * + * @param npixels The number of pixels to advance + * @return False if this goes beyond the end of the image + */ + +bool CRlePaletteBitmap::advancePosition(nxgl_coord_t npixels) +{ + int newcol = m_col + npixels; + + while (newcol >= m_bitmap->width) + { + newcol -= m_bitmap->width; + if (++m_row >= m_bitmap->height) + { + return false; + } + } + + m_col = newcol; + return true; +} + +/** + * Seek ahead the specific number of pixels -- discarding + * and advancing. + * + * @param npixels The number of pixels to skip + */ + +bool CRlePaletteBitmap::skipPixels(nxgl_coord_t npixels) +{ + do + { + // Skip values in the current RLE entry + + if (m_remaining > npixels) + { + // Subtract from the number of pixels remaining + + m_remaining -= npixels; + return advancePosition(npixels); + } + + // Not enough (or just enough) in the current entry. Take what we + // can from the current entry and move to the next entry + + npixels -= m_remaining; + if (!advancePosition(m_remaining)) + { + return false; + } + + m_rle++; + m_remaining = m_rle->npixels; + } + while (npixels > 0); + + return true; +} + +/** Seek to the beginning of the next row + * + * @return False if this was the last row of the image + */ + +bool CRlePaletteBitmap::nextRow(void) +{ + return skipPixels(m_bitmap->width - m_col); +} + +/** Seek to the beignning specific row + * + * @param row The row number to seek to + * @return False if this goes beyond the end of the image + */ + +bool CRlePaletteBitmap::seekRow(nxgl_coord_t row) +{ + // Is the current position already past the requested position? + + if (row > m_row || (row == m_row && m_col != 0)) + { + // Yes.. rewind to the beginning of the image + + startOfImage(); + } + + // Seek ahead, row-by-row until we are at the beginning of + // the requested row + + while (m_row < row) + { + if (!nextRow()) + { + return false; + } + } + + return true; +} + +/** Copy the pixels from the current RLE entry the specified number of times. + * + * @param npixels The number of pixels to copy. Must be less than or equal + * to m_remaining (not checked here, must be handled by higher level code). + * @param data The memory location provided by the caller + * in which to return the data. This should be at least + * (getWidth()*getBitsPerPixl() + 7)/8 bytes in length + * and properly aligned for the pixel color format. + */ + +void CRlePaletteBitmap::copyColor(nxgl_coord_t npixels, FAR void *data) +{ + // Right now, only a single pixel depth is supported + + nxwidget_pixel_t *nxlut = (nxwidget_pixel_t *)m_bitmap->lut; + nxwidget_pixel_t color = nxlut[m_rle->lookup]; + + // Copy the requested pixels + + FAR nxwidget_pixel_t *dest = (FAR nxwidget_pixel_t *)data; + for (int i = 0; i < npixels; i++) + { + *dest++ = color; + } + + // Adjust the number of pixels remaining in the RLE entry + + m_remaining -= npixels; +} + +/** Copy pixels from the current position + * + * @param npixels The number of pixels to copy + * @param data The memory location provided by the caller + * in which to return the data. This should be at least + * (getWidth()*getBitsPerPixl() + 7)/8 bytes in length + * and properly aligned for the pixel color format. + * @return False if this goes beyond the end of the image + */ + +bool CRlePaletteBitmap::copyPixels(nxgl_coord_t npixels, FAR void *data) +{ + FAR nxwidget_pixel_t *ptr = (FAR nxwidget_pixel_t *)data; + do + { + // Get values in the current RLE entry + + if (m_remaining > npixels) + { + // Copy npixels from the current RLE entry (it won't be empty) + + copyColor(npixels, (FAR void *)ptr); + + // Then advance row/column position information + + return advancePosition(npixels); + } + + // Not enough (or just enough) in the current entry. Take what we + // can from the current entry and move to the next entry + + uint8_t nTaken = m_remaining; // Temporary.. copyColor clobbers m_remaining + npixels -= m_remaining; // New number of pixels needed + + // Copy all of the colors available in this RLE entry + + copyColor(m_remaining, (FAR void *)ptr); + + // Then advance row/column position information + + if (!advancePosition(nTaken)) + { + return false; + } + + // Advance the destination pointer by the number of pixels taken + // from the RLE entry + + ptr += nTaken; + + // Then move to the next RLE entry + + m_rle++; + m_remaining = m_rle->npixels; + } + while (npixels > 0); + + return true; +} diff --git a/NxWidgets/libnxwidgets/src/cscrollbarhorizontal.cxx b/NxWidgets/libnxwidgets/src/cscrollbarhorizontal.cxx new file mode 100644 index 000000000..13e33815d --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cscrollbarhorizontal.cxx @@ -0,0 +1,402 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/include/cscrollbarhorizontal.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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "nxconfig.hxx" +#include "cnxwidget.hxx" +#include "cwidgeteventhandler.hxx" +#include "islider.hxx" +#include "cscrollbarhorizontal.hxx" +#include "cglyphbutton.hxx" +#include "csliderhorizontal.hxx" +#include "cnxtimer.hxx" +#include "glyphs.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementation + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The widget control instance for the window. + * @param x The x coordinate of the slider, relative to its parent. + * @param y The y coordinate of the slider, relative to its parent. + * @param width The width of the slider. + * @param height The height of the slider. + * @param style The style that the widget should use. If this is not + * specified, the widget will use the values stored in the global + * g_defaultWidgetStyle object. The widget will copy the properties of + * the style into its own internal style object. + */ + +CScrollbarHorizontal::CScrollbarHorizontal(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + CWidgetStyle* style) +: CNxWidget(pWidgetControl, x, y, width, height, WIDGET_BORDERLESS, style) +{ + m_buttonWidth = 10; + + // Create the children + + m_slider = new CSliderHorizontal(pWidgetControl, m_buttonWidth, 0, + width - (m_buttonWidth << 1), height); + m_slider->addWidgetEventHandler(this); + + // Set up the left glyph button + + m_leftButton = new CGlyphButton(pWidgetControl, + 0, 0, + m_buttonWidth, height, + 0, 0, + &g_arrowLeft, &g_arrowLeft, &m_style); + m_leftButton->addWidgetEventHandler(this); + + // Set up the right glyph button + + m_rightButton = new CGlyphButton(pWidgetControl, + width - m_buttonWidth, 0, + m_buttonWidth, height, + 0, 0, + &g_arrowRight, &g_arrowRight, &m_style); + m_rightButton->addWidgetEventHandler(this); + + // Create timer + + m_scrollTimeout = 10; + m_timer = new CNxTimer(pWidgetControl, m_scrollTimeout, true); + m_timer->addWidgetEventHandler(this); + + addWidget(m_slider); + addWidget(m_leftButton); + addWidget(m_rightButton); + addWidget(m_timer); +} + +/** + * Get the smallest value that the slider can represent. + * + * @return The smallest value. + */ + +const nxgl_coord_t CScrollbarHorizontal::getMinimumValue(void) const +{ + return m_slider->getMinimumValue(); +} + +/** + * Get the largest value that the slider can represent. + * + * @return The largest value. + */ + +const nxgl_coord_t CScrollbarHorizontal::getMaximumValue(void) const +{ + return m_slider->getMaximumValue(); +} + +/** + * Get the current value of the slider. + * + * @return The current slider value. + */ + +const nxgl_coord_t CScrollbarHorizontal::getValue(void) const +{ + return m_slider->getValue(); +} + +/** + * Get the value represented by the height of the grip. + * For sliders, this would typically be 1 (so each new + * grip position is worth 1). For scrollbars, this + * would be the height of the scrolling widget. + * + * @return The page size. + */ + +const nxgl_coord_t CScrollbarHorizontal::getPageSize(void) const +{ + return m_slider->getPageSize(); +} + +/** + * Set the smallest value that the slider can represent. + * + * @param value The smallest value. + */ + +void CScrollbarHorizontal::setMinimumValue(const nxgl_coord_t value) +{ + m_slider->setMinimumValue(value); +} + +/** + * Set the largest value that the slider can represent. + * + * @param value The largest value. + */ + +void CScrollbarHorizontal::setMaximumValue(const nxgl_coord_t value) +{ + m_slider->setMaximumValue(value); +} + +/** + * Set the value that of the slider. This will reposition + * and redraw the grip. + * + * @param value The new value. + */ + +void CScrollbarHorizontal::setValue(const nxgl_coord_t value) +{ + m_slider->setValue(value); +} + +/** + * Set the value that of the slider. This will reposition and redraw + * the grip. The supplied value should be bitshifted left 16 places. + * This ensures greater accuracy than the standard setValue() method if + * the slider is being used as a scrollbar. + * + * @param value The new value. + */ + +void CScrollbarHorizontal::setValueWithBitshift(const int32_t value) +{ + m_slider->setValueWithBitshift(value); +} + +/** + * Set the page size represented by the grip. + * + * @param pageSize The page size. + * @see getPageSize(). + */ + +void CScrollbarHorizontal::setPageSize(nxgl_coord_t pageSize) +{ + m_slider->setPageSize(pageSize); +} + +/** + * Process events fired by the grip. + * + * @param e The event details. + */ + +void CScrollbarHorizontal::handleActionEvent(const CWidgetEventArgs &e) +{ + // Check which widget fired the event + + if (e.getSource() == m_timer) + { + // Which widget is clicked? + + if (m_leftButton->isClicked()) + { + // Move the grip left + + m_slider->setValue(m_slider->getValue() - m_slider->getMinimumStep()); + } + else if (m_rightButton->isClicked()) + { + // Move the grip right + + m_slider->setValue(m_slider->getValue() + m_slider->getMinimumStep()); + } + } +} + +/** + * Process events fired by the grip. + * + * @param e The event details. + */ + +void CScrollbarHorizontal::handleClickEvent(const CWidgetEventArgs &e) +{ + if (e.getSource() == m_leftButton) + { + // Start the timer + + m_timer->start(); + + // Move the grip left + + m_slider->setValue(m_slider->getValue() - m_slider->getMinimumStep()); + } + else if (e.getSource() == m_rightButton) + { + // Start the timer + + m_timer->start(); + + // Move the grip right + + m_slider->setValue(m_slider->getValue() + m_slider->getMinimumStep()); + } +} + +/** + * Process events fired by the grip. + * + * @param e The event details. + */ + +void CScrollbarHorizontal::handleReleaseEvent(const CWidgetEventArgs &e) +{ + if ((e.getSource() == m_leftButton) || (e.getSource() == m_rightButton)) + { + // Stop the timer + + m_timer->stop(); + } +} + +/** + * Process events fired by the grip. + * + * @param e The event details. + */ + +void CScrollbarHorizontal::handleReleaseOutsideEvent(const CWidgetEventArgs &e) +{ + if ((e.getSource() == m_leftButton) || (e.getSource() == m_rightButton)) + { + // Stop the timer + + m_timer->stop(); + } +} + +/** + * Process events fired by the grip. + * + * @param e The event details. + */ + +void CScrollbarHorizontal::handleValueChangeEvent(const CWidgetEventArgs &e) +{ + if (e.getSource() == m_slider) + { + m_widgetEventHandlers->raiseValueChangeEvent(); + } +} + +/** + * Resize the scrollbar to the new dimensions. + * + * @param width The new width. + * @param height The new height. + */ + +void CScrollbarHorizontal::onResize(nxgl_coord_t width, nxgl_coord_t height) +{ + // Remember current values + + nxgl_coord_t value = getValue(); + bool events = raisesEvents(); + + // Disable event raising + + setRaisesEvents(false); + + // Resize and move children + + m_slider->resize(width - (m_buttonWidth << 1), height); + m_leftButton->moveTo(m_slider->getWidth(), 0); + m_rightButton->moveTo(m_slider->getWidth() + m_buttonWidth, 0); + + // Set back to current value + + setValue(value); + + // Reset event raising + + setRaisesEvents(events); +} diff --git a/NxWidgets/libnxwidgets/src/cscrollbarpanel.cxx b/NxWidgets/libnxwidgets/src/cscrollbarpanel.cxx new file mode 100644 index 000000000..f21cd7766 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cscrollbarpanel.cxx @@ -0,0 +1,438 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cscrollbarpanel.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cscrollbarpanel.hxx" +#include "cbutton.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The widget control for the display. + * @param x The x coordinate of the widget. + * @param y The y coordinate of the widget. + * @param width The width of the widget. + * @param height The height of the widget. + * @param flags The usual widget flags. + * @param style The style that the widget should use. If this is not + * specified, the widget will use the values stored in the global + * g_defaultWidgetStyle object. The widget will copy the properties of + * the style into its own internal style object. + */ + +CScollbarPanel::CScollbarPanel(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + uint32_t flags, CWidgetStyle *style) +: CNxWidget(pWidgetControl, x, y, width, height, flags, style) +{ + m_scrollbarWidth = 10; + m_scrollbarHeight = 10; + m_hasVerticalScrollbar = true; + m_hasHorizontalScrollbar = true; + + m_borderSize.top = 0; + m_borderSize.right = 0; + m_borderSize.left = 0; + m_borderSize.bottom = 0; + m_flags.borderless = true; + + m_widgetControl = pWidgetControl; + m_panel = (CScrollingPanel *)NULL; + m_scrollbarVertical = (CScrollbarVertical *)NULL; + m_scrollbarHorizontal = (CScrollbarHorizontal *)NULL; + + buildUI(); +} + +/** + * Scroll the panel by the specified amounts. + * + * @param dx The horizontal distance to scroll. + * @param dy The vertical distance to scroll. + */ + +void CScollbarPanel::scroll(int32_t dx, int32_t dy) +{ + m_panel->scroll(dx, dy); +} + +/** + * Reposition the panel's scrolling region to the specified coordinates. + * + * @param x The new x coordinate of the scrolling region. + * @param y The new y coordinate of the scrolling region. + */ + +void CScollbarPanel::jump(int32_t x, int32_t y) +{ + m_panel->jump(x, y); +} + +/** + * Set whether or not horizontal scrolling is allowed. + * + * @param allow True to allow horizontal scrolling; false to deny it. + */ + +void CScollbarPanel::setAllowsVerticalScroll(bool allow) +{ + m_panel->setAllowsVerticalScroll(allow); + + if (m_hasVerticalScrollbar) + { + if (allow) + { + m_scrollbarVertical->enable(); + } + else + { + m_scrollbarVertical->disable(); + } + } +} + +/** + * Set whether or not horizontal scrolling is allowed. + * + * @param allow True to allow horizontal scrolling; false to deny it. + */ + +void CScollbarPanel::setAllowsHorizontalScroll(bool allow) +{ + m_panel->setAllowsHorizontalScroll(allow); + + if (m_hasHorizontalScrollbar) + { + if (allow) + { + m_scrollbarHorizontal->enable(); + } + else + { + m_scrollbarHorizontal->disable(); + } + } +} + +/** + * Sets the width of the virtual canvas. + * + * @param width The width of the virtual canvas. + */ + +void CScollbarPanel::setCanvasWidth(const int32_t width) +{ + m_panel->setCanvasWidth(width); + m_scrollbarHorizontal->setMaximumValue(width); +} + +/** + * Sets the height of the virtual canvas. + * + * @param height The height of the virtual canvas. + */ + +void CScollbarPanel::setCanvasHeight(const int32_t height) +{ + m_panel->setCanvasHeight(height); + m_scrollbarVertical->setMaximumValue(height); +} + +/** + * Returns true if vertical scrolling is allowed. + * + * @return True if vertical scrolling is allowed. + */ + +bool CScollbarPanel::allowsVerticalScroll(void) const +{ + return m_panel->allowsVerticalScroll(); +} + +/** + * Returns true if horizontal scrolling is allowed. + * + * @return True if horizontal scrolling is allowed. + */ + +bool CScollbarPanel::allowsHorizontalScroll(void) const +{ + return m_panel->allowsHorizontalScroll(); +} + +/** + * Gets the x coordinate of the virtual canvas. + * + * @return The x coordinate of the virtual canvas. + */ + +const int32_t CScollbarPanel::getCanvasX(void) const +{ + return m_panel->getCanvasX(); +} + +/** + * Gets the y coordinate of the virtual canvas. + * + * @return The y coordinate of the virtual canvas. + */ + +const int32_t CScollbarPanel::getCanvasY(void) const +{ + return m_panel->getCanvasY(); +} + +/** + * Gets the width of the virtual canvas. + * + * @return The width of the virtual canvas. + */ + +const int32_t CScollbarPanel::getCanvasWidth(void) const +{ + return m_panel->getCanvasWidth(); +} + +/** + * Gets the height of the virtual canvas. + * + * @return The height of the virtual canvas. + */ + +const int32_t CScollbarPanel::getCanvasHeight(void) const +{ + return m_panel->getCanvasHeight(); +} + +/** + * Handle a widget scroll event. + * + * @param e The event data. + */ + +void CScollbarPanel::handleScrollEvent(const CWidgetEventArgs &e) +{ + if (e.getSource() != NULL) + { + if (e.getSource() == m_panel) + { + if (m_scrollbarVertical != NULL) + { + m_scrollbarVertical->setRaisesEvents(false); + m_scrollbarVertical->setValue(0 - m_panel->getCanvasY()); + m_scrollbarVertical->setRaisesEvents(true); + } + else if (m_scrollbarHorizontal != NULL) + { + m_scrollbarHorizontal->setRaisesEvents(false); + m_scrollbarHorizontal->setValue(0 - m_panel->getCanvasX()); + m_scrollbarHorizontal->setRaisesEvents(true); + } + } + } +} + +/** + * Handle a widget value change event. + * + * @param e The event data. + */ + +void CScollbarPanel::handleValueChangeEvent(const CWidgetEventArgs &e) +{ + if (e.getSource() != NULL) + { + if (e.getSource() == m_scrollbarVertical) + { + if (m_panel != NULL) + { + m_panel->setRaisesEvents(false); + m_panel->jump(m_panel->getCanvasX(), 0 - m_scrollbarVertical->getValue()); + m_panel->setRaisesEvents(true); + } + } + else if (e.getSource() == m_scrollbarHorizontal) + { + if (m_panel != NULL) + { + m_panel->setRaisesEvents(false); + m_panel->jump(0 - m_scrollbarHorizontal->getValue(), m_panel->getCanvasY()); + m_panel->setRaisesEvents(true); + } + } + } +} + +/** + * Creates the child widgets. + */ + +void CScollbarPanel::buildUI(void) +{ + CRect rect; + getClientRect(rect); + + nxgl_coord_t panelWidth = rect.getWidth(); + if (m_hasVerticalScrollbar) + { + panelWidth -= m_scrollbarWidth; + } + + nxgl_coord_t panelHeight = rect.getHeight(); + if (m_hasHorizontalScrollbar) + { + panelHeight -= m_scrollbarHeight; + } + + m_panel = new CScrollingPanel(m_widgetControl, rect.getX(), rect.getY(), + panelWidth, panelHeight, 0, &m_style); + addWidget(m_panel); + + CRect panelRect; + m_panel->getClientRect(panelRect); + + // Disable content scrolling by default, as the panel cannot be drawn to + // without some additional programmer effort + + m_panel->setContentScrolled(false); + + // Adjust scrollbar dimensions based on scrollbar visibility + + nxgl_coord_t verticalScrollHeight = rect.getHeight(); + if (m_hasHorizontalScrollbar) + { + verticalScrollHeight -= m_scrollbarHeight; + } + + nxgl_coord_t horizontalScrollWidth = rect.getWidth(); + if (m_hasVerticalScrollbar) + { + horizontalScrollWidth -= m_scrollbarWidth; + } + + if (m_hasHorizontalScrollbar) + { + m_scrollbarHorizontal = + new CScrollbarHorizontal(m_widgetControl, + rect.getX(), rect.getHeight() - m_scrollbarHeight, + horizontalScrollWidth, m_scrollbarHeight, + &m_style); + m_scrollbarHorizontal->setMinimumValue(0); + m_scrollbarHorizontal->setMaximumValue(getCanvasWidth()); + m_scrollbarHorizontal->setPageSize(panelRect.getWidth()); + m_scrollbarHorizontal->addWidgetEventHandler(this); + addWidget(m_scrollbarHorizontal); + } + + if (m_hasVerticalScrollbar) + { + m_scrollbarVertical = + new CScrollbarVertical(m_widgetControl, + rect.getWidth() - m_scrollbarWidth, + rect.getY(), m_scrollbarWidth, + verticalScrollHeight, &m_style); + m_scrollbarVertical->setMinimumValue(0); + m_scrollbarVertical->setMaximumValue(getCanvasHeight()); + m_scrollbarVertical->setPageSize(panelRect.getHeight()); + m_scrollbarVertical->addWidgetEventHandler(this); + addWidget(m_scrollbarVertical); + } +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CScollbarPanel::drawContents(CGraphicsPort *port) +{ + port->drawFilledRect(0, 0, getWidth(), getHeight(), getBackgroundColor()); +} diff --git a/NxWidgets/libnxwidgets/src/cscrollbarvertical.cxx b/NxWidgets/libnxwidgets/src/cscrollbarvertical.cxx new file mode 100644 index 000000000..76b5c5dec --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cscrollbarvertical.cxx @@ -0,0 +1,404 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/include/cscrollbarhorizontal.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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "nxconfig.hxx" +#include "cscrollbarvertical.hxx" +#include "cglyphbutton.hxx" +#include "cslidervertical.hxx" +#include "cnxtimer.hxx" +#include "glyphs.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementation + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The widget control instance for the window. + * @param x The x coordinate of the slider, relative to its parent. + * @param y The y coordinate of the slider, relative to its parent. + * @param width The width of the slider. + * @param height The height of the slider. + * @param style The style that the widget should use. If this is not + * specified, the widget will use the values stored in the global + * g_defaultWidgetStyle object. The widget will copy the properties of + * the style into its own internal style object. + */ + +CScrollbarVertical::CScrollbarVertical(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + CWidgetStyle *style) +: CNxWidget(pWidgetControl, x, y, width, height, WIDGET_BORDERLESS, style) +{ + m_buttonHeight = 10; + + // Create the children + + m_slider = new CSliderVertical(pWidgetControl, 0, m_buttonHeight, + width, height - (m_buttonHeight << 1)); + m_slider->addWidgetEventHandler(this); + + // Setup the up button + + m_upButton = new CGlyphButton(pWidgetControl, + 0, 0, + width, m_buttonHeight, + 0, 0, + &g_arrowUp, &g_arrowUp, &m_style); + m_upButton->addWidgetEventHandler(this); + + // Setup the down button + + m_downButton = new CGlyphButton(pWidgetControl, + 0, height - m_buttonHeight, + width, m_buttonHeight, + 0, 0, + &g_arrowDown, &g_arrowDown, &m_style); + m_downButton->addWidgetEventHandler(this); + + // Create timer + + m_scrollTimeout = 10; + + m_timer = new CNxTimer(pWidgetControl, m_scrollTimeout, true); + m_timer->addWidgetEventHandler(this); + + addWidget(m_slider); + addWidget(m_upButton); + addWidget(m_downButton); + addWidget(m_timer); +} + +/** + * Get the smallest value that the slider can represent. + * + * @return The smallest value. + */ + +const nxgl_coord_t CScrollbarVertical::getMinimumValue(void) const +{ + return m_slider->getMinimumValue(); +} + +/** + * Get the largest value that the slider can represent. + * + * @return The largest value. + */ + +const nxgl_coord_t CScrollbarVertical::getMaximumValue(void) const +{ + return m_slider->getMaximumValue(); +} + +/** + * Get the current value of the slider. + * + * @return The current slider value. + */ + +const nxgl_coord_t CScrollbarVertical::getValue(void) const +{ + return m_slider->getValue(); +} + +/** + * Get the value represented by the height of the grip. + * For sliders, this would typically be 1 (so each new + * grip position is worth 1). For scrollbars, this + * would be the height of the scrolling widget. + * + * @return The page size. + */ + +const nxgl_coord_t CScrollbarVertical::getPageSize(void) const +{ + return m_slider->getPageSize(); +} + +/** + * Set the smallest value that the slider can represent. + * + * @param value The smallest value. + */ + +void CScrollbarVertical::setMinimumValue(const nxgl_coord_t value) +{ + m_slider->setMinimumValue(value); +} + +/** + * Set the largest value that the slider can represent. + * + * @param value The largest value. + */ + +void CScrollbarVertical::setMaximumValue(const nxgl_coord_t value) +{ + m_slider->setMaximumValue(value); +} + +/** + * Set the value that of the slider. This will reposition + * and redraw the grip. + * + * @param value The new value. + */ + +void CScrollbarVertical::setValue(const nxgl_coord_t value) +{ + m_slider->setValue(value); +} + +/** + * Set the value that of the slider. This will reposition and redraw + * the grip. The supplied value should be bitshifted left 16 places. + * This ensures greater accuracy than the standard setValue() method if + * the slider is being used as a scrollbar. + * + * @param value The new value. + */ + +void CScrollbarVertical::setValueWithBitshift(const int32_t value) +{ + m_slider->setValueWithBitshift(value); +} + +/** + * Set the page size represented by the grip. + * + * @param pageSize The page size. + * @see getPageSize(). + */ + +void CScrollbarVertical::setPageSize(nxgl_coord_t pageSize) +{ + m_slider->setPageSize(pageSize); +} + +/** + * Process events fired by the grip. + * + * @param e The event details. + */ + +void CScrollbarVertical::handleActionEvent(const CWidgetEventArgs &e) +{ + // Check which widget fired the event + + if (e.getSource() == m_timer) + { + // Which widget is clicked? + + if (m_upButton->isClicked()) + { + // Move the grip up + + m_slider->setValue(m_slider->getValue() - m_slider->getMinimumStep()); + } + else if (m_downButton->isClicked()) + { + // Move the grip down + + m_slider->setValue(m_slider->getValue() + m_slider->getMinimumStep()); + } + + m_widgetEventHandlers->raiseValueChangeEvent(); + } +} + +/** + * Process events fired by the grip. + * + * @param e The event details. + */ + +void CScrollbarVertical::handleClickEvent(const CWidgetEventArgs &e) +{ + if (e.getSource() == m_upButton) + { + // Start the timer + + m_timer->start(); + + // Move the grip up + + m_slider->setValue(m_slider->getValue() - m_slider->getMinimumStep()); + m_widgetEventHandlers->raiseValueChangeEvent(); + } + else if (e.getSource() == m_downButton) + { + // Start the timer + + m_timer->start(); + + // Move the grip down + + m_slider->setValue(m_slider->getValue() + m_slider->getMinimumStep()); + m_widgetEventHandlers->raiseValueChangeEvent(); + } +} + +/** + * Process events fired by the grip. + * + * @param e The event details. + */ + +void CScrollbarVertical::handleReleaseEvent(const CWidgetEventArgs &e) +{ + if ((e.getSource() == m_upButton) || (e.getSource() == m_downButton)) + { + // Stop the timer + + m_timer->stop(); + } +} + +/** + * Process events fired by the grip. + * + * @param e The event details. + */ + +void CScrollbarVertical::handleReleaseOutsideEvent(const CWidgetEventArgs &e) +{ + if ((e.getSource() == m_upButton) || (e.getSource() == m_downButton)) + { + // Stop the timer + + m_timer->stop(); + } +} + +/** + * Process events fired by the grip. + * + * @param e The event details. + */ + +void CScrollbarVertical::handleValueChangeEvent(const CWidgetEventArgs &e) +{ + if (e.getSource() == m_slider) + { + m_widgetEventHandlers->raiseValueChangeEvent(); + } +} + +/** + * Resize the scrollbar to the new dimensions. + * + * @param width The new width. + * @param height The new height. + */ + +void CScrollbarVertical::onResize(nxgl_coord_t width, nxgl_coord_t height) +{ + // Remember current values + + nxgl_coord_t value = getValue(); + bool events = raisesEvents(); + + // Disable event raising + + setRaisesEvents(false); + + // Resize and move children + + m_slider->resize(width, height - (m_buttonHeight << 1)); + m_upButton->moveTo(0, m_slider->getHeight()); + m_downButton->moveTo(0, m_slider->getHeight() + m_buttonHeight); + + // Set back to current value + + setValue(value); + + // Reset event raising + + setRaisesEvents(events); +} diff --git a/NxWidgets/libnxwidgets/src/cscrollinglistbox.cxx b/NxWidgets/libnxwidgets/src/cscrollinglistbox.cxx new file mode 100644 index 000000000..e0d041d34 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cscrollinglistbox.cxx @@ -0,0 +1,415 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cscrollinglistbox.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cscrollinglistbox.hxx" +#include "cscrollbarvertical.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The widget control for the display. + * @param x The x coordinate of the widget. + * @param y The y coordinate of the widget. + * @param width The width of the widget. + * @param height The height of the widget. + * @param style The style that the widget should use. If this is not + * specified, the widget will use the values stored in the global + * g_defaultWidgetStyle object. The widget will copy the properties of + * the style into its own internal style object. + */ + +CScrollingListBox::CScrollingListBox(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + CWidgetStyle *style) +: CNxWidget(pWidgetControl, x, y, width, height, 0, style) +{ + m_scrollbarWidth = 10; + + setBorderless(true); + + m_listbox = new CListBox(pWidgetControl, 0, 0, width - m_scrollbarWidth, + height, &m_style); + m_listbox->addWidgetEventHandler(this); + + // Create scrollbar + + CRect rect; + m_listbox->getClientRect(rect); + m_scrollbar = new CScrollbarVertical(pWidgetControl, width - m_scrollbarWidth, + 0, m_scrollbarWidth, height, &m_style); + m_scrollbar->setMinimumValue(0); + m_scrollbar->setMaximumValue(0); + m_scrollbar->setPageSize(rect.getHeight() / m_listbox->getOptionHeight()); + m_scrollbar->addWidgetEventHandler(this); + + // Add children to child array + + addWidget(m_listbox); + addWidget(m_scrollbar); +} + +/** + * Add a new option to the widget using default colors. + * + * @param text Text to show in the option. + * @param value The value of the option. + */ + +void CScrollingListBox::addOption(const CNxString &text, const uint32_t value) +{ + m_listbox->addOption(text, value); + m_scrollbar->setMaximumValue(m_listbox->getOptionCount() - 1); +} + +/** + * Add an option to the widget. + * + * @param option The option to add. + */ + +void CScrollingListBox::addOption(CListBoxDataItem *item) +{ + m_listbox->addOption(item); + m_scrollbar->setMaximumValue(m_listbox->getOptionCount() - 1); +} + +/** + * Add a new option to the widget. + * + * @param text Text to show in the option. + * @param value The value of the option. + * @param normalTextColor Color to draw the text with when not selected. + * @param normalBackColor Color to draw the background with when not selected. + * @param selectedTextColor Color to draw the text with when selected. + * @param selectedBackColor Color to draw the background with when selected. + */ + +void CScrollingListBox::addOption(const CNxString &text, const uint32_t value, + const nxwidget_pixel_t normalTextColor, + const nxwidget_pixel_t normalBackColor, + const nxwidget_pixel_t selectedTextColor, + const nxwidget_pixel_t selectedBackColor) +{ + m_listbox->addOption(text, value, normalTextColor, normalBackColor, + selectedTextColor, selectedBackColor); + m_scrollbar->setMaximumValue(m_listbox->getOptionCount() - 1); +} + +/** + * Remove an option from the widget by its index. + * + * @param index The index of the option to remove. + */ + +void CScrollingListBox::removeOption(const int index) +{ + m_listbox->removeOption(index); + m_scrollbar->setMaximumValue(m_listbox->getOptionCount() - 1); + + // Reposition grip if necessary + + if (m_scrollbar->getValue() > m_listbox->getOptionCount()) + { + m_scrollbar->setValue(0); + } +} + +/** + * Remove all options from the widget. + */ + +void CScrollingListBox::removeAllOptions(void) +{ + m_listbox->removeAllOptions(); + m_scrollbar->setMaximumValue(0); + m_scrollbar->setValue(0); +} + +/** + * Handles events raised by its sub-widgets. + * + * @param e Event arguments. + */ + +void CScrollingListBox::handleValueChangeEvent(const CWidgetEventArgs &e) +{ + if (e.getSource() != NULL) + { + if (e.getSource() == m_scrollbar) + { + if (m_listbox != NULL) + { + m_listbox->setRaisesEvents(false); + m_listbox->jump(0, 0 - (m_scrollbar->getValue() * m_listbox->getOptionHeight())); + m_listbox->setRaisesEvents(true); + } + } + else if (e.getSource() == m_listbox) + { + m_widgetEventHandlers->raiseValueChangeEvent(); + } + } +} + +/** + * Handle a widget action event. + * + * @param e The event data. + */ + +void CScrollingListBox::handleActionEvent(const CWidgetEventArgs &e) +{ + if (e.getSource() != NULL) + { + if (e.getSource() == m_listbox) + { + // Raise action events from list box to event handler + + m_widgetEventHandlers->raiseActionEvent(); + } + } +} + +/** + * Handles events raised by its sub-widgets. + * + * @param e Event arguments. + */ + +void CScrollingListBox::handleScrollEvent(const CWidgetEventArgs &e) +{ + if (e.getSource() != NULL) + { + if (e.getSource() == m_listbox) + { + if (m_scrollbar != NULL) + { + m_scrollbar->setRaisesEvents(false); + + int value = ((0 - m_listbox->getCanvasY()) << 16) / m_listbox->getOptionHeight(); + + m_scrollbar->setValueWithBitshift(value); + m_scrollbar->setRaisesEvents(true); + } + } + } +} + +/** + * Handle a mouse button click event. + * + * @param e The event data. + */ + +void CScrollingListBox::handleClickEvent(const CWidgetEventArgs &e) +{ + m_widgetEventHandlers->raiseClickEvent(e.getX(), e.getY()); +} + +/** + * Handles events raised by its sub-widgets. + * + * @param e Event arguments. + */ + +void CScrollingListBox::handleDoubleClickEvent(const CWidgetEventArgs &e) +{ + m_widgetEventHandlers->raiseDoubleClickEvent(e.getX(), e.getY()); +} + +/** + * Handle a mouse button release event that occurred within the bounds of + * the source widget. + * + * @param e The event data. + */ + +void CScrollingListBox::handleReleaseEvent(const CWidgetEventArgs &e) +{ + m_widgetEventHandlers->raiseReleaseEvent(e.getX(), e.getY()); +} + +/** + * Handle a mouse button release event that occurred outside the bounds of + * the source widget. + * + * @param e The event data. + */ + +void CScrollingListBox::handleReleaseOutsideEvent(const CWidgetEventArgs &e) +{ + // Child raised a release outside event, but we need to raise a different + // event if the release occurred within the bounds of this parent widget + + if (checkCollision(e.getX(), e.getY())) + { + m_widgetEventHandlers->raiseReleaseEvent(e.getX(), e.getY()); + } + else + { + m_widgetEventHandlers->raiseReleaseOutsideEvent(e.getX(), e.getY()); + } +} + +/** + * Set the font used in the textbox. + * + * @param font Pointer to the new font. + */ + +void CScrollingListBox::setFont(CNxFont *font) +{ + m_style.font = font; + m_listbox->setFont(font); + m_scrollbar->setFont(font); +} + +/** + * Insert the dimensions that this widget wants to have into the rect + * passed in as a parameter. All coordinates are relative to the widget's + * parent. Value is based on the length of the largest string in the + * set of options. + * + * @param rect Reference to a rect to populate with data. + */ + +void CScrollingListBox::getPreferredDimensions(CRect &rect) const +{ + // Get the listbox's preferred dimensions + + m_listbox->getPreferredDimensions(rect); + + // Add on the scrollbar width + + nxgl_coord_t width = rect.getWidth(); + rect.setWidth(width + m_scrollbarWidth); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CScrollingListBox::drawContents(CGraphicsPort *port) +{ + port->drawFilledRect(0, 0, getWidth(), getHeight(), getBackgroundColor()); +} + +/** + * Resize the listbox to the new dimensions. + * + * @param width The new width. + * @param height The new height. + */ + +void CScrollingListBox::onResize(nxgl_coord_t width, nxgl_coord_t height) +{ + // Resize the children + + m_listbox->resize(width - m_scrollbarWidth, height); + m_scrollbar->resize(m_scrollbarWidth, height); + + // Adjust scrollbar page size + + CRect rect; + getClientRect(rect); + m_scrollbar->setPageSize(rect.getHeight() / m_listbox->getOptionHeight()); + + // Move the scrollbar + + m_scrollbar->moveTo(width - m_scrollbarWidth, 0); +} + + + + diff --git a/NxWidgets/libnxwidgets/src/cscrollingpanel.cxx b/NxWidgets/libnxwidgets/src/cscrollingpanel.cxx new file mode 100644 index 000000000..d3ee40cf9 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cscrollingpanel.cxx @@ -0,0 +1,320 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cscrollingpanel.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cwidgetcontrol.hxx" +#include "cscrollingpanel.hxx" +#include "cgraphicsport.hxx" +#include "singletons.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The widget control for the display. + * @param x The x coordinate of the widget. + * @param y The y coordinate of the widget. + * @param width The width of the widget. + * @param height The height of the widget. + * @param flags The usual widget flags. + * @param style The style that the widget should use. If this is not + * specified, the widget will use the values stored in the global + * g_defaultWidgetStyle object. The widget will copy the properties of + * the style into its own internal style object. + */ + +CScrollingPanel::CScrollingPanel(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + uint32_t flags, CWidgetStyle* style) +: CNxWidget(pWidgetControl, x, y, width, height, flags, style) +{ + m_widgetControl = pWidgetControl; + CRect rect; + getClientRect(rect); + + m_canvasWidth = rect.getWidth(); + m_canvasHeight = rect.getHeight(); + m_canvasX = 0; + m_canvasY = 0; + + setAllowsVerticalScroll(true); + setAllowsHorizontalScroll(true); + setContentScrolled(true); + + m_flags.permeable = true; +} + +/** + * Scroll the panel by the specified amounts. + * + * @param dx The horizontal distance to scroll. + * @param dy The vertical distance to scroll. + */ + +void CScrollingPanel::scroll(int32_t dx, int32_t dy) +{ + CRect rect; + getClientRect(rect); + + // Prevent scrolling outside boundaries + + if (m_canvasX + dx < -(m_canvasWidth - rect.getWidth())) + { + dx = -(m_canvasWidth - rect.getWidth()) - m_canvasX; + } + else if (m_canvasX + dx > 0) + { + dx = -m_canvasX; + } + + if (m_canvasY + dy < -(m_canvasHeight - rect.getHeight())) + { + dy = -(m_canvasHeight - rect.getHeight()) - m_canvasY; + } + else if (m_canvasY + dy > 0) + { + dy = -m_canvasY; + } + + // Prevent scrolling in disallowed planes + + if (!allowsVerticalScroll()) + { + dy = 0; + } + + if (!allowsHorizontalScroll()) + { + dx = 0; + } + + // Perform scroll if necessary + + if ((dx != 0) || (dy != 0)) + { + // Only scroll if content scrolling is enabled + + if (m_isContentScrolled) + { + // Perform scroll + + TNxArray<CRect> revealedRects; + CGraphicsPort *port = m_widgetControl->getGraphicsPort(); + port->move(getX(), getY(), dx, dy, rect.getWidth(), rect.getHeight()); + + // Adjust the scroll values + + m_canvasY += dy; + m_canvasX += dx; + + if (revealedRects.size() > 0) + { + // Draw revealed sections + + for (int i = 0; i < revealedRects.size(); ++i) + { + drawBorder(port); + drawContents(port); + } + } + } + else + { + // Adjust the scroll values + + m_canvasY += dy; + m_canvasX += dx; + } + + // Scroll all child widgets + + scrollChildren(dx, dy); + + // Notify event handlers + + m_widgetEventHandlers->raiseScrollEvent(dx, dy); + } +} + +/** + * Reposition the panel's scrolling region to the specified coordinates. + * + * @param x The new x coordinate of the scrolling region. + * @param y The new y coordinate of the scrolling region. + */ + +void CScrollingPanel::jump(int32_t x, int32_t y) +{ + // Calculate difference between jump value and current value and scroll + + scroll(x - m_canvasX, y - m_canvasY); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CScrollingPanel::drawContents(CGraphicsPort *port) +{ + port->drawFilledRect(getX(), getY(), getWidth(), getHeight(), + getBackgroundColor()); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CScrollingPanel::drawBorder(CGraphicsPort *port) +{ + // Stop drawing if the widget indicates it should not have an outline + + if (!isBorderless()) + { + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), + getShadowEdgeColor(), getShineEdgeColor()); + } +} + +/** + * Scrolls the panel to match the drag. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + * @param vX The horizontal drag distance. + * @param vY The vertical drag distance. + */ + +void CScrollingPanel::onDrag(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t vX, nxgl_coord_t vY) +{ + scroll(vX, vY); +} + +/** + * Starts the dragging system. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CScrollingPanel::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + startDragging(x, y); +} + +/** + * Scroll all child widgets by the specified amounts. Actually uses + * the widget's moveTo() function to reposition them. + * + * @param dx The horizontal distance to scroll. + * @param dy The vertical distance to scroll. + */ + +void CScrollingPanel::scrollChildren(int32_t dx, int32_t dy) +{ + nxgl_coord_t widgetX = 0; + nxgl_coord_t widgetY = 0; + nxgl_coord_t thisX = getX(); + nxgl_coord_t thisY = getY(); + CNxWidget *widget = (CNxWidget *)NULL; + + for (int32_t i = 0; i < m_children.size(); i++) + { + widget = m_children[i]; + widgetX = (widget->getX() - thisX) + dx; + widgetY = (widget->getY() - thisY) + dy; + widget->moveTo(widgetX, widgetY); + } +} diff --git a/NxWidgets/libnxwidgets/src/cscrollingtextbox.cxx b/NxWidgets/libnxwidgets/src/cscrollingtextbox.cxx new file mode 100644 index 000000000..4de63fdf6 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cscrollingtextbox.cxx @@ -0,0 +1,577 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cscrollingtextbox.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cscrollingtextbox.hxx" +#include "cscrollbarvertical.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The widget control for the display. + * @param x The x coordinate of the text box, relative to its parent. + * @param y The y coordinate of the text box, relative to its parent. + * @param width The width of the textbox. + * @param height The height of the textbox. + * @param text Pointer to a string to display in the textbox. + * @param flags Standard widget flag options. + * @param maxRows The maximum number of rows the textbox can track. Adding + * text beyond this number will cause rows at the start of the text to be + * forgotten; text is essentially stored as a queue, and adding to the back + * of a full queue causes the front items to be popped off. Setting this to + * 0 will make the textbox track only the visible rows. + * @param style The style that the widget should use. If this is not + * specified, the widget will use the values stored in the global + * g_defaultWidgetStyle object. The widget will copy the properties of + * the style into its own internal style object. + */ + +CScrollingTextBox::CScrollingTextBox(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + const CNxString &text, uint32_t flags, + nxgl_coord_t maxRows, CWidgetStyle *style) +: CNxWidget(pWidgetControl, x, y, width, height, flags, style) +{ + m_scrollbarWidth = 10; + setBorderless(true); + + m_texbox = new CMultiLineTextBox(pWidgetControl, + 0, 0, width - m_scrollbarWidth, height, + text, flags, maxRows, &m_style); + m_texbox->addWidgetEventHandler(this); + + // Create scrollbar + + CRect rect; + m_texbox->getClientRect(rect); + m_scrollbar = new CScrollbarVertical(pWidgetControl, + width - m_scrollbarWidth, 0, + m_scrollbarWidth, height, &m_style); + m_scrollbar->setMinimumValue(0); + m_scrollbar->setMaximumValue(m_texbox->getCanvasHeight()); + m_scrollbar->setPageSize(rect.getHeight()); + m_scrollbar->setValue(0 - m_texbox->getCanvasY()); + m_scrollbar->addWidgetEventHandler(this); + + // Add children to child array + + addWidget(m_texbox); + addWidget(m_scrollbar); +} + +/** + * Set the horizontal alignment of text within the textbox. + * + * @param alignment The horizontal position of the text. + */ + +void CScrollingTextBox::setTextAlignmentHoriz(CMultiLineTextBox::TextAlignmentHoriz alignment) +{ + m_texbox->setTextAlignmentHoriz(alignment); +} + +/** + * Set the vertical alignment of text within the textbox. + * + * @param alignment The vertical position of the text. + */ + +void CScrollingTextBox::setTextAlignmentVert(CMultiLineTextBox::TextAlignmentVert alignment) +{ + m_texbox->setTextAlignmentVert(alignment); +} + +/** + * Returns the number of "pages" that the text spans. A page + * is defined as the amount of text that can be displayed within + * the textbox at one time. + * + * @return The page count. + */ + +const uint16_t CScrollingTextBox::getPageCount(void) const +{ + return m_texbox->getPageCount(); +} + +/** + * Returns the current page. + * + * @return The current page. + * @see getPageCount(). + */ + +const uint16_t CScrollingTextBox::getCurrentPage(void) const +{ + return m_texbox->getCurrentPage(); +} + +/** + * Returns a pointer to the Text object that contains the + * wrapped text used in the textbox. It is used as the + * pre-processed data source for the textbox, and should + * not be altered. + * + * @return Pointer to the Text object. + */ + +const CText *CScrollingTextBox::getText(void) const +{ + return m_texbox->getText(); +} + +/** + * Set the text displayed in the textbox. + * + * @param text String to display. + */ + +void CScrollingTextBox::setText(const CNxString &text) +{ + m_texbox->setText(text); + m_scrollbar->redraw(); +} + +/** + * Append new text to the end of the current text + * displayed in the textbox. + * + * @param text String to append. + */ + +void CScrollingTextBox::appendText(const CNxString &text) +{ + m_texbox->appendText(text); + m_scrollbar->redraw(); +} + +/** + * Remove all characters from the string from the start index onwards. + * + * @param startIndex Index to remove from. + */ + +void CScrollingTextBox::removeText(const unsigned int startIndex) +{ + m_texbox->removeText(startIndex); + m_scrollbar->redraw(); +} + +/** + * Remove specified number of characters from the string from the + * start index onwards. + * + * @param startIndex Index to remove from. + * @param count Number of characters to remove. + */ + +void CScrollingTextBox::removeText(const unsigned int startIndex, + const unsigned int count) +{ + m_texbox->removeText(startIndex, count); + m_scrollbar->redraw(); +} + +/** + * Set the font used in the textbox. + * + * @param font Pointer to the new font. + */ + +void CScrollingTextBox::setFont(CNxFont *font) +{ + m_style.font = font; + m_texbox->setFont(font); + m_scrollbar->setFont(font); +} + +/** + * Get the length of the text string. + * + * @return The length of the text string. + */ + +const unsigned int CScrollingTextBox::getTextLength(void) const +{ + return m_texbox->getTextLength(); +} + +/** + * Sets the cursor display mode. + * + * @param cursorMode Determines cursor display mode + */ + +void CScrollingTextBox::showCursor(EShowCursor cursorMode) +{ + m_texbox->showCursor(cursorMode); +} + +/** + * Enables/disables cursor wrapping + * + * @param wrap True enables cursor wrapping + */ + +void CScrollingTextBox::wrapCursor(bool wrap) +{ + m_texbox->wrapCursor(wrap); +} + +/** + * Move the cursor to the text position specified. 0 indicates the start + * of the string. If position is greater than the length of the string, + * the cursor is moved to the end of the string. + * + * @param position The new cursor position. + */ + +void CScrollingTextBox::moveCursorToPosition(const int32_t position) +{ + m_texbox->moveCursorToPosition(position); + m_scrollbar->redraw(); +} + +/** + * Get the cursor position. This is the index within the string that + * the cursor is currently positioned over. + * + * @return position The cursor position. + */ + +const int32_t CScrollingTextBox::getCursorPosition(void) const +{ + return m_texbox->getCursorPosition(); +} + +/** + * Insert text at the specified index. + * + * @param text The text to insert. + * @param index Index at which to insert the text. + */ + +void CScrollingTextBox::insertText(const CNxString &text, + const unsigned int index) +{ + m_texbox->insertText(text, index); + m_scrollbar->redraw(); +} + +/** + * Insert text at the current cursor position. + * + * @param text The text to insert. + */ + +void CScrollingTextBox::insertTextAtCursor(const CNxString &text) +{ + m_texbox->insertTextAtCursor(text); + m_scrollbar->redraw(); +} + +/** + * Handles events raised by its sub-widgets. + * + * @param e Event arguments. + */ + +void CScrollingTextBox::handleValueChangeEvent(const CWidgetEventArgs &e) +{ + if (e.getSource() != NULL) + { + if (e.getSource() == m_scrollbar) + { + if (m_texbox != NULL) + { + m_texbox->setRaisesEvents(false); + m_texbox->jump(0, 0 - m_scrollbar->getValue()); + m_texbox->setRaisesEvents(true); + } + } + else if (e.getSource() == m_texbox) + { + if (m_scrollbar != NULL) + { + m_scrollbar->setRaisesEvents(false); + m_scrollbar->setMaximumValue(m_texbox->getCanvasHeight()); + m_scrollbar->setValue(0 - m_texbox->getCanvasY()); + m_scrollbar->setRaisesEvents(true); + } + } + } +} + +/** + * Handles events raised by its sub-widgets. + * + * @param e Event arguments. + */ + +void CScrollingTextBox::handleScrollEvent(const CWidgetEventArgs &e) +{ + if (e.getSource() != NULL) + { + if (e.getSource() == m_texbox) + { + if (m_scrollbar != NULL) + { + m_scrollbar->setRaisesEvents(false); + m_scrollbar->setValue(0 - m_texbox->getCanvasY()); + m_scrollbar->setRaisesEvents(true); + } + } + } +} + +/** + * Gets the x coordinate of the virtual canvas. + * + * @return The x coordinate of the virtual canvas. + */ + +const int32_t CScrollingTextBox::getCanvasX(void) const +{ + return m_texbox->getCanvasX(); +} + +/** + * Gets the y coordinate of the virtual canvas. + * + * @return The y coordinate of the virtual canvas. + */ + +const int32_t CScrollingTextBox::getCanvasY(void) const +{ + return m_texbox->getCanvasY(); +} + +/** + * Gets the width of the virtual canvas. + * + * @return The width of the virtual canvas. + */ + +const int32_t CScrollingTextBox::getCanvasWidth(void) const +{ + return m_texbox->getCanvasWidth(); +} + +/** + * Gets the height of the virtual canvas. + * + * @return The height of the virtual canvas. + */ + +const int32_t CScrollingTextBox::getCanvasHeight(void) const +{ + return m_texbox->getCanvasHeight(); +} + +/** + * Scroll the panel by the specified amounts. + * + * @param dx The horizontal distance to scroll. + * @param dy The vertical distance to scroll. + */ + +void CScrollingTextBox::scroll(int32_t dx, int32_t dy) +{ + m_texbox->scroll(dx, dy); +} + +/** + * Reposition the panel's scrolling region to the specified coordinates. + * + * @param x The new x coordinate of the scrolling region. + * @param y The new y coordinate of the scrolling region. + */ + +void CScrollingTextBox::jump(int32_t x, int32_t y) +{ + m_texbox->jump(x, y); +} + +/** + * Set whether or not horizontal scrolling is allowed. + * + * @param allow True to allow horizontal scrolling; false to deny it. + */ + +void CScrollingTextBox::setAllowsVerticalScroll(bool allow) +{ + m_texbox->setAllowsVerticalScroll(allow); +} + +/** + * Set whether or not horizontal scrolling is allowed. + * + * @param allow True to allow horizontal scrolling; false to deny it. + */ + +void CScrollingTextBox::setAllowsHorizontalScroll(bool allow) +{ + // NOP +} + +/** + * Sets the width of the virtual canvas. + * + * @param width The width of the virtual canvas. + */ + +void CScrollingTextBox::setCanvasWidth(const int32_t width) +{ + // NOP +} + +/** + * Sets the height of the virtual canvas. + * + * @param height The height of the virtual canvas. + */ + +void CScrollingTextBox::setCanvasHeight(const int32_t height) +{ + // NOP +} + +/** + * Returns true if vertical scrolling is allowed. + * + * @return True if vertical scrolling is allowed. + */ + +bool CScrollingTextBox::allowsVerticalScroll(void) const +{ + return m_texbox->allowsVerticalScroll(); +} + +/** + * Returns true if horizontal scrolling is allowed. + * + * @return True if horizontal scrolling is allowed. + */ + +bool CScrollingTextBox::allowsHorizontalScroll(void) const +{ + return m_texbox->allowsHorizontalScroll(); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CScrollingTextBox::drawContents(CGraphicsPort *port) +{ + port->drawFilledRect(0, 0, getWidth(), getHeight(), getBackgroundColor()); +} + +/** + * Resize the textbox to the new dimensions. + * + * @param width The new width. + * @param height The new height. + */ + +void CScrollingTextBox::onResize(nxgl_coord_t width, nxgl_coord_t height) +{ + // Resize the children + + m_texbox->resize(width - m_scrollbarWidth, height); + m_scrollbar->resize(m_scrollbarWidth, height); + + // Move the scrollbar + + m_scrollbar->moveTo(width - m_scrollbarWidth, 0); +} diff --git a/NxWidgets/libnxwidgets/src/csliderhorizontal.cxx b/NxWidgets/libnxwidgets/src/csliderhorizontal.cxx new file mode 100644 index 000000000..2fe47556c --- /dev/null +++ b/NxWidgets/libnxwidgets/src/csliderhorizontal.cxx @@ -0,0 +1,402 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/csliderhorizontal.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cwidgetcontrol.hxx" +#include "csliderhorizontal.hxx" +#include "csliderhorizontalgrip.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The controlling widget for the display + * @param x The x coordinate of the slider, relative to its parent. + * @param y The y coordinate of the slider, relative to its parent. + * @param width The width of the slider. + * @param height The height of the slider. + */ + +CSliderHorizontal::CSliderHorizontal(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height) +: CNxWidget(pWidgetControl, x, y, width, height, WIDGET_DRAGGABLE) +{ + m_minimumValue = 0; + m_maximumValue = 0; + m_contentSize = 0; + m_value = 0; + m_minimumGripWidth = 10; + m_pageSize = 1; + + m_flags.permeable = false; + m_flags.borderless = false; + m_flags.doubleClickable = false; + + // Create grip + + CRect rect; + getClientRect(rect); + + m_grip = new CSliderHorizontalGrip(pWidgetControl, rect.getX(), rect.getY(), + rect.getWidth(), rect.getHeight()); + m_grip->addWidgetEventHandler(this); + addWidget(m_grip); + + m_gutterWidth = rect.getWidth(); +} + +/** + * Set the value that of the slider. This will reposition + * and redraw the grip. + * + * @param value The new value. + */ + +void CSliderHorizontal::setValue(const nxgl_coord_t value) +{ + setValueWithBitshift((int32_t)value << 16); +} + +/** + * Set the value that of the slider. This will reposition and redraw + * the grip. The supplied value should be bitshifted left 16 places. + * This ensures greater accuracy than the standard setValue() method if + * the slider is being used as a scrollbar. + * + * @param value The new value. + */ + +void CSliderHorizontal::setValueWithBitshift(const int32_t value) +{ + CRect rect; + getClientRect(rect); + + // Can the grip move? + + if ((rect.getWidth() > m_grip->getWidth()) && (m_maximumValue != m_minimumValue)) + { + int32_t newValue = value; + int32_t maxValue = getPhysicalMaximumValueWithBitshift(); + + // Limit to max/min values + + if (newValue > maxValue) + { + newValue = maxValue; + } + + if (newValue >> 16 < m_minimumValue) + { + newValue = m_minimumValue << 16; + } + + uint32_t scrollRatio = newValue / m_contentSize; + int32_t newGripX = m_gutterWidth * scrollRatio; + newGripX += newGripX & 0x8000; + newGripX >>= 16; + newGripX += rect.getX(); + + m_grip->moveTo(newGripX, rect.getY()); + + // Update stored value if necessary + + if (m_value != newValue) + { + m_value = newValue; + m_widgetEventHandlers->raiseValueChangeEvent(); + } + } +} + +/** + * Process events fired by the grip. + * + * @param e The event details. + */ + +void CSliderHorizontal::handleDragEvent(const CWidgetEventArgs &e) +{ + // Handle grip events + + if ((e.getSource() == m_grip) && (e.getSource() != NULL)) + { + int32_t newValue = getGripValue() >> 16; + + // Grip has moved - compare values and raise event if the + // value has changed. Compare using integer values rather + // than fixed-point. + + if (m_value >> 16 != newValue) + { + m_value = newValue << 16; + m_widgetEventHandlers->raiseValueChangeEvent(); + } + } +} + +/** + * Get the smallest value that the slider can move through when + * dragged. + * + * @return The smallest value that the slider can move through when + * dragged. + */ + +nxgl_coord_t CSliderHorizontal::getMinimumStep(void) const +{ + // If the ratio of content to gutter is greater than or equal to one, + // the minimum step that the slider can represent will be that ratio. + + uint32_t gutterRatio = m_contentSize << 16 / m_gutterWidth; + gutterRatio += gutterRatio & 0x8000; + gutterRatio >>= 16; + + if (gutterRatio > 0) + { + return gutterRatio; + } + + return 1; +} + +/** + * Get the maximum possible value that the slider can represent. Useful when + * using the slider as a scrollbar, as the height of the grip prevents the full + * range of values being accessed (intentionally). + * The returned value is bitshfted left 16 places for more accuracy in fixed-point + * calculations. + * + * @return The maximum possible value that the slider can represent. + */ + +int32_t CSliderHorizontal::getPhysicalMaximumValueWithBitshift(void) const +{ + uint32_t maxX = m_gutterWidth - m_grip->getWidth(); + uint32_t scrollRatio = (maxX << 16) / m_gutterWidth; + int32_t value = (scrollRatio * m_contentSize); + + return value; +} + +/** + * Get the value represented by the top of the grip. + * return The value represented by the top of the grip. + */ + +const int32_t CSliderHorizontal::getGripValue(void) const +{ + // Calculate the current value represented by the top of the grip + + CRect rect; + getClientRect(rect); + + uint32_t gripPos = ((m_grip->getX() - getX()) - rect.getX()); + uint32_t scrollRatio = (gripPos << 16) / m_gutterWidth; + int32_t value = (scrollRatio * m_contentSize); + + return value; +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CSliderHorizontal::drawContents(CGraphicsPort *port) +{ + CRect rect; + getRect(rect); + + port->drawFilledRect(rect.getX(), rect.getY(), + rect.getWidth(), rect.getHeight(), + getSelectedBackgroundColor()); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CSliderHorizontal::drawBorder(CGraphicsPort *port) +{ + // Stop drawing if the widget indicates it should not have an outline + + if (!isBorderless()) + { + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), + getShadowEdgeColor(), getShineEdgeColor()); + } +} + +/** + * Resize the slider to the new dimensions. + * + * @param width The new width. + * @param height The new height. + */ + +void CSliderHorizontal::onResize(nxgl_coord_t width, nxgl_coord_t height) +{ + // Remember current values + + int32_t oldValue = m_value; + bool events = raisesEvents(); + + // Disable event raising + + setRaisesEvents(false); + resizeGrip(); + + // Set back to current value + + setValue(oldValue); + + // Reset event raising + + setRaisesEvents(events); +} + +/** + * Moves the grip towards the mouse. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CSliderHorizontal::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + // Which way should the grip move? + + if (x > m_grip->getX()) + { + // Move grip right + + setValueWithBitshift(m_value + (m_pageSize << 16)); + } + else + { + // Move grip left + + setValueWithBitshift(m_value - (m_pageSize << 16)); + } +} + +/** + * Resize and redraw the grip. + */ + +void CSliderHorizontal::resizeGrip(void) +{ + // Get available size + + CRect rect; + getClientRect(rect); + + int32_t gripRatio = (m_pageSize << 16) / m_contentSize; + int32_t gripSize = rect.getWidth() * gripRatio; + gripSize >>= 16; + m_gutterWidth = rect.getWidth(); + + if (gripSize < m_minimumGripWidth) + { + // TODO: Need to implement scaling here. If we resize the grip to be + // artificially larger, we effectively reduce the scale (not just the + // height) of the gutter. Each position in the gutter needs to be + // reduced in value. + } + + m_grip->resize(gripSize, rect.getHeight()); +} + + diff --git a/NxWidgets/libnxwidgets/src/csliderhorizontalgrip.cxx b/NxWidgets/libnxwidgets/src/csliderhorizontalgrip.cxx new file mode 100644 index 000000000..aebdbf51d --- /dev/null +++ b/NxWidgets/libnxwidgets/src/csliderhorizontalgrip.cxx @@ -0,0 +1,246 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/csliderhorizontalgrip.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "csliderhorizontalgrip.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The controlling widget for the display + * @param x The x coordinate of the grip, relative to its parent. + * @param y The y coordinate of the grip, relative to its parent. + * @param width The width of the grip. + * @param height The height of the grip. + */ + +CSliderHorizontalGrip::CSliderHorizontalGrip(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height) +: CNxWidget(pWidgetControl, x, y, width, height, WIDGET_DRAGGABLE) +{ +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CSliderHorizontalGrip::drawContents(CGraphicsPort *port) +{ + CRect rect; + getRect(rect); + + nxwidget_pixel_t color; + if (!m_flags.clicked) + { + color = getSelectedBackgroundColor(); + } + else + { + color = getHighlightColor(); + } + + port->drawFilledRect(rect.getX(), rect.getY(), + rect.getWidth(), rect.getHeight(), + color); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CSliderHorizontalGrip::drawBorder(CGraphicsPort *port) +{ + // Stop drawing if the widget indicates it should not have an outline + + if (!isBorderless()) + { + if (isClicked()) + { + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), + getShadowEdgeColor(), getShineEdgeColor()); + } + else + { + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), + getShineEdgeColor(), getShadowEdgeColor()); + } + } +} + +/** + * Starts dragging the grip and redraws it. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CSliderHorizontalGrip::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + startDragging(x, y); + redraw(); +} + +/** + * Redraws the grip. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + */ + +void CSliderHorizontalGrip::onRelease(nxgl_coord_t x, nxgl_coord_t y) +{ + redraw(); +} + +/** + * Redraws the grip. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + */ + +void CSliderHorizontalGrip::onReleaseOutside(nxgl_coord_t x, nxgl_coord_t y) +{ + redraw(); +} + +/** + * Moves the grip to follow the mouse. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + * @param vX The horizontal distance of the drag. + * @param vY The vertical distance of the drag. + */ + +void CSliderHorizontalGrip::onDrag(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t vX, nxgl_coord_t vY) +{ + // Work out where we're moving to + + nxgl_coord_t destX = x - m_grabPointX - m_parent->getX(); + + // Do we need to move? + + if (destX != m_rect.getX()) + { + // Get parent rect + + CRect rect; + m_parent->getClientRect(rect); + + // Prevent grip from moving outside parent + + if (destX < rect.getX()) + { + destX = rect.getX(); + } + else + { + if (destX + getWidth() > rect.getWidth() + rect.getX()) + { + destX = (rect.getWidth() + rect.getX()) - getWidth() ; + } + } + + // Move to new location + + moveTo(destX, rect.getY()); + } +} diff --git a/NxWidgets/libnxwidgets/src/cslidervertical.cxx b/NxWidgets/libnxwidgets/src/cslidervertical.cxx new file mode 100644 index 000000000..74d2d956b --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cslidervertical.cxx @@ -0,0 +1,402 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cslidervertical.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cwidgetcontrol.hxx" +#include "cslidervertical.hxx" +#include "csliderverticalgrip.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param pWidgetControl The controlling widget for the display + * @param x The x coordinate of the slider, relative to its parent. + * @param y The y coordinate of the slider, relative to its parent. + * @param width The width of the slider. + * @param height The height of the slider. + */ + +CSliderVertical::CSliderVertical(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height) +: CNxWidget(pWidgetControl, x, y, width, height, WIDGET_DRAGGABLE) +{ + m_minimumValue = 0; + m_maximumValue = 0; + m_contentSize = 0; + m_value = 0; + m_minimumGripHeight = 10; + m_pageSize = 1; + + m_flags.permeable = false; + m_flags.borderless = false; + m_flags.doubleClickable = false; + + // Create grip + + CRect rect; + getClientRect(rect); + + m_grip = new CSliderVerticalGrip(pWidgetControl, + rect.getX(), rect.getY(), + rect.getWidth(), rect.getHeight()); + m_grip->addWidgetEventHandler(this); + addWidget(m_grip); + + m_gutterHeight = rect.getHeight(); +} + +/** + * Set the value that of the slider. This will reposition + * and redraw the grip. + * + * @param value The new value. + */ + +void CSliderVertical::setValue(const nxgl_coord_t value) +{ + setValueWithBitshift((int32_t)value << 16); +} + +/** + * Set the value that of the slider. This will reposition and redraw + * the grip. The supplied value should be bitshifted left 16 places. + * This ensures greater accuracy than the standard setValue() method if + * the slider is being used as a scrollbar. + * + * @param value The new value. + */ + +void CSliderVertical::setValueWithBitshift(const int32_t value) +{ + CRect rect; + getClientRect(rect); + + // Can the grip move? + + if ((rect.getHeight() > m_grip->getHeight()) && (m_maximumValue != m_minimumValue)) + { + int32_t newValue = value; + int32_t maxValue = getPhysicalMaximumValueWithBitshift(); + + // Limit to max/min values + + if (newValue > maxValue) + { + newValue = maxValue; + } + + if (newValue >> 16 < m_minimumValue) + { + newValue = m_minimumValue << 16; + } + + uint32_t scrollRatio = newValue / m_contentSize; + int32_t newGripY = m_gutterHeight * scrollRatio; + newGripY += newGripY & 0x8000; + newGripY >>= 16; + newGripY += rect.getY(); + + m_grip->moveTo(rect.getX(), newGripY); + + // Update stored value if necessary + + if (m_value != newValue) + { + m_value = newValue; + m_widgetEventHandlers->raiseValueChangeEvent(); + } + } +} + +/** + * Process events fired by the grip. + * + * @param e The event details. + */ + +void CSliderVertical::handleDragEvent(const CWidgetEventArgs &e) +{ + // Handle grip events + + if ((e.getSource() == m_grip) && (e.getSource() != NULL)) + { + int32_t newValue = getGripValue() >> 16; + + // Grip has moved - compare values and raise event if the + // value has changed. Compare using integer values rather + // than fixed-point. + + if (m_value >> 16 != newValue) + { + m_value = newValue << 16; + m_widgetEventHandlers->raiseValueChangeEvent(); + } + } +} + +/** + * Get the smallest value that the slider can move through when + * dragged. + * + * @return The smallest value that the slider can move through when + * dragged. + */ + +nxgl_coord_t CSliderVertical::getMinimumStep(void) const +{ + // If the ratio of content to gutter is greater than or equal to one, + // the minimum step that the slider can represent will be that ratio. + + uint32_t gutterRatio = m_contentSize << 16 / m_gutterHeight; + gutterRatio += gutterRatio & 0x8000; + gutterRatio >>= 16; + + if (gutterRatio > 0) + { + return gutterRatio; + } + + return 1; +} + +/** + * Get the maximum possible value that the slider can represent. Useful when + * using the slider as a scrollbar, as the height of the grip prevents the full + * range of values being accessed (intentionally). + * The returned value is bitshfted left 16 places for more accuracy in fixed-point + * calculations. + * + * @return The maximum possible value that the slider can represent. + */ + +int32_t CSliderVertical::getPhysicalMaximumValueWithBitshift(void) const +{ + uint32_t maxY = m_gutterHeight - m_grip->getHeight(); + uint32_t scrollRatio = (maxY << 16) / m_gutterHeight; + int32_t value = (scrollRatio * m_contentSize); + + return value; +} + +/** + * Get the value represented by the top of the grip. The value is + * bitshifted left 16 places for accuracy. + * return The value represented by the top of the grip. + */ + +const int32_t CSliderVertical::getGripValue(void) const +{ + // Calculate the current value represented by the top of the grip + + CRect rect; + getClientRect(rect); + + uint32_t gripPos = ((m_grip->getY() - getY()) - rect.getY()); + uint32_t scrollRatio = (gripPos << 16) / m_gutterHeight; + int32_t value = (scrollRatio * m_contentSize); + + return value; +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CSliderVertical::drawContents(CGraphicsPort *port) +{ + CRect rect; + getRect(rect); + + port->drawFilledRect(rect.getX(), rect.getY(), + rect.getWidth(), rect.getHeight(), + getSelectedBackgroundColor()); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CSliderVertical::drawBorder(CGraphicsPort *port) +{ + // Stop drawing if the widget indicates it should not have an outline + + if (!isBorderless()) + { + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), + getShadowEdgeColor(), getShineEdgeColor()); + } +} + +/** + * Resize the slider to the new dimensions. + * + * @param width The new width. + * @param height The new height. + */ + +void CSliderVertical::onResize(nxgl_coord_t width, nxgl_coord_t height) +{ + // Remember current values + + int32_t oldValue = m_value; + bool events = raisesEvents(); + + // Disable event raising + + setRaisesEvents(false); + resizeGrip(); + + // Set back to current value + + setValue(oldValue); + + // Reset event raising + + setRaisesEvents(events); +} + +/** + * Moves the grip towards the mouse. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CSliderVertical::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + // Which way should the grip move? + + if (y > m_grip->getY()) + { + // Move grip down + + setValueWithBitshift(m_value + (m_pageSize << 16)); + } + else + { + // Move grip up + + setValueWithBitshift(m_value - (m_pageSize << 16)); + } +} + +/** + * Resize and redraw the grip. + */ + +void CSliderVertical::resizeGrip(void) +{ + // Get available size + + CRect rect; + getClientRect(rect); + + int32_t gripRatio = (m_pageSize << 16) / m_contentSize; + int32_t gripSize = rect.getHeight() * gripRatio; + gripSize >>= 16; + m_gutterHeight = rect.getHeight(); + + if (gripSize < m_minimumGripHeight) + { + // TODO: Need to implement scaling here. If we resize the grip to be + // artificially larger, we effectively reduce the scale (not just the + // height) of the gutter. Each position in the gutter needs to be + // reduced in value. + } + + m_grip->resize(rect.getWidth(), gripSize); +} diff --git a/NxWidgets/libnxwidgets/src/csliderverticalgrip.cxx b/NxWidgets/libnxwidgets/src/csliderverticalgrip.cxx new file mode 100644 index 000000000..2ddf364e8 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/csliderverticalgrip.cxx @@ -0,0 +1,245 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cslidervertical.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "csliderverticalgrip.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; +/** + * Constructor. + * + * @param pWidgetControl The controlling widget for the display + * @param x The x coordinate of the grip, relative to its parent. + * @param y The y coordinate of the grip, relative to its parent. + * @param width The width of the grip. + * @param height The height of the grip. + */ + +CSliderVerticalGrip::CSliderVerticalGrip(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height) +: CNxWidget(pWidgetControl, x, y, width, height, WIDGET_DRAGGABLE) +{ +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CSliderVerticalGrip::drawContents(CGraphicsPort *port) +{ + CRect rect; + getRect(rect); + + nxwidget_pixel_t color; + if (!m_flags.clicked) + { + color = getSelectedBackgroundColor(); + } + else + { + color = getHighlightColor(); + } + + port->drawFilledRect(rect.getX(), rect.getY(), + rect.getWidth(), rect.getHeight(), + color); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CSliderVerticalGrip::drawBorder(CGraphicsPort *port) +{ + // Stop drawing if the widget indicates it should not have an outline + + if (!isBorderless()) + { + if (isClicked()) + { + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), + getShadowEdgeColor(), getShineEdgeColor()); + } + else + { + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), + getShineEdgeColor(), getShadowEdgeColor()); + } + } +} + +/** + * Starts dragging the grip and redraws it. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CSliderVerticalGrip::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + startDragging(x, y); + redraw(); +} + +/** + * Redraws the grip. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + */ + +void CSliderVerticalGrip::onRelease(nxgl_coord_t x, nxgl_coord_t y) +{ + redraw(); +} + +/** + * Redraws the grip. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + */ + +void CSliderVerticalGrip::onReleaseOutside(nxgl_coord_t x, nxgl_coord_t y) +{ + redraw(); +} + +/** + * Moves the grip to follow the mouse. + * + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + * @param vX The horizontal distance of the drag. + * @param vY The vertical distance of the drag. + */ + +void CSliderVerticalGrip::onDrag(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t vX, nxgl_coord_t vY) +{ + // Work out where we're moving to + + nxgl_coord_t destY = y - m_grabPointY - m_parent->getY(); + + // Do we need to move? + + if (destY != m_rect.getY()) + { + // Get parent rect + + CRect rect; + m_parent->getClientRect(rect); + + // Prevent grip from moving outside parent + + if (destY < rect.getY()) + { + destY = rect.getY(); + } + else + { + if (destY + getHeight() > rect.getHeight() + rect.getY()) + { + destY = (rect.getHeight() + rect.getY()) - getHeight(); + } + } + + // Move to new location + + moveTo(rect.getX(), destY); + } +} diff --git a/NxWidgets/libnxwidgets/src/cstickybutton.cxx b/NxWidgets/libnxwidgets/src/cstickybutton.cxx new file mode 100644 index 000000000..76852eaf7 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cstickybutton.cxx @@ -0,0 +1,168 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cstickybutton.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "cstickybutton.hxx" +#include "cgraphicsport.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CButton Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor for buttons that display a string. + * + * @param pWidgetControl The controlling widget for the display. + * @param x The x coordinate of the button, relative to its parent. + * @param y The y coordinate of the button, relative to its parent. + * @param width The width of the button. + * @param height The height of the button. + * @param text The text for the button to display. + * @param style The style that the button should use. If this is not + * specified, the button will use the global default widget + * style. + */ + +CStickyButton::CStickyButton(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + const CNxString &text, + CWidgetStyle *style) +: CButton(pWidgetControl, x, y, width, height, text, style) +{ + m_isStuckDown = false; +} + +/** + * Sets the key's stuck down state. If this is true, the key has a + * inwards-bevelled border when drawn. If it is false, the key has + * an outwards-bevelled border. + * + * @param stuckDown The new stuck down state. + */ + +void CStickyButton::setStuckDown(bool stuckDown) + { + m_isStuckDown = stuckDown; + redraw(); + } + +/** + * Draws the outline of the button. + * + * @param port Graphics port to draw to. + */ + +void CStickyButton::drawOutline(CGraphicsPort *port) +{ + CButton::drawOutline(port, m_isStuckDown); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CStickyButton::drawContents(CGraphicsPort *port) +{ + CButton::drawContents(port, m_isStuckDown); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CStickyButton::drawBorder(CGraphicsPort *port) +{ + CButton::drawBorder(port, m_isStuckDown); +} diff --git a/NxWidgets/libnxwidgets/src/cstickybuttonarray.cxx b/NxWidgets/libnxwidgets/src/cstickybuttonarray.cxx new file mode 100644 index 000000000..05c9d8928 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cstickybuttonarray.cxx @@ -0,0 +1,292 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/include/cstickybuttonarray.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "cstickybuttonarray.hxx" +#include "cgraphicsport.hxx" +#include "cwidgetstyle.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CStickyButtonArray Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor for an array of sticky buttons. + * + * @param pWidgetControl The widget control for the display. + * @param x The x coordinate of the button array, relative to its parent. + * @param y The y coordinate of the button array, relative to its parent. + * @param buttonColumns The number of buttons in one row of the button array + * @param buttonRows The number of buttons in one column of the button array + * @param buttonWidth The width of one button + * @param buttonHeight The height of one button + * @param style The style that the button should use. If this is not + * specified, the button will use the global default widget + * style. + */ + +CStickyButtonArray::CStickyButtonArray(CWidgetControl *pWidgetControl, + nxgl_coord_t x, nxgl_coord_t y, + uint8_t buttonColumns, uint8_t buttonRows, + nxgl_coord_t buttonWidth, nxgl_coord_t buttonHeight, + CWidgetStyle *style) +: CButtonArray(pWidgetControl, x, y, buttonColumns, buttonRows, buttonWidth, buttonHeight, style) +{ + // Initialize state + + m_isStuckDown = false; + m_stickDown = false; +} + +/** + * Check if any button in the array is stuck down and, if so, + * return the indices of the stuck down button. + * + * @param column The location to return the column index of the button + * of interest + * @param row The location to return the row index of the button of + * interest + * @return True if a button in the array is clicked + */ + +bool CStickyButtonArray::isAnyButtonStuckDown(int &column, int &row) const +{ + // Return the indices of the last stuck button + + column = m_stickyColumn; + row = m_stickyRow; + + // Return true if the button is currently stuck + + return m_isStuckDown; +} + +/** + * Check if this specific button in the array is stuck down + * + * @param column The column of the button to check. + * @param row The row of the button to check. + * @return True if this button is stuck down + */ + +bool CStickyButtonArray::isThisButtonStuckDown(int column, int row) const +{ + // Does this match the index of the last stuck button? + + if (column == m_stickyColumn && row == m_stickyRow) + { + // Yes.. return true if it is still stuck + + return m_isStuckDown; + } + else + { + // This button is definitely not stuck down + + return false; + } +} + +/** + * Force the button at this position into the stuck down state + * + * @param column The column containing the button to stick down + * @param row The rowtcontaining the button to stick down + * @return False(0) is returned if the indices are out of range. + */ + +bool CStickyButtonArray::stickDown(int column, int row) +{ + // Verify that the cursor position is within range + + if ((unsigned)column < m_buttonColumns && (unsigned)row < m_buttonRows) + { + // First, unstick any currently stuck buttons + + unstick(); + + // Then stick this button down + + m_stickyColumn = column; + m_stickyRow = row; + m_isStuckDown = true; + + // We only want to update the stuck down buttons + + m_stickDown = true; + redraw(); + m_stickDown = false; + return true; + } + + return false; +} + +/** + * Unstick all buttons. + */ + +void CStickyButtonArray::unstick(void) +{ + // Is any button stuck down? + + if (m_isStuckDown) + { + // Yes.. unstick it and update the button display + + m_isStuckDown = false; + + // We only want to update the stuck down buttons + + m_stickDown = true; + redraw(); + m_stickDown = false; + } +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CStickyButtonArray::drawContents(CGraphicsPort *port) +{ + // Are we just updating the stuck down button? + + if (m_stickDown) + { + // There are two cases: (1) A sticky button was unstuck, or (2) a new + // button is stuck down. m_isStuckDown will distinguish these + // + // Draw the button using the clicked style if either (1) it is + // stuck down OR (2) it is currently clicked. Draw the button in + // the normal style if is is un-stuck and not clicked. + // + // NOTE: If usedClicked is false, the button may revert to either + // (1) the "normal" button state, or (2) the "highlighted" button + // stated. drawButton() will handle that. + + bool useClicked = m_isStuckDown || isThisButtonClicked(m_stickyColumn, m_stickyRow); + drawButton(port, m_stickyColumn, m_stickyRow, useClicked); + } + + // Do we draw just one button (due to click or release)? + + else if (m_redrawButton) + { + // Just one. Get the row/column indices from the last click + + int column; + int row; + bool useClicked = isButtonClicked(column, row); + + // If this is a press or release on the stuck down button, then don't + // redraw the button. Drawing of stuck down and unstuck buttons is + // controlled entirely by the m_stickDown case. + + if (!isThisButtonStuckDown(column, row)) + { + // Not a stuck down button. Re-draw that button + + drawButton(port, column, row, useClicked); + } + } + + // Do we just draw the hightlighted button? + + else if (m_cursorChange) + { + // Do nothing if the highlighted button is also the stuck down button + // or the clicked button + + if (!isThisButtonStuckDown(m_cursorColumn, m_cursorRow) && + !isThisButtonClicked(m_cursorColumn, m_cursorRow)) + { + drawButton(port, m_cursorColumn, m_cursorRow, false); + } + } + + // Draw all buttons + + else + { + // Visit each column + + for (int column = 0; column < m_buttonColumns; column++) + { + // Visit each row + + for (int row = 0; row < m_buttonRows; row++) + { + // Is the button clicked? + + bool useClicked = isThisButtonClicked(column, row); + + // If the button is not clicked but it is the stuck button, + // then draw it as clicked anyway. + + if (!useClicked) + { + useClicked = isThisButtonStuckDown(column, row); + } + + // Draw each button. If useClicked is false, then drawButton + // will do the right thing if the button is highlighted. + + drawButton(port, column, row, useClicked); + } + } + } +} + diff --git a/NxWidgets/libnxwidgets/src/cstringiterator.cxx b/NxWidgets/libnxwidgets/src/cstringiterator.cxx new file mode 100644 index 000000000..2327af38f --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cstringiterator.cxx @@ -0,0 +1,198 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cgraphicsport.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cnxstring.hxx" +#include "cstringiterator.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. Moves the iterator to the first character in the string. + * + * @param string Pointer to the string that will be iterated over. + */ + +CStringIterator::CStringIterator(FAR const CNxString* string) +{ + m_pString = string; + m_pCurrentChar = m_pString->getCharArray(); + m_currentIndex = 0; +} + +/** + * Moves the iterator to the first character in the string. + * + * @param Returns false if the string is empty + */ + +bool CStringIterator::moveToFirst() +{ + int length = m_pString->getLength(); + if (length > 0) + { + m_pCurrentChar = m_pString->getCharArray(); + m_currentIndex = 0; + return true; + } + + return false; +} + +/** + * Moves the iterator to the last character in the string. + * + * @param Returns false if the string is empty + */ + +bool CStringIterator::moveToLast(void) +{ + int length = m_pString->getLength(); + if (length > 0) + { + m_pCurrentChar = m_pString->getCharArray() + length - 1; + m_currentIndex = length - 1; + return true; + } + + return false; +} + +/** + * Move the iterator to the next character in the string. + * + * @return True if the iterator moved; false if not (indicates end of string). + */ + +bool CStringIterator::moveToNext(void) +{ + if (m_currentIndex < m_pString->getLength() - 1) + { + m_pCurrentChar++; + m_currentIndex++; + return true; + } + + return false; +} + +/** + * Move the iterator to the previous character in the string. + * + * @return True if the iterator moved; false if not (indicates start of string). + */ + +bool CStringIterator::moveToPrevious(void) +{ + if (m_currentIndex > 0) + { + m_pCurrentChar--; + m_currentIndex--; + return true; + } + return false; +} + +/** + * Move the iterator to the specified index. + * + * @param index The index to move to. + * @return True if the iterator moved; false if not (indicates end of string). + */ + +bool CStringIterator::moveTo(int index) +{ + // Abort if index exceeds the size of the string + + if (index < m_pString->getLength()) + { + // Move to the requested position + + m_pCurrentChar = m_pString->getCharArray() + index; + m_currentIndex = index; + return true; + } + return false; +} diff --git a/NxWidgets/libnxwidgets/src/ctext.cxx b/NxWidgets/libnxwidgets/src/ctext.cxx new file mode 100644 index 000000000..688031d88 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/ctext.cxx @@ -0,0 +1,675 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/ctext.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "ctext.hxx" +#include "cstringiterator.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param font The font to use for this text object. + * @param text A string that this text object should wrap around. + * @param width The pixel width at which the text should wrap. + */ + +CText::CText(CNxFont *font, const CNxString &text, nxgl_coord_t width) +: CNxString(text) +{ + m_font = font; + m_width = width; + m_lineSpacing = 1; + wrap(); +} + +/** + * Set the text in the string. + * + * @param text Char array to use as the new data for this string. + */ + +void CText::setText(const CNxString &text) +{ + CNxString::setText(text); + wrap(); +} + +/** + * Set the text in the string. + * + * @param text Char array to use as the new data for this string. + */ + +void CText::setText(FAR const char *text) +{ + CNxString::setText(text); + wrap(); +} + +/** + * Set the text in the string. + * + * @param text Character to to use as the new data for this string. + */ + +void CText::setText(const nxwidget_char_t text) +{ + CNxString::setText(text); + wrap(); +} + +/** + * Append text to the end of the string. + * + * @param text String to append. + */ + +void CText::append(const CNxString &text) +{ + CNxString::append(text); + wrap(getLength() - 1); +} + +/** + * Insert text at the specified character index. + * + * @param text The text to insert. + * @param index The char index to insert at. + */ + +void CText::insert(const CNxString &text, const int index) +{ + CNxString::insert(text, index); + wrap(index); +} + +/** + * Remove all characters from the string from the start index onwards. + * + * @param startIndex The char index to start removing from. + */ + +void CText::remove(const int startIndex) +{ + CNxString::remove(startIndex); + wrap(startIndex); +} + +/** + * Remove all characters from the string from the start index onwards. + * + * @param startIndex The char index to start removing from. + * @param count The number of chars to remove. + */ + +void CText::remove(const int startIndex, const int count) +{ + CNxString::remove(startIndex, count); + wrap(startIndex); +} + + +/** + * Set the vertical spacing between rows of text. + * + * @param lineSpacing The line spacing. + */ + +void CText::setLineSpacing(uint8_t lineSpacing) +{ + m_lineSpacing = lineSpacing; + wrap(); +} + +/** + * Sets the pixel width of the text; text wider than + * this will automatically wrap. + * + * @param width Maximum pixel width of the text. + */ + +void CText::setWidth(nxgl_coord_t width) +{ + m_width = width; + wrap(); +} + +/** + * Set the font to use. + * + * @param font Pointer to the new font. + */ + +void CText::setFont(CNxFont* font) +{ + m_font = font; + wrap(); +} + +/** + * Get the number of characters in the specified line number. + * + * @param lineNumber The line number to check. + * @return The number of characters in the line. + */ + +const int CText::getLineLength(const int lineNumber) const +{ + if (lineNumber < getLineCount() - 1) + { + return m_linePositions[lineNumber + 1] - m_linePositions[lineNumber]; + } + + return getLength() - m_linePositions[lineNumber]; +} + +/** + * Get the number of characters in the specified line number, + * ignoring any trailing blank characters. + * + * @param lineNumber The line number to check. + * @return The number of characters in the line. + */ + +const int CText::getLineTrimmedLength(const int lineNumber) const +{ + nxgl_coord_t length = getLineLength(lineNumber); + + // Loop through string until the end + + CStringIterator *iterator = newStringIterator(); + + // Get char at the end of the line + + if (iterator->moveTo(m_linePositions[lineNumber] + length - 1)) + { + do + { + if (!m_font->isCharBlank(iterator->getChar())) + { + break; + } + length--; + } + while (iterator->moveToPrevious() && (length > 0)); + return length; + } + + // May occur if data has been horribly corrupted somewhere + + return 0; +} + +/** + * Get the width in pixels of the specified line number. + * + * @param lineNumber The line number to check. + * @return The pixel width of the line. + */ + +const nxgl_coord_t CText::getLinePixelLength(const int lineNumber) const +{ + return m_font->getStringWidth(*this, getLineStartIndex(lineNumber), + getLineLength(lineNumber)); +} + +/** + * Get the width in pixels of the specified line number, + * ignoring any trailing blank characters. + * + * @param lineNumber The line number to check. + * @return The pixel width of the line. + */ + +const nxgl_coord_t CText::getLineTrimmedPixelLength(const int lineNumber) const +{ + return m_font->getStringWidth(*this, getLineStartIndex(lineNumber), + getLineTrimmedLength(lineNumber)); +} + +/** + * Get a pointer to the CText object's font. + * + * @return Pointer to the font. + */ + +CNxFont *CText::getFont(void) const +{ + return m_font; +} + +/** + * Removes lines of text from the start of the text buffer. + * + * @param lines Number of lines to remove + */ + +void CText::stripTopLines(const int lines) +{ + // Get the start point of the text we want to keep + + nxgl_coord_t textStart = 0; + + for (int i = 0; i < lines; i++) + { + textStart += getLineLength(i); + } + + // Remove the characters from the start of the string to the found location + + remove(0, textStart); + + // Rewrap the text + + wrap(); +} + +/** + * Wrap all of the text. + */ + +void CText::wrap(void) +{ + wrap(0); +} + +/** + * Wrap the text from the line containing the specified char index onwards. + * + * @param charIndex The index of the char to start wrapping from; note + * that the wrapping function will re-wrap that entire line of text. + */ + +void CText::wrap(int charIndex) +{ + // Declare vars in advance of loop + + int pos = 0; + int lineWidth; + int breakIndex; + bool endReached = false; + + if (m_linePositions.size() == 0) + { + charIndex = 0; + } + + // If we're wrapping from an offset in the text, ensure that any existing data + // after the offset gets removed + + if (charIndex > 0) + { + // Remove wrapping data past this point + + // Get the index of the line in which the char index appears + + int lineIndex = getLineContainingCharIndex(charIndex); + + // Remove any longest line records that occur from the line index onwards + + while ((m_longestLines.size() > 0) && + (m_longestLines[m_longestLines.size() - 1].index >= lineIndex)) + { + m_longestLines.pop_back(); + } + + // If there are any longest line records remaining, update the text pixel width + // The last longest line record will always be the last valid longest line as + // the vector is sorted by length + + if (m_longestLines.size() > 0) + { + m_textPixelWidth = m_longestLines[m_longestLines.size() - 1].width; + } + else + { + m_textPixelWidth = 0; + } + + // Remove any wrapping data from after this line index onwards + + while ((m_linePositions.size() > 0) && + (m_linePositions.size() - 1 > (int)lineIndex)) + { + m_linePositions.pop_back(); + } + + // Adjust start position of wrapping loop so that it starts with + // the current line index + + if (m_linePositions.size() > 0) + { + pos = m_linePositions[m_linePositions.size() - 1]; + } + } + else + { + // Remove all wrapping data + + // Wipe the width variable + + m_textPixelWidth = 0; + + // Empty existing longest lines + + m_longestLines.clear(); + + // Empty existing line positions + + m_linePositions.clear(); + + // Push first line start into vector + + m_linePositions.push_back(0); + } + + // Loop through string until the end + + CStringIterator *iterator = newStringIterator(); + + while (!endReached) + { + breakIndex = 0; + lineWidth = 0; + + if (iterator->moveTo(pos)) + { + // Search for line breaks and valid breakpoints until we + // exceed the width of the text field or we run out of + // string to process + + while (lineWidth + m_font->getCharWidth(iterator->getChar()) <= m_width) + { + lineWidth += m_font->getCharWidth(iterator->getChar()); + + // Check for line return + + if (iterator->getChar() == '\n') + { + // Remember this breakpoint + + breakIndex = iterator->getIndex(); + break; + } + else if ((iterator->getChar() == ' ') || + (iterator->getChar() == ',') || + (iterator->getChar() == '.') || + (iterator->getChar() == '-') || + (iterator->getChar() == ':') || + (iterator->getChar() == ';') || + (iterator->getChar() == '?') || + (iterator->getChar() == '!') || + (iterator->getChar() == '+') || + (iterator->getChar() == '=') || + (iterator->getChar() == '/') || + (iterator->getChar() == '\0')) + { + // Remember the most recent breakpoint + + breakIndex = iterator->getIndex(); + } + + // Move to the next character + + if (!iterator->moveToNext()) + { + // No more text; abort loop + + endReached = true; + break; + } + } + } + else + { + endReached = true; + } + + if ((!endReached) && (iterator->getIndex() > pos)) + { + // Process any found data + + // If we didn't find a breakpoint split at the current position + + if (breakIndex == 0) + { + breakIndex = iterator->getIndex() - 1; + } + + // Trim blank space from the start of the next line + + CStringIterator *breakIterator = newStringIterator(); + + if (breakIterator->moveTo(breakIndex + 1)) + { + while (breakIterator->getChar() == ' ') + { + if (breakIterator->moveToNext()) + { + breakIndex++; + } + else + { + break; + } + } + } + + delete breakIterator; + + // Add the start of the next line to the vector + + pos = breakIndex + 1; + m_linePositions.push_back(pos); + + // Is this the longest line observed so far? + + if (lineWidth > m_textPixelWidth) + { + m_textPixelWidth = lineWidth; + + // Push the description of the line into the longest lines + // vector (note that we store the index in m_linePositions that + // refers to the start of the line, *not* the position of the + // line in the char array) + + LongestLine line; + line.index = m_linePositions.size() - 2; + line.width = lineWidth; + m_longestLines.push_back(line); + } + } + else if (!endReached) + { + // Add a blank row if we're not at the end of the string + + pos++; + m_linePositions.push_back(pos); + } + } + + // Add marker indicating end of text + // If we reached the end of the text, append the stopping point + + if (m_linePositions[m_linePositions.size() - 1] != getLength() + 1) + { + m_linePositions.push_back(getLength()); + } + + delete iterator; + + // Calculate the total height of the text + + m_textPixelHeight = getLineCount() * (m_font->getHeight() + m_lineSpacing); + + // Ensure height is always at least one row + + if (m_textPixelHeight == 0) + { + m_textPixelHeight = m_font->getHeight() + m_lineSpacing; + } +} + +/** + * Get the index of the line of text that contains the specified index + * within the raw char array. + * + * @param index The index to locate within the wrapped lines of text. + * @return The number of the line of wrapped text that contains the + * specified index. + */ + +const int CText::getLineContainingCharIndex(const int index) const +{ + // Early exit if there is no existing line data + + if (m_linePositions.size() == 0) + { + return 0; + } + + // Early exit if the character is in the last row + + if (index >= m_linePositions[m_linePositions.size() - 2]) + { + return m_linePositions.size() - 2; + } + + // Binary search the line vector for the line containing the supplied index + + int bottom = 0; + int top = m_linePositions.size() - 1; + int mid; + + while (bottom <= top) + { + // Standard binary search + + mid = (bottom + top) >> 1; + + if (index < m_linePositions[mid]) + { + // Index is somewhere in the lower search space + + top = mid - 1; + } + else if (index > m_linePositions[mid]) + { + // Index is somewhere in the upper search space + + bottom = mid + 1; + } + else if (index == m_linePositions[mid]) + { + // Located the index + + return mid; + } + + // Check to see if we've moved past the line that contains the index + // We have to do this because the index we're looking for can be within + // a line; it isn't necessarily the start of a line (which is what is + // stored in the m_linePositions vector) + + if (index > m_linePositions[top]) + { + // Search index falls within the line represented by the top position + + return top; + } + else if (index < m_linePositions[bottom]) + { + // Search index falls within the line represented by the bottom position + + return bottom - 1; + } + } + + // Line cannot be found + + return 0; +} diff --git a/NxWidgets/libnxwidgets/src/ctextbox.cxx b/NxWidgets/libnxwidgets/src/ctextbox.cxx new file mode 100644 index 000000000..9c22a2bfa --- /dev/null +++ b/NxWidgets/libnxwidgets/src/ctextbox.cxx @@ -0,0 +1,679 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/ctextbox.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> + +#include "nxconfig.hxx" +#include "ctextbox.hxx" +#include "cgraphicsport.hxx" +#include "cnxtimer.hxx" +#include "cstringiterator.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * CButton Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor for a textbox containing a string. + * + * @param pWidgetControl The controlling widget for the window + * @param x The x coordinate of the text box, relative to its parent. + * @param y The y coordinate of the text box, relative to its parent. + * @param width The width of the textbox. + * @param height The height of the textbox. + * @param text Pointer to a string to display in the textbox. + * @param style The style that the widget should use. If this is not + * specified, the widget will use the values stored in the global + * defaultCWidgetStyle object. The widget will copy the properties of + * the style into its own internal style object. + */ + +CTextBox::CTextBox(CWidgetControl *pWidgetControl, nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t width, nxgl_coord_t height, + const CNxString &text, CWidgetStyle *style) + : CLabel(pWidgetControl, x, y, width, height, text, style) +{ + // Initialize state + + m_cursorPos = 0; + m_showCursor = SHOW_CURSOR_ONFOCUS; + m_wrapCursor = false; + m_textChange = false; + m_flags.doubleClickable = true; + + // Set the border thickness (2 lines) + + m_borderSize.top = 2; + m_borderSize.right = 2; + m_borderSize.bottom = 2; + m_borderSize.left = 2; + + // Move the cursor to the end of the string + + moveCursorToPosition(m_text.getLength()); + + // Register to receive keypress events + + addWidgetEventHandler(static_cast<CWidgetEventHandler *>(this)); +} + +/** + * Shows the cursor. + * + * @param cursorMode Determines cursor display mode + */ + +void CTextBox::showCursor(EShowCursor cursorMode) +{ + if (m_showCursor != cursorMode) + { + m_showCursor = cursorMode; + redraw(); + } +} + +/** + * Set the text displayed in the label. + * + * @param text String to display. + */ + +void CTextBox::setText(const CNxString &text) +{ + m_text.setText(text); + repositionCursor(m_text.getLength()); + onTextChange(); +} + +/** + * Append new text to the end of the current text displayed in the + * label. + * + * @param text String to append. + */ + +void CTextBox::appendText(const CNxString &text) +{ + m_text.append(text); + repositionCursor(m_text.getLength()); + onTextChange(); +} + +/** + * Remove all characters from the string from the start index onwards. + * + * @param startIndex Index to remove from. + */ + +void CTextBox::removeText(const unsigned int startIndex) +{ + m_text.remove(startIndex); + repositionCursor(startIndex); + onTextChange(); +} + +/** + * Remove specified number of characters from the string from the + * start index onwards. + * + * @param startIndex Index to remove from. + * @param count Number of characters to remove. + */ + +void CTextBox::removeText(const unsigned int startIndex, const unsigned int count) +{ + m_text.remove(startIndex, count); + repositionCursor(startIndex); + onTextChange(); +} + +/** + * Insert text at the specified index. + * + * @param text The text to insert. + * @param index Index at which to insert the text. + */ + +void CTextBox::insertText(const CNxString &text, const unsigned int index) +{ + m_text.insert(text, index); + repositionCursor(index + text.getLength()); + onTextChange(); +} + +/** + * Insert text at the current cursor position. + * + * @param text The text to insert. + */ + +void CTextBox::insertTextAtCursor(const CNxString &text) +{ + insertText(text, getCursorPosition()); +} + +/** + * Move the cursor to the text position specified. 0 indicates the + * start of the string. If position is greater than the length of the + * string, the cursor is moved to the end of the string. + * + * @param position The new cursor position. + */ + +void CTextBox::moveCursorToPosition(const int position) +{ + if (repositionCursor(position)) + { + calculateTextPositionHorizontal(); + redraw(); + } +} + +/** + * Handle a keyboard press event. + * + * @param e The event data. + */ + +void CTextBox::handleKeyPressEvent(const CWidgetEventArgs &e) +{ + nxwidget_char_t key = e.getKey(); + + if (key == KEY_CODE_BACKSPACE) + { + if (m_cursorPos == 0) return; + + // Delete the character in front of the cursor + + removeText(m_cursorPos - 1, 1); + } + else if (key == KEY_CODE_ENTER) + { + // Fire an action event + + m_widgetEventHandlers->raiseActionEvent(); + } + else if (key != KEY_CODE_NONE) + { + // Not modifier; append value + + insertTextAtCursor(key); + } +} + +/** + * Handle a cursor control event. Replaces CWidgetEventHandler method. + * + * @param e The event data. + */ + +void CTextBox::handleCursorControlEvent(const CWidgetEventArgs &e) +{ + ECursorControl control = e.getCursorControl(); + + if (control == CURSOR_LEFT) + { + if (m_cursorPos > 0) + { + moveCursorToPosition(m_cursorPos - 1); + } + else if (m_wrapCursor) + { + moveCursorToPosition(m_text.getLength() - 1); + } + } + else if (control == CURSOR_RIGHT) + { + if (m_cursorPos < m_text.getLength()) + { + moveCursorToPosition(m_cursorPos + 1); + } + else if (m_wrapCursor) + { + moveCursorToPosition(0); + } + } +} + +/** + * Redraws the widget + */ + +void CTextBox::onBlur(void) +{ + redraw(); +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CTextBox::drawContents(CGraphicsPort *port) +{ + // Get the drawing area (excluding the border) + + CRect rect; + getRect(rect); + + // Determine the background and text color + + nxgl_mxpixel_t textColor; + nxgl_mxpixel_t backColor; + + if (!isEnabled()) + { + textColor = getDisabledTextColor(); + backColor = getBackgroundColor(); + } + else if (m_highlighted) + { + textColor = getSelectedTextColor(); + backColor = getSelectedBackgroundColor(); + } + else + { + textColor = getEnabledTextColor(); + backColor = getBackgroundColor(); + } + + // Draw the background (excluding the border) + + port->drawFilledRect(rect.getX(), rect.getY(), + rect.getWidth(), rect.getHeight(), backColor); + + // Get the X/Y position of the text within the textbox + + struct nxgl_point_s pos; + pos.x = rect.getX() + m_align.x; + pos.y = rect.getY() + m_align.y; + + // And draw the text + + CNxFont *font = getFont(); + port->drawText(&pos, &rect, font, m_text, 0, m_text.getLength(), textColor); + + // Draw cursor + + if (isCursorVisible()) + { + // Calculate the (relative) cursor position + // Warning: drawText modifies pos! + + pos.x = getCursorXPos() + m_align.x; + pos.y = m_align.y; + + // Calculate the cursor width + + struct nxgl_size_s size; + size.w = getCursorWidth(); + size.h = getFont()->getHeight(); + + // Is the cursor wholly within the visible region? + + if (pos.x >= 0 && pos.x + size.w < rect.getWidth()) + { + // Invert the colors in the cursor region. + + pos.x += rect.getX(); + pos.y += rect.getY(); + + port->invert(pos.x, pos.y, size.w, size.h); + } + } +} + +/** + * Moves the cursor without redrawing. + * + * @param position New cursor position. + */ + +bool CTextBox::repositionCursor(const int position) +{ + int len = m_text.getLength(); + + // Set the cursor position if the new position is within the string. + + if (m_cursorPos != position && position <= len) + { + m_cursorPos = position; + return true; + } + + return false; +} + +/** + * Move the cursor to the specified coordinates. The coordinates + * are expected to be the result of a click, and therefore in + * world-space rather than widget-space. + */ + +void CTextBox::moveCursorToClickLocation(nxgl_coord_t x, nxgl_coord_t y) +{ + // Work out where in the string the click coordinates represent + // and move the cursor to that location + + if (m_text.getLength() > 0) + { + // Transform click coordinates to widget-space coordinates + + nxgl_coord_t clickX = x - getX() - m_borderSize.left; + nxgl_coord_t charX = m_align.x; + + // Locate the first character that comes after the clicked character + + CStringIterator *iterator = m_text.newStringIterator(); + + while (charX < clickX) + { + charX += getFont()->getCharWidth(iterator->getChar()); + + if (!iterator->moveToNext()) + { + break; + } + } + + int index = iterator->getIndex(); + + // Move back to the clicked character if we've moved past it + + if (charX > clickX) + { + iterator->moveToPrevious(); + index = iterator->getIndex(); + } + else if (charX < clickX) + { + // Move past end of string if click is after the text + + index++; + } + + moveCursorToPosition(index); + delete iterator; + } +} + +/** + * Draw the area of this widget that falls within the clipping region. + * Called by the redraw() function to draw all visible regions. + * + * @param port The CGraphicsPort to draw to. + * @see redraw() + */ + +void CTextBox::drawBorder(CGraphicsPort *port) +{ + // Check if the widget indicates it should have an outline: That + // the outline is enabled and the this is not just a text-only + // redraw + + if (!isBorderless() && !isTextChange()) + { + port->drawBevelledRect(getX(), getY(), getWidth(), getHeight(), + getShineEdgeColor(), getShadowEdgeColor()); + port->drawBevelledRect(getX() + 1, getY() + 1, getWidth() - 2, getHeight() - 2, + getShadowEdgeColor(), getShineEdgeColor()); + } +} + +/** + * Moves the cursor to the clicked coordinates. + * + * @param x The x coordinates of the click. + * @param y The y coordinates of the click. + */ + +void CTextBox::onClick(nxgl_coord_t x, nxgl_coord_t y) +{ + moveCursorToClickLocation(x, y); +} + +/** + * Does nothing. + * + * @param x The x coordinates of the click. + * @param y The y coordinates of the click. + */ + +void CTextBox::onDoubleClick(nxgl_coord_t x, nxgl_coord_t y) +{ + // No double click action +} + +/** + * Return true if the cursor is visible + */ + +bool CTextBox::isCursorVisible(void) const +{ + return (m_showCursor == SHOW_CURSOR_ALWAYS || + (m_showCursor == SHOW_CURSOR_ONFOCUS && hasFocus())); +} + +/** + * Get the x coordinate of the cursor in pixels relative + * to the left-hand edge of the client rect. + * + * @return The x coordinate of the cursor in pixels. + */ + +const nxgl_coord_t CTextBox::getCursorXPos(void) const +{ + // Calculate position of cursor + + nxgl_coord_t cursorX = 0; + + CStringIterator *iterator = m_text.newStringIterator(); + + for (nxgl_coord_t i = 0; i < m_cursorPos; i++) + { + cursorX += getFont()->getCharWidth(iterator->getChar()); + iterator->moveToNext(); + } + + delete iterator; + return cursorX; +} + +/** + * Get the width of the cursor in pixels. + * + * @return The width of the cursor in pixels. + */ + +nxgl_coord_t CTextBox::getCursorWidth(void) const +{ + if (m_cursorPos < m_text.getLength()) + { + // Cursor within the string - get the width of the character + + return getFont()->getCharWidth(m_text.getCharAt(m_cursorPos)); + } + else + { + // Cursor past end of string - get the width of a space + + return getFont()->getCharWidth(' '); + } +} + +/** + * Calculate the horizontal position of the string based on its length + * and the alignment options. Alignment options are overridden if the + * width of the string exceeds the width of the textbox. + */ + +void CTextBox::calculateTextPositionHorizontal(void) +{ + // Calculate the string width - if the width is longer than the box, + // ignore alignment and align left + + nxgl_coord_t stringWidth = getFont()->getStringWidth(m_text); + + // Add the width of a blank space to the width to ensure that we can + // see the cursor + + if (isCursorVisible()) + { + stringWidth += getFont()->getCharWidth(' '); + } + + CRect rect; + getClientRect(rect); + + // Use alignment options if cursor is hidden or string is smaller + // than textbox + + nxgl_coord_t width = rect.getWidth(); + if ((stringWidth < width) || !isCursorVisible()) + { + // Text not wider than box, so apply alignment options + + switch (m_hAlignment) + { + case TEXT_ALIGNMENT_HORIZ_CENTER: + m_align.x = (width - stringWidth) >> 1; + break; + + case TEXT_ALIGNMENT_HORIZ_LEFT: + m_align.x = rect.getX(); + break; + + case TEXT_ALIGNMENT_HORIZ_RIGHT: + m_align.x = width - stringWidth; + break; + } + + return; + } + + // Text is wider than box - view needs to follow the cursor + // If cursor is at the end of the text, we can just right-align + + if (m_cursorPos == m_text.getLength()) + { + m_align.x = width - stringWidth; + return; + } + + // Work out the coordinates of the left edge of the cursor + + int cursorX1 = getCursorXPos(); + + // Work out the coordinates of the right edge of the cursor + + int cursorX2 = cursorX1 + getCursorWidth(); + + // Ensure that the cursor is on-screen + + if (cursorX1 + m_align.x < 0) + { + // Cursor is off left side of screen, so adjust m_align.x + + m_align.x = 0 - cursorX1; + } + else if (cursorX2 + m_align.x > width) + { + // Cursor is off right side of screen, so adjust m_align.x + + m_align.x = width - cursorX2; + } + + // We need to ensure that the text cannot be positioned in + // such a way that there is a gap between the end of the + // text and the right edge of the textbox + + if (stringWidth + m_align.x < width) + { + m_align.x = width - stringWidth; + } +} diff --git a/NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx b/NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx new file mode 100644 index 000000000..5ea672a2f --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx @@ -0,0 +1,890 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> +#include <cstring> + +#include "nxconfig.hxx" +#include "cnxserver.hxx" +#include "cnxwidget.hxx" +#include "cnxfont.hxx" +#include "cwidgetstyle.hxx" +#include "cnxtimer.hxx" +#include "cgraphicsport.hxx" +#include "cwidgetcontrol.hxx" +#include "singletons.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Global Static Data + ****************************************************************************/ + +using namespace NXWidgets; + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +/** + * CWidgetControl constructor (for the case where the display size is known) + * + * @param style The style that the widget should use. If this is not + * specified, the widget will use the values stored in the global + * defaultCWidgetStyle object. The widget will copy the properties of + * the style into its own internal style object. + */ + +CWidgetControl::CWidgetControl(FAR const CWidgetStyle *style) +{ + // Initialize state + + m_port = (CGraphicsPort *)NULL; + m_modal = false; + m_clickedWidget = (CNxWidget *)NULL; + m_focusedWidget = (CNxWidget *)NULL; + + // Initialize data that we will get from the position callback + + m_hWindow = NULL; + m_size.h = 0; + m_size.w = 0; + m_pos.x = 0; + m_pos.y = 0; + m_bounds.pt1.x = 0; + m_bounds.pt1.y = 0; + m_bounds.pt2.y = 0; + m_bounds.pt2.y = 0; + + // Initialize the mouse/touchscreen event and keyboard data structures + + memset(&m_mouse, 0, sizeof(struct SMouse)); + m_nCh = 0; + m_nCc = 0; + + // Enable the semaphore that will wake up the modal loop on mouse or + // keypress events + + sem_init(&m_modalsem, 0, 0); + + // Do we need to fetch the default style? + + if (style == (CWidgetStyle *)NULL) + { + // Get the style from the controlling widget + + copyWidgetStyle(&m_style, g_defaultWidgetStyle); + } + else + { + // Use specified style + + copyWidgetStyle(&m_style, style); + } +} + + +/** + * Destructor. + */ + +CWidgetControl::~CWidgetControl(void) +{ + // Stop any ongoing modal operation + + stopModal(); + + // Delete any contained instances + + if (m_port) + { + delete m_port; + } + + // Flush the delete queue + + processDeleteQueue(); + + // Delete controlled widget list + + while (m_widgets.size() > 0) + { + m_widgets[0]->destroy(); + } +} + +/** + * Run the widget modally. This will run the CWidgetControl + * application until stopModal() is called. + */ + +void CWidgetControl::goModal(void) +{ + // Enter modal + + m_modal = true; + + // Loop until stopModal() is called + + while (m_modal) + { + // Process pending events + + bool interestingEvent = pollEvents(); + + // Did any interesting events occur? + + if (!interestingEvent) + { + // No, give up the CPU until something interesting happens. + + waitForModalEvent(); + } + } +} + +/** + * Wait for an interesting modal event to occur (like a mouse or keyboard event) + */ + +void CWidgetControl::waitForModalEvent(void) +{ + // It would be an error if this were called outside of a modal loop + + if (m_modal) + { + // Wait for an interesting event (like a mouse or keyboard event) + + (void)sem_wait(&m_modalsem); + } +} + +/** + * Wake up the modal loop + */ + +void CWidgetControl::wakeupModalLoop(void) +{ + if (m_modal) + { + (void)sem_post(&m_modalsem); + } +} + +/** + * Stop the widget running modally. + */ + +void CWidgetControl::stopModal(void) +{ + if (m_modal) + { + // No longer modal + + m_modal = false; + + // Wake up the modal loop so that it can terminate properly + + (void)sem_post(&m_modalsem); + } +} + +/** + * 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 CWidgetControl::pollEvents(CNxWidget *widget) +{ + // Delete any queued widgets + + processDeleteQueue(); + + // Handle mouse input + + bool mouseEvent = pollMouseEvents(widget); + + // Handle keyboard input + + bool keyboardEvent = pollKeyboardEvents(); + + // Handle cursor control input + + bool cursorControlEvent = pollCursorControlEvents(); + return mouseEvent || keyboardEvent || cursorControlEvent; +} + +/** + * 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 CWidgetControl::getWidgetIndex(const CNxWidget *widget) const +{ + for (int i = 0; i < m_widgets.size(); i++) + { + if (m_widgets[i] == widget) + { + return i; + } + } + + return -1; +} + +/** + * Redraws any dirty regions within the supplied region. + * + * @param rect The region to redraw + */ + +void CWidgetControl::eraseRect(CRect rect) +{ + // Create pointer to a vector to store the invalid rectangles + + TNxArray<CRect> *invalidRectangles = new TNxArray<CRect>(); + + if (invalidRectangles != (TNxArray<CRect> *)NULL) + { + // Add rectangle into the vector + + invalidRectangles->push_back(rect); + + // Refresh children + + for (int i = m_widgets.size() - 1; i > -1 ; i--) + { + if (invalidRectangles->size() > 0) + { + m_widgets[i]->redrawDirty(invalidRectangles, (CNxWidget *)NULL); + } + else + { + break; + } + } + + // Tidy up + + delete invalidRectangles; + } +} + +/** + * Remove a controlled widget + * + * @param widget The widget to be removed + */ + +void CWidgetControl::removeControlledWidget(CNxWidget *widget) +{ + // Locate the widget + + int index = getWidgetIndex(widget); + if (index >= 0) + { + m_widgets.erase(index); + } +} + +/** + * 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 CWidgetControl::addToDeleteQueue(CNxWidget *widget) +{ + m_deleteQueue.push_back(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 CWidgetControl::setClickedWidget(CNxWidget *widget) +{ + // Do we have a clicked widget already? + + if (m_clickedWidget != (CNxWidget *)NULL) + { + // Ensure that the existing clicked widget is released *outside* its bounds + + m_clickedWidget->release(m_clickedWidget->getX() - 10, 0); + } + + // Update the pointer + + m_clickedWidget = widget; +} + +/** + * Set the focused widget that will receive keyboard input. + * + * @param widget The new focused widget. + */ + +void CWidgetControl::setFocusedWidget(CNxWidget *widget) +{ + if (m_focusedWidget != widget) + { + // This widget will now receive focus + + m_focusedWidget = widget; + + // Make sure that the widget knows that is has focus + + widget->focus(); + } +#warning "Widgets with focus need to go on a stack so that focus can be restored" +} + +/** + * This event is called from CCallback instance to provide + * notifications of certain NX-server related events. This event, + * in particular, 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 CWidgetControl::geometryEvent(NXHANDLE hWindow, + const struct nxgl_size_s *size, + const struct nxgl_point_s *pos, + const struct nxgl_rect_s *bounds) +{ + // Save positional data that may change dynamically + + m_pos.x = pos->x; + m_pos.y = pos->y; + m_size.h = size->h; + m_size.w = size->w; + + // The first callback is important. This is the handshake that proves + // that we are truly communicating with the servier. This is also + // a critical point because this is when we know the physical + // dimensions of the underlying window. + + if (!m_hWindow) + { + // Save one-time server specific information + + m_hWindow = hWindow; + nxgl_rectcopy(&m_bounds, bounds); + } +} + +/** + * This event is called from CCallback instance to provide + * notifications of certain NX-server related events. This event, + * in particular, will occur when the a portion of the window that was + * previously obscured is now exposed. + * + * @param rect The region in the window that must be redrawn. + * @param more True means that more re-draw requests will follow + */ + +void CWidgetControl::redrawEvent(FAR const struct nxgl_rect_s *nxRect, bool more) +{ + CRect rect; + rect.setNxRect(nxRect); + eraseRect(rect); +} + +/** + * This event is called from CCallback instance to provide notifications of + * certain NX-server related events. This event, in particular, 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 CWidgetControl::newMouseEvent(FAR const struct nxgl_point_s *pPos, uint8_t buttons) +{ + // Save the mouse X/Y position + + m_mouse.x = pPos->x; + m_mouse.y = pPos->y; + + // Update button press states + + clearMouseEvents(); + + if ((buttons & NX_MOUSE_LEFTBUTTON) != 0) + { + // Handle left button press events. leftHeld means that the left mouse + // button was pressed on the previous sample as well. + + if (m_mouse.leftHeld) + { + m_mouse.leftDrag = 1; + } + else + { + // New left button press + + m_mouse.leftPressed = 1; + + (void)clock_gettime(CLOCK_REALTIME, &m_mouse.leftPressTime); + + // Check for double click event + + if (elapsedTime(&m_mouse.leftReleaseTime) <= CONFIG_NXWIDGETS_DOUBLECLICK_TIME) + { + m_mouse.doubleClick = 1; + } + } + + m_mouse.leftHeld = 1; + } + else + { + // Handle left button release events + + if (m_mouse.leftHeld) + { + // New left button release + + m_mouse.leftReleased = 1; + (void)clock_gettime(CLOCK_REALTIME, &m_mouse.leftReleaseTime); + } + + m_mouse.leftHeld = 0; + } + +#if 0 // Center and right buttons not used + if ((buttons & NX_MOUSE_CENTERBUTTON) != 0) + { + // Handle center button press events. centerHeld means that the center mouse + // button was pressed on the previous sample as well. + + if (m_mouse.centerHeld) + { + m_mouse.centerDrag = 1; + } + else + { + // New center button press + + m_mouse.centerPressed = 1; + } + + m_mouse.centerHeld = 1; + } + else + { + // Handle center button release events + + if (m_mouse.centerHeld) + { + // New center button release + + m_mouse.centerReleased = 1; + } + + m_mouse.centerHeld = 0; + } + + if ((buttons & NX_MOUSE_RIGHTBUTTON) != 0) + { + // Handle right button press events. rightHeld means that the right mouse + // button was pressed on the previous sample as well. + + if (m_mouse.rightHeld) + { + m_mouse.rightDrag = 1; + } + else + { + // New right button press + + m_mouse.rightPressed = 1; + } + + m_mouse.rightHeld = 1; + } + else + { + // Handle right button release events + + if (m_mouse.rightHeld) + { + // New right button release + + m_mouse.rightReleased = 1; + } + + m_mouse.rightHeld = 0; + } +#endif + + // Then wake up the modal loop + + wakeupModalLoop(); +} + +/** + * This event is called from CCallback instance to provide notifications of + * certain NX-server related events. This event, in particular, 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 CWidgetControl::newKeyboardEvent(uint8_t nCh, FAR const uint8_t *pStr) +{ + FAR uint8_t *pBuffer = &m_kbdbuf[m_nCh]; + + // Append each new character to keyboard character buffer + + for (uint8_t i = 0; + i < nCh && m_nCh < CONFIG_NXWIDGETS_KBDBUFFER_SIZE; + i++, m_nCh++) + { + *pBuffer++ = *pStr++; + } + + // Then wake up the modal loop + + wakeupModalLoop(); +} + +/** + * This event means that cursor control data is available for the window. + * + * @param cursorControl The cursor control code received. + */ + +void CWidgetControl::newCursorControlEvent(ECursorControl cursorControl) +{ + // Append the new cursor control + + if (m_nCc < CONFIG_NXWIDGETS_CURSORCONTROL_SIZE) + { + m_controls[m_nCc] = (uint8_t)cursorControl; + m_nCc++; + } + + // Then wake up the modal loop + + wakeupModalLoop(); +} + +/** + * Copy a widget style + * + * @param dest The destination style + * @param src The source to use + */ + +void CWidgetControl::copyWidgetStyle(CWidgetStyle *dest, const CWidgetStyle *src) +{ + dest->colors.background = src->colors.background; + dest->colors.selectedBackground = src->colors.selectedBackground; + dest->colors.shineEdge = src->colors.shineEdge; + dest->colors.shadowEdge = src->colors.shadowEdge; + dest->colors.highlight = src->colors.highlight; + dest->colors.disabledText = src->colors.disabledText; + dest->colors.enabledText = src->colors.enabledText; + dest->colors.selectedText = src->colors.selectedText; + dest->font = src->font; +} + +/** + * Return the elapsed time in millisconds + * + * @param tp A time in the past from which to compute the elapsed time. + * @return The elapsed time since tp + */ + +uint32_t CWidgetControl::elapsedTime(FAR const struct timespec *startTime) +{ + struct timespec endTime; + + (void)clock_gettime(CLOCK_REALTIME, &endTime); + if (startTime->tv_sec <= endTime.tv_sec) + { + // Get the elapsed seconds + + uint32_t seconds = endTime.tv_sec - startTime->tv_sec; + + // Get the elapsed nanoseconds, borrowing from the seconds if necessary + + int32_t endNanoSeconds = endTime.tv_nsec; + if (startTime->tv_nsec > endNanoSeconds) + { + // Are there any seconds to borrow from? + + if (seconds < 1) + { + // startTime is in the future??? + + return 0; + } + + // Borrow from the seconds + + seconds--; + endNanoSeconds += 1000000000; + } + uint32_t nanoseconds = endNanoSeconds - startTime->tv_nsec; + + // Then return the elapsed time in milliseconds + + return seconds * 1000000 + nanoseconds / 1000; + } + + // startTime is in the future??? + + return 0; +} + +/** + * Pass clicks to the widget hierarchy. 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 CWidgetControl::handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, CNxWidget *widget) +{ + // Working with a modal widget or the whole structure? + + if (widget == (CNxWidget *)NULL) + { + // All widgets + + for (int i = m_widgets.size() - 1; i > -1; i--) + { + if (m_widgets[i]->click(x, y)) + { + return; + } + } + } + else + { + // One widget + + (void)widget->click(x, y); + } +} + +/** + * Delete any widgets in the deletion queue. + */ + +void CWidgetControl::processDeleteQueue(void) +{ + int i = 0; + while (i < m_deleteQueue.size()) + { + m_deleteQueue[i]->destroy(); + i++; + } + + m_deleteQueue.clear(); +} + +/** + * 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 CWidgetControl::pollMouseEvents(CNxWidget *widget) +{ + bool mouseEvent = true; // Assume that an interesting mouse event occurred + + // All widgets + + if (m_mouse.leftPressed) + { + // Handle a new left button press event + + handleLeftClick(m_mouse.x, m_mouse.y, widget); + } + else if (m_mouse.leftDrag) + { + // The left button is still being held down + + if (m_clickedWidget != (CNxWidget *)NULL) + { + // Handle a mouse drag event + + m_clickedWidget->drag(m_mouse.x, m_mouse.y, + m_mouse.x - m_mouse.lastX, + m_mouse.y - m_mouse.lastY); + } + } + else if (m_clickedWidget != (CNxWidget *)NULL) + { + // Mouse left button release event + + m_clickedWidget->release(m_mouse.x, m_mouse.y); + } + else + { + // No interesting mouse events + + mouseEvent = false; + } + + // Clear all press and release events once they have been processed + + clearMouseEvents(); + + // Save the mouse position for the next poll + + m_mouse.lastX = m_mouse.x; + m_mouse.lastY = m_mouse.y; + return mouseEvent; +} + +/** + * Process keypad events and send throughout the hierarchy. + * + * @return True means a keyboard event occurred + */ + +bool CWidgetControl::pollKeyboardEvents(void) +{ + bool keyboardEvent = false; // Assume no interesting keyboard events + + // Keyboard presses with no focused widget is not an interesting + // event + + if (m_focusedWidget != (CNxWidget *)NULL) + { + // Forward each character to the widget with the focus + + for (uint8_t i = 0; i < m_nCh; i++) + { + m_focusedWidget->keyPress((nxwidget_char_t)m_kbdbuf[i]); + keyboardEvent = true; + } + } + + // All of the buffered characters have been consumed + + m_nCh = 0; + return keyboardEvent; +} + +/** + * Process cursor control events and send throughout the hierarchy. + * + * @return True means a cursor control event was processes + */ + +bool CWidgetControl::pollCursorControlEvents(void) +{ + bool cursorControlEvent = false; // Assume no interesting cursor events + + // Cursor controls with no focused widget is not an interesting + // event + + if (m_focusedWidget != (CNxWidget *)NULL) + { + // Forward each cursor control to the widget with the focus + + for (uint8_t i = 0; i < m_nCc; i++) + { + m_focusedWidget->cursorControl((ECursorControl)m_controls[i]); + cursorControlEvent = true; + } + } + + // All of the buffered events have been consumed + + m_nCc = 0; + return cursorControlEvent; +} + +/** + * Clear all mouse events + */ + +void CWidgetControl::clearMouseEvents(void) +{ + // Clear all press and release events once they have been processed + + m_mouse.leftPressed = 0; + m_mouse.leftReleased = 0; + m_mouse.leftDrag = 0; + +#if 0 // Center and right buttons are not used + m_mouse.centerPressed = 0; + m_mouse.centerReleased = 0; + m_mouse.centerDrag = 0; + + m_mouse.rightPressed = 0; + m_mouse.rightReleased = 0; + m_mouse.rightDrag = 0; +#endif + + m_mouse.doubleClick = 0; +} diff --git a/NxWidgets/libnxwidgets/src/cwidgeteventhandlerlist.cxx b/NxWidgets/libnxwidgets/src/cwidgeteventhandlerlist.cxx new file mode 100644 index 000000000..48b762d0d --- /dev/null +++ b/NxWidgets/libnxwidgets/src/cwidgeteventhandlerlist.cxx @@ -0,0 +1,606 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/cwidgeteventhandlerlist.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> +#include <stdbool.h> + +#include "cnxwidget.hxx" +#include "cwidgeteventhandler.hxx" +#include "cwidgeteventargs.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +#define DOUBLE_CLICK_BOUNDS 10 + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +using namespace NXWidgets; + +/** + * Constructor. + * + * @param widget The owning widget. + */ + +CWidgetEventHandlerList::CWidgetEventHandlerList(CNxWidget *widget) +{ + m_widget = widget; + m_isEnabled = true; +} + +/** + * Check if the object raises events or not. + * + * @return True if events are enabled. + */ + +const bool CWidgetEventHandlerList::isEnabled(void) const +{ + return m_isEnabled && !m_widget->isDeleted(); +} + +/** + * Adds a widget event handler. The event handler will receive + * all events raised by this object. + * @param eventHandler A pointer to the event handler. + */ + +void CWidgetEventHandlerList::addWidgetEventHandler(CWidgetEventHandler *eventHandler) +{ + // Prevent insertion if the handler already exists + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + if (m_widgetEventHandlers.at(i) == eventHandler) + { + return; + } + } + + // Add the new handler + + m_widgetEventHandlers.push_back(eventHandler); +} + +/** + * Remove a widget event handler. + * + * @param eventHandler A pointer to the event handler to remove. + */ + +void CWidgetEventHandlerList::removeWidgetEventHandler(CWidgetEventHandler *eventHandler) +{ + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + if (m_widgetEventHandlers.at(i) == eventHandler) + { + m_widgetEventHandlers.erase(i); + return; + } + } +} + +/** + * Raise a click event to the event handler. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CWidgetEventHandlerList::raiseClickEvent(nxgl_coord_t x, nxgl_coord_t y) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, x, y, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleClickEvent(e); + } + } +} + +/** + * Raise a double-click event to the event handler. + * + * @param x The x coordinate of the click. + * @param y The y coordinate of the click. + */ + +void CWidgetEventHandlerList::raiseDoubleClickEvent(nxgl_coord_t x, nxgl_coord_t y) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, x, y, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleDoubleClickEvent(e); + } + } +} + +/** + * Raise a mouse release event to the event handler. + * + * @param x The x coordinate of the release. + * @param y The y coordinate of the release. + */ + +void CWidgetEventHandlerList::raiseReleaseEvent(nxgl_coord_t x, nxgl_coord_t y) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, x, y, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleReleaseEvent(e); + } + } +} + +/** + * Raise a mouse release-outside event to the event handler. + * + * @param x The x coordinate of the release. + * @param y The y coordinate of the release. + */ + +void CWidgetEventHandlerList::raiseReleaseOutsideEvent(nxgl_coord_t x, nxgl_coord_t y) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, x, y, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleReleaseOutsideEvent(e); + } + } +} + +/** + * Raise a mouse drag event to the event handler. + * + * @param x The x coordinate of the mouse when the drag started. + * @param y The y coordinate of the mouse when the drag started. + * @param vX The horizontal distance dragged. + * @param vY The vertical distance dragged. + */ + +void CWidgetEventHandlerList::raiseDragEvent(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t vX, nxgl_coord_t vY) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, x, y, vX, vY, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleDragEvent(e); + } + } +} + +/** + * Raise a widget drop event to the event handler. + * + * @param x The x coordinate of the mouse when the drop occurred. + * @param y The y coordinate of the mouse when the drop occurred. + */ + +void CWidgetEventHandlerList::raiseDropEvent(nxgl_coord_t x, nxgl_coord_t y) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, x, y, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleDropEvent(e); + } + } +} + +/** + * Raise a move forward event to the event handler. + */ + +void CWidgetEventHandlerList::raiseMoveForwardEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleMoveForwardEvent(e); + } + } +} + +/** + * Raise a move backward event to the event handler. + */ + +void CWidgetEventHandlerList::raiseMoveBackwardEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleMoveBackwardEvent(e); + } + } +} + +/** + * Raise a key press event to the event handler. + * + * @param key The code of the key that caused the event. + */ + +void CWidgetEventHandlerList::raiseKeyPressEvent(nxwidget_char_t key) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, key); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleKeyPressEvent(e); + } + } +} + +/** + * Raise a cursor control event to the event handler. + * + * @param cursorControl The cursor control code that caused the event. + */ + +void CWidgetEventHandlerList::raiseCursorControlEvent(ECursorControl cursorControl) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, (nxwidget_char_t)cursorControl); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleCursorControlEvent(e); + } + } +} + +/** + * Raise a focus event to the event handler. + */ + +void CWidgetEventHandlerList::raiseFocusEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleFocusEvent(e); + } + } +} + +/** + * Raise a blur event to the event handler. + */ + +void CWidgetEventHandlerList::raiseBlurEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleBlurEvent(e); + } + } +} + +/** + * Raise a close event to the event handler. + */ + +void CWidgetEventHandlerList::raiseCloseEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleCloseEvent(e); + } + } +} + +/** + * Raise a hide event to the event handler. + */ + +void CWidgetEventHandlerList::raiseHideEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleHideEvent(e); + } + } +} + +/** + * Raise a show event to the event handler. + */ + +void CWidgetEventHandlerList::raiseShowEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleShowEvent(e); + } + } +} + +/** + * Raise a shelve event to the event handler. + */ + +void CWidgetEventHandlerList::raiseShelveEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleShelveEvent(e); + } + } +} + +/** + * Raise a unshelve event to the event handler. + */ + +void CWidgetEventHandlerList::raiseUnshelveEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleUnshelveEvent(e); + } + } +} + +/** + * Raise an enable event to the event handler. + */ + +void CWidgetEventHandlerList::raiseEnableEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleEnableEvent(e); + } + } +} + +/** + * Raise a disable event to the event handler. + */ + +void CWidgetEventHandlerList::raiseDisableEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleDisableEvent(e); + } + } +} + +/** + * Raise a value change event to the event handler. + */ + +void CWidgetEventHandlerList::raiseValueChangeEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleValueChangeEvent(e); + } + } +} + +/** + * Raise a resize event to the event handler. + * + * @param width The new width of the widget. + * @param height The new height of the widget. + */ + +void CWidgetEventHandlerList::raiseResizeEvent(nxgl_coord_t width, nxgl_coord_t height) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleResizeEvent(e); + } + } +} + +/** + * Raise a move event to the event handler. + * + * @param x The new x coordinate of the widget. + * @param y The new y coordinate of the widget. + * @param vX The horizontal distance moved. + * @param vY The vertical distance moved. + */ + +void CWidgetEventHandlerList::raiseMoveEvent(nxgl_coord_t x, nxgl_coord_t y, + nxgl_coord_t vX, nxgl_coord_t vY) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, x, y, vX, vY, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleMoveEvent(e); + } + } +} + +/** + * Raise an action event to the event handler. This should be called + * when a widget's purpose has been fulfilled. For example, in the case + * of a button, this event is raised when the button is released within + * its boundaries. The button has produced a valid click, and thus + * fulfilled its purpose, so it needs to raise an "action" event. + */ + +void CWidgetEventHandlerList::raiseActionEvent(void) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, 0, 0, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleActionEvent(e); + } + } +} + +/** + * Raises a scroll event. Fired when the panel scrolls. + * + * @param vX Horizontal distance scrolled. + * @param vY Vertical distance scrolled. + */ + +void CWidgetEventHandlerList::raiseScrollEvent(nxgl_coord_t vX, nxgl_coord_t vY) +{ + if (isEnabled()) + { + CWidgetEventArgs e(m_widget, 0, 0, vX, vY, KEY_CODE_NONE); + + for (int i = 0; i < m_widgetEventHandlers.size(); ++i) + { + m_widgetEventHandlers.at(i)->handleScrollEvent(e); + } + } +} diff --git a/NxWidgets/libnxwidgets/src/glyph_arrowdown.cxx b/NxWidgets/libnxwidgets/src/glyph_arrowdown.cxx new file mode 100644 index 000000000..ec2a6baf0 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_arrowdown.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_arrowdown.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_arrowDownGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_BLACK, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_BLACK, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_BLACK, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_BLACK, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_BLACK, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_BLACK, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_BLACK, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_BLACK, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_arrowDownGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_BLACK, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_BLACK, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_BLACK, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_BLACK, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_BLACK, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_BLACK, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_BLACK, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_BLACK, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_arrowDown = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 6, // width - Width in pixels + 10, // height - Height in rows + (6*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_arrowDownGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_arrowleft.cxx b/NxWidgets/libnxwidgets/src/glyph_arrowleft.cxx new file mode 100644 index 000000000..6b3e8ee92 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_arrowleft.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_glypharrowleft.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_arrowLeftGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_arrowLeftGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_arrowLeft = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 7, // width - Width in pixels + 10, // height - Height in rows + (7*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_arrowLeftGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_arrowright.cxx b/NxWidgets/libnxwidgets/src/glyph_arrowright.cxx new file mode 100644 index 000000000..74763a6fd --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_arrowright.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_arrowright.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_arrowRightGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_arrowRightGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_arrowRight = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 7, // width - Width in pixels + 10, // height - Height in rows + (7*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_arrowRightGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_arrowup.cxx b/NxWidgets/libnxwidgets/src/glyph_arrowup.cxx new file mode 100644 index 000000000..9ec840d43 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_arrowup.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_arrowup.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_arrowUpGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_arrowUpGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_arrowUp = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 6, // width - Width in pixels + 10, // height - Height in rows + (6*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_arrowUpGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_backspace.cxx b/NxWidgets/libnxwidgets/src/glyph_backspace.cxx new file mode 100644 index 000000000..967963347 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_backspace.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_backspace.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_backspaceGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_backspaceGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_backspace = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 8, // width - Width in pixels + 10, // height - Height in rows + (8*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_backspaceGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_capslock.cxx b/NxWidgets/libnxwidgets/src/glyph_capslock.cxx new file mode 100644 index 000000000..663e601f0 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_capslock.cxx @@ -0,0 +1,155 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_capslock.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_capslockGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_capslockGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_capslock = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 8, // width - Width in pixels + 10, // height - Height in rows + (8*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_capslockGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 + diff --git a/NxWidgets/libnxwidgets/src/glyph_checkboxmu.cxx b/NxWidgets/libnxwidgets/src/glyph_checkboxmu.cxx new file mode 100644 index 000000000..681c17445 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_checkboxmu.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_checkboxmu.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_checkBoxMuGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, RGB16_WHITE, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, RGB16_WHITE, RGB16_TRANSP, + RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, + RGB16_WHITE, RGB16_WHITE, RGB16_TRANSP, RGB16_WHITE, RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_checkBoxMuGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, RGB24_WHITE, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, RGB24_WHITE, RGB24_TRANSP, + RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, + RGB24_WHITE, RGB24_WHITE, RGB24_TRANSP, RGB24_WHITE, RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_checkBoxMu = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 8, // width - Width in pixels + 10, // height - Height in rows + (8*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_checkBoxMuGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_checkboxoff.cxx b/NxWidgets/libnxwidgets/src/glyph_checkboxoff.cxx new file mode 100644 index 000000000..250d2455e --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_checkboxoff.cxx @@ -0,0 +1,121 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_checkboxoff.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_checkBoxOff = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 0, // width - Width in pixels + 0, // height - Height in rows + (0*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + (const nxgl_mxpixel_t*)NULL // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_checkboxon.cxx b/NxWidgets/libnxwidgets/src/glyph_checkboxon.cxx new file mode 100644 index 000000000..5b9c18b78 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_checkboxon.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_checkboxon.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_checkBoxOnGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_checkBoxOnGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_checkBoxOn = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 8, // width - Width in pixels + 10, // height - Height in rows + (8*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_checkBoxOnGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_control.cxx b/NxWidgets/libnxwidgets/src/glyph_control.cxx new file mode 100644 index 000000000..ffbdf965b --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_control.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_control.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_controlGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, + RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_controlGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, + RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_control = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 7, // width - Width in pixels + 10, // height - Height in rows + (7*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_controlGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_cycle.cxx b/NxWidgets/libnxwidgets/src/glyph_cycle.cxx new file mode 100644 index 000000000..5c98b8b90 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_cycle.cxx @@ -0,0 +1,155 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_cycle.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_cycleGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_cycleGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_cycle = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 7, // width - Width in pixels + 10, // height - Height in rows + (7*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_cycleGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 + diff --git a/NxWidgets/libnxwidgets/src/glyph_nxlogo.cxx b/NxWidgets/libnxwidgets/src/glyph_nxlogo.cxx new file mode 100644 index 000000000..1b3aab143 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_nxlogo.cxx @@ -0,0 +1,3450 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_nxlogo.cxx + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "crlepalettebitmap.hxx" +#include "glyphs.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +/* RGB24 (8-8-8) Colors */ + +#if CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define BITMAP_NLUTCODES 164 /* Number of unique RGB colors in the image */ + +static const uint32_t g_nuttxLut[BITMAP_NLUTCODES] = +{ + 0x000000, 0x102028, 0x5898e0, 0x3c30e4, 0x3c34e4, 0x0c0828, 0x382ce4, 0x3c34e8, /* Codes 0-7 */ + 0x3834d4, 0x241c74, 0x2c2490, 0x343c8c, 0x5ca0ec, 0x4454d0, 0x2c288c, 0x5ca0e8, /* Codes 8-15 */ + 0x3830d4, 0x687078, 0xd0e4f0, 0x3428e4, 0x24282c, 0xcce4f0, 0x848cec, 0xdcf4f4, /* Codes 16-23 */ + 0xd8ecf0, 0x2c24e0, 0xa8b8c4, 0xb4c4f0, 0x5854e4, 0xd8f0f0, 0xd8f0f4, 0x484890, /* Codes 24-31 */ + 0x2c287c, 0x28287c, 0x282478, 0x342cb4, 0xcce0f0, 0xd8e8f4, 0xa8bcc8, 0x587c98, /* Codes 32-39 */ + 0x5c98bc, 0x2c4c60, 0xe0f8fc, 0x1c1478, 0x2c2884, 0x302894, 0xfcfcfc, 0xd4e8f4, /* Codes 40-47 */ + 0x5090b8, 0x101c20, 0xd8ecf8, 0x5c94bc, 0x8c90ec, 0x7c84bc, 0xc8e0f0, 0x98c0d8, /* Codes 48-55 */ + 0xe8f0f8, 0x94bcd8, 0x3830e4, 0xb0bcec, 0xf4f8fc, 0xe4f0f8, 0x3c34ec, 0x142028, /* Codes 56-63 */ + 0x5894bc, 0x5078ac, 0x5084b4, 0x282080, 0x3428b4, 0xd0e4f4, 0x70a4c8, 0x3c34d8, /* Codes 64-71 */ + 0x7880b0, 0x5490b8, 0x5484b4, 0x281c78, 0x5ca4ec, 0xdcf4fc, 0x181078, 0x2c2880, /* Codes 72-79 */ + 0x382cd0, 0x342cb8, 0x1c1888, 0x888cf0, 0xc4e0f0, 0x98c4dc, 0x180c74, 0x5080b0, /* Codes 80-87 */ + 0x282480, 0x04000c, 0x282474, 0x4038f4, 0x3024ec, 0x302c9c, 0x7c84b4, 0x0c1c28, /* Codes 88-95 */ + 0x5090e0, 0x3020e4, 0xd8f0f8, 0x7478b4, 0x100870, 0x08006c, 0x24188c, 0x201c7c, /* Codes 96-103 */ + 0x2c2090, 0x5098d0, 0xd4e4f0, 0x589cd0, 0x3840e0, 0x4048e4, 0xc4dcf0, 0xdcf4f8, /* Codes 104-111 */ + 0x3024e8, 0x342cac, 0x4878b8, 0x4048e0, 0x8084e8, 0x2c248c, 0x3430bc, 0x241c70, /* Codes 112-119 */ + 0x141074, 0x3428e0, 0x342cec, 0x2c24b4, 0x201c78, 0x3028d0, 0x241c8c, 0x7078b4, /* Codes 120-127 */ + 0x040028, 0xd4e8f0, 0x4c7cd4, 0x282078, 0x5484b0, 0x20285c, 0x20187c, 0x4c7cb0, /* Codes 128-135 */ + 0x3830d0, 0x4034f0, 0x2820c8, 0xdcf0f4, 0x34408c, 0x98d4ec, 0x2c1ce0, 0x5080ac, /* Codes 136-143 */ + 0x3c30e8, 0x7078a8, 0x04001c, 0x2c3034, 0x305064, 0x2c4458, 0x74a8c8, 0xf8f8fc, /* Codes 144-151 */ + 0xdcecf8, 0xb0c0dc, 0xa0b0bc, 0xb4d4e4, 0x707880, 0x7c98a8, 0xdcf4f0, 0x2820ac, /* Codes 152-159 */ + 0x201874, 0x302898, 0x3844ac, 0x507ce0, /* Codes 160-163 */ +}; + +/* RGB16 (565) Colors (four of the colors in this map are duplicates) */ + +#elif CONFIG_NXWIDGETS_BPP == 16 +# define BITMAP_NLUTCODES 141 /* Number of unique RGB colors in the image */ + +static const uint16_t g_nuttxLut[BITMAP_NLUTCODES] = +{ + 0x0000, 0x1105, 0x5cdc, 0x399c, 0x41bc, 0x0845, 0x397c, 0x39bc, 0x41bd, 0x39ba, /* Codes 0-9 */ + 0x28ee, 0x3132, 0x31f2, 0x5d1d, 0x42ba, 0x3152, 0x399a, 0x6b8f, 0xd73e, 0x315c, /* Codes 10-19 */ + 0x2945, 0x8c7d, 0xe7be, 0xdf7e, 0x313c, 0xadd9, 0xb63e, 0x5abd, 0xdf9e, 0xdf9f, /* Codes 20-29 */ + 0x4a52, 0x2950, 0x292f, 0x3176, 0xcf1e, 0xdf5f, 0xadf9, 0x5bf3, 0x5cd8, 0x326c, /* Codes 30-39 */ + 0xe7df, 0x18af, 0x3153, 0xdf5e, 0xffff, 0x5497, 0x10e4, 0xdf7f, 0x5cb8, 0x8c9d, /* Codes 40-49 */ + 0x8437, 0x9e1b, 0xef9f, 0x9dfb, 0xb5fe, 0xffdf, 0x41be, 0x53d6, 0x5436, 0x2910, /* Codes 50-59 */ + 0x3156, 0x7539, 0x39bb, 0x7c16, 0x95fb, 0x28ef, 0x653d, 0xe7bf, 0x188f, 0x397a, /* Codes 60-69 */ + 0x3977, 0x20d1, 0x8c7e, 0xe79f, 0x9e3b, 0x186e, 0x5416, 0x2930, 0x0801, 0x41de, /* Codes 70-79 */ + 0x313d, 0x3173, 0x7c36, 0x08e5, 0x549c, 0xd75f, 0x311c, 0x73d6, 0x3150, 0x315d, /* Codes 80-89 */ + 0x104e, 0x080e, 0x20f0, 0x2912, 0x54da, 0xdf3e, 0x5cfa, 0x3a1c, 0x425c, 0xcefe, /* Codes 90-99 */ + 0x4bd7, 0x843d, 0x2932, 0x3997, 0xf7df, 0x397d, 0x2936, 0x20ef, 0x315a, 0x20f1, /* Codes 100-109 */ + 0x0005, 0xd75e, 0x53fa, 0x290f, 0x214b, 0x20cf, 0x4bf6, 0x2919, 0x3212, 0x9ebd, /* Codes 110-119 */ + 0x28fc, 0x5415, 0x399d, 0x73d5, 0x0804, 0x3187, 0x328d, 0x2a2b, 0x7559, 0xe77f, /* Codes 120-129 */ + 0xb61c, 0x3186, 0xa598, 0xbebd, 0x73d0, 0x84d5, 0x5cb7, 0x2916, 0x20ce, 0x3a35, /* Codes 130-139 */ + 0x53fc /* Codes 140-140 */ +}; + +/* 8-bit color lookups. NOTE: This is really dumb! The lookup index is 8-bits and it used + * to lookup an 8-bit value. There is no savings in that! It would be better to just put + * the 8-bit color/greyscale value in the run-length encoded image and save the cost of these + * pointless lookups. But these p;ointless lookups do make the logic compatible with the + * 16- and 24-bit types. + */ + +#elif CONFIG_NXWIDGETS_BPP == 8 +# ifdef CONFIG_NXWIDGETS_GREYSCALE +# define BITMAP_NLUTCODES 116 /* Number of unique greyscale levels in the image */ + +/* 8-bit Greyscale */ + +static const uint8_t g_nuttxLut[BITMAP_NLUTCODES] = +{ + 0x00, 0x19, 0x8b, 0x46, 0x4a, 0x0b, 0x8d, 0x41, 0x44, 0x27, 0x32, 0x92, 0x59, 0x34, 0x6d, 0xdb, /* Codes 0-15 */ + 0x3f, 0x26, 0x91, 0xec, 0xe5, 0x39, 0xb4, 0xc0, 0x62, 0xe6, 0x4c, 0x2f, 0x2e, 0x3c, 0xda, 0xe4, /* Codes 16-31 */ + 0x72, 0x86, 0xed, 0x1d, 0x35, 0xe2, 0xfc, 0xe3, 0x7d, 0x16, 0x97, 0x87, 0xee, 0xb2, 0x42, 0xbc, /* Codes 32-47 */ + 0xf6, 0x4b, 0x1c, 0x70, 0x90, 0x77, 0x2c, 0xdf, 0x96, 0x29, 0x45, 0x7f, 0x81, 0xb1, 0x28, 0xea, /* Codes 48-63 */ + 0x40, 0x3d, 0x23, 0x95, 0xe9, 0xd6, 0xb7, 0x2d, 0x02, 0x3a, 0x85, 0x17, 0x82, 0xe7, 0x7b, 0x33, /* Codes 64-79 */ + 0x0e, 0x25, 0x84, 0xe0, 0x8c, 0x4d, 0x56, 0x1e, 0x3b, 0x6e, 0x31, 0x3e, 0xf3, 0x1a, 0x20, 0x04, /* Codes 80-95 */ + 0xe1, 0x74, 0x2a, 0x79, 0x21, 0x71, 0xc4, 0x76, 0x48, 0x98, 0xf7, 0x94, 0xe8, 0xbe, 0xac, 0xc9, /* Codes 96-111 */ + 0x75, 0x8e, 0x49, 0x7a /* Codes 112-115 */ +}; + +# else /* CONFIG_NXWIDGETS_GREYSCALE */ +# define BITMAP_NLUTCODES 27 /* Number of unique RGB colors in the image */ + +/* RGB8 (332) Colors */ + +static const nxgl_mxpixel_t g_nuttxLut[BITMAP_NLUTCODES] = +{ + 0x00, 0x25, 0x77, 0x4b, 0x01, 0x47, 0x26, 0x4a, 0x4f, 0x72, 0xdf, 0x93, 0xff, 0x27, 0xbb, 0xdb, /* Codes 0-15 */ + 0x6f, 0x29, 0x53, 0x97, 0x73, 0x22, 0x05, 0x02, 0x57, 0xbf, 0x4e /* Codes 16-26 */ +}; + +# endif +#else +# error "Unsupport pixel format" +#endif + +#if CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 + +static const struct SRlePaletteBitmapEntry g_nuttxRleEntries[] = +{ + { 76, 0}, { 1, 1}, { 1, 2}, { 1, 3}, { 4, 4}, { 1, 5}, { 76, 0}, /* Row 0 */ + { 75, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 2, 7}, { 3, 4}, { 1, 5}, /* Row 1 */ + { 75, 0}, + { 74, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 9}, { 1, 10}, /* Row 2 */ + { 1, 7}, { 3, 4}, { 1, 5}, { 74, 0}, + { 73, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 12}, /* Row 3 */ + { 1, 13}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 73, 0}, + { 72, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 4 */ + { 1, 6}, { 1, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 72, 0}, + { 71, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 5 */ + { 1, 6}, { 3, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 71, 0}, + { 70, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 6 */ + { 1, 6}, { 5, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 70, 0}, + { 69, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 7 */ + { 1, 6}, { 7, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 69, 0}, + { 68, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 8 */ + { 1, 6}, { 9, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 68, 0}, + { 67, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 9 */ + { 1, 6}, { 11, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 67, 0}, + { 66, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 10 */ + { 1, 6}, { 13, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 66, 0}, + { 65, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 11 */ + { 1, 6}, { 15, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 65, 0}, + { 64, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 12 */ + { 1, 6}, { 17, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 64, 0}, + { 63, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 13 */ + { 1, 6}, { 19, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 63, 0}, + { 62, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 14 */ + { 1, 6}, { 21, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 62, 0}, + { 61, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 15 */ + { 1, 6}, { 23, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 61, 0}, + { 60, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 16 */ + { 1, 6}, { 25, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 60, 0}, + { 59, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 17 */ + { 1, 6}, { 27, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 59, 0}, + { 58, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 18 */ + { 1, 6}, { 29, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 26, 0}, + { 1, 17}, { 5, 18}, { 1, 17}, { 25, 0}, + { 57, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 19 */ + { 1, 6}, { 10, 4}, { 5, 19}, { 16, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, + { 1, 5}, { 23, 0}, { 1, 20}, { 1, 18}, { 1, 21}, { 5, 18}, { 1, 21}, { 1, 18}, + { 1, 20}, { 23, 0}, + { 56, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, /* Row 20 */ + { 1, 6}, { 9, 4}, { 1, 19}, { 1, 22}, { 1, 23}, { 3, 24}, { 1, 23}, { 1, 22}, + { 1, 25}, { 15, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 22, 0}, + { 11, 18}, { 1, 20}, { 22, 0}, + { 23, 0}, { 1, 17}, { 5, 18}, { 1, 26}, { 25, 0}, { 1, 1}, { 1, 2}, { 1, 6}, /* Row 21 */ + { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 9, 4}, { 1, 19}, { 1, 27}, + { 1, 21}, { 5, 18}, { 1, 21}, { 1, 23}, { 1, 28}, { 15, 4}, { 1, 16}, { 1, 14}, + { 1, 7}, { 3, 4}, { 1, 5}, { 20, 0}, { 1, 17}, { 1, 21}, { 11, 18}, { 1, 20}, + { 21, 0}, + { 21, 0}, { 1, 20}, { 1, 18}, { 1, 21}, { 5, 18}, { 1, 21}, { 1, 18}, { 1, 20}, /* Row 22 */ + { 22, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, + { 1, 6}, { 9, 4}, { 1, 19}, { 1, 27}, { 1, 21}, { 8, 18}, { 1, 29}, { 1, 28}, + { 4, 7}, { 11, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 19, 0}, + { 14, 18}, { 21, 0}, + { 21, 0}, { 11, 18}, { 1, 20}, { 20, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, /* Row 23 */ + { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 10, 4}, { 1, 22}, { 1, 21}, { 10, 18}, + { 1, 30}, { 1, 31}, { 1, 32}, { 1, 33}, { 1, 34}, { 1, 35}, { 1, 7}, { 10, 4}, + { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 17, 0}, { 1, 17}, { 1, 21}, + { 4, 18}, { 1, 36}, { 2, 37}, { 1, 36}, { 4, 18}, { 1, 21}, { 1, 17}, { 20, 0}, + { 20, 0}, { 1, 38}, { 1, 21}, { 11, 18}, { 1, 39}, { 4, 40}, { 1, 41}, { 13, 0}, /* Row 24 */ + { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, + { 10, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 3, 36}, { 5, 18}, { 1, 42}, { 1, 43}, + { 3, 44}, { 1, 45}, { 1, 7}, { 10, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, + { 1, 5}, { 16, 0}, { 5, 18}, { 1, 37}, { 4, 46}, { 1, 37}, { 4, 18}, { 1, 47}, + { 1, 48}, { 1, 49}, { 18, 0}, + { 19, 0}, { 1, 17}, { 1, 21}, { 12, 18}, { 1, 50}, { 1, 48}, { 3, 40}, { 1, 51}, /* Row 25 */ + { 1, 40}, { 11, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, + { 1, 15}, { 1, 6}, { 11, 4}, { 1, 52}, { 1, 21}, { 3, 18}, { 1, 37}, { 3, 46}, + { 1, 37}, { 4, 18}, { 1, 21}, { 1, 53}, { 4, 44}, { 1, 45}, { 1, 7}, { 10, 4}, + { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 14, 0}, { 1, 17}, { 1, 21}, + { 3, 18}, { 1, 54}, { 6, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 55}, { 1, 40}, + { 1, 49}, { 17, 0}, + { 19, 0}, { 5, 18}, { 1, 54}, { 2, 56}, { 1, 37}, { 5, 18}, { 1, 21}, { 1, 57}, /* Row 26 */ + { 4, 40}, { 1, 51}, { 1, 41}, { 9, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, + { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 11, 4}, { 1, 58}, { 1, 59}, { 3, 18}, + { 1, 21}, { 1, 60}, { 4, 46}, { 1, 37}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, + { 1, 45}, { 1, 7}, { 10, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, + { 13, 0}, { 5, 18}, { 1, 56}, { 6, 46}, { 1, 56}, { 4, 18}, { 1, 57}, { 2, 40}, + { 1, 49}, { 16, 0}, + { 18, 0}, { 1, 17}, { 1, 21}, { 3, 18}, { 1, 37}, { 4, 46}, { 1, 37}, { 5, 18}, /* Row 27 */ + { 1, 50}, { 1, 48}, { 5, 40}, { 8, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, + { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 12, 4}, { 1, 19}, { 1, 24}, { 3, 18}, + { 1, 37}, { 6, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, + { 11, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 11, 0}, { 1, 17}, + { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 57}, { 3, 40}, + { 16, 0}, + { 18, 0}, { 4, 18}, { 1, 54}, { 5, 46}, { 1, 60}, { 1, 36}, { 4, 18}, { 1, 21}, /* Row 28 */ + { 1, 57}, { 4, 40}, { 1, 51}, { 1, 41}, { 6, 0}, { 1, 1}, { 1, 2}, { 1, 6}, + { 1, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 13, 4}, { 1, 19}, { 1, 24}, + { 3, 18}, { 1, 61}, { 6, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, + { 1, 34}, { 1, 62}, { 11, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, + { 10, 0}, { 5, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 55}, + { 2, 40}, { 1, 51}, { 1, 41}, { 15, 0}, + { 18, 0}, { 4, 18}, { 1, 56}, { 6, 46}, { 1, 56}, { 5, 18}, { 1, 50}, { 1, 48}, /* Row 29 */ + { 5, 40}, { 5, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, + { 1, 15}, { 1, 6}, { 14, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, + { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 12, 4}, { 1, 16}, + { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 8, 0}, { 1, 17}, { 1, 21}, { 3, 18}, + { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, { 4, 40}, { 15, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 57}, /* Row 30 */ + { 4, 40}, { 1, 51}, { 1, 41}, { 3, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, + { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 15, 4}, { 1, 19}, { 1, 24}, { 2, 18}, + { 1, 36}, { 8, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, + { 1, 62}, { 12, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 7, 0}, + { 5, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 57}, { 5, 40}, + { 1, 63}, { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 56}, { 5, 18}, { 1, 50}, { 1, 48}, /* Row 31 */ + { 5, 40}, { 2, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, + { 1, 15}, { 1, 6}, { 16, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 9, 46}, + { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 13, 4}, { 1, 16}, + { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 5, 0}, { 1, 17}, { 1, 21}, { 3, 18}, + { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, { 5, 40}, { 1, 41}, + { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 9, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 57}, /* Row 32 */ + { 4, 40}, { 1, 51}, { 1, 41}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 4}, { 1, 8}, + { 1, 11}, { 1, 15}, { 1, 6}, { 17, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, + { 9, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, + { 13, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 4, 0}, { 5, 18}, + { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 57}, { 6, 40}, { 1, 63}, + { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 9, 46}, { 1, 56}, { 5, 18}, { 1, 50}, { 1, 48}, /* Row 33 */ + { 3, 40}, { 1, 64}, { 1, 65}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 8}, { 1, 11}, + { 1, 15}, { 1, 6}, { 18, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 10, 46}, + { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 14, 4}, { 1, 16}, + { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 2, 0}, { 1, 17}, { 1, 21}, { 3, 18}, + { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, { 6, 40}, { 15, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 10, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 57}, /* Row 34 */ + { 2, 40}, { 1, 64}, { 1, 66}, { 1, 67}, { 1, 68}, { 1, 4}, { 1, 8}, { 1, 11}, + { 1, 15}, { 1, 6}, { 19, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 10, 46}, + { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 14, 4}, + { 1, 16}, { 1, 14}, { 1, 7}, { 3, 4}, { 1, 5}, { 1, 0}, { 5, 18}, { 1, 56}, + { 7, 46}, { 1, 54}, { 3, 18}, { 1, 69}, { 1, 70}, { 5, 40}, { 1, 51}, { 1, 41}, + { 15, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 10, 46}, { 1, 56}, { 5, 18}, { 1, 50}, { 1, 48}, /* Row 35 */ + { 1, 64}, { 1, 66}, { 1, 67}, { 1, 44}, { 1, 34}, { 1, 71}, { 1, 11}, { 1, 15}, + { 1, 6}, { 20, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 11, 46}, { 1, 54}, + { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 15, 4}, { 1, 16}, { 1, 14}, + { 1, 7}, { 3, 4}, { 1, 72}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, + { 4, 18}, { 1, 50}, { 1, 73}, { 6, 40}, { 16, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 11, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 57}, /* Row 36 */ + { 1, 74}, { 1, 67}, { 3, 44}, { 1, 75}, { 1, 76}, { 1, 6}, { 21, 4}, { 1, 19}, + { 1, 24}, { 2, 18}, { 1, 36}, { 11, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, + { 4, 44}, { 1, 34}, { 1, 62}, { 15, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 1, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 57}, { 5, 40}, { 1, 51}, { 1, 41}, { 16, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 11, 46}, { 1, 56}, { 5, 18}, { 1, 77}, { 1, 78}, /* Row 37 */ + { 4, 44}, { 1, 79}, { 1, 80}, { 22, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, + { 12, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 16, 4}, + { 1, 16}, { 1, 14}, { 1, 7}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, + { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, { 6, 40}, { 17, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 12, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, /* Row 38 */ + { 5, 44}, { 1, 81}, { 22, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 12, 46}, + { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 16, 4}, + { 1, 16}, { 1, 82}, { 1, 23}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, + { 1, 21}, { 1, 57}, { 5, 40}, { 1, 51}, { 1, 41}, { 17, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 12, 46}, { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, /* Row 39 */ + { 4, 44}, { 1, 34}, { 1, 62}, { 21, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, + { 13, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 17, 4}, + { 1, 83}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 50}, + { 1, 48}, { 6, 40}, { 18, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 13, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, /* Row 40 */ + { 5, 44}, { 1, 35}, { 21, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 13, 46}, + { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 15, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 57}, { 5, 40}, { 1, 51}, { 1, 41}, { 18, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 13, 46}, { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, /* Row 41 */ + { 4, 44}, { 1, 34}, { 1, 62}, { 20, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, + { 14, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 15, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 50}, + { 1, 48}, { 6, 40}, { 19, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 14, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, /* Row 42 */ + { 5, 44}, { 1, 35}, { 20, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 14, 46}, + { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 13, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 57}, { 5, 40}, { 1, 51}, { 1, 41}, { 19, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 14, 46}, { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, /* Row 43 */ + { 4, 44}, { 1, 34}, { 1, 62}, { 19, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, + { 7, 46}, { 1, 61}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, + { 1, 35}, { 13, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, + { 4, 18}, { 1, 50}, { 1, 48}, { 6, 40}, { 20, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 15, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, /* Row 44 */ + { 5, 44}, { 1, 35}, { 19, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, + { 1, 84}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, + { 1, 62}, { 11, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, + { 3, 18}, { 1, 21}, { 1, 57}, { 5, 40}, { 1, 51}, { 1, 41}, { 20, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 61}, { 6, 46}, { 1, 56}, { 5, 18}, /* Row 45 */ + { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 18, 4}, { 1, 19}, { 1, 24}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, + { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 11, 4}, { 1, 22}, { 1, 21}, { 3, 18}, + { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, { 6, 40}, { 21, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 84}, { 7, 46}, { 1, 54}, { 4, 18}, /* Row 46 */ + { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 18, 4}, { 1, 19}, { 1, 24}, { 2, 18}, + { 1, 36}, { 7, 46}, { 1, 36}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 9, 4}, { 1, 25}, { 1, 23}, { 4, 18}, + { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 57}, { 5, 40}, { 1, 51}, + { 1, 41}, { 21, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 1, 56}, { 6, 46}, { 1, 56}, /* Row 47 */ + { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 17, 4}, { 1, 19}, + { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 1, 18}, { 1, 56}, { 7, 46}, + { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 9, 4}, { 1, 22}, + { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, + { 6, 40}, { 22, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 1, 54}, { 7, 46}, { 1, 54}, /* Row 48 */ + { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 17, 4}, { 1, 19}, { 1, 24}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 1, 18}, { 1, 54}, { 7, 46}, { 1, 56}, + { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 7, 4}, { 1, 25}, + { 1, 23}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 85}, + { 1, 51}, { 4, 40}, { 1, 51}, { 1, 41}, { 22, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 1, 18}, { 1, 56}, { 6, 46}, /* Row 49 */ + { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 16, 4}, + { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 56}, + { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 7, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 86}, { 1, 66}, { 1, 64}, { 4, 40}, { 23, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 1, 18}, { 1, 54}, { 7, 46}, /* Row 50 */ + { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 16, 4}, { 1, 19}, + { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 54}, { 7, 46}, + { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 5, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 53}, { 1, 44}, { 1, 67}, { 1, 66}, { 1, 64}, { 1, 40}, { 1, 51}, { 1, 41}, + { 23, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 56}, { 6, 46}, /* Row 51 */ + { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 15, 4}, + { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 3, 18}, { 1, 56}, + { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 5, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 2, 44}, { 1, 67}, { 1, 66}, { 1, 64}, { 1, 40}, { 24, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 54}, { 7, 46}, /* Row 52 */ + { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 15, 4}, { 1, 19}, + { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 3, 18}, { 1, 54}, { 7, 46}, + { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 3, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 53}, { 4, 44}, { 1, 67}, { 1, 87}, { 1, 41}, { 24, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 3, 18}, { 1, 56}, { 6, 46}, /* Row 53 */ + { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 14, 4}, + { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 4, 18}, { 1, 56}, + { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 3, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 5, 44}, { 1, 88}, { 1, 89}, { 24, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 3, 18}, { 1, 54}, { 7, 46}, /* Row 54 */ + { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 14, 4}, { 1, 19}, + { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 4, 18}, { 1, 54}, { 7, 46}, + { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 1, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 53}, { 6, 44}, { 1, 90}, { 1, 62}, { 1, 5}, { 23, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 4, 18}, { 1, 56}, { 6, 46}, /* Row 55 */ + { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 13, 4}, + { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 5, 18}, { 1, 56}, + { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 1, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 5, 44}, { 1, 33}, { 1, 91}, { 2, 4}, { 1, 5}, { 22, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 4, 18}, { 1, 54}, { 7, 46}, /* Row 56 */ + { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 13, 4}, { 1, 19}, + { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 5, 18}, { 1, 54}, { 7, 46}, + { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 92}, { 1, 23}, + { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, + { 1, 93}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 21, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 5, 18}, { 1, 56}, { 6, 46}, /* Row 57 */ + { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 12, 4}, + { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 6, 18}, { 1, 56}, + { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 94}, { 1, 21}, + { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, + { 1, 34}, { 1, 62}, { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 20, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 5, 18}, { 1, 54}, { 7, 46}, /* Row 58 */ + { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 12, 4}, { 1, 19}, + { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 6, 18}, { 1, 54}, { 7, 46}, + { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 3, 44}, { 1, 43}, { 1, 42}, { 4, 18}, + { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 35}, + { 2, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 19, 0}, + { 17, 0}, { 1, 95}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 6, 18}, { 1, 56}, /* Row 59 */ + { 6, 46}, { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, + { 11, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 7, 18}, + { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 3, 44}, { 1, 53}, + { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, + { 5, 44}, { 1, 34}, { 1, 62}, { 3, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, + { 1, 5}, { 18, 0}, + { 16, 0}, { 1, 1}, { 1, 96}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, /* Row 60 */ + { 6, 18}, { 1, 54}, { 7, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, + { 1, 35}, { 11, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, + { 2, 18}, { 1, 21}, { 1, 47}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, + { 1, 42}, { 1, 43}, { 1, 44}, { 1, 43}, { 1, 42}, { 4, 18}, { 1, 56}, { 7, 46}, + { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 35}, { 5, 4}, { 1, 16}, + { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 17, 0}, + { 15, 0}, { 1, 1}, { 1, 2}, { 1, 97}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, /* Row 61 */ + { 1, 36}, { 7, 18}, { 1, 56}, { 6, 46}, { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, + { 4, 44}, { 1, 34}, { 1, 62}, { 10, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, + { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 99}, { 1, 21}, { 3, 18}, { 1, 56}, + { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 1, 44}, { 1, 53}, { 1, 21}, + { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, + { 1, 34}, { 1, 62}, { 6, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, + { 16, 0}, + { 14, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, /* Row 62 */ + { 8, 46}, { 1, 36}, { 7, 18}, { 1, 54}, { 7, 46}, { 1, 54}, { 4, 18}, { 1, 21}, + { 1, 53}, { 5, 44}, { 1, 35}, { 10, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, + { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 100}, { 1, 42}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 101}, { 1, 42}, { 4, 18}, { 1, 56}, + { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 35}, { 8, 4}, + { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 15, 0}, + { 13, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 102}, { 1, 98}, { 2, 18}, /* Row 63 */ + { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 21}, { 1, 47}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, + { 9, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, + { 1, 98}, { 1, 103}, { 1, 53}, { 1, 21}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, + { 3, 18}, { 1, 21}, { 1, 98}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, + { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, { 1, 34}, { 1, 62}, { 9, 4}, { 1, 16}, + { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 14, 0}, + { 12, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 105}, { 1, 106}, /* Row 64 */ + { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 99}, { 1, 21}, + { 3, 18}, { 1, 54}, { 7, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, + { 1, 35}, { 9, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, + { 2, 18}, { 1, 98}, { 1, 103}, { 1, 43}, { 1, 42}, { 3, 18}, { 1, 54}, { 7, 46}, + { 1, 56}, { 9, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, + { 6, 44}, { 1, 35}, { 11, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, + { 13, 0}, + { 11, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 108}, /* Row 65 */ + { 1, 29}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 100}, + { 1, 42}, { 4, 18}, { 1, 56}, { 6, 46}, { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, + { 4, 44}, { 1, 34}, { 1, 62}, { 8, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, + { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 1, 44}, { 1, 53}, { 1, 21}, + { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 7, 18}, { 1, 54}, { 7, 46}, { 1, 56}, + { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, { 1, 34}, { 1, 62}, { 12, 4}, { 1, 16}, + { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 12, 0}, + { 10, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, /* Row 66 */ + { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, + { 1, 103}, { 1, 53}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 54}, { 4, 18}, + { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 8, 4}, { 1, 19}, { 1, 24}, { 2, 18}, + { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 1, 44}, { 1, 43}, + { 1, 42}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 7, 18}, { 1, 56}, { 7, 46}, + { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 35}, { 14, 4}, { 1, 16}, + { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 11, 0}, + { 9, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, /* Row 67 */ + { 1, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, + { 1, 98}, { 1, 103}, { 1, 43}, { 1, 42}, { 4, 18}, { 1, 56}, { 6, 46}, { 1, 56}, + { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 7, 4}, { 1, 19}, + { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 2, 44}, { 1, 53}, { 1, 21}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 5, 18}, + { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, { 1, 34}, + { 1, 62}, { 15, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 10, 0}, + { 8, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, /* Row 68 */ + { 2, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, + { 1, 98}, { 1, 103}, { 1, 44}, { 1, 53}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, + { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 7, 4}, { 1, 19}, + { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 2, 44}, { 1, 43}, { 1, 42}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 5, 18}, + { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 35}, + { 17, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 9, 0}, + { 7, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, /* Row 69 */ + { 3, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, + { 1, 98}, { 1, 103}, { 1, 44}, { 1, 43}, { 1, 42}, { 4, 18}, { 1, 56}, { 6, 46}, + { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 6, 4}, + { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, + { 1, 103}, { 3, 44}, { 1, 53}, { 1, 21}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, + { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, + { 1, 34}, { 1, 62}, { 18, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, + { 8, 0}, + { 6, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, /* Row 70 */ + { 4, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, + { 1, 98}, { 1, 103}, { 2, 44}, { 1, 53}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, + { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 6, 4}, { 1, 19}, + { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 3, 44}, { 1, 43}, { 1, 42}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 3, 18}, + { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 35}, + { 20, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 7, 0}, + { 5, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, /* Row 71 */ + { 5, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, + { 1, 98}, { 1, 103}, { 2, 44}, { 1, 43}, { 1, 42}, { 4, 18}, { 1, 56}, { 6, 46}, + { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 5, 4}, + { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, + { 1, 103}, { 4, 44}, { 1, 53}, { 1, 21}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, + { 1, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, + { 1, 34}, { 1, 62}, { 21, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, + { 6, 0}, + { 4, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, /* Row 72 */ + { 6, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, + { 1, 98}, { 1, 103}, { 3, 44}, { 1, 53}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, + { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 5, 4}, { 1, 19}, + { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 4, 44}, { 1, 43}, { 1, 42}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 1, 18}, + { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 35}, + { 23, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 5, 0}, + { 3, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, /* Row 73 */ + { 7, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, + { 1, 98}, { 1, 103}, { 3, 44}, { 1, 43}, { 1, 42}, { 4, 18}, { 1, 56}, { 6, 46}, + { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 4, 4}, + { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, + { 1, 103}, { 5, 44}, { 1, 53}, { 1, 21}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 110}, + { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, { 1, 34}, { 1, 62}, + { 24, 4}, { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 4, 0}, + { 2, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, /* Row 74 */ + { 8, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, + { 1, 98}, { 1, 103}, { 4, 44}, { 1, 53}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, + { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 4, 4}, { 1, 19}, + { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 5, 44}, { 1, 43}, { 1, 111}, { 3, 18}, { 1, 54}, { 15, 46}, { 1, 54}, { 3, 18}, + { 1, 21}, { 1, 53}, { 6, 44}, { 1, 35}, { 26, 4}, { 1, 16}, { 1, 14}, { 1, 7}, + { 2, 4}, { 1, 5}, { 3, 0}, + { 1, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, /* Row 75 */ + { 9, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, + { 1, 98}, { 1, 103}, { 4, 44}, { 1, 43}, { 1, 42}, { 4, 18}, { 1, 56}, { 6, 46}, + { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 3, 4}, + { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, + { 1, 103}, { 5, 44}, { 1, 32}, { 1, 83}, { 1, 21}, { 3, 18}, { 1, 56}, { 13, 46}, + { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, { 1, 34}, { 1, 62}, { 27, 4}, + { 1, 16}, { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, { 2, 0}, + { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, { 10, 4}, /* Row 76 */ + { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, + { 1, 103}, { 5, 44}, { 1, 53}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 54}, + { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 3, 4}, { 1, 19}, { 1, 24}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, + { 1, 33}, { 1, 112}, { 1, 23}, { 3, 18}, { 1, 54}, { 13, 46}, { 1, 54}, { 3, 18}, + { 1, 21}, { 1, 53}, { 6, 44}, { 1, 35}, { 29, 4}, { 1, 16}, { 1, 14}, { 1, 7}, + { 2, 4}, { 1, 5}, { 1, 0}, + { 1, 2}, { 1, 6}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, { 11, 4}, { 1, 19}, /* Row 77 */ + { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 5, 44}, { 1, 43}, { 1, 111}, { 4, 18}, { 1, 56}, { 6, 46}, { 1, 56}, { 5, 18}, + { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 2, 4}, { 1, 19}, { 1, 24}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, + { 1, 33}, { 1, 7}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 56}, { 11, 46}, { 1, 56}, + { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, { 1, 34}, { 1, 62}, { 30, 4}, { 1, 16}, + { 1, 14}, { 1, 7}, { 2, 4}, { 1, 5}, + { 1, 3}, { 1, 7}, { 1, 104}, { 1, 107}, { 1, 109}, { 12, 4}, { 1, 19}, { 1, 24}, /* Row 78 */ + { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, + { 1, 32}, { 1, 83}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 54}, { 4, 18}, + { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 2, 4}, { 1, 19}, { 1, 24}, { 2, 18}, + { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, + { 1, 7}, { 1, 25}, { 1, 23}, { 3, 18}, { 1, 54}, { 11, 46}, { 1, 54}, { 3, 18}, + { 1, 21}, { 1, 53}, { 6, 44}, { 1, 35}, { 32, 4}, { 1, 16}, { 1, 14}, { 1, 7}, + { 2, 4}, + { 1, 4}, { 1, 113}, { 1, 114}, { 1, 115}, { 13, 4}, { 1, 19}, { 1, 24}, { 2, 18}, /* Row 79 */ + { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, + { 1, 112}, { 1, 23}, { 4, 18}, { 1, 56}, { 6, 46}, { 1, 56}, { 5, 18}, { 1, 42}, + { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 1, 4}, { 1, 19}, { 1, 24}, { 2, 18}, + { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, + { 1, 7}, { 1, 4}, { 1, 116}, { 4, 18}, { 1, 56}, { 9, 46}, { 1, 61}, { 4, 18}, + { 1, 42}, { 1, 43}, { 5, 44}, { 1, 34}, { 1, 62}, { 33, 4}, { 1, 16}, { 1, 14}, + { 1, 62}, { 1, 4}, + { 1, 4}, { 1, 7}, { 1, 117}, { 1, 8}, { 13, 4}, { 1, 19}, { 1, 24}, { 2, 18}, /* Row 80 */ + { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, + { 1, 7}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 54}, { 4, 18}, + { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 1, 4}, { 1, 19}, { 1, 24}, { 2, 18}, + { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, + { 1, 7}, { 1, 4}, { 1, 116}, { 4, 18}, { 1, 54}, { 9, 46}, { 1, 37}, { 3, 18}, + { 1, 21}, { 1, 53}, { 6, 44}, { 1, 35}, { 35, 4}, { 1, 118}, { 1, 119}, { 1, 7}, + { 2, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 12, 4}, { 1, 19}, { 1, 24}, { 2, 18}, /* Row 81 */ + { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, + { 1, 7}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 6, 46}, { 1, 56}, { 5, 18}, + { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 62}, { 1, 19}, { 1, 24}, { 2, 18}, + { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, + { 1, 7}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 8, 46}, { 1, 60}, { 1, 21}, + { 3, 18}, { 1, 98}, { 1, 120}, { 5, 44}, { 1, 33}, { 1, 62}, { 34, 4}, { 1, 8}, + { 1, 11}, { 1, 76}, { 1, 3}, + { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 11, 4}, { 1, 19}, { 1, 24}, { 2, 18}, /* Row 82 */ + { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, + { 1, 7}, { 1, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 54}, + { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 35}, { 1, 121}, { 1, 24}, { 2, 18}, + { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, + { 1, 7}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 10, 46}, { 1, 54}, { 3, 18}, + { 1, 21}, { 1, 53}, { 5, 44}, { 1, 33}, { 1, 62}, { 33, 4}, { 1, 8}, { 1, 11}, + { 1, 15}, { 1, 6}, { 1, 4}, + { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 10, 4}, { 1, 19}, { 1, 24}, /* Row 83 */ + { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, + { 1, 33}, { 1, 7}, { 1, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 6, 46}, + { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 34}, { 1, 122}, { 1, 24}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, + { 1, 33}, { 1, 112}, { 1, 23}, { 4, 18}, { 1, 56}, { 10, 46}, { 1, 56}, { 4, 18}, + { 1, 42}, { 1, 43}, { 5, 44}, { 1, 35}, { 32, 4}, { 1, 8}, { 1, 11}, { 1, 15}, + { 1, 6}, { 1, 4}, { 1, 5}, + { 1, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 9, 4}, { 1, 19}, /* Row 84 */ + { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 5, 44}, { 1, 33}, { 1, 7}, { 2, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 123}, { 1, 24}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, + { 1, 32}, { 1, 83}, { 1, 21}, { 3, 18}, { 1, 54}, { 12, 46}, { 1, 54}, { 3, 18}, + { 1, 21}, { 1, 53}, { 5, 44}, { 1, 34}, { 1, 62}, { 30, 4}, { 1, 8}, { 1, 11}, + { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 1, 0}, + { 2, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 8, 4}, { 1, 19}, /* Row 85 */ + { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 5, 44}, { 1, 33}, { 1, 7}, { 2, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 124}, { 1, 98}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, + { 1, 43}, { 1, 111}, { 4, 18}, { 1, 56}, { 12, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 5, 44}, { 1, 35}, { 29, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, + { 1, 4}, { 1, 5}, { 2, 0}, + { 3, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 7, 4}, { 1, 19}, /* Row 86 */ + { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 5, 44}, { 1, 33}, { 1, 7}, { 3, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 4, 44}, { 1, 103}, { 1, 98}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, + { 1, 53}, { 1, 21}, { 3, 18}, { 1, 54}, { 14, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 53}, { 5, 44}, { 1, 34}, { 1, 62}, { 27, 4}, { 1, 8}, { 1, 11}, { 1, 15}, + { 1, 6}, { 1, 4}, { 1, 5}, { 3, 0}, + { 4, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 6, 4}, { 1, 19}, /* Row 87 */ + { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 5, 44}, { 1, 33}, { 1, 7}, { 3, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 3, 44}, { 1, 103}, { 1, 98}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 4, 44}, + { 1, 43}, { 1, 42}, { 4, 18}, { 1, 56}, { 14, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 5, 44}, { 1, 35}, { 26, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, + { 1, 4}, { 1, 5}, { 4, 0}, + { 5, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 5, 4}, { 1, 19}, /* Row 88 */ + { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 5, 44}, { 1, 33}, { 1, 7}, { 4, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 3, 44}, { 1, 103}, { 1, 98}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 4, 44}, + { 1, 53}, { 1, 21}, { 3, 18}, { 1, 54}, { 16, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 53}, { 5, 44}, { 1, 34}, { 1, 62}, { 24, 4}, { 1, 8}, { 1, 11}, { 1, 15}, + { 1, 6}, { 1, 4}, { 1, 5}, { 5, 0}, + { 6, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 4, 4}, { 1, 19}, /* Row 89 */ + { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 5, 44}, { 1, 33}, { 1, 7}, { 4, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 2, 44}, { 1, 103}, { 1, 98}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 3, 44}, + { 1, 43}, { 1, 42}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 56}, { 1, 54}, { 7, 46}, + { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, { 1, 35}, { 23, 4}, { 1, 8}, + { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 6, 0}, + { 7, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 3, 4}, { 1, 19}, /* Row 90 */ + { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 5, 44}, { 1, 33}, { 1, 7}, { 5, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 2, 44}, { 1, 103}, { 1, 98}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 3, 44}, + { 1, 53}, { 1, 21}, { 3, 18}, { 1, 54}, { 8, 46}, { 1, 54}, { 1, 18}, { 1, 56}, + { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 34}, { 1, 62}, + { 21, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 7, 0}, + { 8, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 2, 4}, { 1, 19}, /* Row 91 */ + { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 5, 44}, { 1, 33}, { 1, 7}, { 5, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 1, 44}, { 1, 103}, { 1, 98}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 2, 44}, + { 1, 43}, { 1, 42}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 56}, { 2, 18}, { 1, 54}, + { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, { 1, 35}, { 20, 4}, + { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 8, 0}, + { 9, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 1, 4}, { 1, 19}, /* Row 92 */ + { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, + { 5, 44}, { 1, 33}, { 1, 7}, { 6, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 54}, { 4, 18}, { 1, 21}, { 1, 53}, { 1, 44}, { 1, 103}, { 1, 98}, + { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 2, 44}, + { 1, 53}, { 1, 21}, { 3, 18}, { 1, 54}, { 8, 46}, { 1, 54}, { 3, 18}, { 1, 56}, + { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 34}, { 1, 62}, + { 18, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 9, 0}, + { 10, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 1, 121}, { 1, 24}, /* Row 93 */ + { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, + { 1, 33}, { 1, 7}, { 6, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 6, 46}, + { 1, 56}, { 5, 18}, { 1, 42}, { 1, 43}, { 1, 103}, { 1, 98}, { 2, 18}, { 1, 36}, + { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 1, 44}, { 1, 43}, { 1, 42}, + { 4, 18}, { 1, 56}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 54}, { 7, 46}, { 1, 56}, + { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, { 1, 35}, { 17, 4}, { 1, 8}, { 1, 11}, + { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 10, 0}, + { 11, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 125}, { 1, 24}, { 2, 18}, /* Row 94 */ + { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, + { 1, 7}, { 7, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 54}, + { 4, 18}, { 1, 21}, { 1, 53}, { 1, 103}, { 1, 98}, { 2, 18}, { 1, 36}, { 7, 46}, + { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 1, 44}, { 1, 53}, { 1, 21}, { 3, 18}, + { 1, 54}, { 8, 46}, { 1, 54}, { 5, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, + { 1, 21}, { 1, 53}, { 5, 44}, { 1, 34}, { 1, 62}, { 15, 4}, { 1, 8}, { 1, 11}, + { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 11, 0}, + { 12, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 126}, { 1, 98}, { 2, 18}, { 1, 36}, /* Row 95 */ + { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, { 1, 7}, + { 7, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 6, 46}, { 1, 56}, { 5, 18}, + { 1, 42}, { 1, 100}, { 1, 98}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, + { 1, 98}, { 1, 103}, { 1, 43}, { 1, 42}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 56}, + { 6, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, + { 1, 35}, { 14, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, + { 12, 0}, + { 13, 0}, { 1, 5}, { 3, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, /* Row 96 */ + { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, { 1, 7}, { 8, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 54}, { 4, 18}, { 1, 21}, + { 1, 99}, { 1, 98}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, + { 1, 103}, { 1, 53}, { 1, 21}, { 3, 18}, { 1, 54}, { 8, 46}, { 1, 54}, { 7, 18}, + { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 34}, + { 1, 62}, { 12, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, + { 13, 0}, + { 14, 0}, { 1, 5}, { 2, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, /* Row 97 */ + { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, { 1, 7}, { 8, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 6, 46}, { 1, 56}, { 5, 18}, { 1, 47}, + { 1, 21}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 100}, + { 1, 42}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 47}, { 1, 21}, + { 2, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, + { 1, 35}, { 11, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, + { 14, 0}, + { 15, 0}, { 1, 5}, { 1, 4}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, /* Row 98 */ + { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, { 1, 7}, { 9, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 54}, { 8, 18}, { 1, 36}, + { 7, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 99}, { 1, 21}, { 3, 18}, { 1, 54}, + { 8, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 127}, { 1, 42}, { 3, 18}, { 1, 56}, + { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 34}, { 1, 62}, + { 9, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 15, 0}, + { 16, 0}, { 1, 5}, { 1, 19}, { 1, 24}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, /* Row 99 */ + { 2, 18}, { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, { 1, 7}, { 9, 4}, { 1, 25}, + { 1, 23}, { 4, 18}, { 1, 56}, { 6, 46}, { 1, 56}, { 8, 18}, { 1, 36}, { 7, 46}, + { 1, 36}, { 2, 18}, { 1, 21}, { 1, 47}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 56}, + { 4, 18}, { 1, 42}, { 1, 43}, { 1, 53}, { 1, 21}, { 2, 18}, { 1, 54}, { 7, 46}, + { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, { 1, 35}, { 8, 4}, { 1, 8}, + { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 16, 0}, + { 17, 0}, { 1, 128}, { 1, 129}, { 2, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, /* Row 100 */ + { 1, 98}, { 1, 103}, { 5, 44}, { 1, 33}, { 1, 7}, { 10, 4}, { 1, 22}, { 1, 21}, + { 3, 18}, { 1, 54}, { 7, 46}, { 1, 54}, { 7, 18}, { 1, 36}, { 7, 46}, { 1, 36}, + { 7, 18}, { 1, 54}, { 8, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 1, 44}, + { 1, 43}, { 1, 42}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 53}, { 5, 44}, { 1, 34}, { 1, 62}, { 6, 4}, { 1, 8}, { 1, 11}, { 1, 15}, + { 1, 6}, { 1, 4}, { 1, 5}, { 17, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 101 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 10, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 7, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 7, 18}, { 1, 56}, + { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 2, 44}, { 1, 53}, { 1, 21}, + { 2, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, + { 1, 35}, { 5, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, + { 18, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 102 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 11, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 54}, { 6, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 6, 18}, { 1, 54}, + { 8, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 3, 44}, { 1, 43}, { 1, 42}, + { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, + { 1, 34}, { 1, 62}, { 3, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, + { 1, 5}, { 19, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 103 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 11, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 6, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 6, 18}, { 1, 56}, + { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 4, 44}, { 1, 53}, { 1, 21}, + { 2, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, + { 1, 35}, { 2, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, + { 20, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 104 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 12, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 54}, { 5, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 5, 18}, { 1, 54}, + { 8, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, { 1, 43}, { 1, 42}, + { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 5, 44}, + { 1, 34}, { 1, 62}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, + { 21, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 105 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 12, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 5, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 5, 18}, { 1, 56}, + { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 6, 44}, { 1, 94}, { 1, 21}, + { 2, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 5, 44}, + { 1, 93}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 22, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 106 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 13, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 54}, { 4, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 4, 18}, { 1, 54}, + { 8, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 34}, { 1, 92}, + { 1, 23}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, + { 5, 44}, { 1, 88}, { 1, 130}, { 1, 6}, { 1, 4}, { 1, 5}, { 23, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 107 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 13, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 4, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 4, 18}, { 1, 56}, + { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 6, 44}, { 1, 35}, { 1, 4}, + { 1, 22}, { 1, 21}, { 2, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 5, 44}, { 1, 131}, { 1, 7}, { 1, 5}, { 24, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 108 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 14, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 54}, { 3, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 3, 18}, { 1, 54}, + { 8, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, + { 1, 4}, { 1, 25}, { 1, 23}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, + { 1, 21}, { 1, 53}, { 4, 44}, { 1, 67}, { 1, 132}, { 1, 133}, { 25, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 109 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 14, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 3, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 3, 18}, { 1, 56}, + { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 6, 44}, { 1, 35}, { 3, 4}, + { 1, 22}, { 1, 21}, { 2, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 2, 44}, { 1, 67}, { 1, 66}, { 1, 64}, { 1, 40}, { 25, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 110 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 15, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 54}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 54}, + { 8, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, + { 3, 4}, { 1, 25}, { 1, 23}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, + { 1, 21}, { 1, 53}, { 1, 44}, { 1, 67}, { 1, 66}, { 1, 64}, { 1, 40}, { 1, 51}, + { 1, 41}, { 24, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 111 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 15, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 2, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 2, 18}, { 1, 56}, + { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 6, 44}, { 1, 35}, { 5, 4}, + { 1, 22}, { 1, 21}, { 2, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 86}, { 1, 66}, { 1, 64}, { 4, 40}, { 24, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 112 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 16, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 54}, { 1, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 1, 18}, { 1, 54}, + { 8, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, + { 5, 4}, { 1, 25}, { 1, 23}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, + { 1, 21}, { 1, 85}, { 1, 51}, { 4, 40}, { 1, 51}, { 1, 41}, { 23, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 113 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 16, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 1, 18}, { 1, 36}, { 7, 46}, { 1, 36}, { 1, 18}, { 1, 56}, + { 7, 46}, { 1, 56}, { 4, 18}, { 1, 42}, { 1, 43}, { 6, 44}, { 1, 35}, { 7, 4}, + { 1, 22}, { 1, 21}, { 2, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 50}, + { 1, 48}, { 6, 40}, { 23, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 114 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 17, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 54}, { 1, 36}, { 7, 46}, { 1, 36}, { 1, 54}, { 8, 46}, { 1, 54}, + { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, { 7, 4}, { 1, 25}, + { 1, 23}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 57}, + { 5, 40}, { 1, 51}, { 1, 41}, { 22, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 103}, /* Row 115 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 17, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, + { 6, 46}, { 1, 56}, { 1, 36}, { 7, 46}, { 1, 36}, { 1, 56}, { 7, 46}, { 1, 56}, + { 4, 18}, { 1, 42}, { 1, 43}, { 6, 44}, { 1, 35}, { 9, 4}, { 1, 22}, { 1, 21}, + { 2, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, { 6, 40}, + { 22, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 98}, { 1, 134}, /* Row 116 */ + { 5, 44}, { 1, 33}, { 1, 7}, { 18, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, + { 7, 46}, { 1, 84}, { 7, 46}, { 1, 84}, { 8, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, { 9, 4}, { 1, 25}, { 1, 23}, { 3, 18}, + { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 57}, { 5, 40}, { 1, 51}, + { 1, 41}, { 21, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 135}, /* Row 117 */ + { 1, 67}, { 4, 44}, { 1, 33}, { 1, 7}, { 18, 4}, { 1, 25}, { 1, 23}, { 4, 18}, + { 1, 56}, { 6, 46}, { 1, 61}, { 7, 46}, { 1, 61}, { 7, 46}, { 1, 56}, { 4, 18}, + { 1, 42}, { 1, 43}, { 6, 44}, { 1, 35}, { 11, 4}, { 1, 22}, { 1, 21}, { 2, 18}, + { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, { 6, 40}, { 21, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 118 */ + { 1, 66}, { 1, 67}, { 3, 44}, { 1, 79}, { 1, 136}, { 19, 4}, { 1, 22}, { 1, 21}, + { 3, 18}, { 1, 54}, { 22, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, + { 1, 34}, { 1, 62}, { 11, 4}, { 1, 25}, { 1, 23}, { 3, 18}, { 1, 56}, { 7, 46}, + { 1, 54}, { 3, 18}, { 1, 21}, { 1, 57}, { 5, 40}, { 1, 51}, { 1, 41}, { 20, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 119 */ + { 1, 64}, { 1, 66}, { 1, 67}, { 2, 44}, { 1, 79}, { 1, 45}, { 1, 16}, { 18, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 20, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 6, 44}, { 1, 35}, { 13, 4}, { 1, 22}, { 1, 21}, { 2, 18}, { 1, 54}, + { 7, 46}, { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, { 6, 40}, { 20, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 120 */ + { 1, 40}, { 1, 64}, { 1, 66}, { 1, 67}, { 1, 44}, { 1, 33}, { 1, 137}, { 1, 14}, + { 1, 16}, { 18, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 20, 46}, { 1, 54}, + { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, { 13, 4}, { 1, 138}, + { 1, 139}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 57}, + { 5, 40}, { 1, 51}, { 1, 41}, { 19, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 121 */ + { 2, 40}, { 1, 64}, { 1, 66}, { 1, 67}, { 1, 33}, { 2, 7}, { 1, 14}, { 1, 16}, + { 17, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 18, 46}, { 1, 56}, { 4, 18}, + { 1, 42}, { 1, 43}, { 6, 44}, { 1, 35}, { 13, 4}, { 1, 8}, { 1, 140}, { 1, 141}, + { 1, 21}, { 2, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, + { 6, 40}, { 19, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 122 */ + { 3, 40}, { 1, 64}, { 1, 66}, { 1, 131}, { 1, 7}, { 1, 4}, { 1, 7}, { 1, 14}, + { 1, 16}, { 17, 4}, { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 18, 46}, { 1, 54}, + { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, { 12, 4}, { 1, 8}, + { 1, 11}, { 1, 15}, { 1, 142}, { 1, 23}, { 3, 18}, { 1, 56}, { 7, 46}, { 1, 54}, + { 3, 18}, { 1, 21}, { 1, 57}, { 5, 40}, { 1, 51}, { 1, 41}, { 18, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 123 */ + { 4, 40}, { 1, 64}, { 1, 143}, { 1, 144}, { 2, 4}, { 1, 7}, { 1, 14}, { 1, 16}, + { 16, 4}, { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 16, 46}, { 1, 56}, { 4, 18}, + { 1, 42}, { 1, 43}, { 6, 44}, { 1, 35}, { 12, 4}, { 1, 8}, { 1, 11}, { 1, 15}, + { 1, 6}, { 1, 4}, { 1, 145}, { 3, 18}, { 1, 54}, { 7, 46}, { 1, 56}, { 4, 18}, + { 1, 50}, { 1, 48}, { 6, 40}, { 18, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 124 */ + { 5, 40}, { 1, 64}, { 1, 146}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 16, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 16, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, { 11, 4}, { 1, 8}, { 1, 11}, { 1, 15}, + { 1, 6}, { 1, 4}, { 1, 5}, { 1, 147}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, + { 3, 18}, { 1, 21}, { 1, 57}, { 5, 40}, { 1, 51}, { 1, 41}, { 17, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 125 */ + { 6, 40}, { 1, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 15, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 14, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 6, 44}, { 1, 35}, { 11, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, + { 1, 4}, { 1, 5}, { 2, 0}, { 1, 17}, { 1, 21}, { 2, 18}, { 1, 54}, { 7, 46}, + { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, { 6, 40}, { 17, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 126 */ + { 6, 40}, { 2, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 15, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 14, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, { 10, 4}, { 1, 8}, { 1, 11}, { 1, 15}, + { 1, 6}, { 1, 4}, { 1, 5}, { 4, 0}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, + { 3, 18}, { 1, 21}, { 1, 57}, { 5, 40}, { 1, 51}, { 1, 41}, { 16, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 127 */ + { 6, 40}, { 3, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 14, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 12, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 6, 44}, { 1, 35}, { 10, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, + { 1, 4}, { 1, 5}, { 5, 0}, { 1, 17}, { 1, 21}, { 2, 18}, { 1, 54}, { 7, 46}, + { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, { 6, 40}, { 16, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 128 */ + { 6, 40}, { 4, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 14, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 12, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, { 9, 4}, { 1, 8}, { 1, 11}, { 1, 15}, + { 1, 6}, { 1, 4}, { 1, 5}, { 7, 0}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, + { 3, 18}, { 1, 21}, { 1, 57}, { 5, 40}, { 1, 51}, { 1, 41}, { 15, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 129 */ + { 6, 40}, { 5, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 13, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 10, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 6, 44}, { 1, 35}, { 9, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, + { 1, 4}, { 1, 5}, { 8, 0}, { 1, 17}, { 1, 21}, { 2, 18}, { 1, 54}, { 7, 46}, + { 1, 56}, { 4, 18}, { 1, 50}, { 1, 48}, { 6, 40}, { 15, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 130 */ + { 6, 40}, { 6, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 13, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 10, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, { 8, 4}, { 1, 8}, { 1, 11}, { 1, 15}, + { 1, 6}, { 1, 4}, { 1, 5}, { 10, 0}, { 4, 18}, { 1, 56}, { 7, 46}, { 1, 54}, + { 3, 18}, { 1, 21}, { 1, 55}, { 5, 40}, { 1, 51}, { 1, 148}, { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 131 */ + { 6, 40}, { 7, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 12, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 8, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 6, 44}, { 1, 35}, { 8, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, + { 1, 4}, { 1, 5}, { 11, 0}, { 1, 17}, { 1, 21}, { 2, 18}, { 1, 54}, { 7, 46}, + { 1, 56}, { 4, 18}, { 1, 57}, { 6, 40}, { 1, 149}, { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 132 */ + { 6, 40}, { 8, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 12, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 54}, { 8, 46}, { 1, 54}, { 3, 18}, { 1, 21}, + { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, { 7, 4}, { 1, 8}, { 1, 11}, { 1, 15}, + { 1, 6}, { 1, 4}, { 1, 5}, { 13, 0}, { 4, 18}, { 1, 56}, { 6, 46}, { 1, 56}, + { 4, 18}, { 1, 57}, { 7, 40}, { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 133 */ + { 6, 40}, { 9, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 11, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 56}, { 6, 46}, { 1, 56}, { 4, 18}, { 1, 42}, + { 1, 43}, { 6, 44}, { 1, 35}, { 7, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, + { 1, 4}, { 1, 5}, { 14, 0}, { 1, 17}, { 1, 21}, { 2, 18}, { 1, 54}, { 6, 46}, + { 1, 56}, { 3, 18}, { 1, 69}, { 1, 150}, { 6, 40}, { 1, 51}, { 1, 148}, { 13, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 134 */ + { 6, 40}, { 10, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 11, 4}, + { 1, 22}, { 1, 21}, { 3, 18}, { 1, 36}, { 1, 151}, { 4, 46}, { 1, 151}, { 1, 36}, + { 3, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, { 6, 4}, { 1, 8}, + { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 16, 0}, { 4, 18}, { 1, 56}, + { 5, 46}, { 1, 54}, { 3, 18}, { 1, 50}, { 1, 73}, { 7, 40}, { 1, 41}, { 13, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 135 */ + { 6, 40}, { 11, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 10, 4}, + { 1, 25}, { 1, 23}, { 4, 18}, { 1, 36}, { 1, 56}, { 2, 46}, { 1, 56}, { 1, 36}, + { 4, 18}, { 1, 42}, { 1, 43}, { 6, 44}, { 1, 35}, { 6, 4}, { 1, 8}, { 1, 11}, + { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 17, 0}, { 1, 17}, { 1, 21}, { 2, 18}, + { 1, 36}, { 1, 56}, { 2, 46}, { 1, 56}, { 1, 54}, { 3, 18}, { 1, 21}, { 1, 57}, + { 8, 40}, { 1, 41}, { 13, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 136 */ + { 6, 40}, { 12, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 10, 4}, + { 1, 22}, { 1, 21}, { 5, 18}, { 2, 36}, { 5, 18}, { 1, 21}, { 1, 53}, { 6, 44}, + { 1, 34}, { 1, 62}, { 5, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, + { 1, 5}, { 19, 0}, { 5, 18}, { 2, 36}, { 5, 18}, { 1, 50}, { 1, 48}, { 8, 40}, + { 1, 63}, { 13, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 137 */ + { 6, 40}, { 13, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 9, 4}, + { 1, 25}, { 1, 23}, { 12, 18}, { 1, 42}, { 1, 43}, { 6, 44}, { 1, 35}, { 5, 4}, + { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 20, 0}, { 1, 17}, + { 1, 21}, { 9, 18}, { 1, 47}, { 1, 70}, { 9, 40}, { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 36}, { 2, 18}, { 1, 47}, { 1, 73}, /* Row 138 */ + { 6, 40}, { 14, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 9, 4}, + { 1, 22}, { 1, 21}, { 10, 18}, { 1, 21}, { 1, 53}, { 6, 44}, { 1, 34}, { 1, 62}, + { 4, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 22, 0}, + { 9, 18}, { 1, 47}, { 1, 70}, { 8, 40}, { 1, 51}, { 1, 41}, { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 36}, { 8, 46}, { 1, 69}, { 2, 47}, { 1, 152}, { 1, 73}, /* Row 139 */ + { 6, 40}, { 15, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 8, 4}, + { 1, 19}, { 1, 27}, { 1, 21}, { 8, 18}, { 1, 21}, { 1, 153}, { 1, 103}, { 6, 44}, + { 1, 35}, { 4, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, + { 23, 0}, { 1, 147}, { 1, 154}, { 1, 18}, { 1, 21}, { 2, 18}, { 1, 21}, { 1, 47}, + { 1, 155}, { 1, 150}, { 10, 40}, { 15, 0}, + { 25, 0}, { 5, 48}, { 4, 73}, { 7, 40}, { 16, 0}, { 1, 5}, { 3, 4}, { 1, 7}, /* Row 140 */ + { 1, 14}, { 1, 16}, { 8, 4}, { 1, 19}, { 1, 22}, { 1, 23}, { 1, 21}, { 4, 18}, + { 1, 21}, { 1, 42}, { 1, 53}, { 1, 103}, { 6, 44}, { 1, 34}, { 1, 62}, { 3, 4}, + { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 27, 0}, { 1, 156}, + { 1, 17}, { 1, 157}, { 1, 55}, { 1, 48}, { 1, 64}, { 9, 40}, { 1, 51}, { 1, 41}, + { 15, 0}, + { 25, 0}, { 16, 40}, { 17, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, /* Row 141 */ + { 9, 4}, { 1, 25}, { 1, 22}, { 1, 158}, { 2, 98}, { 1, 77}, { 1, 53}, { 1, 43}, + { 7, 44}, { 1, 33}, { 1, 136}, { 3, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, + { 1, 4}, { 1, 5}, { 30, 0}, { 1, 63}, { 11, 40}, { 1, 51}, { 1, 40}, { 16, 0}, + { 25, 0}, { 16, 40}, { 18, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, /* Row 142 */ + { 10, 4}, { 1, 19}, { 1, 159}, { 1, 160}, { 1, 103}, { 7, 44}, { 1, 79}, { 1, 161}, + { 1, 136}, { 3, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, + { 32, 0}, { 1, 41}, { 1, 51}, { 8, 40}, { 1, 51}, { 1, 40}, { 17, 0}, + { 25, 0}, { 16, 40}, { 19, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, /* Row 143 */ + { 11, 4}, { 1, 62}, { 1, 35}, { 1, 34}, { 5, 33}, { 1, 161}, { 1, 136}, { 1, 7}, + { 3, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 34, 0}, + { 8, 40}, { 1, 51}, { 1, 40}, { 18, 0}, + { 25, 0}, { 16, 40}, { 20, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, /* Row 144 */ + { 12, 4}, { 7, 7}, { 4, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, + { 1, 5}, { 35, 0}, { 1, 49}, { 7, 40}, { 1, 41}, { 19, 0}, + { 25, 0}, { 16, 40}, { 21, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, /* Row 145 */ + { 21, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 64, 0}, + { 25, 0}, { 16, 40}, { 22, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, /* Row 146 */ + { 19, 4}, { 1, 8}, { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 65, 0}, + { 64, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 17, 4}, { 1, 8}, /* Row 147 */ + { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 66, 0}, + { 65, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 15, 4}, { 1, 8}, /* Row 148 */ + { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 67, 0}, + { 66, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 13, 4}, { 1, 8}, /* Row 149 */ + { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 68, 0}, + { 67, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 11, 4}, { 1, 8}, /* Row 150 */ + { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 69, 0}, + { 68, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 9, 4}, { 1, 8}, /* Row 151 */ + { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 70, 0}, + { 69, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 7, 4}, { 1, 8}, /* Row 152 */ + { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 71, 0}, + { 70, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 5, 4}, { 1, 8}, /* Row 153 */ + { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 72, 0}, + { 71, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 3, 4}, { 1, 8}, /* Row 154 */ + { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 73, 0}, + { 72, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 16}, { 1, 4}, { 1, 8}, /* Row 155 */ + { 1, 11}, { 1, 15}, { 1, 6}, { 1, 4}, { 1, 5}, { 74, 0}, + { 73, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 14}, { 1, 118}, { 1, 11}, { 1, 15}, /* Row 156 */ + { 1, 6}, { 1, 4}, { 1, 5}, { 75, 0}, + { 74, 0}, { 1, 5}, { 3, 4}, { 1, 7}, { 1, 162}, { 1, 15}, { 1, 6}, { 1, 4}, /* Row 157 */ + { 1, 5}, { 76, 0}, + { 75, 0}, { 1, 5}, { 2, 4}, { 1, 3}, { 1, 163}, { 1, 6}, { 1, 4}, { 1, 5}, /* Row 158 */ + { 77, 0}, + { 76, 0}, { 1, 5}, { 4, 4}, { 1, 5}, { 78, 0} /* Row 159 */ + }; + +#elif CONFIG_NXWIDGETS_BPP == 16 + +static const struct SRlePaletteBitmapEntry g_nuttxRleEntries[] = +{ + { 76, 0}, { 1, 1}, { 1, 2}, { 1, 3}, { 4, 4}, { 1, 5}, { 76, 0}, /* Row 0 */ + { 75, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 2, 8}, { 3, 4}, { 1, 5}, /* Row 1 */ + { 75, 0}, + { 74, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 10}, { 1, 11}, /* Row 2 */ + { 1, 8}, { 3, 4}, { 1, 5}, { 74, 0}, + { 73, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 3 */ + { 1, 14}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, { 73, 0}, + { 72, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 4 */ + { 1, 6}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, { 72, 0}, + { 71, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 5 */ + { 1, 6}, { 2, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 71, 0}, + { 70, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 6 */ + { 1, 6}, { 4, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 70, 0}, + { 69, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 7 */ + { 1, 6}, { 6, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 69, 0}, + { 68, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 8 */ + { 1, 6}, { 8, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 68, 0}, + { 67, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 9 */ + { 1, 6}, { 10, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 67, 0}, + { 66, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 10 */ + { 1, 6}, { 12, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 66, 0}, + { 65, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 11 */ + { 1, 6}, { 14, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 65, 0}, + { 64, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 12 */ + { 1, 6}, { 16, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 64, 0}, + { 63, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 13 */ + { 1, 6}, { 18, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 63, 0}, + { 62, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 14 */ + { 1, 6}, { 20, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 62, 0}, + { 61, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 15 */ + { 1, 6}, { 22, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 61, 0}, + { 60, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 16 */ + { 1, 6}, { 24, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 60, 0}, + { 59, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 17 */ + { 1, 6}, { 26, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 59, 0}, + { 58, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 18 */ + { 1, 6}, { 28, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 26, 0}, { 1, 17}, { 5, 18}, { 1, 17}, { 25, 0}, + { 57, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 19 */ + { 1, 6}, { 10, 4}, { 5, 19}, { 15, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, + { 3, 4}, { 1, 5}, { 23, 0}, { 1, 20}, { 9, 18}, { 1, 20}, { 23, 0}, + { 56, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, /* Row 20 */ + { 1, 6}, { 9, 4}, { 1, 19}, { 1, 21}, { 1, 22}, { 3, 23}, { 1, 22}, { 1, 21}, + { 1, 24}, { 14, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 22, 0}, { 11, 18}, { 1, 20}, { 22, 0}, + { 23, 0}, { 1, 17}, { 5, 18}, { 1, 25}, { 25, 0}, { 1, 1}, { 1, 2}, { 1, 6}, /* Row 21 */ + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 9, 4}, { 1, 19}, { 1, 26}, + { 7, 18}, { 1, 22}, { 1, 27}, { 14, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, + { 3, 4}, { 1, 5}, { 20, 0}, { 1, 17}, { 12, 18}, { 1, 20}, { 21, 0}, + { 21, 0}, { 1, 20}, { 9, 18}, { 1, 20}, { 22, 0}, { 1, 1}, { 1, 2}, { 1, 6}, /* Row 22 */ + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 9, 4}, { 1, 19}, { 1, 26}, + { 9, 18}, { 1, 28}, { 1, 27}, { 4, 8}, { 1, 7}, { 9, 4}, { 1, 7}, { 1, 16}, + { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, { 19, 0}, { 14, 18}, { 21, 0}, + { 21, 0}, { 11, 18}, { 1, 20}, { 20, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, /* Row 23 */ + { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 10, 4}, { 1, 21}, { 11, 18}, { 1, 29}, + { 1, 30}, { 2, 31}, { 1, 32}, { 1, 33}, { 1, 8}, { 9, 4}, { 1, 7}, { 1, 16}, + { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, { 17, 0}, { 1, 17}, { 5, 18}, { 1, 34}, + { 2, 35}, { 1, 34}, { 5, 18}, { 1, 17}, { 20, 0}, + { 20, 0}, { 1, 36}, { 12, 18}, { 1, 37}, { 4, 38}, { 1, 39}, { 13, 0}, { 1, 1}, /* Row 24 */ + { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 10, 4}, + { 1, 24}, { 1, 22}, { 4, 18}, { 3, 34}, { 5, 18}, { 1, 40}, { 1, 41}, { 3, 31}, + { 1, 42}, { 1, 8}, { 9, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, + { 1, 5}, { 16, 0}, { 5, 18}, { 1, 43}, { 4, 44}, { 1, 43}, { 4, 18}, { 1, 35}, + { 1, 45}, { 1, 46}, { 18, 0}, + { 19, 0}, { 1, 17}, { 13, 18}, { 1, 47}, { 1, 45}, { 3, 38}, { 1, 48}, { 1, 38}, /* Row 25 */ + { 11, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, + { 1, 6}, { 11, 4}, { 1, 49}, { 4, 18}, { 1, 35}, { 3, 44}, { 1, 43}, { 5, 18}, + { 1, 50}, { 4, 31}, { 1, 42}, { 1, 8}, { 9, 4}, { 1, 7}, { 1, 16}, { 1, 15}, + { 1, 8}, { 3, 4}, { 1, 5}, { 14, 0}, { 1, 17}, { 4, 18}, { 1, 34}, { 6, 44}, + { 1, 34}, { 4, 18}, { 1, 51}, { 1, 38}, { 1, 46}, { 17, 0}, + { 19, 0}, { 5, 18}, { 1, 34}, { 2, 52}, { 1, 35}, { 6, 18}, { 1, 53}, { 4, 38}, /* Row 26 */ + { 1, 48}, { 1, 39}, { 9, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, + { 1, 12}, { 1, 13}, { 1, 6}, { 11, 4}, { 1, 3}, { 1, 54}, { 4, 18}, { 1, 55}, + { 4, 44}, { 1, 43}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 42}, { 1, 8}, + { 9, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, { 13, 0}, + { 5, 18}, { 1, 52}, { 6, 44}, { 1, 52}, { 4, 18}, { 1, 53}, { 2, 38}, { 1, 46}, + { 16, 0}, + { 18, 0}, { 1, 17}, { 4, 18}, { 1, 43}, { 4, 44}, { 1, 35}, { 5, 18}, { 1, 47}, /* Row 27 */ + { 1, 45}, { 5, 38}, { 8, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, + { 1, 12}, { 1, 13}, { 1, 6}, { 12, 4}, { 1, 19}, { 1, 23}, { 3, 18}, { 1, 35}, + { 6, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 9, 4}, + { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, { 11, 0}, { 1, 17}, + { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 53}, { 3, 38}, { 16, 0}, + { 18, 0}, { 4, 18}, { 1, 34}, { 5, 44}, { 1, 55}, { 1, 34}, { 5, 18}, { 1, 53}, /* Row 28 */ + { 4, 38}, { 1, 48}, { 1, 39}, { 6, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, + { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 13, 4}, { 1, 19}, { 1, 23}, { 3, 18}, + { 1, 52}, { 6, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, + { 1, 56}, { 10, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, + { 10, 0}, { 5, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 51}, { 2, 38}, + { 1, 48}, { 1, 39}, { 15, 0}, + { 18, 0}, { 4, 18}, { 1, 52}, { 6, 44}, { 1, 52}, { 5, 18}, { 1, 47}, { 1, 45}, /* Row 29 */ + { 5, 38}, { 5, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 14, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, + { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 10, 4}, { 1, 7}, + { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, { 8, 0}, { 1, 17}, { 4, 18}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, { 4, 38}, { 15, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 5, 18}, { 1, 53}, { 4, 38}, /* Row 30 */ + { 1, 48}, { 1, 39}, { 3, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, + { 1, 12}, { 1, 13}, { 1, 6}, { 15, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, + { 8, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, + { 11, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, { 7, 0}, + { 5, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 53}, { 5, 38}, { 1, 1}, + { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 52}, { 5, 18}, { 1, 47}, { 1, 45}, /* Row 31 */ + { 5, 38}, { 2, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 16, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 9, 44}, + { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 11, 4}, { 1, 7}, + { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, { 5, 0}, { 1, 17}, { 4, 18}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, { 5, 38}, { 1, 39}, + { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 9, 44}, { 1, 34}, { 5, 18}, { 1, 53}, { 4, 38}, /* Row 32 */ + { 1, 48}, { 1, 39}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 17, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 9, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 12, 4}, + { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, { 4, 0}, { 5, 18}, + { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 53}, { 6, 38}, { 1, 1}, { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 9, 44}, { 1, 52}, { 5, 18}, { 1, 47}, { 1, 45}, /* Row 33 */ + { 3, 38}, { 1, 48}, { 1, 57}, { 1, 13}, { 1, 6}, { 1, 7}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 18, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 10, 44}, + { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 12, 4}, { 1, 7}, + { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, { 2, 0}, { 1, 17}, { 4, 18}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, { 6, 38}, { 15, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 10, 44}, { 1, 34}, { 5, 18}, { 1, 53}, { 2, 38}, /* Row 34 */ + { 1, 48}, { 1, 58}, { 1, 59}, { 1, 60}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, + { 1, 6}, { 19, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 10, 44}, { 1, 52}, + { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 13, 4}, { 1, 7}, + { 1, 16}, { 1, 15}, { 1, 8}, { 3, 4}, { 1, 5}, { 1, 0}, { 5, 18}, { 1, 52}, + { 7, 44}, { 1, 34}, { 4, 18}, { 1, 61}, { 5, 38}, { 1, 48}, { 1, 39}, { 15, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 10, 44}, { 1, 52}, { 5, 18}, { 1, 47}, { 1, 45}, /* Row 35 */ + { 1, 48}, { 1, 58}, { 1, 59}, { 1, 31}, { 1, 32}, { 1, 62}, { 1, 12}, { 1, 13}, + { 1, 6}, { 20, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 11, 44}, { 1, 34}, + { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 13, 4}, { 1, 7}, { 1, 16}, + { 1, 15}, { 1, 8}, { 3, 4}, { 1, 63}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, + { 4, 18}, { 1, 47}, { 1, 45}, { 6, 38}, { 16, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 11, 44}, { 1, 34}, { 5, 18}, { 1, 64}, { 1, 58}, /* Row 36 */ + { 1, 59}, { 3, 31}, { 1, 65}, { 1, 66}, { 1, 6}, { 21, 4}, { 1, 19}, { 1, 23}, + { 2, 18}, { 1, 34}, { 11, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, + { 1, 32}, { 1, 56}, { 14, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 1, 4}, + { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 53}, + { 5, 38}, { 1, 48}, { 1, 39}, { 16, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 11, 44}, { 1, 52}, { 5, 18}, { 1, 67}, { 1, 68}, /* Row 37 */ + { 5, 31}, { 1, 69}, { 22, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 12, 44}, + { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 14, 4}, { 1, 7}, + { 1, 16}, { 1, 15}, { 1, 8}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, + { 4, 18}, { 1, 47}, { 1, 45}, { 6, 38}, { 17, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 12, 44}, { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, /* Row 38 */ + { 1, 70}, { 1, 7}, { 21, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 12, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 15, 4}, + { 1, 7}, { 1, 16}, { 1, 71}, { 1, 67}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, + { 4, 18}, { 1, 53}, { 5, 38}, { 1, 48}, { 1, 39}, { 17, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 12, 44}, { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, /* Row 39 */ + { 4, 31}, { 1, 32}, { 1, 56}, { 21, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, + { 13, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 16, 4}, + { 1, 72}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, + { 6, 38}, { 18, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 13, 44}, { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, /* Row 40 */ + { 1, 33}, { 1, 7}, { 20, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 13, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 15, 4}, + { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 53}, + { 5, 38}, { 1, 48}, { 1, 39}, { 18, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 13, 44}, { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, /* Row 41 */ + { 4, 31}, { 1, 32}, { 1, 56}, { 20, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, + { 14, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 14, 4}, + { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, + { 6, 38}, { 19, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 14, 44}, { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, /* Row 42 */ + { 1, 33}, { 1, 7}, { 19, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 14, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 13, 4}, + { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 53}, + { 5, 38}, { 1, 48}, { 1, 39}, { 19, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 14, 44}, { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, /* Row 43 */ + { 4, 31}, { 1, 32}, { 1, 56}, { 19, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, + { 7, 44}, { 1, 73}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, + { 1, 7}, { 12, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, + { 1, 47}, { 1, 45}, { 6, 38}, { 20, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 15, 44}, { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, /* Row 44 */ + { 1, 33}, { 1, 7}, { 18, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, + { 1, 56}, { 11, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, + { 4, 18}, { 1, 53}, { 5, 38}, { 1, 48}, { 1, 39}, { 20, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 73}, { 6, 44}, { 1, 52}, { 5, 18}, /* Row 45 */ + { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 18, 4}, { 1, 19}, { 1, 23}, + { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, + { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 10, 4}, { 1, 21}, { 4, 18}, { 1, 34}, + { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, { 6, 38}, { 21, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, /* Row 46 */ + { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 17, 4}, { 1, 19}, { 1, 23}, { 2, 18}, + { 1, 34}, { 7, 44}, { 2, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, + { 4, 31}, { 1, 32}, { 1, 56}, { 9, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, + { 7, 44}, { 1, 34}, { 4, 18}, { 1, 53}, { 5, 38}, { 1, 48}, { 1, 39}, { 21, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 1, 52}, { 6, 44}, { 1, 52}, /* Row 47 */ + { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 17, 4}, { 1, 19}, + { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 1, 18}, { 1, 52}, { 7, 44}, + { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 8, 4}, { 1, 21}, + { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, { 6, 38}, + { 22, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 2, 34}, { 7, 44}, { 1, 34}, { 5, 18}, /* Row 48 */ + { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 16, 4}, { 1, 19}, { 1, 23}, { 2, 18}, + { 1, 34}, { 7, 44}, { 1, 34}, { 1, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, + { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 7, 4}, { 1, 24}, { 1, 22}, + { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 74}, { 1, 48}, { 4, 38}, + { 1, 48}, { 1, 39}, { 22, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 1, 18}, { 1, 52}, { 6, 44}, /* Row 49 */ + { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 16, 4}, + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 52}, + { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 6, 4}, + { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 75}, + { 1, 58}, { 1, 48}, { 4, 38}, { 23, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 1, 18}, { 1, 34}, { 7, 44}, /* Row 50 */ + { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 15, 4}, { 1, 19}, + { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 34}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 5, 4}, + { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, + { 1, 31}, { 1, 59}, { 1, 58}, { 1, 48}, { 1, 38}, { 1, 48}, { 1, 39}, { 23, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 52}, { 6, 44}, /* Row 51 */ + { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 15, 4}, + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 3, 18}, { 1, 52}, + { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 4, 4}, + { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, + { 2, 31}, { 1, 59}, { 1, 58}, { 1, 48}, { 1, 38}, { 24, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 34}, { 7, 44}, /* Row 52 */ + { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 14, 4}, { 1, 19}, + { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 3, 18}, { 1, 34}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 3, 4}, + { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, + { 4, 31}, { 1, 59}, { 1, 76}, { 1, 39}, { 24, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 3, 18}, { 1, 52}, { 6, 44}, /* Row 53 */ + { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 14, 4}, + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 52}, + { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 2, 4}, + { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, + { 5, 31}, { 1, 77}, { 1, 78}, { 24, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 3, 18}, { 1, 34}, { 7, 44}, /* Row 54 */ + { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 13, 4}, { 1, 19}, + { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 34}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 1, 4}, + { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, + { 6, 31}, { 1, 32}, { 1, 56}, { 1, 5}, { 23, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 4, 18}, { 1, 52}, { 6, 44}, /* Row 55 */ + { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 13, 4}, + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 52}, + { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 4}, { 1, 21}, + { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 6, 31}, + { 1, 79}, { 1, 7}, { 1, 4}, { 1, 5}, { 22, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 4, 18}, { 1, 34}, { 7, 44}, /* Row 56 */ + { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 12, 4}, { 1, 19}, + { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 34}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 80}, { 1, 22}, + { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 81}, + { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 21, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 5, 18}, { 1, 52}, { 6, 44}, /* Row 57 */ + { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 12, 4}, + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 6, 18}, { 1, 52}, + { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 82}, { 4, 18}, { 1, 34}, + { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 32}, { 1, 56}, + { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 20, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 5, 18}, { 1, 34}, { 7, 44}, /* Row 58 */ + { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 11, 4}, { 1, 19}, + { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 6, 18}, { 1, 34}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 3, 31}, { 1, 41}, { 1, 40}, { 4, 18}, + { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 33}, { 2, 7}, + { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 19, 0}, + { 17, 0}, { 1, 83}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 6, 18}, { 1, 52}, /* Row 59 */ + { 6, 44}, { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, + { 11, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 7, 18}, + { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 3, 31}, { 1, 50}, { 4, 18}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 32}, + { 1, 56}, { 2, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, + { 18, 0}, + { 16, 0}, { 1, 1}, { 1, 84}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, /* Row 60 */ + { 6, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, { 1, 33}, + { 1, 7}, { 10, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 3, 18}, { 1, 85}, { 3, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, + { 1, 41}, { 1, 31}, { 1, 41}, { 1, 40}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, + { 4, 18}, { 1, 50}, { 6, 31}, { 1, 33}, { 1, 7}, { 3, 4}, { 1, 7}, { 1, 16}, + { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 17, 0}, + { 15, 0}, { 1, 1}, { 1, 2}, { 1, 86}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, /* Row 61 */ + { 1, 34}, { 7, 18}, { 1, 52}, { 6, 44}, { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, + { 4, 31}, { 1, 32}, { 1, 56}, { 10, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, + { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 87}, { 4, 18}, { 1, 52}, { 7, 44}, + { 1, 34}, { 4, 18}, { 1, 50}, { 1, 88}, { 1, 50}, { 4, 18}, { 1, 34}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 32}, { 1, 56}, { 5, 4}, + { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 16, 0}, + { 14, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 89}, { 1, 23}, { 2, 18}, { 1, 34}, /* Row 62 */ + { 8, 44}, { 1, 34}, { 7, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 50}, + { 5, 31}, { 1, 33}, { 1, 7}, { 9, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, + { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 90}, { 1, 40}, { 3, 18}, { 1, 34}, + { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 91}, { 1, 40}, { 4, 18}, { 1, 52}, + { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 33}, { 1, 7}, { 6, 4}, + { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 15, 0}, + { 13, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 71}, { 1, 29}, { 2, 18}, /* Row 63 */ + { 1, 34}, { 8, 44}, { 1, 34}, { 3, 18}, { 1, 85}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 9, 4}, + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 1, 50}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 29}, + { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, + { 1, 32}, { 1, 56}, { 8, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, + { 1, 5}, { 14, 0}, + { 12, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 94}, { 1, 95}, /* Row 64 */ + { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 87}, { 4, 18}, + { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, + { 8, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, + { 1, 29}, { 1, 92}, { 1, 41}, { 1, 40}, { 3, 18}, { 1, 34}, { 7, 44}, { 1, 52}, + { 9, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 33}, + { 1, 7}, { 9, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, + { 13, 0}, + { 11, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 97}, /* Row 65 */ + { 1, 28}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 90}, + { 1, 40}, { 4, 18}, { 1, 52}, { 6, 44}, { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, + { 4, 31}, { 1, 32}, { 1, 56}, { 8, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, + { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 1, 31}, { 1, 50}, { 4, 18}, + { 1, 52}, { 7, 44}, { 1, 34}, { 7, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, + { 1, 40}, { 1, 41}, { 5, 31}, { 1, 32}, { 1, 56}, { 11, 4}, { 1, 7}, { 1, 16}, + { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 12, 0}, + { 10, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, /* Row 66 */ + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 1, 50}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 50}, + { 5, 31}, { 1, 33}, { 1, 7}, { 7, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, + { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 1, 31}, { 1, 41}, { 1, 40}, + { 3, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 7, 18}, { 1, 52}, { 7, 44}, { 1, 34}, + { 4, 18}, { 1, 50}, { 6, 31}, { 1, 33}, { 1, 7}, { 12, 4}, { 1, 7}, { 1, 16}, + { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 11, 0}, + { 9, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, /* Row 67 */ + { 1, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, + { 1, 29}, { 1, 92}, { 1, 41}, { 1, 40}, { 4, 18}, { 1, 52}, { 6, 44}, { 1, 52}, + { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 7, 4}, { 1, 19}, + { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, + { 2, 31}, { 1, 50}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 34}, + { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 32}, { 1, 56}, + { 14, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 10, 0}, + { 8, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, /* Row 68 */ + { 2, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, + { 1, 29}, { 1, 92}, { 1, 31}, { 1, 50}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 5, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 6, 4}, { 1, 19}, { 1, 23}, + { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 2, 31}, + { 1, 41}, { 1, 40}, { 3, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 5, 18}, { 1, 52}, + { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 33}, { 1, 7}, { 15, 4}, + { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 9, 0}, + { 7, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, /* Row 69 */ + { 3, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, + { 1, 29}, { 1, 92}, { 1, 31}, { 1, 41}, { 1, 40}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 6, 4}, + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 3, 31}, { 1, 50}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 3, 18}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 32}, + { 1, 56}, { 17, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, + { 8, 0}, + { 6, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, /* Row 70 */ + { 4, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, + { 1, 29}, { 1, 92}, { 2, 31}, { 1, 50}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 5, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 5, 4}, { 1, 19}, { 1, 23}, + { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 3, 31}, + { 1, 41}, { 1, 40}, { 3, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 3, 18}, { 1, 52}, + { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 33}, { 1, 7}, { 18, 4}, + { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 7, 0}, + { 5, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, /* Row 71 */ + { 5, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, + { 1, 29}, { 1, 92}, { 2, 31}, { 1, 41}, { 1, 40}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 5, 4}, + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 4, 31}, { 1, 50}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 1, 18}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 32}, + { 1, 56}, { 20, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, + { 6, 0}, + { 4, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, /* Row 72 */ + { 6, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, + { 1, 29}, { 1, 92}, { 3, 31}, { 1, 50}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 5, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 4, 4}, { 1, 19}, { 1, 23}, + { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 4, 31}, + { 1, 41}, { 1, 40}, { 3, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 1, 18}, { 1, 52}, + { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 33}, { 1, 7}, { 21, 4}, + { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 5, 0}, + { 3, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, /* Row 73 */ + { 7, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, + { 1, 29}, { 1, 92}, { 3, 31}, { 1, 41}, { 1, 40}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 4, 4}, + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 5, 31}, { 1, 50}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 99}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 32}, { 1, 56}, { 23, 4}, + { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 4, 0}, + { 2, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, /* Row 74 */ + { 8, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, + { 1, 29}, { 1, 92}, { 4, 31}, { 1, 50}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 5, 18}, { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 3, 4}, { 1, 19}, { 1, 23}, + { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 5, 31}, + { 1, 41}, { 1, 67}, { 3, 18}, { 1, 34}, { 15, 44}, { 1, 34}, { 4, 18}, { 1, 50}, + { 6, 31}, { 1, 33}, { 1, 7}, { 24, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, + { 2, 4}, { 1, 5}, { 3, 0}, + { 1, 0}, { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, /* Row 75 */ + { 9, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, + { 1, 29}, { 1, 92}, { 4, 31}, { 1, 41}, { 1, 40}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 3, 4}, + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 6, 31}, { 1, 72}, { 4, 18}, { 1, 52}, { 13, 44}, { 1, 52}, { 4, 18}, + { 1, 40}, { 1, 41}, { 5, 31}, { 1, 32}, { 1, 56}, { 26, 4}, { 1, 7}, { 1, 16}, + { 1, 15}, { 1, 8}, { 2, 4}, { 1, 5}, { 2, 0}, + { 1, 1}, { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, { 10, 4}, /* Row 76 */ + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 5, 31}, { 1, 50}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, + { 1, 50}, { 5, 31}, { 1, 33}, { 1, 7}, { 2, 4}, { 1, 19}, { 1, 23}, { 2, 18}, + { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 80}, + { 1, 22}, { 3, 18}, { 1, 34}, { 13, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, + { 1, 33}, { 1, 7}, { 27, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, + { 1, 5}, { 1, 0}, + { 1, 2}, { 1, 6}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, { 11, 4}, { 1, 19}, /* Row 77 */ + { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, + { 5, 31}, { 1, 41}, { 1, 67}, { 4, 18}, { 1, 52}, { 6, 44}, { 1, 52}, { 5, 18}, + { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 2, 4}, { 1, 19}, { 1, 23}, + { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, + { 1, 8}, { 1, 21}, { 4, 18}, { 1, 52}, { 11, 44}, { 1, 52}, { 4, 18}, { 1, 40}, + { 1, 41}, { 5, 31}, { 1, 32}, { 1, 56}, { 29, 4}, { 1, 7}, { 1, 16}, { 1, 15}, + { 1, 8}, { 2, 4}, { 1, 5}, + { 1, 3}, { 1, 8}, { 1, 93}, { 1, 96}, { 1, 98}, { 12, 4}, { 1, 19}, { 1, 23}, /* Row 78 */ + { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, + { 1, 72}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, + { 1, 33}, { 1, 7}, { 1, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, + { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 8}, { 1, 24}, { 1, 22}, + { 3, 18}, { 1, 34}, { 11, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 33}, + { 1, 7}, { 30, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 8}, { 2, 4}, + { 1, 4}, { 1, 33}, { 1, 100}, { 1, 98}, { 13, 4}, { 1, 19}, { 1, 23}, { 2, 18}, /* Row 79 */ + { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 80}, + { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, + { 4, 31}, { 1, 32}, { 1, 56}, { 1, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, + { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 8}, { 1, 4}, + { 1, 101}, { 4, 18}, { 1, 52}, { 9, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, + { 5, 31}, { 1, 32}, { 1, 56}, { 32, 4}, { 1, 7}, { 1, 16}, { 1, 15}, { 1, 56}, + { 1, 7}, + { 1, 4}, { 1, 8}, { 1, 102}, { 1, 9}, { 1, 7}, { 12, 4}, { 1, 19}, { 1, 23}, /* Row 80 */ + { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, + { 1, 8}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 50}, + { 5, 31}, { 1, 33}, { 1, 7}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, + { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 8}, { 1, 4}, { 1, 101}, + { 4, 18}, { 1, 34}, { 9, 44}, { 1, 35}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 33}, + { 1, 7}, { 33, 4}, { 1, 7}, { 1, 103}, { 1, 10}, { 1, 8}, + { 2, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 11, 4}, { 1, 19}, { 1, 23}, /* Row 81 */ + { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, + { 1, 8}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, { 1, 52}, { 5, 18}, + { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 56}, { 1, 19}, { 1, 23}, { 2, 18}, + { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 8}, + { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 8, 44}, { 1, 104}, { 4, 18}, { 1, 29}, + { 1, 68}, { 6, 31}, { 1, 56}, { 33, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 66}, + { 1, 3}, + { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 10, 4}, { 1, 19}, { 1, 23}, /* Row 82 */ + { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, + { 1, 8}, { 1, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, + { 1, 50}, { 5, 31}, { 1, 33}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 7, 44}, + { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 8}, { 1, 21}, { 4, 18}, + { 1, 34}, { 10, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 56}, { 32, 4}, + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, + { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 9, 4}, { 1, 19}, /* Row 83 */ + { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, + { 6, 31}, { 1, 8}, { 1, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 32}, { 1, 105}, { 1, 23}, + { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, + { 1, 80}, { 1, 22}, { 4, 18}, { 1, 52}, { 10, 44}, { 1, 52}, { 4, 18}, { 1, 40}, + { 1, 41}, { 5, 31}, { 1, 33}, { 1, 7}, { 30, 4}, { 1, 7}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, + { 1, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 8, 4}, /* Row 84 */ + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 6, 31}, { 1, 8}, { 2, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, + { 1, 34}, { 5, 18}, { 1, 50}, { 5, 31}, { 1, 106}, { 1, 23}, { 2, 18}, { 1, 34}, + { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 72}, { 4, 18}, + { 1, 34}, { 12, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 32}, { 1, 56}, + { 29, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, + { 1, 0}, + { 2, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 7, 4}, /* Row 85 */ + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 6, 31}, { 1, 8}, { 2, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, + { 6, 44}, { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 107}, { 1, 29}, + { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 5, 31}, + { 1, 41}, { 1, 67}, { 4, 18}, { 1, 52}, { 12, 44}, { 1, 52}, { 4, 18}, { 1, 40}, + { 1, 41}, { 5, 31}, { 1, 33}, { 1, 7}, { 27, 4}, { 1, 7}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 2, 0}, + { 3, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 6, 4}, /* Row 86 */ + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 6, 31}, { 1, 8}, { 3, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, + { 1, 34}, { 5, 18}, { 1, 50}, { 4, 31}, { 1, 92}, { 1, 29}, { 2, 18}, { 1, 34}, + { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 5, 31}, { 1, 50}, { 4, 18}, + { 1, 34}, { 14, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 32}, { 1, 56}, + { 26, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, + { 3, 0}, + { 4, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 5, 4}, /* Row 87 */ + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 6, 31}, { 1, 8}, { 3, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, + { 6, 44}, { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 3, 31}, { 1, 92}, { 1, 29}, + { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 4, 31}, + { 1, 41}, { 1, 40}, { 4, 18}, { 1, 52}, { 14, 44}, { 1, 52}, { 4, 18}, { 1, 40}, + { 1, 41}, { 5, 31}, { 1, 33}, { 1, 7}, { 24, 4}, { 1, 7}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 4, 0}, + { 5, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 4, 4}, /* Row 88 */ + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 6, 31}, { 1, 8}, { 4, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, + { 1, 34}, { 5, 18}, { 1, 50}, { 3, 31}, { 1, 92}, { 1, 29}, { 2, 18}, { 1, 34}, + { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 4, 31}, { 1, 50}, { 4, 18}, + { 1, 34}, { 16, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 32}, { 1, 56}, + { 23, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, + { 5, 0}, + { 6, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 3, 4}, /* Row 89 */ + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 6, 31}, { 1, 8}, { 4, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, + { 6, 44}, { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 2, 31}, { 1, 92}, { 1, 29}, + { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 3, 31}, + { 1, 41}, { 1, 40}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 52}, { 1, 34}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 33}, { 1, 7}, { 21, 4}, + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 6, 0}, + { 7, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 2, 4}, /* Row 90 */ + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 6, 31}, { 1, 8}, { 5, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, + { 1, 34}, { 5, 18}, { 1, 50}, { 2, 31}, { 1, 92}, { 1, 29}, { 2, 18}, { 1, 34}, + { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 3, 31}, { 1, 50}, { 4, 18}, + { 1, 34}, { 8, 44}, { 1, 34}, { 1, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, + { 1, 50}, { 5, 31}, { 1, 32}, { 1, 56}, { 20, 4}, { 1, 7}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 7, 0}, + { 8, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 1, 4}, /* Row 91 */ + { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 6, 31}, { 1, 8}, { 5, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, + { 6, 44}, { 1, 52}, { 5, 18}, { 1, 40}, { 1, 41}, { 1, 31}, { 1, 92}, { 1, 29}, + { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 2, 31}, + { 1, 41}, { 1, 40}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 52}, { 2, 18}, { 1, 34}, + { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 33}, { 1, 7}, + { 18, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, + { 8, 0}, + { 9, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 1, 19}, /* Row 92 */ + { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, + { 6, 31}, { 1, 8}, { 6, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 5, 18}, { 1, 50}, { 1, 31}, { 1, 92}, { 1, 29}, { 2, 18}, { 1, 34}, { 7, 44}, + { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 2, 31}, { 1, 50}, { 4, 18}, { 1, 34}, + { 8, 44}, { 1, 34}, { 3, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, + { 5, 31}, { 1, 32}, { 1, 56}, { 17, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, + { 1, 6}, { 1, 4}, { 1, 5}, { 9, 0}, + { 10, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 19}, { 1, 23}, /* Row 93 */ + { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, + { 1, 8}, { 6, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, { 1, 52}, + { 5, 18}, { 1, 40}, { 1, 41}, { 1, 92}, { 1, 29}, { 2, 18}, { 1, 34}, { 7, 44}, + { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 1, 31}, { 1, 41}, { 1, 40}, { 4, 18}, + { 1, 52}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, + { 1, 40}, { 1, 41}, { 5, 31}, { 1, 33}, { 1, 7}, { 15, 4}, { 1, 7}, { 1, 9}, + { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 10, 0}, + { 11, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 108}, { 1, 23}, { 2, 18}, /* Row 94 */ + { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 8}, + { 7, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 50}, + { 1, 92}, { 1, 29}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 1, 31}, { 1, 50}, { 4, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 5, 18}, + { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 32}, { 1, 56}, + { 14, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, + { 11, 0}, + { 12, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 109}, { 1, 29}, { 2, 18}, { 1, 34}, /* Row 95 */ + { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 8}, { 7, 4}, + { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, { 1, 52}, { 5, 18}, { 1, 40}, + { 1, 90}, { 1, 29}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, + { 1, 92}, { 1, 41}, { 1, 40}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 52}, { 6, 18}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 33}, + { 1, 7}, { 12, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, + { 1, 5}, { 12, 0}, + { 13, 0}, { 1, 5}, { 3, 4}, { 1, 89}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, /* Row 96 */ + { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 8}, { 8, 4}, { 1, 21}, + { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 87}, { 1, 29}, { 2, 18}, + { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 1, 50}, { 4, 18}, + { 1, 34}, { 8, 44}, { 1, 34}, { 7, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, + { 1, 50}, { 5, 31}, { 1, 32}, { 1, 56}, { 11, 4}, { 1, 7}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 13, 0}, + { 14, 0}, { 1, 5}, { 2, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, /* Row 97 */ + { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 8}, { 8, 4}, { 1, 24}, + { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, { 1, 52}, { 5, 18}, { 1, 85}, { 3, 18}, + { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 90}, { 1, 40}, { 4, 18}, + { 1, 52}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 85}, { 3, 18}, { 1, 34}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 33}, { 1, 7}, { 9, 4}, + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 14, 0}, + { 15, 0}, { 1, 5}, { 1, 4}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, /* Row 98 */ + { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 8}, { 9, 4}, { 1, 21}, + { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 8, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 2, 18}, { 1, 29}, { 1, 87}, { 4, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 4, 18}, + { 1, 87}, { 1, 40}, { 3, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, + { 5, 31}, { 1, 32}, { 1, 56}, { 8, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, + { 1, 6}, { 1, 4}, { 1, 5}, { 15, 0}, + { 16, 0}, { 1, 5}, { 1, 19}, { 1, 23}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, /* Row 99 */ + { 2, 18}, { 1, 29}, { 1, 92}, { 6, 31}, { 1, 8}, { 9, 4}, { 1, 24}, { 1, 22}, + { 4, 18}, { 1, 52}, { 6, 44}, { 1, 52}, { 8, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 3, 18}, { 1, 85}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, + { 1, 41}, { 1, 50}, { 3, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, + { 1, 41}, { 5, 31}, { 1, 33}, { 1, 7}, { 6, 4}, { 1, 7}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 16, 0}, + { 17, 0}, { 1, 110}, { 1, 111}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, /* Row 100 */ + { 1, 29}, { 1, 92}, { 6, 31}, { 1, 8}, { 10, 4}, { 1, 21}, { 4, 18}, { 1, 34}, + { 7, 44}, { 1, 34}, { 7, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 7, 18}, { 1, 34}, + { 8, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 1, 31}, { 1, 41}, { 1, 40}, { 3, 18}, + { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 32}, { 1, 56}, + { 5, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, + { 17, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 101 */ + { 6, 31}, { 1, 8}, { 10, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 7, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 7, 18}, { 1, 52}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 2, 31}, { 1, 50}, { 3, 18}, { 1, 34}, + { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 33}, { 1, 7}, + { 3, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, + { 18, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 102 */ + { 6, 31}, { 1, 8}, { 11, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 6, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 6, 18}, { 1, 34}, { 8, 44}, { 1, 34}, + { 4, 18}, { 1, 50}, { 3, 31}, { 1, 41}, { 1, 40}, { 3, 18}, { 1, 52}, { 7, 44}, + { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 32}, { 1, 56}, { 2, 4}, { 1, 7}, + { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 19, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 103 */ + { 6, 31}, { 1, 8}, { 11, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 6, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 6, 18}, { 1, 52}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 4, 31}, { 1, 50}, { 3, 18}, { 1, 34}, + { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 33}, { 2, 7}, + { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 20, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 104 */ + { 6, 31}, { 1, 8}, { 12, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 5, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 34}, { 8, 44}, { 1, 34}, + { 4, 18}, { 1, 50}, { 5, 31}, { 1, 41}, { 1, 40}, { 3, 18}, { 1, 52}, { 7, 44}, + { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 32}, { 1, 56}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 21, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 105 */ + { 6, 31}, { 1, 8}, { 12, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 5, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 5, 18}, { 1, 52}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 6, 31}, { 1, 82}, { 3, 18}, { 1, 34}, + { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, { 1, 81}, { 1, 12}, + { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 22, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 106 */ + { 6, 31}, { 1, 8}, { 13, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 34}, { 8, 44}, { 1, 34}, + { 4, 18}, { 1, 50}, { 6, 31}, { 1, 32}, { 1, 80}, { 1, 22}, { 3, 18}, { 1, 52}, + { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 5, 31}, { 1, 77}, { 1, 112}, { 1, 6}, + { 1, 4}, { 1, 5}, { 23, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 107 */ + { 6, 31}, { 1, 8}, { 13, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 52}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 4}, { 1, 21}, + { 3, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 5, 31}, + { 1, 113}, { 1, 8}, { 1, 5}, { 24, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 108 */ + { 6, 31}, { 1, 8}, { 14, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 3, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, + { 4, 18}, { 1, 50}, { 6, 31}, { 1, 32}, { 1, 56}, { 1, 4}, { 1, 24}, { 1, 22}, + { 3, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 4, 31}, { 1, 59}, + { 1, 58}, { 1, 114}, { 25, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 109 */ + { 6, 31}, { 1, 8}, { 14, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 3, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 3, 18}, { 1, 52}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 2, 4}, + { 1, 21}, { 3, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, + { 2, 31}, { 1, 59}, { 1, 58}, { 1, 48}, { 1, 38}, { 25, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 110 */ + { 6, 31}, { 1, 8}, { 15, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 34}, { 8, 44}, { 1, 34}, + { 4, 18}, { 1, 50}, { 6, 31}, { 1, 32}, { 1, 56}, { 3, 4}, { 1, 24}, { 1, 22}, + { 3, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 1, 31}, { 1, 59}, + { 1, 58}, { 1, 48}, { 1, 38}, { 1, 48}, { 1, 39}, { 24, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 111 */ + { 6, 31}, { 1, 8}, { 15, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 2, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 2, 18}, { 1, 52}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 4, 4}, + { 1, 21}, { 3, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, { 1, 75}, + { 1, 58}, { 1, 48}, { 4, 38}, { 24, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 112 */ + { 6, 31}, { 1, 8}, { 16, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 1, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 1, 18}, { 1, 34}, { 8, 44}, { 1, 34}, + { 4, 18}, { 1, 50}, { 6, 31}, { 1, 32}, { 1, 56}, { 5, 4}, { 1, 24}, { 1, 22}, + { 3, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 74}, { 1, 48}, { 4, 38}, + { 1, 48}, { 1, 39}, { 23, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 113 */ + { 6, 31}, { 1, 8}, { 16, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 1, 18}, { 1, 34}, { 7, 44}, { 1, 34}, { 1, 18}, { 1, 52}, { 7, 44}, + { 1, 52}, { 4, 18}, { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 6, 4}, + { 1, 21}, { 3, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, + { 6, 38}, { 23, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 114 */ + { 6, 31}, { 1, 8}, { 17, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 2, 34}, + { 7, 44}, { 2, 34}, { 8, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 32}, + { 1, 56}, { 7, 4}, { 1, 24}, { 1, 22}, { 3, 18}, { 1, 52}, { 7, 44}, { 1, 34}, + { 4, 18}, { 1, 53}, { 5, 38}, { 1, 48}, { 1, 39}, { 22, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 92}, /* Row 115 */ + { 6, 31}, { 1, 8}, { 17, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, + { 1, 52}, { 1, 34}, { 7, 44}, { 1, 34}, { 1, 52}, { 7, 44}, { 1, 52}, { 4, 18}, + { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 8, 4}, { 1, 21}, { 3, 18}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, { 6, 38}, { 22, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 29}, { 1, 115}, /* Row 116 */ + { 6, 31}, { 1, 8}, { 18, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 7, 44}, { 1, 34}, + { 7, 44}, { 1, 34}, { 8, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 32}, + { 1, 56}, { 9, 4}, { 1, 24}, { 1, 22}, { 3, 18}, { 1, 52}, { 7, 44}, { 1, 34}, + { 4, 18}, { 1, 53}, { 5, 38}, { 1, 48}, { 1, 39}, { 21, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 116}, /* Row 117 */ + { 1, 59}, { 5, 31}, { 1, 8}, { 18, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, + { 6, 44}, { 1, 73}, { 7, 44}, { 1, 73}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 40}, + { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 10, 4}, { 1, 21}, { 3, 18}, { 1, 34}, + { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, { 6, 38}, { 21, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 118 */ + { 1, 58}, { 1, 59}, { 4, 31}, { 1, 16}, { 1, 7}, { 18, 4}, { 1, 21}, { 4, 18}, + { 1, 34}, { 22, 44}, { 1, 34}, { 4, 18}, { 1, 50}, { 6, 31}, { 1, 32}, { 1, 56}, + { 11, 4}, { 1, 24}, { 1, 22}, { 3, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, + { 1, 53}, { 5, 38}, { 1, 48}, { 1, 39}, { 20, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 119 */ + { 1, 48}, { 1, 58}, { 1, 59}, { 3, 31}, { 1, 42}, { 1, 16}, { 1, 7}, { 17, 4}, + { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 20, 44}, { 1, 52}, { 4, 18}, { 1, 40}, + { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 12, 4}, { 1, 21}, { 3, 18}, { 1, 34}, + { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, { 6, 38}, { 20, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 120 */ + { 1, 38}, { 1, 48}, { 1, 58}, { 1, 59}, { 2, 31}, { 1, 56}, { 1, 15}, { 1, 16}, + { 1, 7}, { 17, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 20, 44}, { 1, 34}, { 4, 18}, + { 1, 50}, { 6, 31}, { 1, 32}, { 1, 56}, { 12, 4}, { 1, 7}, { 1, 117}, { 1, 73}, + { 3, 18}, { 1, 52}, { 7, 44}, { 1, 34}, { 4, 18}, { 1, 53}, { 5, 38}, { 1, 48}, + { 1, 39}, { 19, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 121 */ + { 2, 38}, { 1, 48}, { 1, 58}, { 1, 59}, { 1, 31}, { 2, 8}, { 1, 15}, { 1, 16}, + { 1, 7}, { 16, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 18, 44}, { 1, 52}, + { 4, 18}, { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 11, 4}, { 1, 7}, + { 1, 9}, { 1, 118}, { 1, 119}, { 3, 18}, { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, + { 1, 47}, { 1, 45}, { 6, 38}, { 19, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 122 */ + { 3, 38}, { 1, 48}, { 1, 58}, { 1, 113}, { 1, 8}, { 1, 4}, { 1, 8}, { 1, 15}, + { 1, 16}, { 1, 7}, { 16, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 18, 44}, { 1, 34}, + { 4, 18}, { 1, 50}, { 6, 31}, { 1, 32}, { 1, 56}, { 11, 4}, { 1, 7}, { 1, 9}, + { 1, 12}, { 1, 13}, { 1, 120}, { 1, 22}, { 3, 18}, { 1, 52}, { 7, 44}, { 1, 34}, + { 4, 18}, { 1, 53}, { 5, 38}, { 1, 48}, { 1, 39}, { 18, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 123 */ + { 4, 38}, { 1, 48}, { 1, 121}, { 1, 122}, { 2, 4}, { 1, 8}, { 1, 15}, { 1, 16}, + { 1, 7}, { 15, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 16, 44}, { 1, 52}, + { 4, 18}, { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 10, 4}, { 1, 7}, + { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 123}, { 3, 18}, { 1, 34}, + { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, { 6, 38}, { 18, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 124 */ + { 5, 38}, { 1, 48}, { 1, 124}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 15, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 16, 44}, { 1, 34}, { 4, 18}, { 1, 50}, + { 6, 31}, { 1, 32}, { 1, 56}, { 10, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, + { 1, 6}, { 1, 4}, { 1, 5}, { 1, 125}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, + { 4, 18}, { 1, 53}, { 5, 38}, { 1, 48}, { 1, 39}, { 17, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 125 */ + { 6, 38}, { 1, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 14, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 14, 44}, { 1, 52}, { 4, 18}, + { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 9, 4}, { 1, 7}, { 1, 9}, + { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 2, 0}, { 1, 17}, { 3, 18}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, { 6, 38}, { 17, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 126 */ + { 6, 38}, { 2, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 14, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 14, 44}, { 1, 34}, { 4, 18}, { 1, 50}, + { 6, 31}, { 1, 32}, { 1, 56}, { 9, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, + { 1, 6}, { 1, 4}, { 1, 5}, { 4, 0}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, + { 4, 18}, { 1, 53}, { 5, 38}, { 1, 48}, { 1, 39}, { 16, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 127 */ + { 6, 38}, { 3, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 13, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 12, 44}, { 1, 52}, { 4, 18}, + { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 8, 4}, { 1, 7}, { 1, 9}, + { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 5, 0}, { 1, 17}, { 3, 18}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, { 6, 38}, { 16, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 128 */ + { 6, 38}, { 4, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 13, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 12, 44}, { 1, 34}, { 4, 18}, { 1, 50}, + { 6, 31}, { 1, 32}, { 1, 56}, { 8, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, + { 1, 6}, { 1, 4}, { 1, 5}, { 7, 0}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, + { 4, 18}, { 1, 53}, { 5, 38}, { 1, 48}, { 1, 39}, { 15, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 129 */ + { 6, 38}, { 5, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 12, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 10, 44}, { 1, 52}, { 4, 18}, + { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 7, 4}, { 1, 7}, { 1, 9}, + { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 8, 0}, { 1, 17}, { 3, 18}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 47}, { 1, 45}, { 6, 38}, { 15, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 130 */ + { 6, 38}, { 6, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 12, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 10, 44}, { 1, 34}, { 4, 18}, { 1, 50}, + { 6, 31}, { 1, 32}, { 1, 56}, { 7, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, + { 1, 6}, { 1, 4}, { 1, 5}, { 10, 0}, { 4, 18}, { 1, 52}, { 7, 44}, { 1, 34}, + { 4, 18}, { 1, 51}, { 5, 38}, { 1, 48}, { 1, 126}, { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 131 */ + { 6, 38}, { 7, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 11, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 8, 44}, { 1, 52}, { 4, 18}, + { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 6, 4}, { 1, 7}, { 1, 9}, + { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 11, 0}, { 1, 17}, { 3, 18}, + { 1, 34}, { 7, 44}, { 1, 52}, { 4, 18}, { 1, 53}, { 6, 38}, { 1, 127}, { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 132 */ + { 6, 38}, { 8, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 11, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 4, 18}, { 1, 50}, + { 6, 31}, { 1, 32}, { 1, 56}, { 6, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, + { 1, 6}, { 1, 4}, { 1, 5}, { 13, 0}, { 4, 18}, { 1, 52}, { 6, 44}, { 1, 52}, + { 4, 18}, { 1, 53}, { 7, 38}, { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 133 */ + { 6, 38}, { 9, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 10, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 52}, { 6, 44}, { 1, 52}, { 4, 18}, + { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 5, 4}, { 1, 7}, { 1, 9}, + { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 14, 0}, { 1, 17}, { 3, 18}, + { 1, 34}, { 6, 44}, { 1, 52}, { 4, 18}, { 1, 128}, { 6, 38}, { 1, 48}, { 1, 126}, + { 13, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 134 */ + { 6, 38}, { 10, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 10, 4}, { 1, 21}, { 4, 18}, { 1, 34}, { 1, 55}, { 4, 44}, { 1, 55}, { 1, 34}, + { 4, 18}, { 1, 50}, { 6, 31}, { 1, 32}, { 1, 56}, { 5, 4}, { 1, 7}, { 1, 9}, + { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 16, 0}, { 4, 18}, { 1, 52}, + { 5, 44}, { 1, 34}, { 3, 18}, { 1, 47}, { 1, 45}, { 7, 38}, { 1, 39}, { 13, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 135 */ + { 6, 38}, { 11, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 9, 4}, { 1, 24}, { 1, 22}, { 4, 18}, { 1, 34}, { 1, 52}, { 2, 44}, { 1, 52}, + { 1, 34}, { 4, 18}, { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, { 1, 7}, { 4, 4}, + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 17, 0}, + { 1, 17}, { 3, 18}, { 1, 34}, { 1, 52}, { 2, 44}, { 1, 52}, { 1, 34}, { 4, 18}, + { 1, 53}, { 8, 38}, { 1, 39}, { 13, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 136 */ + { 6, 38}, { 12, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 9, 4}, { 1, 21}, { 6, 18}, { 2, 34}, { 6, 18}, { 1, 50}, { 6, 31}, { 1, 32}, + { 1, 56}, { 4, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, + { 1, 5}, { 19, 0}, { 5, 18}, { 2, 34}, { 5, 18}, { 1, 47}, { 1, 45}, { 8, 38}, + { 1, 1}, { 13, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 137 */ + { 6, 38}, { 13, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 8, 4}, { 1, 24}, { 1, 22}, { 12, 18}, { 1, 40}, { 1, 41}, { 6, 31}, { 1, 33}, + { 1, 7}, { 3, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, + { 1, 5}, { 20, 0}, { 1, 17}, { 10, 18}, { 1, 35}, { 1, 61}, { 9, 38}, { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 34}, { 2, 18}, { 1, 35}, { 1, 45}, /* Row 138 */ + { 6, 38}, { 14, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 8, 4}, { 1, 21}, { 12, 18}, { 1, 50}, { 6, 31}, { 1, 32}, { 1, 56}, { 3, 4}, + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 22, 0}, + { 9, 18}, { 1, 35}, { 1, 61}, { 8, 38}, { 1, 48}, { 1, 39}, { 14, 0}, + { 18, 0}, { 3, 18}, { 1, 34}, { 8, 44}, { 1, 18}, { 2, 35}, { 1, 129}, { 1, 45}, /* Row 139 */ + { 6, 38}, { 15, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, + { 7, 4}, { 1, 19}, { 1, 26}, { 10, 18}, { 1, 130}, { 1, 107}, { 6, 31}, { 1, 33}, + { 1, 7}, { 2, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, + { 1, 5}, { 23, 0}, { 1, 131}, { 1, 132}, { 5, 18}, { 1, 35}, { 1, 133}, { 1, 128}, + { 10, 38}, { 15, 0}, + { 25, 0}, { 9, 45}, { 7, 38}, { 16, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, /* Row 140 */ + { 1, 16}, { 1, 7}, { 7, 4}, { 1, 19}, { 1, 21}, { 1, 22}, { 6, 18}, { 1, 40}, + { 1, 50}, { 1, 107}, { 6, 31}, { 1, 32}, { 1, 56}, { 2, 4}, { 1, 7}, { 1, 9}, + { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 27, 0}, { 1, 134}, { 1, 17}, + { 1, 135}, { 1, 51}, { 1, 45}, { 1, 136}, { 9, 38}, { 1, 48}, { 1, 39}, { 15, 0}, + { 25, 0}, { 16, 38}, { 17, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, /* Row 141 */ + { 1, 7}, { 8, 4}, { 1, 24}, { 1, 21}, { 1, 22}, { 2, 29}, { 1, 67}, { 1, 50}, + { 1, 41}, { 8, 31}, { 1, 16}, { 1, 7}, { 1, 4}, { 1, 7}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 30, 0}, { 1, 1}, { 11, 38}, { 1, 48}, + { 1, 38}, { 16, 0}, + { 25, 0}, { 16, 38}, { 18, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, /* Row 142 */ + { 1, 7}, { 9, 4}, { 1, 89}, { 1, 137}, { 1, 138}, { 1, 92}, { 8, 31}, { 1, 42}, + { 1, 16}, { 1, 7}, { 1, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, + { 1, 4}, { 1, 5}, { 32, 0}, { 1, 39}, { 1, 48}, { 8, 38}, { 1, 48}, { 1, 38}, + { 17, 0}, + { 25, 0}, { 16, 38}, { 19, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, /* Row 143 */ + { 1, 7}, { 9, 4}, { 1, 7}, { 1, 56}, { 1, 33}, { 1, 32}, { 5, 31}, { 1, 42}, + { 1, 16}, { 1, 8}, { 2, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, + { 1, 4}, { 1, 5}, { 34, 0}, { 8, 38}, { 1, 48}, { 1, 38}, { 18, 0}, + { 25, 0}, { 16, 38}, { 20, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, /* Row 144 */ + { 1, 7}, { 10, 4}, { 1, 7}, { 7, 8}, { 3, 4}, { 1, 7}, { 1, 9}, { 1, 12}, + { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 35, 0}, { 1, 46}, { 7, 38}, { 1, 39}, + { 19, 0}, + { 25, 0}, { 16, 38}, { 21, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, /* Row 145 */ + { 1, 7}, { 19, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, + { 1, 5}, { 64, 0}, + { 25, 0}, { 16, 38}, { 22, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, /* Row 146 */ + { 1, 7}, { 17, 4}, { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, + { 1, 5}, { 65, 0}, + { 64, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 15, 4}, /* Row 147 */ + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 66, 0}, + { 65, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 13, 4}, /* Row 148 */ + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 67, 0}, + { 66, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 11, 4}, /* Row 149 */ + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 68, 0}, + { 67, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 9, 4}, /* Row 150 */ + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 69, 0}, + { 68, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 7, 4}, /* Row 151 */ + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 70, 0}, + { 69, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 5, 4}, /* Row 152 */ + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 71, 0}, + { 70, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 3, 4}, /* Row 153 */ + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 72, 0}, + { 71, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 1, 4}, /* Row 154 */ + { 1, 7}, { 1, 9}, { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 73, 0}, + { 72, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 16}, { 1, 7}, { 1, 9}, /* Row 155 */ + { 1, 12}, { 1, 13}, { 1, 6}, { 1, 4}, { 1, 5}, { 74, 0}, + { 73, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 15}, { 1, 103}, { 1, 12}, { 1, 13}, /* Row 156 */ + { 1, 6}, { 1, 4}, { 1, 5}, { 75, 0}, + { 74, 0}, { 1, 5}, { 3, 4}, { 1, 8}, { 1, 139}, { 1, 13}, { 1, 6}, { 1, 4}, /* Row 157 */ + { 1, 5}, { 76, 0}, + { 75, 0}, { 1, 5}, { 2, 4}, { 1, 3}, { 1, 140}, { 1, 6}, { 1, 4}, { 1, 5}, /* Row 158 */ + { 77, 0}, + { 76, 0}, { 1, 5}, { 4, 4}, { 1, 5}, { 78, 0} /* Row 159 */ +}; + +#elif CONFIG_NXWIDGETS_BPP == 8 +# ifdef CONFIG_NXWIDGETS_GREYSCALE + + { 76, 0}, { 1, 1}, { 1, 2}, { 1, 3}, { 4, 4}, { 1, 5}, { 76, 0}, /* Row 0 */ + { 75, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 5, 4}, { 1, 5}, { 75, 0}, /* Row 1 */ + { 74, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 9}, { 1, 10}, /* Row 2 */ + { 4, 4}, { 1, 5}, { 74, 0}, + { 73, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 3 */ + { 1, 12}, { 1, 13}, { 4, 4}, { 1, 5}, { 73, 0}, + { 72, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 4 */ + { 1, 7}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 72, 0}, + { 71, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 5 */ + { 1, 7}, { 2, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 71, 0}, + { 70, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 6 */ + { 1, 7}, { 4, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 70, 0}, + { 69, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 7 */ + { 1, 7}, { 6, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 69, 0}, + { 68, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 8 */ + { 1, 7}, { 8, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 68, 0}, + { 67, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 9 */ + { 1, 7}, { 10, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 67, 0}, + { 66, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 10 */ + { 1, 7}, { 12, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 66, 0}, + { 65, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 11 */ + { 1, 7}, { 14, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 65, 0}, + { 64, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 12 */ + { 1, 7}, { 16, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 64, 0}, + { 63, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 13 */ + { 1, 7}, { 18, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 63, 0}, + { 62, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 14 */ + { 1, 7}, { 20, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 62, 0}, + { 61, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 15 */ + { 1, 7}, { 22, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 61, 0}, + { 60, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 16 */ + { 1, 7}, { 24, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 60, 0}, + { 59, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 17 */ + { 1, 7}, { 26, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 59, 0}, + { 58, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 18 */ + { 1, 7}, { 28, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 26, 0}, + { 1, 14}, { 5, 15}, { 1, 14}, { 25, 0}, + { 57, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 19 */ + { 1, 7}, { 10, 4}, { 5, 16}, { 15, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, + { 1, 5}, { 23, 0}, { 1, 17}, { 9, 15}, { 1, 17}, { 23, 0}, + { 56, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, /* Row 20 */ + { 1, 7}, { 9, 4}, { 1, 16}, { 1, 18}, { 1, 19}, { 3, 20}, { 1, 19}, { 1, 18}, + { 1, 21}, { 14, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 22, 0}, + { 11, 15}, { 1, 17}, { 22, 0}, + { 23, 0}, { 1, 14}, { 5, 15}, { 1, 22}, { 25, 0}, { 1, 1}, { 1, 6}, { 1, 7}, /* Row 21 */ + { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 9, 4}, { 1, 16}, { 1, 23}, + { 7, 15}, { 1, 19}, { 1, 24}, { 14, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, + { 1, 5}, { 20, 0}, { 1, 14}, { 12, 15}, { 1, 17}, { 21, 0}, + { 21, 0}, { 1, 17}, { 9, 15}, { 1, 17}, { 22, 0}, { 1, 1}, { 1, 6}, { 1, 7}, /* Row 22 */ + { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 9, 4}, { 1, 16}, { 1, 23}, + { 9, 15}, { 1, 20}, { 1, 24}, { 4, 4}, { 1, 3}, { 9, 4}, { 1, 3}, { 1, 8}, + { 1, 13}, { 4, 4}, { 1, 5}, { 19, 0}, { 14, 15}, { 21, 0}, + { 21, 0}, { 11, 15}, { 1, 17}, { 20, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, /* Row 23 */ + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 10, 4}, { 1, 18}, { 11, 15}, { 1, 25}, + { 1, 26}, { 2, 27}, { 1, 28}, { 1, 29}, { 10, 4}, { 1, 3}, { 1, 8}, { 1, 13}, + { 4, 4}, { 1, 5}, { 17, 0}, { 1, 14}, { 5, 15}, { 1, 30}, { 2, 31}, { 1, 30}, + { 5, 15}, { 1, 14}, { 20, 0}, + { 20, 0}, { 1, 22}, { 12, 15}, { 1, 32}, { 4, 33}, { 1, 7}, { 13, 0}, { 1, 1}, /* Row 24 */ + { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 10, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 3, 30}, { 5, 15}, { 1, 34}, { 1, 35}, { 3, 27}, + { 1, 36}, { 10, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 16, 0}, + { 5, 15}, { 1, 37}, { 4, 38}, { 1, 37}, { 4, 15}, { 1, 39}, { 1, 40}, { 1, 41}, + { 18, 0}, + { 19, 0}, { 1, 14}, { 13, 15}, { 1, 31}, { 1, 40}, { 5, 33}, { 11, 0}, { 1, 1}, /* Row 25 */ + { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 11, 4}, + { 1, 42}, { 4, 15}, { 1, 31}, { 3, 38}, { 1, 37}, { 5, 15}, { 1, 43}, { 4, 27}, + { 1, 36}, { 10, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 14, 0}, + { 1, 14}, { 4, 15}, { 1, 30}, { 6, 38}, { 1, 30}, { 4, 15}, { 1, 22}, { 1, 33}, + { 1, 41}, { 17, 0}, + { 19, 0}, { 5, 15}, { 1, 30}, { 1, 44}, { 1, 34}, { 1, 31}, { 6, 15}, { 1, 45}, /* Row 26 */ + { 5, 33}, { 1, 7}, { 9, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, + { 1, 7}, { 1, 11}, { 1, 7}, { 11, 4}, { 1, 46}, { 1, 47}, { 4, 15}, { 1, 48}, + { 4, 38}, { 1, 37}, { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 36}, { 10, 4}, + { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 13, 0}, { 5, 15}, { 1, 34}, + { 6, 38}, { 1, 44}, { 4, 15}, { 1, 45}, { 2, 33}, { 1, 41}, { 16, 0}, + { 18, 0}, { 1, 14}, { 4, 15}, { 1, 37}, { 4, 38}, { 1, 31}, { 5, 15}, { 1, 31}, /* Row 27 */ + { 1, 40}, { 5, 33}, { 8, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, + { 1, 7}, { 1, 11}, { 1, 7}, { 12, 4}, { 1, 16}, { 1, 20}, { 3, 15}, { 1, 31}, + { 6, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 9, 4}, + { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 11, 0}, { 1, 14}, { 4, 15}, + { 1, 30}, { 7, 38}, { 1, 44}, { 4, 15}, { 1, 45}, { 3, 33}, { 16, 0}, + { 18, 0}, { 4, 15}, { 1, 30}, { 5, 38}, { 1, 48}, { 1, 30}, { 5, 15}, { 1, 45}, /* Row 28 */ + { 5, 33}, { 1, 7}, { 6, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, + { 1, 7}, { 1, 11}, { 1, 7}, { 13, 4}, { 1, 16}, { 1, 20}, { 3, 15}, { 1, 19}, + { 6, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, + { 10, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 10, 0}, { 5, 15}, + { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 22}, { 3, 33}, { 1, 7}, { 15, 0}, + { 18, 0}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, { 5, 15}, { 1, 31}, { 1, 40}, /* Row 29 */ + { 5, 33}, { 5, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, + { 1, 11}, { 1, 7}, { 14, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, + { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 10, 4}, { 1, 3}, + { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 8, 0}, { 1, 14}, { 4, 15}, { 1, 30}, + { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, { 4, 33}, { 15, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 5, 15}, { 1, 45}, { 5, 33}, /* Row 30 */ + { 1, 7}, { 3, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, + { 1, 11}, { 1, 7}, { 15, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 11, 4}, + { 1, 3}, { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 7, 0}, { 5, 15}, { 1, 34}, + { 7, 38}, { 1, 30}, { 4, 15}, { 1, 45}, { 5, 33}, { 1, 50}, { 14, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 34}, { 5, 15}, { 1, 31}, { 1, 40}, /* Row 31 */ + { 5, 33}, { 2, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, + { 1, 11}, { 1, 7}, { 16, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 9, 38}, + { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 11, 4}, { 1, 3}, + { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 5, 0}, { 1, 14}, { 4, 15}, { 1, 30}, + { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, { 5, 33}, { 1, 7}, { 14, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 9, 38}, { 1, 30}, { 5, 15}, { 1, 45}, { 5, 33}, /* Row 32 */ + { 1, 7}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, + { 1, 7}, { 17, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 9, 38}, { 1, 34}, + { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 12, 4}, { 1, 3}, + { 1, 8}, { 1, 13}, { 4, 4}, { 1, 5}, { 4, 0}, { 5, 15}, { 1, 34}, { 7, 38}, + { 1, 30}, { 4, 15}, { 1, 45}, { 6, 33}, { 1, 50}, { 14, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 9, 38}, { 1, 34}, { 5, 15}, { 1, 31}, { 1, 40}, /* Row 33 */ + { 4, 33}, { 1, 51}, { 1, 52}, { 1, 7}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, + { 1, 7}, { 18, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 10, 38}, { 1, 30}, + { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 12, 4}, { 1, 3}, { 1, 8}, + { 1, 13}, { 4, 4}, { 1, 5}, { 2, 0}, { 1, 14}, { 4, 15}, { 1, 30}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, { 6, 33}, { 15, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 10, 38}, { 1, 30}, { 5, 15}, { 1, 45}, { 3, 33}, /* Row 34 */ + { 1, 53}, { 1, 54}, { 1, 21}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, + { 19, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 10, 38}, { 1, 34}, { 4, 15}, + { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 13, 4}, { 1, 3}, { 1, 8}, + { 1, 13}, { 4, 4}, { 1, 5}, { 1, 0}, { 5, 15}, { 1, 34}, { 7, 38}, { 1, 30}, + { 3, 15}, { 1, 55}, { 1, 56}, { 6, 33}, { 1, 7}, { 15, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 10, 38}, { 1, 34}, { 5, 15}, { 1, 31}, { 1, 40}, /* Row 35 */ + { 1, 33}, { 1, 53}, { 1, 57}, { 1, 27}, { 1, 28}, { 1, 58}, { 1, 7}, { 1, 11}, + { 1, 7}, { 20, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 11, 38}, { 1, 30}, + { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 13, 4}, { 1, 3}, { 1, 8}, + { 1, 13}, { 4, 4}, { 1, 59}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, + { 1, 31}, { 1, 60}, { 6, 33}, { 16, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 11, 38}, { 1, 30}, { 5, 15}, { 1, 61}, { 1, 53}, /* Row 36 */ + { 1, 57}, { 3, 27}, { 1, 62}, { 1, 56}, { 1, 7}, { 21, 4}, { 1, 16}, { 1, 20}, + { 2, 15}, { 1, 30}, { 11, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, + { 1, 28}, { 1, 49}, { 14, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 2, 4}, { 1, 21}, + { 1, 19}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 45}, { 6, 33}, + { 1, 7}, { 16, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 11, 38}, { 1, 34}, { 5, 15}, { 1, 63}, { 1, 35}, /* Row 37 */ + { 5, 27}, { 1, 64}, { 22, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 12, 38}, + { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 14, 4}, { 1, 3}, + { 1, 8}, { 1, 13}, { 1, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, + { 4, 15}, { 1, 31}, { 1, 40}, { 6, 33}, { 17, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 12, 38}, { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, /* Row 38 */ + { 1, 65}, { 1, 3}, { 21, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 12, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 15, 4}, + { 1, 3}, { 1, 8}, { 1, 66}, { 1, 19}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, + { 4, 15}, { 1, 45}, { 6, 33}, { 1, 7}, { 17, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 12, 38}, { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, /* Row 39 */ + { 4, 27}, { 1, 28}, { 1, 49}, { 21, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, + { 13, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 16, 4}, + { 1, 67}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, + { 6, 33}, { 18, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 13, 38}, { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, /* Row 40 */ + { 1, 29}, { 1, 3}, { 20, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 13, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 15, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 45}, + { 6, 33}, { 1, 7}, { 18, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 13, 38}, { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, /* Row 41 */ + { 4, 27}, { 1, 28}, { 1, 49}, { 20, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, + { 14, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 14, 4}, + { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, + { 6, 33}, { 19, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 14, 38}, { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, /* Row 42 */ + { 1, 29}, { 1, 3}, { 19, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 14, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 13, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 45}, + { 6, 33}, { 1, 7}, { 19, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 14, 38}, { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, /* Row 43 */ + { 4, 27}, { 1, 28}, { 1, 49}, { 19, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 68}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, + { 1, 3}, { 12, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, + { 1, 31}, { 1, 40}, { 6, 33}, { 20, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 15, 38}, { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, /* Row 44 */ + { 1, 29}, { 1, 3}, { 18, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, + { 1, 69}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, + { 1, 49}, { 11, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, + { 4, 15}, { 1, 45}, { 6, 33}, { 1, 7}, { 20, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 68}, { 6, 38}, { 1, 34}, { 5, 15}, /* Row 45 */ + { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 18, 4}, { 1, 16}, { 1, 20}, + { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, + { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 10, 4}, { 1, 18}, { 4, 15}, { 1, 30}, + { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, { 6, 33}, { 21, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 69}, { 7, 38}, { 1, 30}, { 5, 15}, /* Row 46 */ + { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 17, 4}, { 1, 16}, { 1, 20}, { 2, 15}, + { 1, 30}, { 7, 38}, { 2, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, + { 4, 27}, { 1, 28}, { 1, 49}, { 9, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, + { 7, 38}, { 1, 30}, { 4, 15}, { 1, 45}, { 6, 33}, { 1, 7}, { 21, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 1, 34}, { 6, 38}, { 1, 34}, /* Row 47 */ + { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 17, 4}, { 1, 16}, + { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 1, 15}, { 1, 34}, { 7, 38}, + { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 8, 4}, { 1, 18}, + { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, { 6, 33}, + { 22, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 2, 30}, { 7, 38}, { 1, 30}, { 5, 15}, /* Row 48 */ + { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 16, 4}, { 1, 16}, { 1, 20}, { 2, 15}, + { 1, 30}, { 7, 38}, { 1, 30}, { 1, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, + { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 7, 4}, { 1, 21}, { 1, 19}, + { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 70}, { 6, 33}, { 1, 7}, + { 22, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 1, 15}, { 1, 34}, { 6, 38}, /* Row 49 */ + { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 16, 4}, + { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 34}, + { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 6, 4}, + { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 1}, + { 1, 53}, { 5, 33}, { 23, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 1, 15}, { 1, 30}, { 7, 38}, /* Row 50 */ + { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 15, 4}, { 1, 16}, + { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 30}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 5, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, + { 1, 27}, { 1, 57}, { 1, 53}, { 3, 33}, { 1, 7}, { 23, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 34}, { 6, 38}, /* Row 51 */ + { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 15, 4}, + { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 3, 15}, { 1, 34}, + { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 4, 4}, + { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, + { 2, 27}, { 1, 57}, { 1, 53}, { 2, 33}, { 24, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 30}, { 7, 38}, /* Row 52 */ + { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 14, 4}, { 1, 16}, + { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 3, 15}, { 1, 30}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 3, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, + { 4, 27}, { 1, 57}, { 1, 53}, { 1, 7}, { 24, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 3, 15}, { 1, 34}, { 6, 38}, /* Row 53 */ + { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 14, 4}, + { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 34}, + { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 2, 4}, + { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, + { 5, 27}, { 1, 71}, { 1, 72}, { 24, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 3, 15}, { 1, 30}, { 7, 38}, /* Row 54 */ + { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 13, 4}, { 1, 16}, + { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 30}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 1, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, + { 6, 27}, { 1, 28}, { 1, 49}, { 1, 5}, { 23, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 4, 15}, { 1, 34}, { 6, 38}, /* Row 55 */ + { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 13, 4}, + { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 34}, + { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 4}, { 1, 18}, + { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 6, 27}, + { 1, 49}, { 1, 3}, { 1, 4}, { 1, 5}, { 22, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 4, 15}, { 1, 30}, { 7, 38}, /* Row 56 */ + { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 12, 4}, { 1, 16}, + { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 30}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 73}, { 1, 19}, + { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 36}, + { 1, 13}, { 3, 4}, { 1, 5}, { 21, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 5, 15}, { 1, 34}, { 6, 38}, /* Row 57 */ + { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 12, 4}, + { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 6, 15}, { 1, 34}, + { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 74}, { 4, 15}, { 1, 30}, + { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 28}, { 1, 49}, + { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, { 20, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 5, 15}, { 1, 30}, { 7, 38}, /* Row 58 */ + { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 11, 4}, { 1, 16}, + { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 6, 15}, { 1, 30}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 3, 27}, { 1, 35}, { 1, 34}, { 4, 15}, + { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 29}, { 2, 3}, + { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, { 19, 0}, + { 17, 0}, { 1, 75}, { 1, 55}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 6, 15}, /* Row 59 */ + { 1, 34}, { 6, 38}, { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, + { 1, 49}, { 11, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, + { 7, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 3, 27}, { 1, 43}, + { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, + { 1, 28}, { 1, 49}, { 2, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, + { 18, 0}, + { 16, 0}, { 1, 1}, { 1, 76}, { 1, 37}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, /* Row 60 */ + { 6, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, { 1, 29}, + { 1, 3}, { 10, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, + { 3, 15}, { 1, 37}, { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, + { 1, 35}, { 1, 27}, { 1, 35}, { 1, 34}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, + { 4, 15}, { 1, 43}, { 6, 27}, { 1, 29}, { 1, 3}, { 3, 4}, { 1, 3}, { 1, 8}, + { 1, 13}, { 3, 4}, { 1, 5}, { 17, 0}, + { 15, 0}, { 1, 1}, { 1, 6}, { 1, 73}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, /* Row 61 */ + { 1, 30}, { 7, 15}, { 1, 34}, { 6, 38}, { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, + { 4, 27}, { 1, 28}, { 1, 49}, { 10, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 77}, { 1, 78}, { 4, 15}, { 1, 34}, { 7, 38}, + { 1, 30}, { 4, 15}, { 1, 43}, { 1, 79}, { 1, 43}, { 4, 15}, { 1, 30}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 28}, { 1, 49}, { 5, 4}, + { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, { 16, 0}, + { 14, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, /* Row 62 */ + { 8, 38}, { 1, 30}, { 7, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 43}, + { 5, 27}, { 1, 29}, { 1, 3}, { 9, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 41}, { 1, 34}, { 3, 15}, { 1, 30}, + { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 80}, { 1, 34}, { 4, 15}, { 1, 34}, + { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 29}, { 1, 3}, { 6, 4}, + { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, { 15, 0}, + { 13, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 9}, { 1, 77}, { 2, 15}, /* Row 63 */ + { 1, 30}, { 8, 38}, { 1, 30}, { 3, 15}, { 1, 37}, { 4, 15}, { 1, 34}, { 6, 38}, + { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 9, 4}, + { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, + { 1, 81}, { 1, 43}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 68}, + { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, + { 1, 28}, { 1, 49}, { 8, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, + { 14, 0}, + { 12, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 82}, { 1, 83}, /* Row 64 */ + { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 77}, { 1, 78}, { 4, 15}, + { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, + { 8, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 1, 35}, { 1, 34}, { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, + { 9, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 29}, + { 1, 3}, { 9, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, { 13, 0}, + { 11, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 85}, /* Row 65 */ + { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 41}, + { 1, 34}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, + { 4, 27}, { 1, 28}, { 1, 49}, { 8, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 1, 27}, { 1, 43}, { 4, 15}, + { 1, 34}, { 7, 38}, { 1, 30}, { 7, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, + { 1, 34}, { 1, 35}, { 5, 27}, { 1, 28}, { 1, 49}, { 11, 4}, { 1, 3}, { 1, 8}, + { 1, 13}, { 3, 4}, { 1, 5}, { 12, 0}, + { 10, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, /* Row 66 */ + { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, + { 1, 81}, { 1, 43}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 43}, + { 5, 27}, { 1, 29}, { 1, 3}, { 7, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 1, 27}, { 1, 35}, { 1, 34}, + { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 7, 15}, { 1, 34}, { 7, 38}, { 1, 30}, + { 4, 15}, { 1, 43}, { 6, 27}, { 1, 29}, { 1, 3}, { 12, 4}, { 1, 3}, { 1, 8}, + { 1, 13}, { 3, 4}, { 1, 5}, { 11, 0}, + { 9, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, /* Row 67 */ + { 1, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 1, 35}, { 1, 34}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 7, 4}, { 1, 16}, + { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, + { 2, 27}, { 1, 43}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 30}, + { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 28}, { 1, 49}, + { 14, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, { 10, 0}, + { 8, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, /* Row 68 */ + { 2, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 1, 27}, { 1, 43}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, + { 5, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 6, 4}, { 1, 16}, { 1, 20}, + { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 2, 27}, + { 1, 35}, { 1, 34}, { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 5, 15}, { 1, 34}, + { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 29}, { 1, 3}, { 15, 4}, + { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, { 9, 0}, + { 7, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, /* Row 69 */ + { 3, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 1, 27}, { 1, 35}, { 1, 34}, { 4, 15}, { 1, 34}, { 6, 38}, + { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 6, 4}, + { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, + { 1, 81}, { 3, 27}, { 1, 43}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 3, 15}, + { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 28}, + { 1, 49}, { 17, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, { 8, 0}, + { 6, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, /* Row 70 */ + { 4, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 2, 27}, { 1, 43}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, + { 5, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 5, 4}, { 1, 16}, { 1, 20}, + { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 3, 27}, + { 1, 35}, { 1, 34}, { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 3, 15}, { 1, 34}, + { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 29}, { 1, 3}, { 18, 4}, + { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, { 7, 0}, + { 5, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, /* Row 71 */ + { 5, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 2, 27}, { 1, 35}, { 1, 34}, { 4, 15}, { 1, 34}, { 6, 38}, + { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 5, 4}, + { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, + { 1, 81}, { 4, 27}, { 1, 43}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 1, 15}, + { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 28}, + { 1, 49}, { 20, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, { 6, 0}, + { 4, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, /* Row 72 */ + { 6, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 3, 27}, { 1, 43}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, + { 5, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 4, 4}, { 1, 16}, { 1, 20}, + { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 4, 27}, + { 1, 35}, { 1, 34}, { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 1, 15}, { 1, 34}, + { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 29}, { 1, 3}, { 21, 4}, + { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, { 5, 0}, + { 3, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, /* Row 73 */ + { 7, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 3, 27}, { 1, 35}, { 1, 34}, { 4, 15}, { 1, 34}, { 6, 38}, + { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 4, 4}, + { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, + { 1, 81}, { 5, 27}, { 1, 43}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 69}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 28}, { 1, 49}, { 23, 4}, + { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, { 4, 0}, + { 2, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, /* Row 74 */ + { 8, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 4, 27}, { 1, 43}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, + { 5, 15}, { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 3, 4}, { 1, 16}, { 1, 20}, + { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 5, 27}, + { 1, 87}, { 1, 34}, { 3, 15}, { 1, 30}, { 15, 38}, { 1, 30}, { 4, 15}, { 1, 43}, + { 6, 27}, { 1, 29}, { 1, 3}, { 24, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, + { 1, 5}, { 3, 0}, + { 1, 0}, { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, /* Row 75 */ + { 9, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 4, 27}, { 1, 35}, { 1, 34}, { 4, 15}, { 1, 34}, { 6, 38}, + { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 3, 4}, + { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, + { 1, 81}, { 6, 27}, { 1, 67}, { 4, 15}, { 1, 34}, { 13, 38}, { 1, 34}, { 4, 15}, + { 1, 34}, { 1, 35}, { 5, 27}, { 1, 28}, { 1, 49}, { 26, 4}, { 1, 3}, { 1, 8}, + { 1, 13}, { 3, 4}, { 1, 5}, { 2, 0}, + { 1, 1}, { 1, 6}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, { 10, 4}, /* Row 76 */ + { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, + { 1, 81}, { 5, 27}, { 1, 43}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, + { 1, 43}, { 5, 27}, { 1, 29}, { 1, 3}, { 2, 4}, { 1, 16}, { 1, 20}, { 2, 15}, + { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 1, 21}, + { 1, 19}, { 3, 15}, { 1, 30}, { 13, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, + { 1, 29}, { 1, 3}, { 27, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, { 1, 5}, + { 1, 0}, + { 1, 2}, { 1, 7}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, { 11, 4}, { 1, 16}, /* Row 77 */ + { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, + { 5, 27}, { 1, 87}, { 1, 34}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, { 5, 15}, + { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 2, 4}, { 1, 16}, { 1, 20}, + { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, + { 1, 4}, { 1, 18}, { 4, 15}, { 1, 34}, { 11, 38}, { 1, 34}, { 4, 15}, { 1, 34}, + { 1, 35}, { 5, 27}, { 1, 28}, { 1, 49}, { 29, 4}, { 1, 3}, { 1, 8}, { 1, 13}, + { 3, 4}, { 1, 5}, + { 1, 3}, { 1, 4}, { 1, 28}, { 1, 84}, { 1, 86}, { 12, 4}, { 1, 16}, { 1, 20}, /* Row 78 */ + { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, + { 1, 67}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, + { 1, 29}, { 1, 3}, { 1, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, + { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 1, 4}, { 1, 21}, { 1, 19}, + { 3, 15}, { 1, 30}, { 11, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 29}, + { 1, 3}, { 30, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 3, 4}, + { 1, 4}, { 1, 88}, { 1, 89}, { 1, 86}, { 13, 4}, { 1, 16}, { 1, 20}, { 2, 15}, /* Row 79 */ + { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 1, 21}, + { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, { 5, 15}, { 1, 34}, { 1, 35}, + { 4, 27}, { 1, 28}, { 1, 49}, { 1, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 2, 4}, { 1, 6}, + { 4, 15}, { 1, 34}, { 9, 38}, { 1, 19}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, + { 1, 28}, { 1, 49}, { 32, 4}, { 1, 3}, { 1, 8}, { 1, 13}, { 1, 49}, { 1, 3}, + { 2, 4}, { 1, 90}, { 1, 8}, { 1, 3}, { 12, 4}, { 1, 16}, { 1, 20}, { 2, 15}, /* Row 80 */ + { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 1, 4}, + { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, + { 1, 29}, { 1, 3}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, + { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 2, 4}, { 1, 6}, { 4, 15}, { 1, 69}, + { 9, 38}, { 1, 31}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 29}, { 1, 3}, { 33, 4}, + { 1, 3}, { 1, 91}, { 1, 81}, { 1, 4}, + { 3, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 11, 4}, { 1, 16}, { 1, 20}, { 2, 15}, /* Row 81 */ + { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 1, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, { 5, 15}, { 1, 34}, + { 1, 35}, { 4, 27}, { 1, 28}, { 1, 49}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 1, 4}, { 1, 21}, + { 1, 19}, { 4, 15}, { 1, 34}, { 8, 38}, { 1, 92}, { 4, 15}, { 1, 68}, { 1, 93}, + { 6, 27}, { 1, 49}, { 33, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 56}, { 1, 8}, + { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 10, 4}, { 1, 16}, { 1, 20}, { 2, 15}, /* Row 82 */ + { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 2, 4}, + { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 43}, { 5, 27}, + { 1, 29}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 6, 27}, { 1, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 10, 38}, + { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 49}, { 32, 4}, { 1, 3}, { 1, 8}, + { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, + { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 9, 4}, { 1, 16}, { 1, 20}, /* Row 83 */ + { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, + { 2, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, { 5, 15}, + { 1, 34}, { 1, 35}, { 4, 27}, { 1, 28}, { 1, 7}, { 1, 20}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 1, 21}, { 1, 19}, + { 4, 15}, { 1, 34}, { 10, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, + { 1, 29}, { 1, 3}, { 30, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, + { 1, 4}, { 1, 5}, + { 1, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 8, 4}, { 1, 16}, /* Row 84 */ + { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, + { 6, 27}, { 3, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, + { 1, 43}, { 5, 27}, { 1, 10}, { 1, 20}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, + { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 1, 67}, { 4, 15}, { 1, 30}, { 12, 38}, + { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 28}, { 1, 49}, { 29, 4}, { 1, 3}, + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 1, 0}, + { 2, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 7, 4}, { 1, 16}, /* Row 85 */ + { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, + { 6, 27}, { 3, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 5, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 81}, { 1, 77}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 5, 27}, { 1, 87}, { 1, 34}, + { 4, 15}, { 1, 34}, { 12, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, + { 1, 29}, { 1, 3}, { 27, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, + { 1, 4}, { 1, 5}, { 2, 0}, + { 3, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 6, 4}, { 1, 16}, /* Row 86 */ + { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, + { 6, 27}, { 4, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, + { 1, 43}, { 4, 27}, { 1, 81}, { 1, 25}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, + { 2, 15}, { 1, 25}, { 1, 81}, { 5, 27}, { 1, 43}, { 4, 15}, { 1, 30}, { 14, 38}, + { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 28}, { 1, 49}, { 26, 4}, { 1, 3}, + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 3, 0}, + { 4, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 5, 4}, { 1, 16}, /* Row 87 */ + { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, + { 6, 27}, { 4, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 5, 15}, { 1, 34}, { 1, 35}, { 3, 27}, { 1, 81}, { 1, 25}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 4, 27}, { 1, 35}, { 1, 34}, + { 4, 15}, { 1, 34}, { 14, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, + { 1, 29}, { 1, 3}, { 24, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, + { 1, 4}, { 1, 5}, { 4, 0}, + { 5, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 4, 4}, { 1, 16}, /* Row 88 */ + { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, + { 6, 27}, { 5, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, + { 1, 43}, { 3, 27}, { 1, 81}, { 1, 25}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, + { 2, 15}, { 1, 25}, { 1, 81}, { 4, 27}, { 1, 43}, { 4, 15}, { 1, 30}, { 16, 38}, + { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 28}, { 1, 49}, { 23, 4}, { 1, 3}, + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 5, 0}, + { 6, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 3, 4}, { 1, 16}, /* Row 89 */ + { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, + { 6, 27}, { 5, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 5, 15}, { 1, 34}, { 1, 35}, { 2, 27}, { 1, 81}, { 1, 25}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 3, 27}, { 1, 35}, { 1, 34}, + { 4, 15}, { 1, 34}, { 7, 38}, { 1, 34}, { 1, 69}, { 7, 38}, { 1, 34}, { 4, 15}, + { 1, 34}, { 1, 35}, { 5, 27}, { 1, 29}, { 1, 3}, { 21, 4}, { 1, 3}, { 1, 8}, + { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 6, 0}, + { 7, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 2, 4}, { 1, 16}, /* Row 90 */ + { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, + { 6, 27}, { 6, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, + { 1, 43}, { 2, 27}, { 1, 81}, { 1, 25}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, + { 2, 15}, { 1, 25}, { 1, 81}, { 3, 27}, { 1, 43}, { 4, 15}, { 1, 30}, { 8, 38}, + { 1, 30}, { 1, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, + { 1, 28}, { 1, 49}, { 20, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, + { 1, 4}, { 1, 5}, { 7, 0}, + { 8, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 1, 4}, { 1, 16}, /* Row 91 */ + { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, + { 6, 27}, { 6, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 5, 15}, { 1, 34}, { 1, 35}, { 1, 27}, { 1, 81}, { 1, 25}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 2, 27}, { 1, 35}, { 1, 34}, + { 4, 15}, { 1, 34}, { 7, 38}, { 1, 34}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 34}, + { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 29}, { 1, 3}, { 18, 4}, { 1, 3}, + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 8, 0}, + { 9, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 1, 16}, { 1, 20}, /* Row 92 */ + { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, + { 7, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 43}, + { 1, 27}, { 1, 81}, { 1, 25}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 2, 27}, { 1, 43}, { 4, 15}, { 1, 30}, { 8, 38}, { 1, 30}, + { 3, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 28}, + { 1, 49}, { 17, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, + { 1, 5}, { 9, 0}, + { 10, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 16}, { 1, 20}, { 2, 15}, /* Row 93 */ + { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 7, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, { 5, 15}, { 1, 34}, + { 1, 35}, { 1, 81}, { 1, 25}, { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, + { 1, 25}, { 1, 81}, { 1, 27}, { 1, 35}, { 1, 34}, { 4, 15}, { 1, 34}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, + { 5, 27}, { 1, 29}, { 1, 3}, { 15, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, + { 1, 7}, { 1, 4}, { 1, 5}, { 10, 0}, + { 11, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 73}, { 1, 20}, { 2, 15}, { 1, 30}, /* Row 94 */ + { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 8, 4}, { 1, 18}, + { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 43}, { 1, 81}, { 1, 25}, + { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 1, 27}, + { 1, 43}, { 4, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 5, 15}, { 1, 34}, { 7, 38}, + { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 28}, { 1, 49}, { 14, 4}, { 1, 3}, + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 11, 0}, + { 12, 0}, { 1, 5}, { 4, 4}, { 1, 57}, { 1, 77}, { 2, 15}, { 1, 30}, { 8, 38}, /* Row 95 */ + { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 8, 4}, { 1, 21}, { 1, 19}, + { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, { 5, 15}, { 1, 34}, { 1, 41}, { 1, 25}, + { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 1, 35}, + { 1, 34}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 34}, { 6, 15}, { 1, 30}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 29}, { 1, 3}, { 12, 4}, + { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 12, 0}, + { 13, 0}, { 1, 5}, { 3, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, /* Row 96 */ + { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 9, 4}, { 1, 18}, { 4, 15}, + { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 78}, { 1, 77}, { 2, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 1, 43}, { 4, 15}, { 1, 30}, + { 8, 38}, { 1, 30}, { 7, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, + { 5, 27}, { 1, 28}, { 1, 49}, { 11, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, + { 1, 7}, { 1, 4}, { 1, 5}, { 13, 0}, + { 14, 0}, { 1, 5}, { 2, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, /* Row 97 */ + { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 9, 4}, { 1, 21}, { 1, 19}, + { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, { 5, 15}, { 1, 37}, { 3, 15}, { 1, 30}, + { 7, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 41}, { 1, 34}, { 4, 15}, { 1, 34}, + { 7, 38}, { 1, 34}, { 4, 15}, { 1, 37}, { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, + { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 29}, { 1, 3}, { 9, 4}, { 1, 3}, + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 14, 0}, + { 15, 0}, { 1, 5}, { 1, 4}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, /* Row 98 */ + { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 10, 4}, { 1, 18}, { 4, 15}, + { 1, 30}, { 7, 38}, { 1, 30}, { 8, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, + { 1, 77}, { 1, 78}, { 4, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 4, 15}, { 1, 78}, + { 1, 34}, { 3, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, + { 1, 28}, { 1, 49}, { 8, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, + { 1, 4}, { 1, 5}, { 15, 0}, + { 16, 0}, { 1, 5}, { 1, 16}, { 1, 20}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, /* Row 99 */ + { 2, 15}, { 1, 25}, { 1, 81}, { 6, 27}, { 10, 4}, { 1, 21}, { 1, 19}, { 4, 15}, + { 1, 34}, { 6, 38}, { 1, 34}, { 8, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 3, 15}, + { 1, 37}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 94}, + { 1, 43}, { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, + { 5, 27}, { 1, 29}, { 1, 3}, { 6, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, + { 1, 7}, { 1, 4}, { 1, 5}, { 16, 0}, + { 17, 0}, { 1, 95}, { 1, 96}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, /* Row 100 */ + { 1, 25}, { 1, 81}, { 6, 27}, { 11, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, + { 1, 30}, { 7, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 7, 15}, { 1, 30}, { 8, 38}, + { 1, 30}, { 4, 15}, { 1, 43}, { 1, 27}, { 1, 35}, { 1, 34}, { 3, 15}, { 1, 34}, + { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 28}, { 1, 49}, { 5, 4}, + { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 17, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 101 */ + { 6, 27}, { 11, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 7, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 7, 15}, { 1, 34}, { 7, 38}, { 1, 34}, + { 4, 15}, { 1, 34}, { 1, 35}, { 2, 27}, { 1, 43}, { 3, 15}, { 1, 30}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 29}, { 1, 3}, { 3, 4}, + { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 18, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 102 */ + { 6, 27}, { 12, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 6, 15}, + { 1, 30}, { 7, 38}, { 1, 30}, { 6, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 4, 15}, + { 1, 43}, { 3, 27}, { 1, 35}, { 1, 34}, { 3, 15}, { 1, 34}, { 7, 38}, { 1, 30}, + { 4, 15}, { 1, 43}, { 5, 27}, { 1, 28}, { 1, 49}, { 2, 4}, { 1, 3}, { 1, 8}, + { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 19, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 103 */ + { 6, 27}, { 12, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 6, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 6, 15}, { 1, 34}, { 7, 38}, { 1, 34}, + { 4, 15}, { 1, 34}, { 1, 35}, { 4, 27}, { 1, 43}, { 3, 15}, { 1, 30}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 29}, { 2, 3}, { 1, 8}, + { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 20, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 104 */ + { 6, 27}, { 13, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, + { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 4, 15}, + { 1, 43}, { 5, 27}, { 1, 35}, { 1, 34}, { 3, 15}, { 1, 34}, { 7, 38}, { 1, 30}, + { 4, 15}, { 1, 43}, { 5, 27}, { 1, 28}, { 1, 49}, { 1, 8}, { 1, 7}, { 1, 11}, + { 1, 7}, { 1, 4}, { 1, 5}, { 21, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 105 */ + { 6, 27}, { 13, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 5, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 5, 15}, { 1, 34}, { 7, 38}, { 1, 34}, + { 4, 15}, { 1, 34}, { 1, 35}, { 6, 27}, { 1, 74}, { 3, 15}, { 1, 30}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 36}, { 1, 7}, { 1, 11}, + { 1, 7}, { 1, 4}, { 1, 5}, { 22, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 106 */ + { 6, 27}, { 14, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 4, 15}, + { 1, 30}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 4, 15}, + { 1, 43}, { 6, 27}, { 1, 28}, { 1, 73}, { 1, 19}, { 3, 15}, { 1, 34}, { 7, 38}, + { 1, 30}, { 4, 15}, { 1, 43}, { 5, 27}, { 1, 54}, { 1, 97}, { 1, 7}, { 1, 4}, + { 1, 5}, { 23, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 107 */ + { 6, 27}, { 14, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 34}, + { 4, 15}, { 1, 34}, { 1, 35}, { 6, 27}, { 1, 29}, { 1, 4}, { 1, 18}, { 3, 15}, + { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 5, 27}, { 1, 98}, + { 1, 4}, { 1, 5}, { 24, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 108 */ + { 6, 27}, { 15, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 3, 15}, + { 1, 30}, { 7, 38}, { 1, 30}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 4, 15}, + { 1, 43}, { 6, 27}, { 1, 28}, { 1, 49}, { 1, 4}, { 1, 21}, { 1, 19}, { 3, 15}, + { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 4, 27}, { 1, 57}, { 1, 99}, + { 1, 9}, { 25, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 109 */ + { 6, 27}, { 15, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 3, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 3, 15}, { 1, 34}, { 7, 38}, { 1, 34}, + { 4, 15}, { 1, 34}, { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 2, 4}, { 1, 18}, + { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, { 2, 27}, + { 1, 57}, { 1, 53}, { 2, 33}, { 25, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 110 */ + { 6, 27}, { 16, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, + { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 4, 15}, + { 1, 43}, { 6, 27}, { 1, 28}, { 1, 49}, { 3, 4}, { 1, 21}, { 1, 19}, { 3, 15}, + { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 1, 27}, { 1, 57}, { 1, 53}, + { 3, 33}, { 1, 7}, { 24, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 111 */ + { 6, 27}, { 16, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 2, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 2, 15}, { 1, 34}, { 7, 38}, { 1, 34}, + { 4, 15}, { 1, 34}, { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 4, 4}, { 1, 18}, + { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 1}, { 1, 53}, + { 5, 33}, { 24, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 112 */ + { 6, 27}, { 17, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 1, 15}, + { 1, 30}, { 7, 38}, { 1, 30}, { 1, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 4, 15}, + { 1, 43}, { 6, 27}, { 1, 28}, { 1, 49}, { 5, 4}, { 1, 21}, { 1, 19}, { 3, 15}, + { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 70}, { 6, 33}, { 1, 7}, { 23, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 113 */ + { 6, 27}, { 17, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 1, 15}, { 1, 30}, { 7, 38}, { 1, 30}, { 1, 15}, { 1, 34}, { 7, 38}, { 1, 34}, + { 4, 15}, { 1, 34}, { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 6, 4}, { 1, 18}, + { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, { 6, 33}, + { 23, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 114 */ + { 6, 27}, { 18, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 2, 30}, { 7, 38}, + { 2, 30}, { 8, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 28}, { 1, 49}, + { 7, 4}, { 1, 21}, { 1, 19}, { 3, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, + { 1, 45}, { 6, 33}, { 1, 7}, { 22, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 25}, { 1, 81}, /* Row 115 */ + { 6, 27}, { 18, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, + { 1, 30}, { 7, 38}, { 1, 30}, { 1, 34}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, + { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 8, 4}, { 1, 18}, { 3, 15}, { 1, 30}, + { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, { 6, 33}, { 22, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 77}, { 1, 100}, /* Row 116 */ + { 6, 27}, { 19, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 7, 38}, { 1, 69}, { 7, 38}, + { 1, 69}, { 8, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 28}, { 1, 49}, + { 9, 4}, { 1, 21}, { 1, 19}, { 3, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, + { 1, 45}, { 6, 33}, { 1, 7}, { 21, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 101}, /* Row 117 */ + { 1, 57}, { 5, 27}, { 19, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, + { 1, 68}, { 7, 38}, { 1, 68}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 34}, { 1, 35}, + { 6, 27}, { 1, 29}, { 1, 3}, { 10, 4}, { 1, 18}, { 3, 15}, { 1, 30}, { 7, 38}, + { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, { 6, 33}, { 21, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 118 */ + { 1, 53}, { 1, 57}, { 4, 27}, { 1, 8}, { 1, 3}, { 18, 4}, { 1, 18}, { 4, 15}, + { 1, 30}, { 22, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 28}, { 1, 49}, + { 11, 4}, { 1, 21}, { 1, 19}, { 3, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, + { 1, 45}, { 6, 33}, { 1, 7}, { 20, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 119 */ + { 1, 33}, { 1, 53}, { 1, 57}, { 3, 27}, { 1, 36}, { 1, 8}, { 1, 3}, { 17, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 20, 38}, { 1, 34}, { 4, 15}, { 1, 34}, + { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 12, 4}, { 1, 18}, { 3, 15}, { 1, 30}, + { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, { 6, 33}, { 20, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 120 */ + { 2, 33}, { 1, 53}, { 1, 57}, { 2, 27}, { 1, 49}, { 1, 13}, { 1, 8}, { 1, 3}, + { 17, 4}, { 1, 18}, { 4, 15}, { 1, 30}, { 20, 38}, { 1, 30}, { 4, 15}, { 1, 43}, + { 6, 27}, { 1, 28}, { 1, 49}, { 12, 4}, { 1, 3}, { 1, 79}, { 1, 63}, { 3, 15}, + { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 45}, { 6, 33}, { 1, 7}, { 19, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 121 */ + { 3, 33}, { 1, 53}, { 1, 57}, { 1, 27}, { 2, 4}, { 1, 13}, { 1, 8}, { 1, 3}, + { 16, 4}, { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 18, 38}, { 1, 34}, { 4, 15}, + { 1, 34}, { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 11, 4}, { 1, 3}, { 1, 8}, + { 1, 7}, { 1, 102}, { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, + { 1, 40}, { 6, 33}, { 19, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 122 */ + { 4, 33}, { 1, 53}, { 1, 62}, { 3, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 16, 4}, + { 1, 18}, { 4, 15}, { 1, 30}, { 18, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, + { 1, 28}, { 1, 49}, { 11, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 79}, + { 1, 19}, { 3, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 45}, { 6, 33}, + { 1, 7}, { 18, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 123 */ + { 5, 33}, { 1, 103}, { 1, 3}, { 3, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 15, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 16, 38}, { 1, 34}, { 4, 15}, { 1, 34}, + { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 10, 4}, { 1, 3}, { 1, 8}, { 1, 7}, + { 1, 11}, { 1, 7}, { 1, 4}, { 1, 53}, { 3, 15}, { 1, 30}, { 7, 38}, { 1, 34}, + { 4, 15}, { 1, 31}, { 1, 40}, { 6, 33}, { 18, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 124 */ + { 6, 33}, { 1, 95}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 15, 4}, { 1, 18}, + { 4, 15}, { 1, 30}, { 16, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, { 1, 28}, + { 1, 49}, { 10, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, + { 1, 5}, { 1, 27}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, { 1, 45}, + { 6, 33}, { 1, 7}, { 17, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 125 */ + { 6, 33}, { 1, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 14, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 14, 38}, { 1, 34}, { 4, 15}, { 1, 34}, + { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 9, 4}, { 1, 3}, { 1, 8}, { 1, 7}, + { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 2, 0}, { 1, 14}, { 3, 15}, { 1, 30}, + { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, { 6, 33}, { 17, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 126 */ + { 6, 33}, { 2, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 14, 4}, + { 1, 18}, { 4, 15}, { 1, 30}, { 14, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, + { 1, 28}, { 1, 49}, { 9, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, + { 1, 4}, { 1, 5}, { 4, 0}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, + { 1, 45}, { 6, 33}, { 1, 7}, { 16, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 127 */ + { 6, 33}, { 3, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 13, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 12, 38}, { 1, 34}, { 4, 15}, { 1, 34}, + { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 8, 4}, { 1, 3}, { 1, 8}, { 1, 7}, + { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 5, 0}, { 1, 14}, { 3, 15}, { 1, 30}, + { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, { 6, 33}, { 16, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 128 */ + { 6, 33}, { 4, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 13, 4}, + { 1, 18}, { 4, 15}, { 1, 30}, { 12, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, + { 1, 28}, { 1, 49}, { 8, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, + { 1, 4}, { 1, 5}, { 7, 0}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, + { 1, 45}, { 6, 33}, { 1, 7}, { 15, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 129 */ + { 6, 33}, { 5, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 12, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 10, 38}, { 1, 34}, { 4, 15}, { 1, 34}, + { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 7, 4}, { 1, 3}, { 1, 8}, { 1, 7}, + { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 8, 0}, { 1, 14}, { 3, 15}, { 1, 30}, + { 7, 38}, { 1, 34}, { 4, 15}, { 1, 31}, { 1, 40}, { 6, 33}, { 15, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 130 */ + { 6, 33}, { 6, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 12, 4}, + { 1, 18}, { 4, 15}, { 1, 30}, { 10, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, + { 1, 28}, { 1, 49}, { 7, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, + { 1, 4}, { 1, 5}, { 10, 0}, { 4, 15}, { 1, 34}, { 7, 38}, { 1, 30}, { 4, 15}, + { 1, 22}, { 6, 33}, { 1, 104}, { 14, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 131 */ + { 6, 33}, { 7, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 11, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 8, 38}, { 1, 34}, { 4, 15}, { 1, 34}, + { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 6, 4}, { 1, 3}, { 1, 8}, { 1, 7}, + { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 11, 0}, { 1, 14}, { 3, 15}, { 1, 30}, + { 7, 38}, { 1, 44}, { 4, 15}, { 1, 45}, { 6, 33}, { 1, 65}, { 14, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 132 */ + { 6, 33}, { 8, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 11, 4}, + { 1, 18}, { 4, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 4, 15}, { 1, 43}, { 6, 27}, + { 1, 28}, { 1, 49}, { 6, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, + { 1, 4}, { 1, 5}, { 13, 0}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, { 4, 15}, + { 1, 45}, { 7, 33}, { 14, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 133 */ + { 6, 33}, { 9, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 10, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 34}, { 6, 38}, { 1, 34}, { 4, 15}, { 1, 34}, + { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 5, 4}, { 1, 3}, { 1, 8}, { 1, 7}, + { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 14, 0}, { 1, 14}, { 3, 15}, { 1, 30}, + { 6, 38}, { 1, 44}, { 3, 15}, { 1, 55}, { 1, 105}, { 7, 33}, { 1, 104}, { 13, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 134 */ + { 6, 33}, { 10, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 10, 4}, + { 1, 18}, { 4, 15}, { 1, 30}, { 1, 106}, { 4, 38}, { 1, 106}, { 1, 30}, { 4, 15}, + { 1, 43}, { 6, 27}, { 1, 28}, { 1, 49}, { 5, 4}, { 1, 3}, { 1, 8}, { 1, 7}, + { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 16, 0}, { 4, 15}, { 1, 34}, { 5, 38}, + { 1, 30}, { 3, 15}, { 1, 31}, { 1, 60}, { 7, 33}, { 1, 7}, { 13, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 135 */ + { 6, 33}, { 11, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 9, 4}, + { 1, 21}, { 1, 19}, { 4, 15}, { 1, 30}, { 1, 34}, { 2, 38}, { 1, 34}, { 1, 30}, + { 4, 15}, { 1, 34}, { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, { 4, 4}, { 1, 3}, + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 17, 0}, { 1, 14}, + { 3, 15}, { 1, 30}, { 1, 34}, { 2, 38}, { 1, 34}, { 1, 30}, { 4, 15}, { 1, 45}, + { 8, 33}, { 1, 7}, { 13, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 136 */ + { 6, 33}, { 12, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 9, 4}, + { 1, 18}, { 6, 15}, { 2, 30}, { 6, 15}, { 1, 43}, { 6, 27}, { 1, 28}, { 1, 49}, + { 4, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, + { 19, 0}, { 5, 15}, { 2, 30}, { 5, 15}, { 1, 31}, { 1, 40}, { 8, 33}, { 1, 50}, + { 13, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 137 */ + { 6, 33}, { 13, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 8, 4}, + { 1, 21}, { 1, 19}, { 12, 15}, { 1, 34}, { 1, 35}, { 6, 27}, { 1, 29}, { 1, 3}, + { 3, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, + { 20, 0}, { 1, 14}, { 10, 15}, { 1, 39}, { 1, 107}, { 9, 33}, { 14, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 30}, { 2, 15}, { 1, 96}, { 1, 60}, /* Row 138 */ + { 6, 33}, { 14, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 8, 4}, + { 1, 18}, { 12, 15}, { 1, 43}, { 6, 27}, { 1, 28}, { 1, 49}, { 3, 4}, { 1, 3}, + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 22, 0}, { 9, 15}, + { 1, 39}, { 1, 107}, { 9, 33}, { 1, 7}, { 14, 0}, + { 18, 0}, { 3, 15}, { 1, 30}, { 8, 38}, { 1, 55}, { 2, 96}, { 1, 108}, { 1, 60}, /* Row 139 */ + { 6, 33}, { 15, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 7, 4}, + { 1, 16}, { 1, 23}, { 10, 15}, { 1, 109}, { 1, 81}, { 6, 27}, { 1, 29}, { 1, 3}, + { 2, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, + { 23, 0}, { 1, 28}, { 1, 110}, { 5, 15}, { 1, 39}, { 1, 111}, { 1, 105}, { 10, 33}, + { 15, 0}, + { 25, 0}, { 1, 59}, { 4, 40}, { 4, 60}, { 7, 33}, { 16, 0}, { 1, 5}, { 4, 4}, /* Row 140 */ + { 1, 13}, { 1, 8}, { 1, 3}, { 7, 4}, { 1, 16}, { 1, 18}, { 1, 19}, { 6, 15}, + { 1, 34}, { 1, 43}, { 1, 81}, { 6, 27}, { 1, 28}, { 1, 49}, { 2, 4}, { 1, 3}, + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 27, 0}, { 1, 112}, + { 1, 14}, { 1, 113}, { 1, 22}, { 1, 40}, { 1, 76}, { 10, 33}, { 1, 7}, { 15, 0}, + { 25, 0}, { 16, 33}, { 17, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, /* Row 141 */ + { 8, 4}, { 1, 21}, { 1, 18}, { 1, 19}, { 1, 77}, { 1, 25}, { 1, 34}, { 1, 43}, + { 1, 35}, { 8, 27}, { 1, 8}, { 1, 3}, { 1, 4}, { 1, 3}, { 1, 8}, { 1, 7}, + { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 30, 0}, { 1, 50}, { 13, 33}, { 16, 0}, + { 25, 0}, { 16, 33}, { 18, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, /* Row 142 */ + { 9, 4}, { 1, 16}, { 1, 10}, { 1, 66}, { 1, 81}, { 8, 27}, { 1, 36}, { 1, 8}, + { 1, 3}, { 1, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, + { 1, 5}, { 32, 0}, { 1, 7}, { 11, 33}, { 17, 0}, + { 25, 0}, { 16, 33}, { 19, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, /* Row 143 */ + { 9, 4}, { 1, 3}, { 1, 49}, { 1, 29}, { 1, 28}, { 5, 27}, { 1, 36}, { 1, 8}, + { 3, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, + { 34, 0}, { 10, 33}, { 18, 0}, + { 25, 0}, { 16, 33}, { 20, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, /* Row 144 */ + { 10, 4}, { 1, 3}, { 10, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, + { 1, 4}, { 1, 5}, { 35, 0}, { 1, 41}, { 7, 33}, { 1, 7}, { 19, 0}, + { 25, 0}, { 16, 33}, { 21, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, /* Row 145 */ + { 19, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, + { 64, 0}, + { 25, 0}, { 16, 33}, { 22, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, /* Row 146 */ + { 17, 4}, { 1, 3}, { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, + { 65, 0}, + { 64, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 15, 4}, { 1, 3}, /* Row 147 */ + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 66, 0}, + { 65, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 13, 4}, { 1, 3}, /* Row 148 */ + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 67, 0}, + { 66, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 11, 4}, { 1, 3}, /* Row 149 */ + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 68, 0}, + { 67, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 9, 4}, { 1, 3}, /* Row 150 */ + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 69, 0}, + { 68, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 7, 4}, { 1, 3}, /* Row 151 */ + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 70, 0}, + { 69, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 5, 4}, { 1, 3}, /* Row 152 */ + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 71, 0}, + { 70, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 3, 4}, { 1, 3}, /* Row 153 */ + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 72, 0}, + { 71, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 1, 4}, { 1, 3}, /* Row 154 */ + { 1, 8}, { 1, 7}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 73, 0}, + { 72, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 8}, { 1, 3}, { 1, 8}, { 1, 7}, /* Row 155 */ + { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, { 74, 0}, + { 73, 0}, { 1, 5}, { 4, 4}, { 1, 13}, { 1, 91}, { 1, 7}, { 1, 11}, { 1, 7}, /* Row 156 */ + { 1, 4}, { 1, 5}, { 75, 0}, + { 74, 0}, { 1, 5}, { 4, 4}, { 1, 114}, { 1, 11}, { 1, 7}, { 1, 4}, { 1, 5}, /* Row 157 */ + { 76, 0}, + { 75, 0}, { 1, 5}, { 2, 4}, { 1, 8}, { 1, 115}, { 1, 7}, { 1, 4}, { 1, 5}, /* Row 158 */ + { 77, 0}, + { 76, 0}, { 1, 5}, { 4, 4}, { 1, 5}, { 78, 0} /* Row 159 */ + +# else /* CONFIG_NXWIDGETS_GREYSCALE */ + +static const struct SRlePaletteBitmapEntry g_nuttxRleEntries[] = +{ + { 76, 0}, { 1, 1}, { 1, 2}, { 5, 3}, { 1, 4}, { 76, 0}, /* Row 0 */ + { 75, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 6, 3}, { 1, 4}, { 75, 0}, /* Row 1 */ + { 74, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 2, 6}, { 4, 3}, { 1, 4}, /* Row 2 */ + { 74, 0}, + { 73, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 8}, /* Row 3 */ + { 1, 6}, { 4, 3}, { 1, 4}, { 73, 0}, + { 72, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 4 */ + { 2, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 72, 0}, + { 71, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 5 */ + { 4, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 71, 0}, + { 70, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 6 */ + { 6, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 70, 0}, + { 69, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 7 */ + { 8, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 69, 0}, + { 68, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 8 */ + { 10, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 68, 0}, + { 67, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 9 */ + { 12, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 67, 0}, + { 66, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 10 */ + { 14, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 66, 0}, + { 65, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 11 */ + { 16, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 65, 0}, + { 64, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 12 */ + { 18, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 64, 0}, + { 63, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 13 */ + { 20, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 63, 0}, + { 62, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 14 */ + { 22, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 62, 0}, + { 61, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 15 */ + { 24, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 61, 0}, + { 60, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 16 */ + { 26, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 60, 0}, + { 59, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 17 */ + { 28, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 59, 0}, + { 58, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 18 */ + { 30, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 26, 0}, { 1, 9}, { 5, 10}, { 1, 9}, + { 25, 0}, + { 57, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 19 */ + { 10, 3}, { 5, 5}, { 17, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 23, 0}, { 1, 1}, + { 9, 10}, { 1, 1}, { 23, 0}, + { 56, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 20 */ + { 9, 3}, { 1, 5}, { 1, 11}, { 5, 12}, { 1, 11}, { 1, 13}, { 16, 3}, { 1, 6}, + { 4, 3}, { 1, 4}, { 22, 0}, { 11, 10}, { 1, 1}, { 22, 0}, + { 23, 0}, { 1, 9}, { 5, 10}, { 1, 14}, { 25, 0}, { 1, 1}, { 1, 2}, { 1, 5}, /* Row 21 */ + { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 9, 3}, { 1, 5}, { 1, 15}, { 7, 10}, + { 1, 12}, { 1, 16}, { 16, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 20, 0}, { 1, 9}, + { 12, 10}, { 1, 1}, { 21, 0}, + { 21, 0}, { 1, 1}, { 9, 10}, { 1, 1}, { 22, 0}, { 1, 1}, { 1, 2}, { 1, 5}, /* Row 22 */ + { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 9, 3}, { 1, 5}, { 1, 15}, { 9, 10}, + { 1, 12}, { 1, 16}, { 16, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 19, 0}, { 14, 10}, + { 21, 0}, + { 21, 0}, { 11, 10}, { 1, 1}, { 20, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, /* Row 23 */ + { 1, 7}, { 1, 2}, { 1, 5}, { 10, 3}, { 1, 11}, { 11, 10}, { 1, 12}, { 1, 7}, + { 3, 6}, { 1, 5}, { 12, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 17, 0}, { 1, 9}, + { 6, 10}, { 2, 12}, { 6, 10}, { 1, 9}, { 20, 0}, + { 20, 0}, { 1, 14}, { 12, 10}, { 1, 9}, { 4, 2}, { 1, 17}, { 13, 0}, { 1, 1}, /* Row 24 */ + { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 10, 3}, { 1, 13}, + { 1, 12}, { 12, 10}, { 1, 12}, { 5, 6}, { 12, 3}, { 1, 6}, { 4, 3}, { 1, 4}, + { 16, 0}, { 5, 10}, { 6, 12}, { 4, 10}, { 1, 12}, { 1, 18}, { 1, 1}, { 18, 0}, + { 19, 0}, { 1, 9}, { 13, 10}, { 1, 12}, { 1, 18}, { 5, 2}, { 11, 0}, { 1, 1}, /* Row 25 */ + { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 11, 3}, { 1, 19}, + { 4, 10}, { 5, 12}, { 5, 10}, { 1, 11}, { 5, 6}, { 12, 3}, { 1, 6}, { 4, 3}, + { 1, 4}, { 14, 0}, { 1, 9}, { 5, 10}, { 6, 12}, { 5, 10}, { 1, 14}, { 1, 2}, + { 1, 1}, { 17, 0}, + { 19, 0}, { 6, 10}, { 3, 12}, { 6, 10}, { 1, 14}, { 5, 2}, { 1, 17}, { 9, 0}, /* Row 26 */ + { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 11, 3}, + { 1, 5}, { 1, 14}, { 4, 10}, { 6, 12}, { 4, 10}, { 1, 12}, { 6, 6}, { 12, 3}, + { 1, 6}, { 4, 3}, { 1, 4}, { 13, 0}, { 5, 10}, { 8, 12}, { 4, 10}, { 1, 14}, + { 2, 2}, { 1, 1}, { 16, 0}, + { 18, 0}, { 1, 9}, { 4, 10}, { 6, 12}, { 5, 10}, { 1, 12}, { 1, 18}, { 5, 2}, /* Row 27 */ + { 8, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, + { 12, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 5, 10}, { 1, 11}, { 5, 6}, + { 1, 5}, { 12, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 11, 0}, { 1, 9}, { 5, 10}, + { 8, 12}, { 4, 10}, { 1, 14}, { 3, 2}, { 16, 0}, + { 18, 0}, { 5, 10}, { 6, 12}, { 6, 10}, { 1, 14}, { 5, 2}, { 1, 17}, { 6, 0}, /* Row 28 */ + { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 13, 3}, + { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 6, 6}, { 13, 3}, + { 1, 6}, { 4, 3}, { 1, 4}, { 10, 0}, { 5, 10}, { 8, 12}, { 5, 10}, { 1, 14}, + { 3, 2}, { 1, 17}, { 15, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 1, 18}, { 5, 2}, { 5, 0}, /* Row 29 */ + { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 14, 3}, + { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 5, 6}, { 1, 5}, + { 13, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 8, 0}, { 1, 9}, { 5, 10}, { 8, 12}, + { 4, 10}, { 1, 12}, { 1, 18}, { 4, 2}, { 15, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 6, 10}, { 1, 14}, { 5, 2}, { 1, 17}, { 3, 0}, /* Row 30 */ + { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 15, 3}, + { 1, 5}, { 1, 12}, { 3, 10}, { 9, 12}, { 4, 10}, { 1, 12}, { 6, 6}, { 14, 3}, + { 1, 6}, { 4, 3}, { 1, 4}, { 7, 0}, { 5, 10}, { 8, 12}, { 5, 10}, { 1, 14}, + { 5, 2}, { 1, 1}, { 14, 0}, + { 18, 0}, { 4, 10}, { 9, 12}, { 5, 10}, { 1, 12}, { 1, 18}, { 5, 2}, { 2, 0}, /* Row 31 */ + { 1, 1}, { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 16, 3}, + { 1, 5}, { 1, 12}, { 3, 10}, { 9, 12}, { 5, 10}, { 1, 11}, { 5, 6}, { 1, 5}, + { 14, 3}, { 1, 6}, { 4, 3}, { 1, 4}, { 5, 0}, { 1, 9}, { 5, 10}, { 8, 12}, + { 4, 10}, { 1, 12}, { 1, 18}, { 5, 2}, { 1, 17}, { 14, 0}, + { 18, 0}, { 4, 10}, { 9, 12}, { 6, 10}, { 1, 14}, { 5, 2}, { 1, 17}, { 1, 1}, /* Row 32 */ + { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 17, 3}, { 1, 5}, + { 1, 12}, { 3, 10}, { 10, 12}, { 4, 10}, { 1, 12}, { 6, 6}, { 15, 3}, { 1, 6}, + { 4, 3}, { 1, 4}, { 4, 0}, { 5, 10}, { 8, 12}, { 5, 10}, { 1, 14}, { 6, 2}, + { 1, 1}, { 14, 0}, + { 18, 0}, { 4, 10}, { 10, 12}, { 5, 10}, { 1, 12}, { 1, 18}, { 4, 2}, { 1, 18}, /* Row 33 */ + { 1, 2}, { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 18, 3}, { 1, 5}, + { 1, 12}, { 3, 10}, { 10, 12}, { 5, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 15, 3}, + { 1, 6}, { 4, 3}, { 1, 4}, { 2, 0}, { 1, 9}, { 5, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 1, 18}, { 6, 2}, { 15, 0}, + { 18, 0}, { 4, 10}, { 10, 12}, { 6, 10}, { 1, 14}, { 3, 2}, { 1, 20}, { 1, 6}, /* Row 34 */ + { 1, 5}, { 2, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 19, 3}, { 1, 5}, { 1, 12}, + { 3, 10}, { 11, 12}, { 4, 10}, { 1, 12}, { 6, 6}, { 16, 3}, { 1, 6}, { 4, 3}, + { 1, 4}, { 1, 0}, { 5, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 7, 2}, { 1, 17}, + { 15, 0}, + { 18, 0}, { 4, 10}, { 11, 12}, { 5, 10}, { 1, 12}, { 1, 18}, { 1, 2}, { 1, 20}, /* Row 35 */ + { 3, 6}, { 1, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 20, 3}, { 1, 5}, { 1, 12}, + { 3, 10}, { 11, 12}, { 5, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 16, 3}, { 1, 6}, + { 4, 3}, { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 7, 2}, { 16, 0}, + { 18, 0}, { 4, 10}, { 11, 12}, { 6, 10}, { 1, 14}, { 1, 20}, { 5, 6}, { 1, 2}, /* Row 36 */ + { 1, 5}, { 21, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 12, 12}, { 4, 10}, { 1, 12}, + { 6, 6}, { 17, 3}, { 1, 6}, { 2, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, + { 5, 10}, { 1, 14}, { 6, 2}, { 1, 17}, { 16, 0}, + { 18, 0}, { 4, 10}, { 12, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 1, 5}, { 22, 3}, /* Row 37 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 12, 12}, { 5, 10}, { 1, 11}, { 5, 6}, { 1, 5}, + { 17, 3}, { 1, 6}, { 1, 3}, { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, { 1, 12}, + { 1, 18}, { 6, 2}, { 17, 0}, + { 18, 0}, { 4, 10}, { 12, 12}, { 6, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 22, 3}, /* Row 38 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 13, 12}, { 4, 10}, { 1, 12}, { 6, 6}, { 18, 3}, + { 1, 6}, { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 14}, { 6, 2}, { 1, 17}, + { 17, 0}, + { 18, 0}, { 4, 10}, { 13, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 22, 3}, { 1, 5}, /* Row 39 */ + { 1, 12}, { 3, 10}, { 13, 12}, { 5, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 17, 3}, + { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 1, 18}, { 6, 2}, { 18, 0}, + { 18, 0}, { 4, 10}, { 13, 12}, { 6, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 21, 3}, /* Row 40 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 14, 12}, { 4, 10}, { 1, 12}, { 6, 6}, { 16, 3}, + { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 14}, { 6, 2}, { 1, 17}, + { 18, 0}, + { 18, 0}, { 4, 10}, { 14, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 21, 3}, { 1, 5}, /* Row 41 */ + { 1, 12}, { 3, 10}, { 14, 12}, { 5, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 15, 3}, + { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 1, 18}, { 6, 2}, { 19, 0}, + { 18, 0}, { 4, 10}, { 14, 12}, { 6, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 20, 3}, /* Row 42 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 15, 12}, { 4, 10}, { 1, 12}, { 6, 6}, { 14, 3}, + { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 14}, { 6, 2}, { 1, 17}, + { 19, 0}, + { 18, 0}, { 4, 10}, { 15, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 20, 3}, { 1, 5}, /* Row 43 */ + { 1, 12}, { 3, 10}, { 15, 12}, { 5, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 13, 3}, + { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 1, 18}, { 6, 2}, { 20, 0}, + { 18, 0}, { 4, 10}, { 15, 12}, { 6, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 19, 3}, /* Row 44 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 1, 10}, { 8, 12}, { 4, 10}, { 1, 12}, + { 6, 6}, { 12, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 14}, + { 6, 2}, { 1, 17}, { 20, 0}, + { 18, 0}, { 4, 10}, { 16, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 19, 3}, { 1, 5}, /* Row 45 */ + { 1, 12}, { 3, 10}, { 7, 12}, { 1, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 5, 6}, + { 1, 5}, { 11, 3}, { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 1, 18}, + { 6, 2}, { 21, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 1, 10}, { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, /* Row 46 */ + { 1, 5}, { 18, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 2, 10}, { 8, 12}, + { 4, 10}, { 1, 12}, { 6, 6}, { 10, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, + { 5, 10}, { 1, 14}, { 6, 2}, { 1, 17}, { 21, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 1, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, /* Row 47 */ + { 18, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 2, 10}, { 8, 12}, { 5, 10}, + { 1, 11}, { 5, 6}, { 1, 5}, { 9, 3}, { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 1, 18}, { 6, 2}, { 22, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 2, 10}, { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, /* Row 48 */ + { 1, 5}, { 17, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 8, 12}, + { 4, 10}, { 1, 12}, { 6, 6}, { 8, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, + { 5, 10}, { 1, 14}, { 6, 2}, { 1, 17}, { 22, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 2, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, /* Row 49 */ + { 17, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 8, 12}, { 5, 10}, + { 1, 11}, { 5, 6}, { 1, 5}, { 7, 3}, { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 1, 21}, { 1, 20}, { 5, 2}, { 23, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, /* Row 50 */ + { 1, 5}, { 16, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 4, 10}, { 8, 12}, + { 4, 10}, { 1, 12}, { 6, 6}, { 6, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, + { 5, 10}, { 1, 11}, { 2, 6}, { 1, 20}, { 3, 2}, { 1, 17}, { 23, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, /* Row 51 */ + { 16, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 4, 10}, { 8, 12}, { 5, 10}, + { 1, 11}, { 5, 6}, { 1, 5}, { 5, 3}, { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 4, 6}, { 1, 20}, { 2, 2}, { 24, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 4, 10}, { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, /* Row 52 */ + { 1, 5}, { 15, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 5, 10}, { 8, 12}, + { 4, 10}, { 1, 12}, { 6, 6}, { 4, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, + { 5, 10}, { 1, 11}, { 5, 6}, { 1, 20}, { 1, 17}, { 24, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, /* Row 53 */ + { 15, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 5, 10}, { 8, 12}, { 5, 10}, + { 1, 11}, { 5, 6}, { 1, 5}, { 3, 3}, { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 25, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 5, 10}, { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, /* Row 54 */ + { 1, 5}, { 14, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 6, 10}, { 8, 12}, + { 4, 10}, { 1, 12}, { 6, 6}, { 2, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, + { 5, 10}, { 1, 11}, { 7, 6}, { 1, 3}, { 1, 4}, { 23, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 5, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, /* Row 55 */ + { 14, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 6, 10}, { 8, 12}, { 5, 10}, + { 1, 11}, { 5, 6}, { 1, 5}, { 1, 3}, { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 3, 3}, { 1, 4}, { 22, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 6, 10}, { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, /* Row 56 */ + { 1, 5}, { 13, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 7, 10}, { 8, 12}, + { 4, 10}, { 1, 12}, { 6, 6}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, + { 1, 11}, { 8, 6}, { 3, 3}, { 1, 4}, { 21, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 6, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, /* Row 57 */ + { 13, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 7, 10}, { 8, 12}, { 5, 10}, + { 1, 11}, { 5, 6}, { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 7, 6}, + { 2, 3}, { 1, 6}, { 3, 3}, { 1, 4}, { 20, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 7, 10}, { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, /* Row 58 */ + { 1, 5}, { 12, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 8, 10}, { 8, 12}, + { 4, 10}, { 1, 12}, { 5, 6}, { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 6, 6}, { 1, 5}, { 3, 3}, { 1, 6}, { 3, 3}, { 1, 4}, { 19, 0}, + { 17, 0}, { 1, 22}, { 1, 12}, { 3, 10}, { 8, 12}, { 7, 10}, { 8, 12}, { 5, 10}, /* Row 59 */ + { 1, 12}, { 6, 6}, { 12, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 8, 10}, + { 8, 12}, { 5, 10}, { 1, 11}, { 3, 6}, { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 5, 3}, { 1, 6}, { 3, 3}, { 1, 4}, { 18, 0}, + { 16, 0}, { 1, 1}, { 1, 18}, { 1, 12}, { 3, 10}, { 8, 12}, { 8, 10}, { 7, 12}, /* Row 60 */ + { 6, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 11, 3}, { 1, 5}, { 1, 12}, { 3, 10}, + { 7, 12}, { 4, 10}, { 1, 12}, { 4, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 3, 6}, + { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 1, 5}, { 6, 3}, + { 1, 6}, { 3, 3}, { 1, 4}, { 17, 0}, + { 15, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 8, 10}, /* Row 61 */ + { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 11, 3}, { 1, 5}, { 1, 12}, { 3, 10}, + { 7, 12}, { 3, 10}, { 1, 12}, { 1, 11}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 1, 6}, { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 7, 6}, { 8, 3}, + { 1, 6}, { 3, 3}, { 1, 4}, { 16, 0}, + { 14, 0}, { 1, 1}, { 1, 2}, { 2, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 9, 10}, /* Row 62 */ + { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 10, 3}, { 1, 5}, { 1, 12}, + { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 1, 21}, { 1, 12}, { 4, 10}, { 8, 12}, + { 4, 10}, { 1, 12}, { 1, 23}, { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 6, 6}, { 1, 5}, { 9, 3}, { 1, 6}, { 3, 3}, { 1, 4}, { 15, 0}, + { 13, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 12}, { 3, 10}, /* Row 63 */ + { 8, 12}, { 4, 10}, { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, + { 10, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 1, 6}, + { 1, 11}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 5, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 11, 3}, { 1, 6}, { 3, 3}, { 1, 4}, { 14, 0}, + { 12, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 24}, { 1, 12}, /* Row 64 */ + { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 1, 11}, { 5, 10}, { 7, 12}, { 6, 10}, + { 1, 11}, { 5, 6}, { 1, 5}, { 9, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, + { 3, 10}, { 1, 12}, { 2, 6}, { 1, 12}, { 4, 10}, { 8, 12}, { 9, 10}, { 8, 12}, + { 5, 10}, { 1, 11}, { 6, 6}, { 1, 5}, { 12, 3}, { 1, 6}, { 3, 3}, { 1, 4}, + { 13, 0}, + { 11, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 1, 3}, /* Row 65 */ + { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 1, 21}, { 1, 12}, { 4, 10}, + { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 9, 3}, { 1, 5}, { 1, 12}, { 3, 10}, + { 7, 12}, { 3, 10}, { 1, 12}, { 2, 6}, { 1, 11}, { 4, 10}, { 8, 12}, { 9, 10}, + { 8, 12}, { 4, 10}, { 1, 12}, { 7, 6}, { 14, 3}, { 1, 6}, { 3, 3}, { 1, 4}, + { 12, 0}, + { 10, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 1, 3}, /* Row 66 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 1, 6}, { 1, 11}, + { 5, 10}, { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 8, 3}, { 1, 5}, + { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 3, 6}, { 1, 12}, { 4, 10}, + { 8, 12}, { 7, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 1, 5}, { 15, 3}, + { 1, 6}, { 3, 3}, { 1, 4}, { 11, 0}, + { 9, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 2, 3}, /* Row 67 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 2, 6}, { 1, 12}, + { 4, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 8, 3}, { 1, 5}, { 1, 12}, + { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 3, 6}, { 1, 11}, { 4, 10}, { 8, 12}, + { 7, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 7, 6}, { 17, 3}, { 1, 6}, { 3, 3}, + { 1, 4}, { 10, 0}, + { 8, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 3, 3}, /* Row 68 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 2, 6}, { 1, 11}, + { 5, 10}, { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 7, 3}, { 1, 5}, + { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 4, 6}, { 1, 12}, { 4, 10}, + { 8, 12}, { 5, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 1, 5}, { 18, 3}, + { 1, 6}, { 3, 3}, { 1, 4}, { 9, 0}, + { 7, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 4, 3}, /* Row 69 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 3, 6}, { 1, 12}, + { 4, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 7, 3}, { 1, 5}, { 1, 12}, + { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 4, 6}, { 1, 11}, { 4, 10}, { 8, 12}, + { 5, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 7, 6}, { 20, 3}, { 1, 6}, { 3, 3}, + { 1, 4}, { 8, 0}, + { 6, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 5, 3}, /* Row 70 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 3, 6}, { 1, 11}, + { 5, 10}, { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 6, 3}, { 1, 5}, + { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 5, 6}, { 1, 12}, { 4, 10}, + { 8, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 1, 5}, { 21, 3}, + { 1, 6}, { 3, 3}, { 1, 4}, { 7, 0}, + { 5, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 6, 3}, /* Row 71 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 4, 6}, { 1, 12}, + { 4, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 6, 3}, { 1, 5}, { 1, 12}, + { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 5, 6}, { 1, 11}, { 4, 10}, { 8, 12}, + { 3, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 7, 6}, { 23, 3}, { 1, 6}, { 3, 3}, + { 1, 4}, { 6, 0}, + { 4, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 7, 3}, /* Row 72 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 4, 6}, { 1, 11}, + { 5, 10}, { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 5, 3}, { 1, 5}, + { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 6, 6}, { 1, 12}, { 4, 10}, + { 8, 12}, { 1, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 1, 5}, { 24, 3}, + { 1, 6}, { 3, 3}, { 1, 4}, { 5, 0}, + { 3, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 8, 3}, /* Row 73 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 5, 6}, { 1, 12}, + { 4, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 5, 3}, { 1, 5}, { 1, 12}, + { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 6, 6}, { 1, 11}, { 4, 10}, { 8, 12}, + { 1, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 7, 6}, { 26, 3}, { 1, 6}, { 3, 3}, + { 1, 4}, { 4, 0}, + { 2, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 9, 3}, /* Row 74 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 5, 6}, { 1, 11}, + { 5, 10}, { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 4, 3}, { 1, 5}, + { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 1, 12}, { 4, 10}, + { 15, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 1, 5}, { 27, 3}, { 1, 6}, { 3, 3}, + { 1, 4}, { 3, 0}, + { 1, 0}, { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 10, 3}, /* Row 75 */ + { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 6, 6}, { 1, 12}, + { 4, 10}, { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 4, 3}, { 1, 5}, { 1, 12}, + { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 1, 11}, { 4, 10}, { 15, 12}, + { 4, 10}, { 1, 12}, { 7, 6}, { 29, 3}, { 1, 6}, { 3, 3}, { 1, 4}, { 2, 0}, + { 1, 1}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 11, 3}, { 1, 5}, /* Row 76 */ + { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 6, 6}, { 1, 11}, { 5, 10}, + { 7, 12}, { 6, 10}, { 1, 11}, { 5, 6}, { 1, 5}, { 3, 3}, { 1, 5}, { 1, 12}, + { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 1, 13}, { 1, 12}, { 4, 10}, + { 13, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 1, 5}, { 30, 3}, { 1, 6}, { 3, 3}, + { 1, 4}, { 1, 0}, + { 1, 2}, { 1, 5}, { 1, 3}, { 1, 6}, { 1, 2}, { 12, 3}, { 1, 5}, { 1, 12}, /* Row 77 */ + { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 1, 12}, { 4, 10}, { 8, 12}, + { 5, 10}, { 1, 12}, { 6, 6}, { 3, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, + { 3, 10}, { 1, 12}, { 7, 6}, { 1, 3}, { 1, 11}, { 4, 10}, { 13, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 32, 3}, { 1, 6}, { 3, 3}, { 1, 4}, + { 2, 3}, { 1, 6}, { 1, 2}, { 13, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, /* Row 78 */ + { 3, 10}, { 1, 12}, { 7, 6}, { 1, 11}, { 5, 10}, { 7, 12}, { 6, 10}, { 1, 11}, + { 5, 6}, { 1, 5}, { 2, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, + { 1, 12}, { 7, 6}, { 1, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 11, 12}, { 5, 10}, + { 1, 11}, { 6, 6}, { 1, 5}, { 33, 3}, { 1, 6}, { 3, 3}, + { 1, 3}, { 1, 5}, { 1, 18}, { 14, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, /* Row 79 */ + { 3, 10}, { 1, 12}, { 7, 6}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, + { 1, 12}, { 6, 6}, { 2, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, + { 1, 12}, { 7, 6}, { 2, 3}, { 1, 11}, { 4, 10}, { 11, 12}, { 4, 10}, { 1, 12}, + { 7, 6}, { 35, 3}, { 1, 6}, { 2, 3}, + { 2, 3}, { 1, 6}, { 14, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, /* Row 80 */ + { 1, 12}, { 7, 6}, { 1, 3}, { 1, 11}, { 5, 10}, { 7, 12}, { 6, 10}, { 1, 11}, + { 5, 6}, { 1, 5}, { 1, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, + { 1, 12}, { 7, 6}, { 2, 3}, { 1, 11}, { 5, 10}, { 10, 12}, { 4, 10}, { 1, 11}, + { 6, 6}, { 1, 5}, { 35, 3}, { 1, 5}, { 1, 6}, { 1, 3}, + { 3, 3}, { 1, 6}, { 13, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, /* Row 81 */ + { 1, 12}, { 7, 6}, { 1, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, + { 1, 12}, { 6, 6}, { 1, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, + { 1, 12}, { 7, 6}, { 1, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 10, 12}, { 4, 10}, + { 1, 12}, { 1, 21}, { 6, 6}, { 36, 3}, { 1, 7}, { 1, 2}, { 1, 5}, + { 4, 3}, { 1, 6}, { 12, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, /* Row 82 */ + { 1, 12}, { 7, 6}, { 2, 3}, { 1, 11}, { 5, 10}, { 7, 12}, { 6, 10}, { 1, 11}, + { 5, 6}, { 2, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 7, 6}, + { 1, 3}, { 1, 11}, { 5, 10}, { 10, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 35, 3}, + { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, + { 1, 4}, { 4, 3}, { 1, 6}, { 11, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, /* Row 83 */ + { 3, 10}, { 1, 12}, { 7, 6}, { 2, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, + { 5, 10}, { 1, 12}, { 6, 6}, { 1, 5}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, + { 1, 12}, { 7, 6}, { 1, 13}, { 1, 12}, { 4, 10}, { 12, 12}, { 4, 10}, { 1, 12}, + { 6, 6}, { 1, 5}, { 33, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, + { 1, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 10, 3}, { 1, 5}, { 1, 12}, { 3, 10}, /* Row 84 */ + { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 3, 3}, { 1, 11}, { 5, 10}, { 7, 12}, + { 6, 10}, { 1, 11}, { 5, 6}, { 1, 13}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, + { 1, 12}, { 7, 6}, { 1, 11}, { 5, 10}, { 12, 12}, { 5, 10}, { 1, 11}, { 6, 6}, + { 32, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 1, 0}, + { 2, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 9, 3}, { 1, 5}, { 1, 12}, { 3, 10}, /* Row 85 */ + { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 3, 3}, { 1, 13}, { 1, 12}, { 4, 10}, + { 8, 12}, { 5, 10}, { 1, 12}, { 6, 6}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, + { 1, 12}, { 7, 6}, { 1, 12}, { 4, 10}, { 14, 12}, { 4, 10}, { 1, 12}, { 6, 6}, + { 1, 5}, { 30, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 2, 0}, + { 3, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 8, 3}, { 1, 5}, { 1, 12}, { 3, 10}, /* Row 86 */ + { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 4, 3}, { 1, 11}, { 5, 10}, { 7, 12}, + { 6, 10}, { 1, 11}, { 5, 6}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, + { 6, 6}, { 1, 11}, { 5, 10}, { 14, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 29, 3}, + { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 3, 0}, + { 4, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 7, 3}, { 1, 5}, { 1, 12}, { 3, 10}, /* Row 87 */ + { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 4, 3}, { 1, 13}, { 1, 12}, { 4, 10}, + { 8, 12}, { 5, 10}, { 1, 12}, { 5, 6}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, + { 1, 12}, { 6, 6}, { 1, 12}, { 4, 10}, { 16, 12}, { 4, 10}, { 1, 12}, { 6, 6}, + { 1, 5}, { 27, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 4, 0}, + { 5, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 6, 3}, { 1, 5}, { 1, 12}, { 3, 10}, /* Row 88 */ + { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 5, 3}, { 1, 11}, { 5, 10}, { 7, 12}, + { 6, 10}, { 1, 11}, { 4, 6}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, + { 5, 6}, { 1, 11}, { 5, 10}, { 16, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 26, 3}, + { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 5, 0}, + { 6, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 5, 3}, { 1, 5}, { 1, 12}, { 3, 10}, /* Row 89 */ + { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 5, 3}, { 1, 13}, { 1, 12}, { 4, 10}, + { 8, 12}, { 5, 10}, { 1, 12}, { 4, 6}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, + { 1, 12}, { 5, 6}, { 1, 12}, { 4, 10}, { 9, 12}, { 1, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 6, 6}, { 1, 5}, { 24, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, + { 1, 4}, { 6, 0}, + { 7, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 4, 3}, { 1, 5}, { 1, 12}, { 3, 10}, /* Row 90 */ + { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 6, 3}, { 1, 11}, { 5, 10}, { 7, 12}, + { 6, 10}, { 1, 11}, { 3, 6}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, + { 4, 6}, { 1, 11}, { 5, 10}, { 8, 12}, { 2, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 6, 6}, { 23, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 7, 0}, + { 8, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 3, 3}, { 1, 5}, { 1, 12}, { 3, 10}, /* Row 91 */ + { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 6, 3}, { 1, 13}, { 1, 12}, { 4, 10}, + { 8, 12}, { 5, 10}, { 1, 12}, { 3, 6}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, + { 1, 12}, { 4, 6}, { 1, 12}, { 4, 10}, { 9, 12}, { 3, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 6, 6}, { 1, 5}, { 21, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, + { 1, 4}, { 8, 0}, + { 9, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 2, 3}, { 1, 5}, { 1, 12}, { 3, 10}, /* Row 92 */ + { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 7, 3}, { 1, 11}, { 5, 10}, { 7, 12}, + { 6, 10}, { 1, 11}, { 2, 6}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, + { 3, 6}, { 1, 11}, { 5, 10}, { 8, 12}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 6, 6}, { 20, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 9, 0}, + { 10, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 1, 3}, { 1, 5}, { 1, 12}, { 3, 10}, /* Row 93 */ + { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 7, 3}, { 1, 13}, { 1, 12}, { 4, 10}, + { 8, 12}, { 5, 10}, { 1, 12}, { 2, 6}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, + { 1, 12}, { 3, 6}, { 1, 12}, { 4, 10}, { 9, 12}, { 5, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 6, 6}, { 1, 5}, { 18, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, + { 1, 4}, { 10, 0}, + { 11, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 1, 13}, { 1, 12}, { 3, 10}, { 8, 12}, /* Row 94 */ + { 3, 10}, { 1, 12}, { 7, 6}, { 8, 3}, { 1, 11}, { 5, 10}, { 7, 12}, { 6, 10}, + { 1, 11}, { 1, 6}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 2, 6}, + { 1, 11}, { 5, 10}, { 8, 12}, { 6, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 6, 6}, + { 17, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 11, 0}, + { 12, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, /* Row 95 */ + { 1, 12}, { 7, 6}, { 8, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, + { 1, 12}, { 1, 21}, { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 2, 6}, + { 1, 12}, { 4, 10}, { 9, 12}, { 7, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 6, 6}, + { 1, 5}, { 15, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 12, 0}, + { 13, 0}, { 1, 4}, { 3, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, /* Row 96 */ + { 1, 12}, { 7, 6}, { 9, 3}, { 1, 11}, { 5, 10}, { 7, 12}, { 6, 10}, { 1, 11}, + { 1, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 1, 6}, { 1, 11}, { 5, 10}, + { 8, 12}, { 8, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 14, 3}, { 1, 7}, + { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 13, 0}, + { 14, 0}, { 1, 4}, { 2, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, /* Row 97 */ + { 1, 12}, { 7, 6}, { 9, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, + { 1, 12}, { 4, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 1, 21}, { 1, 12}, { 4, 10}, + { 9, 12}, { 4, 10}, { 1, 12}, { 4, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 6, 6}, + { 1, 5}, { 12, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 14, 0}, + { 15, 0}, { 1, 4}, { 1, 3}, { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, /* Row 98 */ + { 1, 12}, { 7, 6}, { 10, 3}, { 1, 11}, { 5, 10}, { 7, 12}, { 10, 10}, { 7, 12}, + { 3, 10}, { 1, 12}, { 1, 11}, { 5, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 1, 12}, + { 3, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 11, 3}, { 1, 7}, { 1, 2}, + { 1, 5}, { 1, 3}, { 1, 4}, { 15, 0}, + { 16, 0}, { 1, 4}, { 1, 5}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, /* Row 99 */ + { 7, 6}, { 10, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, { 9, 10}, { 7, 12}, + { 4, 10}, { 1, 12}, { 4, 10}, { 9, 12}, { 4, 10}, { 1, 12}, { 1, 6}, { 1, 11}, + { 4, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 6, 6}, { 1, 5}, { 9, 3}, { 1, 7}, + { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 16, 0}, + { 17, 0}, { 1, 4}, { 1, 12}, { 3, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, /* Row 100 */ + { 11, 3}, { 1, 11}, { 5, 10}, { 7, 12}, { 9, 10}, { 7, 12}, { 9, 10}, { 8, 12}, + { 5, 10}, { 1, 11}, { 2, 6}, { 1, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 6, 6}, { 8, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 17, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 11, 3}, { 1, 13}, /* Row 101 */ + { 1, 12}, { 4, 10}, { 8, 12}, { 8, 10}, { 7, 12}, { 8, 10}, { 9, 12}, { 4, 10}, + { 1, 12}, { 3, 6}, { 1, 11}, { 4, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 6, 6}, + { 1, 5}, { 6, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 18, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 12, 3}, { 1, 11}, /* Row 102 */ + { 5, 10}, { 7, 12}, { 8, 10}, { 7, 12}, { 8, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 4, 6}, { 1, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 5, 3}, + { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 19, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 12, 3}, { 1, 13}, /* Row 103 */ + { 1, 12}, { 4, 10}, { 8, 12}, { 7, 10}, { 7, 12}, { 7, 10}, { 9, 12}, { 4, 10}, + { 1, 12}, { 5, 6}, { 1, 11}, { 4, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 6, 6}, + { 1, 5}, { 3, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 20, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 13, 3}, { 1, 11}, /* Row 104 */ + { 5, 10}, { 7, 12}, { 7, 10}, { 7, 12}, { 7, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 6, 6}, { 1, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 6, 6}, { 2, 3}, + { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 21, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 13, 3}, { 1, 13}, /* Row 105 */ + { 1, 12}, { 4, 10}, { 8, 12}, { 6, 10}, { 7, 12}, { 6, 10}, { 9, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 11}, { 4, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 7, 6}, + { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 22, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 14, 3}, { 1, 11}, /* Row 106 */ + { 5, 10}, { 7, 12}, { 6, 10}, { 7, 12}, { 6, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 1, 13}, { 1, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 11}, { 6, 6}, + { 1, 18}, { 1, 5}, { 1, 3}, { 1, 4}, { 23, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 14, 3}, { 1, 13}, /* Row 107 */ + { 1, 12}, { 4, 10}, { 8, 12}, { 5, 10}, { 7, 12}, { 5, 10}, { 9, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 5}, { 1, 3}, { 1, 11}, { 4, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 3}, { 1, 4}, { 24, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 15, 3}, { 1, 11}, /* Row 108 */ + { 5, 10}, { 7, 12}, { 5, 10}, { 7, 12}, { 5, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 2, 3}, { 1, 13}, { 1, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 5, 6}, { 1, 20}, { 1, 1}, { 25, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 15, 3}, { 1, 13}, /* Row 109 */ + { 1, 12}, { 4, 10}, { 8, 12}, { 4, 10}, { 7, 12}, { 4, 10}, { 9, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 5}, { 3, 3}, { 1, 11}, { 4, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 4, 6}, { 1, 20}, { 2, 2}, { 25, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 16, 3}, { 1, 11}, /* Row 110 */ + { 5, 10}, { 7, 12}, { 4, 10}, { 7, 12}, { 4, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 4, 3}, { 1, 13}, { 1, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 2, 6}, { 1, 20}, { 3, 2}, { 1, 17}, { 24, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 16, 3}, { 1, 13}, /* Row 111 */ + { 1, 12}, { 4, 10}, { 8, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 9, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 5}, { 5, 3}, { 1, 11}, { 4, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 1, 21}, { 1, 20}, { 5, 2}, { 24, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 17, 3}, { 1, 11}, /* Row 112 */ + { 5, 10}, { 7, 12}, { 3, 10}, { 7, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 6, 3}, { 1, 13}, { 1, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 14}, + { 6, 2}, { 1, 17}, { 23, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 17, 3}, { 1, 13}, /* Row 113 */ + { 1, 12}, { 4, 10}, { 8, 12}, { 2, 10}, { 7, 12}, { 2, 10}, { 9, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 5}, { 7, 3}, { 1, 11}, { 4, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 1, 18}, { 6, 2}, { 23, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 18, 3}, { 1, 11}, /* Row 114 */ + { 5, 10}, { 7, 12}, { 2, 10}, { 7, 12}, { 2, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 8, 3}, { 1, 13}, { 1, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 14}, + { 6, 2}, { 1, 17}, { 22, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 18, 3}, { 1, 13}, /* Row 115 */ + { 1, 12}, { 4, 10}, { 8, 12}, { 1, 10}, { 7, 12}, { 1, 10}, { 9, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 5}, { 9, 3}, { 1, 11}, { 4, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 1, 18}, { 6, 2}, { 22, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 6}, { 19, 3}, { 1, 11}, /* Row 116 */ + { 5, 10}, { 7, 12}, { 1, 10}, { 7, 12}, { 1, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 10, 3}, { 1, 13}, { 1, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 14}, + { 6, 2}, { 1, 17}, { 21, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 1, 18}, { 6, 6}, { 19, 3}, /* Row 117 */ + { 1, 13}, { 1, 12}, { 4, 10}, { 24, 12}, { 4, 10}, { 1, 12}, { 7, 6}, { 1, 5}, + { 11, 3}, { 1, 11}, { 4, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 1, 18}, { 6, 2}, + { 21, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 1, 2}, { 1, 20}, { 5, 6}, /* Row 118 */ + { 20, 3}, { 1, 11}, { 5, 10}, { 22, 12}, { 5, 10}, { 1, 11}, { 7, 6}, { 12, 3}, + { 1, 13}, { 1, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 14}, { 6, 2}, { 1, 17}, + { 20, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 2, 2}, { 1, 20}, { 5, 6}, /* Row 119 */ + { 19, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 22, 12}, { 4, 10}, { 1, 12}, { 7, 6}, + { 1, 5}, { 13, 3}, { 1, 11}, { 4, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 1, 18}, + { 6, 2}, { 20, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 3, 2}, { 1, 20}, { 3, 6}, /* Row 120 */ + { 1, 3}, { 1, 6}, { 19, 3}, { 1, 11}, { 5, 10}, { 20, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 14, 3}, { 1, 13}, { 1, 12}, { 3, 10}, { 8, 12}, { 5, 10}, { 1, 14}, + { 6, 2}, { 1, 17}, { 19, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 4, 2}, { 1, 20}, { 2, 6}, /* Row 121 */ + { 2, 3}, { 1, 6}, { 18, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 20, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 5}, { 14, 3}, { 1, 7}, { 1, 25}, { 4, 10}, { 8, 12}, + { 4, 10}, { 1, 12}, { 1, 18}, { 6, 2}, { 19, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 5, 2}, { 1, 20}, { 1, 6}, /* Row 122 */ + { 3, 3}, { 1, 6}, { 18, 3}, { 1, 11}, { 5, 10}, { 18, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 14, 3}, { 1, 7}, { 1, 2}, { 1, 13}, { 1, 12}, { 3, 10}, { 8, 12}, + { 5, 10}, { 1, 14}, { 6, 2}, { 1, 17}, { 18, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 6, 2}, { 1, 20}, { 4, 3}, /* Row 123 */ + { 1, 6}, { 17, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 18, 12}, { 4, 10}, { 1, 12}, + { 7, 6}, { 1, 5}, { 13, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 20}, + { 4, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 1, 18}, { 6, 2}, { 18, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 1, 0}, { 4, 3}, /* Row 124 */ + { 1, 6}, { 17, 3}, { 1, 11}, { 5, 10}, { 16, 12}, { 5, 10}, { 1, 11}, { 7, 6}, + { 13, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 1, 17}, { 4, 10}, + { 8, 12}, { 5, 10}, { 1, 14}, { 6, 2}, { 1, 17}, { 17, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 1, 0}, { 1, 4}, /* Row 125 */ + { 4, 3}, { 1, 6}, { 16, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 16, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 5}, { 12, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, + { 1, 4}, { 2, 0}, { 1, 9}, { 4, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 1, 18}, + { 6, 2}, { 17, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 2, 0}, { 1, 4}, /* Row 126 */ + { 4, 3}, { 1, 6}, { 16, 3}, { 1, 11}, { 5, 10}, { 14, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 12, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 4, 0}, + { 4, 10}, { 8, 12}, { 5, 10}, { 1, 14}, { 6, 2}, { 1, 17}, { 16, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 3, 0}, { 1, 4}, /* Row 127 */ + { 4, 3}, { 1, 6}, { 15, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 14, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 5}, { 11, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, + { 1, 4}, { 5, 0}, { 1, 9}, { 4, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 1, 18}, + { 6, 2}, { 16, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 4, 0}, { 1, 4}, /* Row 128 */ + { 4, 3}, { 1, 6}, { 15, 3}, { 1, 11}, { 5, 10}, { 12, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 11, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 7, 0}, + { 4, 10}, { 8, 12}, { 5, 10}, { 1, 14}, { 6, 2}, { 1, 17}, { 15, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 5, 0}, { 1, 4}, /* Row 129 */ + { 4, 3}, { 1, 6}, { 14, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 12, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 5}, { 10, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, + { 1, 4}, { 8, 0}, { 1, 9}, { 4, 10}, { 8, 12}, { 4, 10}, { 1, 12}, { 1, 18}, + { 6, 2}, { 15, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 6, 0}, { 1, 4}, /* Row 130 */ + { 4, 3}, { 1, 6}, { 14, 3}, { 1, 11}, { 5, 10}, { 10, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 10, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 10, 0}, + { 4, 10}, { 8, 12}, { 5, 10}, { 1, 14}, { 6, 2}, { 1, 26}, { 14, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 7, 0}, { 1, 4}, /* Row 131 */ + { 4, 3}, { 1, 6}, { 13, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 10, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 5}, { 9, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, + { 1, 4}, { 11, 0}, { 1, 9}, { 4, 10}, { 8, 12}, { 4, 10}, { 1, 14}, { 6, 2}, + { 1, 17}, { 14, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 8, 0}, { 1, 4}, /* Row 132 */ + { 4, 3}, { 1, 6}, { 13, 3}, { 1, 11}, { 5, 10}, { 8, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 9, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 13, 0}, + { 4, 10}, { 8, 12}, { 4, 10}, { 1, 14}, { 7, 2}, { 14, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 9, 0}, { 1, 4}, /* Row 133 */ + { 4, 3}, { 1, 6}, { 12, 3}, { 1, 13}, { 1, 12}, { 4, 10}, { 8, 12}, { 4, 10}, + { 1, 12}, { 7, 6}, { 1, 5}, { 8, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, + { 1, 4}, { 14, 0}, { 1, 9}, { 4, 10}, { 7, 12}, { 3, 10}, { 1, 12}, { 1, 19}, + { 7, 2}, { 1, 26}, { 13, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 10, 0}, { 1, 4}, /* Row 134 */ + { 4, 3}, { 1, 6}, { 12, 3}, { 1, 11}, { 5, 10}, { 6, 12}, { 5, 10}, { 1, 11}, + { 7, 6}, { 8, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 16, 0}, + { 4, 10}, { 6, 12}, { 4, 10}, { 1, 12}, { 8, 2}, { 1, 17}, { 13, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 11, 0}, { 1, 4}, /* Row 135 */ + { 4, 3}, { 1, 6}, { 11, 3}, { 1, 13}, { 1, 12}, { 5, 10}, { 4, 12}, { 5, 10}, + { 1, 12}, { 7, 6}, { 1, 5}, { 7, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, + { 1, 4}, { 17, 0}, { 1, 9}, { 4, 10}, { 4, 12}, { 5, 10}, { 1, 14}, { 8, 2}, + { 1, 17}, { 13, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 12, 0}, { 1, 4}, /* Row 136 */ + { 4, 3}, { 1, 6}, { 11, 3}, { 1, 11}, { 14, 10}, { 1, 11}, { 7, 6}, { 7, 3}, + { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 19, 0}, { 12, 10}, { 1, 12}, + { 1, 18}, { 8, 2}, { 1, 1}, { 13, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 13, 0}, { 1, 4}, /* Row 137 */ + { 4, 3}, { 1, 6}, { 10, 3}, { 1, 13}, { 1, 12}, { 12, 10}, { 1, 12}, { 7, 6}, + { 1, 5}, { 6, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 20, 0}, + { 1, 9}, { 10, 10}, { 1, 12}, { 10, 2}, { 14, 0}, + { 18, 0}, { 4, 10}, { 8, 12}, { 3, 10}, { 1, 12}, { 7, 2}, { 14, 0}, { 1, 4}, /* Row 138 */ + { 4, 3}, { 1, 6}, { 10, 3}, { 1, 11}, { 12, 10}, { 1, 11}, { 7, 6}, { 6, 3}, + { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 22, 0}, { 9, 10}, { 1, 12}, + { 10, 2}, { 1, 17}, { 14, 0}, + { 18, 0}, { 4, 10}, { 12, 12}, { 7, 2}, { 15, 0}, { 1, 4}, { 4, 3}, { 1, 6}, /* Row 139 */ + { 9, 3}, { 1, 5}, { 1, 15}, { 10, 10}, { 1, 15}, { 7, 6}, { 1, 5}, { 5, 3}, + { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 23, 0}, { 1, 17}, { 1, 14}, + { 5, 10}, { 1, 12}, { 1, 10}, { 1, 19}, { 10, 2}, { 15, 0}, + { 25, 0}, { 1, 20}, { 4, 18}, { 11, 2}, { 16, 0}, { 1, 4}, { 4, 3}, { 1, 6}, /* Row 140 */ + { 9, 3}, { 1, 5}, { 1, 11}, { 1, 12}, { 6, 10}, { 1, 12}, { 1, 11}, { 8, 6}, + { 5, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 27, 0}, { 2, 9}, + { 1, 19}, { 1, 14}, { 1, 18}, { 11, 2}, { 1, 17}, { 15, 0}, + { 25, 0}, { 16, 2}, { 17, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 10, 3}, { 1, 13}, /* Row 141 */ + { 1, 11}, { 4, 12}, { 1, 11}, { 9, 6}, { 5, 3}, { 1, 7}, { 1, 2}, { 1, 5}, + { 1, 3}, { 1, 4}, { 30, 0}, { 1, 1}, { 13, 2}, { 16, 0}, + { 25, 0}, { 16, 2}, { 18, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 11, 3}, { 1, 5}, /* Row 142 */ + { 1, 13}, { 11, 6}, { 5, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, + { 32, 0}, { 1, 17}, { 11, 2}, { 17, 0}, + { 25, 0}, { 16, 2}, { 19, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 13, 3}, { 1, 5}, /* Row 143 */ + { 7, 6}, { 6, 3}, { 1, 7}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 34, 0}, + { 10, 2}, { 18, 0}, + { 25, 0}, { 16, 2}, { 20, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 25, 3}, { 1, 7}, /* Row 144 */ + { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 35, 0}, { 1, 1}, { 7, 2}, { 1, 17}, + { 19, 0}, + { 25, 0}, { 16, 2}, { 21, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 23, 3}, { 1, 7}, /* Row 145 */ + { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 64, 0}, + { 25, 0}, { 16, 2}, { 22, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 21, 3}, { 1, 7}, /* Row 146 */ + { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 65, 0}, + { 64, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 19, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 147 */ + { 1, 3}, { 1, 4}, { 66, 0}, + { 65, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 17, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 148 */ + { 1, 3}, { 1, 4}, { 67, 0}, + { 66, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 15, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 149 */ + { 1, 3}, { 1, 4}, { 68, 0}, + { 67, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 13, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 150 */ + { 1, 3}, { 1, 4}, { 69, 0}, + { 68, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 11, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 151 */ + { 1, 3}, { 1, 4}, { 70, 0}, + { 69, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 9, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 152 */ + { 1, 3}, { 1, 4}, { 71, 0}, + { 70, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 7, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 153 */ + { 1, 3}, { 1, 4}, { 72, 0}, + { 71, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 5, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 154 */ + { 1, 3}, { 1, 4}, { 73, 0}, + { 72, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 3, 3}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 155 */ + { 1, 3}, { 1, 4}, { 74, 0}, + { 73, 0}, { 1, 4}, { 4, 3}, { 1, 6}, { 1, 5}, { 1, 7}, { 1, 2}, { 1, 5}, /* Row 156 */ + { 1, 3}, { 1, 4}, { 75, 0}, + { 74, 0}, { 1, 4}, { 5, 3}, { 1, 2}, { 1, 5}, { 1, 3}, { 1, 4}, { 76, 0}, /* Row 157 */ + { 75, 0}, { 1, 4}, { 2, 3}, { 1, 5}, { 1, 20}, { 1, 5}, { 1, 3}, { 1, 4}, /* Row 158 */ + { 77, 0}, + { 76, 0}, { 1, 4}, { 4, 3}, { 1, 4}, { 78, 0} /* Row 159 */ +}; + +# endif +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SRlePaletteBitmap NXWidgets::g_nuttxBitmap = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + CONFIG_NXWIDGETS_FMT, // fmt - Color format + BITMAP_NLUTCODES, // nlut - Number of colors in the lLook-Up Table (LUT) + 160, // width - Width in pixels + 160, // height - Height in rows + g_nuttxLut, // lut - Pointer to the beginning of the Look-Up Table (LUT) + g_nuttxRleEntries // data - Pointer to the beginning of the RLE data +}; diff --git a/NxWidgets/libnxwidgets/src/glyph_radiobuttonmu.cxx b/NxWidgets/libnxwidgets/src/glyph_radiobuttonmu.cxx new file mode 100644 index 000000000..a9e4d6708 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_radiobuttonmu.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_radiobuttonmu.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_radioButtonMuGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_radioButtonMuGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_radioButtonMu = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 8, // width - Width in pixels + 10, // height - Height in rows + (8*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_radioButtonMuGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_radiobuttonoff.cxx b/NxWidgets/libnxwidgets/src/glyph_radiobuttonoff.cxx new file mode 100644 index 000000000..029b93896 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_radiobuttonoff.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_radiobuttonoff.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_radioButtonOffGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, + RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_TRANSP, RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_radioButtonOffGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, + RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_TRANSP, RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_radioButtonOff = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 8, // width - Width in pixels + 10, // height - Height in rows + (8*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_radioButtonOffGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_radiobuttonon.cxx b/NxWidgets/libnxwidgets/src/glyph_radiobuttonon.cxx new file mode 100644 index 000000000..242f6f373 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_radiobuttonon.cxx @@ -0,0 +1,156 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_radiobuttonon.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 +# define RGB16_COLOR RGBTO16(216,196,96) + +static const uint16_t g_radioButtonOnGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_COLOR, RGB16_COLOR, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, + RGB16_DARKRED, RGB16_TRANSP, RGB16_COLOR, RGB16_COLOR, RGB16_COLOR, RGB16_COLOR, RGB16_TRANSP, RGB16_WHITE, + RGB16_DARKRED, RGB16_TRANSP, RGB16_COLOR, RGB16_COLOR, RGB16_COLOR, RGB16_COLOR, RGB16_TRANSP, RGB16_WHITE, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_COLOR, RGB16_COLOR, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 +# define RGB24_COLOR RGBTO24(216,196,96) + +static const uint32_t g_radioButtonOnGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_COLOR, RGB24_COLOR, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, + RGB24_DARKRED, RGB24_TRANSP, RGB24_COLOR, RGB24_COLOR, RGB24_COLOR, RGB24_COLOR, RGB24_TRANSP, RGB24_WHITE, + RGB24_DARKRED, RGB24_TRANSP, RGB24_COLOR, RGB24_COLOR, RGB24_COLOR, RGB24_COLOR, RGB24_TRANSP, RGB24_WHITE, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_COLOR, RGB24_COLOR, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_radioButtonOn = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 8, // width - Width in pixels + 10, // height - Height in rows + (8*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_radioButtonOnGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_return.cxx b/NxWidgets/libnxwidgets/src/glyph_return.cxx new file mode 100644 index 000000000..47314f65c --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_return.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_return.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_returnGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_returnGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_return = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 7, // width - Width in pixels + 10, // height - Height in rows + (7*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_returnGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_screendepthdown.cxx b/NxWidgets/libnxwidgets/src/glyph_screendepthdown.cxx new file mode 100644 index 000000000..c3f0e15ee --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_screendepthdown.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_screendepthdown.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_screenDepthDownGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, RGB16_WHITE, RGB16_DARKRED, + RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_screenDepthDownGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, RGB24_WHITE, RGB24_DARKRED, + RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_screenDepthDown = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 8, // width - Width in pixels + 10, // height - Height in rows + (8*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_screenDepthDownGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_screendepthup.cxx b/NxWidgets/libnxwidgets/src/glyph_screendepthup.cxx new file mode 100644 index 000000000..e4574a367 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_screendepthup.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_screendepthup.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_screenDepthUpGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_screenDepthUpGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_screenDepthUp = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 8, // width - Width in pixels + 10, // height - Height in rows + (8*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_screenDepthUpGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_screenflipdown.cxx b/NxWidgets/libnxwidgets/src/glyph_screenflipdown.cxx new file mode 100644 index 000000000..253ad6afb --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_screenflipdown.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_screenflipdown.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_screenFlipDownGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_screenFlipDownGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_screenFlipDown = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 7, // width - Width in pixels + 10, // height - Height in rows + (7*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_screenFlipDownGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_screenflipup.cxx b/NxWidgets/libnxwidgets/src/glyph_screenflipup.cxx new file mode 100644 index 000000000..63b58a4a6 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_screenflipup.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_screenflipup.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_screenFlipUpGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_screenFlipUpGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_screenFlipUp = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 7, // width - Width in pixels + 10, // height - Height in rows + (7*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_screenFlipUpGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_shift.cxx b/NxWidgets/libnxwidgets/src/glyph_shift.cxx new file mode 100644 index 000000000..193fd1719 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_shift.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_shift.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_shiftGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, + RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_shiftGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, + RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_shift = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 8, // width - Width in pixels + 10, // height - Height in rows + (8*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_shiftGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_windowclose.cxx b/NxWidgets/libnxwidgets/src/glyph_windowclose.cxx new file mode 100644 index 000000000..3a60aa137 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_windowclose.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_windowclose.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_windowCloseGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_windowCloseGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_windowClose = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 6, // width - Width in pixels + 10, // height - Height in rows + (6*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_windowCloseGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_windowdepthdown.cxx b/NxWidgets/libnxwidgets/src/glyph_windowdepthdown.cxx new file mode 100644 index 000000000..d75b7d676 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_windowdepthdown.cxx @@ -0,0 +1,154 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_windowdepthdown.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_windowDepthDownGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, RGB16_WHITE, RGB16_DARKRED, + RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_windowDepthDownGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, RGB24_WHITE, RGB24_DARKRED, + RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_windowDepthDown = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 8, // width - Width in pixels + 10, // height - Height in rows + (8*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_windowDepthDownGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 diff --git a/NxWidgets/libnxwidgets/src/glyph_windowdepthup.cxx b/NxWidgets/libnxwidgets/src/glyph_windowdepthup.cxx new file mode 100644 index 000000000..f5d67e968 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/glyph_windowdepthup.cxx @@ -0,0 +1,156 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/glyph_windowdepthup.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> + +#include <nuttx/nx/nxglib.h> +#include <nuttx/fb.h> +#include <nuttx/rgbcolors.h> + +#include "nxconfig.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +#if CONFIG_NXWIDGETS_BPP != 8 // No support for 8-bit color format + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Bitmap Data + ****************************************************************************/ + +using namespace NXWidgets; + +#if CONFIG_NXWIDGETS_BPP == 16 +# define COLOR_FMT FB_FMT_RGB16_565 +# define RGB16_TRANSP 0x0000 + +static const uint16_t g_windowDepthUpGlyph[] = +{ + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_TRANSP, RGB16_TRANSP, + RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_DARKRED, RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_WHITE, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, RGB16_DARKRED, + RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, RGB16_TRANSP, +}; + +#elif CONFIG_NXWIDGETS_BPP == 24 || CONFIG_NXWIDGETS_BPP == 32 +# define COLOR_FMT FB_FMT_RGB24 +# define RGB24_TRANSP 0x00000000 + +static const uint32_t g_windowDepthUpGlyph[] = +{ + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_TRANSP, RGB24_TRANSP, + RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_DARKRED, RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_WHITE, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, RGB24_DARKRED, + RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, RGB24_TRANSP, +}; + +#else +# warning "Other pixel depths not yet supported" +#endif + +/**************************************************************************** + * Public Bitmap Structure Defintions + ****************************************************************************/ + +const struct SBitmap NXWidgets::g_windowDepthUp = +{ + CONFIG_NXWIDGETS_BPP, // bpp - Bits per pixel + COLOR_FMT, // fmt - Color format + 8, // width - Width in pixels + 10, // height - Height in rows + (8*CONFIG_NXWIDGETS_BPP + 7) / 8, // stride - Width in bytes + g_windowDepthUpGlyph // data - Pointer to the beginning of pixel data +}; + +#endif // CONFIG_NXWIDGETS_BPP != 8 + + diff --git a/NxWidgets/libnxwidgets/src/singletons.cxx b/NxWidgets/libnxwidgets/src/singletons.cxx new file mode 100644 index 000000000..fc5d919e6 --- /dev/null +++ b/NxWidgets/libnxwidgets/src/singletons.cxx @@ -0,0 +1,202 @@ +/**************************************************************************** + * NxWidgets/libnxwidgets/src/singletons.cxx + * + * 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. + * + **************************************************************************** + * + * Portions of this package derive from Woopsi (http://woopsi.org/) and + * portions are original efforts. It is difficult to determine at this + * point what parts are original efforts and which parts derive from Woopsi. + * However, in any event, the work of Antony Dzeryn will be acknowledged + * in most NxWidget files. Thanks Antony! + * + * Copyright (c) 2007-2011, Antony Dzeryn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the names "Woopsi", "Simian Zombie" nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``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 Antony Dzeryn 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <sched.h> +#include <debug.h> + +#include "nxconfig.hxx" +#include "cnxserver.hxx" +#include "cnxstring.hxx" +#include "cwidgetstyle.hxx" +#include "cnxfont.hxx" +#include "singletons.hxx" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Global Static Data + ****************************************************************************/ + +using namespace NXWidgets; + +CWidgetStyle *NXWidgets::g_defaultWidgetStyle; /**< The default widget style */ +CNxString *NXWidgets::g_nullString; /**< The reusable empty string */ +TNxArray<CNxTimer*> *NXWidgets::g_nxTimers; /**< An array of all timers */ + +/**************************************************************************** + * Method Implementations + ****************************************************************************/ + +/** + * Setup misc singleton instances. Why is there here? Because it needs to be + * done one time before any widgets are created. So why isn't it just the + * default style just a statically constructed class? Because not all platforms + * will support static class constructions. + */ + +void NXWidgets::instantiateSingletons(void) +{ + // Disable pre-emption. Since we are dealing with global resources here we + // are not inherently thread-safe. + + sched_lock(); + + // Create a global, empty string that may be used whereever a string is + // required, but not needed. + + if (!g_nullString) + { + g_nullString = new CNxString(); + } + + // Setup the default widget style + + if (!g_defaultWidgetStyle) + { + // Create the singleton + + g_defaultWidgetStyle = new CWidgetStyle(); + + // Default colors + + g_defaultWidgetStyle->colors.background = CONFIG_NXWIDGETS_DEFAULT_BACKGROUNDCOLOR; + g_defaultWidgetStyle->colors.selectedBackground = CONFIG_NXWIDGETS_DEFAULT_SELECTEDBACKGROUNDCOLOR; + g_defaultWidgetStyle->colors.shineEdge = CONFIG_NXWIDGETS_DEFAULT_SHINEEDGECOLOR; + g_defaultWidgetStyle->colors.shadowEdge = CONFIG_NXWIDGETS_DEFAULT_SHADOWEDGECOLOR; + g_defaultWidgetStyle->colors.highlight = CONFIG_NXWIDGETS_DEFAULT_HIGHLIGHTCOLOR; + + g_defaultWidgetStyle->colors.disabledText = CONFIG_NXWIDGETS_DEFAULT_DISABLEDTEXTCOLOR; + g_defaultWidgetStyle->colors.enabledText = CONFIG_NXWIDGETS_DEFAULT_ENABLEDTEXTCOLOR; + g_defaultWidgetStyle->colors.selectedText = CONFIG_NXWIDGETS_DEFAULT_SELECTEDTEXTCOLOR; + + // Default font using the default font ID and the default font colors + + g_defaultWidgetStyle->font = new CNxFont((enum nx_fontid_e)CONFIG_NXWIDGETS_DEFAULT_FONTID, + CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR, + CONFIG_NXWIDGETS_TRANSPARENT_COLOR); + } + + // Create the timer list + + if (!g_nxTimers) + { + g_nxTimers = new TNxArray<CNxTimer*>(); + } + + sched_unlock(); +} + +/** + * Free the singleton instances when the last NX server is destroyed. + */ + +void NXWidgets::freeSingletons(void) +{ + // Delete the null string singleton + + if (g_nullString) + { + delete g_nullString; + g_nullString = (CNxString *)NULL; + } + + // Delete the default widget style singleton + + if (g_defaultWidgetStyle) + { + if (g_defaultWidgetStyle->font) + { + delete g_defaultWidgetStyle->font; + } + + delete g_defaultWidgetStyle; + g_defaultWidgetStyle = (CWidgetStyle *)NULL; + } + + // Free the timer list + + if (g_nxTimers) + { + delete g_nxTimers; + g_nxTimers = (TNxArray<CNxTimer*> *)NULL; + } + +} + |