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/UnitTests | |
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/UnitTests')
71 files changed, 14989 insertions, 0 deletions
diff --git a/NxWidgets/UnitTests/CButton/Makefile b/NxWidgets/UnitTests/CButton/Makefile new file mode 100644 index 000000000..fbb7d815b --- /dev/null +++ b/NxWidgets/UnitTests/CButton/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/Unitests/CButton/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx cbuttontest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = cbutton +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CButton/cbuttontest.cxx b/NxWidgets/UnitTests/CButton/cbuttontest.cxx new file mode 100644 index 000000000..49f32f551 --- /dev/null +++ b/NxWidgets/UnitTests/CButton/cbuttontest.cxx @@ -0,0 +1,325 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CButton/cbuttontest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "cbuttontest.hxx" +#include "cbgwindow.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CButtonTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CButtonTest Constructor + +CButtonTest::CButtonTest() +{ + m_bgWindow = (CBgWindow *)NULL; + m_nxFont = (CNxFont *)NULL; + m_text = (CNxString *)NULL; +} + +// CButtonTest Descriptor + +CButtonTest::~CButtonTest() +{ + disconnect(); +} + +// Connect to the NX server + +bool CButtonTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Create the default font instance + + m_nxFont = new CNxFont(NXFONT_DEFAULT, + CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR, + CONFIG_NXWIDGETS_TRANSPARENT_COLOR); + if (!m_nxFont) + { + printf("CButtonTest::connect: Failed to create the default font\n"); + } + + // Set the background color + + if (!setBackgroundColor(CONFIG_CBUTTONTEST_BGCOLOR)) + { + printf("CButtonTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CButtonTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + } + + // Free the display string + + if (m_text) + { + delete m_text; + m_text = (CNxString *)NULL; + } + + // Free the default font + + if (m_nxFont) + { + delete m_nxFont; + m_nxFont = (CNxFont *)NULL; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CButtonTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + printf("CButtonTest::createGraphics: Failed to create CBgWindow instance\n"); + delete m_widgetControl; + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + printf("CButtonTest::createGraphics: Failed to open background window\n"); + delete m_bgWindow; + m_bgWindow = (CBgWindow*)0; + return false; + } + + return true; +} + +// Create a CButton instance + +CButton *CButtonTest::createButton(FAR const char *text) +{ + // Get the width of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + printf("CButtonTest::createGraphics: Failed to get window size\n"); + return (CButton *)NULL; + } + + // Create a CNxString instance to contain the C string + + m_text = new CNxString(text); + + // Get the height and width of the text display area + + nxgl_coord_t stringWidth = m_nxFont->getStringWidth(*m_text); + nxgl_coord_t stringHeight = (nxgl_coord_t)m_nxFont->getHeight(); + + // The default CButton has borders enabled with thickness of the border + // width. Add twice the thickness of the borderto the width and height. (We + // could let CButton do this for us by calling CButton::getPreferredDimensions()) + + stringWidth += 2 * 1; + stringHeight += 2 * 1; + + // Pick an X/Y position such that the button will be centered in the display + + nxgl_coord_t buttonX; + if (stringWidth >= windowSize.w) + { + buttonX = 0; + } + else + { + buttonX = (windowSize.w - stringWidth) >> 1; + } + + nxgl_coord_t buttonY; + if (stringHeight >= windowSize.h) + { + buttonY = 0; + } + else + { + buttonY = (windowSize.h - stringHeight) >> 1; + } + + // Save the center position of the button for use by click and release + + m_center.x = buttonX + (stringWidth >> 1); + m_center.y = buttonY + (stringHeight >> 1); + + // Now we have enough information to create the button + + return new CButton(m_widgetControl, buttonX, buttonY, stringWidth, stringHeight, *m_text); +} + +// Draw the button + +void CButtonTest::showButton(CButton *button) +{ + button->enable(); // Un-necessary, the widget is enabled by default + button->enableDrawing(); + button->redraw(); +} + +// Perform a simulated mouse click on the button. This method injects +// the mouse click through the NX heirarchy just as would real mouse +// hardward. + +void CButtonTest::click(void) +{ + // nx_mousein is meant to be called by mouse handling software. + // Here we just inject a left-button click directly in the center of + // the button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // Then inject the mouse click + + (void)nx_mousein(handle, m_center.x, m_center.y, NX_MOUSE_LEFTBUTTON); +} + +// The counterpart to click. This simulates a button release through +// the same mechanism. + +void CButtonTest::release(void) +{ + // nx_mousein is meant to be called by mouse handling software. + // Here we just inject a left-button click directly in the center of + // the button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // Then inject the mouse click + + (void)nx_mousein(handle, m_center.x, m_center.y, NX_MOUSE_NOBUTTONS); +} + +// Widget events are normally handled in a modal loop (by calling goModal()). +// However, for this case we know when there should be press and release +// events so we don't have to poll. We can just perform a one pass poll +// then check if the event was processed corredly. + +bool CButtonTest::poll(CButton *button) +{ + // Poll for mouse events + + m_widgetControl->pollEvents(button); + + // And return the button clicked state + + return button->isClicked(); +} + diff --git a/NxWidgets/UnitTests/CButton/cbuttontest.hxx b/NxWidgets/UnitTests/CButton/cbuttontest.hxx new file mode 100644 index 000000000..f125af6b3 --- /dev/null +++ b/NxWidgets/UnitTests/CButton/cbuttontest.hxx @@ -0,0 +1,167 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CButton/cbuttontest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CBUTTON_CBUTTONTEST_HXX +#define __UNITTESTS_CBUTTON_CBUTTONTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cnxfont.hxx" +#include "cnxstring.hxx" +#include "cbutton.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CBUTTONTEST_BGCOLOR +# define CONFIG_CBUTTONTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +#ifndef CONFIG_CBUTTONTEST_FONTCOLOR +# define CONFIG_CBUTTONTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME cbutton_main +# define MAIN_STRING "cbutton_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CButtonTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CNxFont *m_nxFont; // Default font + CBgWindow *m_bgWindow; // Background window instance + CNxString *m_text; // The button string + struct nxgl_point_s m_center; // X, Y position the center of the button + +public: + // Constructor/destructors + + CButtonTest(); + ~CButtonTest(); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a CButton instance. This method will show you how to create + // a CButton widget + + CButton *createButton(FAR const char *text); + + // Draw the button. This method illustrates how to draw the CButton widget. + + void showButton(CButton *button); + + // Perform a simulated mouse click on the button. This method injects + // the mouse click through the NX heirarchy just as would real mouse + // hardward. + + void click(void); + + // The counterpart to click. This simulates a button release through + // the same mechanism. + + void release(void); + + // Widget events are normally handled in a model loop (by calling goModel()). + // However, for this case we know when there should be press and release + // events so we don't have to poll. We can just perform a one pass poll + // then check if the event was processed corredly. + + bool poll(CButton *button); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + + +#endif // __UNITTESTS_CBUTTON_CBUTTONTEST_HXX diff --git a/NxWidgets/UnitTests/CButton/main.cxx b/NxWidgets/UnitTests/CButton/main.cxx new file mode 100644 index 000000000..13e9099d9 --- /dev/null +++ b/NxWidgets/UnitTests/CButton/main.cxx @@ -0,0 +1,155 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CButton/main.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 <nuttx/init.h> +#include <cstdio> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "cbuttontest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static const char g_pushme[] = "Push Me"; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Create an instance of the font test + + printf(MAIN_STRING "Create CButtonTest instance\n"); + CButtonTest *test = new CButtonTest(); + + // Connect the NX server + + printf(MAIN_STRING "Connect the CButtonTest instance to the NX server\n"); + if (!test->connect()) + { + printf(MAIN_STRING "Failed to connect the CButtonTest instance to the NX server\n"); + delete test; + return 1; + } + + // Create a window to draw into + + printf(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + printf(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + + // Create a CButton instance + + CButton *button = test->createButton(g_pushme); + if (!button) + { + printf(MAIN_STRING "Failed to create a button\n"); + delete test; + return 1; + } + + // Show the button + + printf(MAIN_STRING "Show the button\n"); + test->showButton(button); + + // Wait two seconds, then perform a simulated mouse click on the button + + sleep(2); + printf(MAIN_STRING "Click the button\n"); + test->click(); + + // Poll for the mouse click event (of course this can hang if something fails) + + bool clicked = test->poll(button); + printf(MAIN_STRING "Button is %s\n", clicked ? "clicked" : "released"); + + // Wait a second, then release the mouse buttone + + sleep(1); + test->release(); + + // Poll for the mouse release event (of course this can hang if something fails) + + clicked = test->poll(button); + printf(MAIN_STRING "Button is %s\n", clicked ? "clicked" : "released"); + + // Wait a few more seconds so that the tester can ponder the result + + sleep(3); + + // Clean up and exit + + printf(MAIN_STRING "Clean-up and exit\n"); + delete button; + delete test; + return 0; +} + diff --git a/NxWidgets/UnitTests/CButtonArray/Makefile b/NxWidgets/UnitTests/CButtonArray/Makefile new file mode 100644 index 000000000..6bb67424c --- /dev/null +++ b/NxWidgets/UnitTests/CButtonArray/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CButtonArray/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx cbuttonarraytest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = cbuttonarray +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.cxx b/NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.cxx new file mode 100644 index 000000000..4e4f4487f --- /dev/null +++ b/NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.cxx @@ -0,0 +1,301 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "cbuttonarraytest.hxx" +#include "cbgwindow.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CButtonArrayTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CButtonArrayTest Constructor + +CButtonArrayTest::CButtonArrayTest() +{ + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; +} + +// CButtonArrayTest Descriptor + +CButtonArrayTest::~CButtonArrayTest() +{ + disconnect(); +} + +// Connect to the NX server + +bool CButtonArrayTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CBUTTONARRAYTEST_BGCOLOR)) + { + message("CButtonArrayTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CButtonArrayTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + } + + // Destroy the widget control + + if (m_widgetControl) + { + delete m_widgetControl; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CButtonArrayTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CButtonArrayTest::createGraphics: Failed to create CBgWindow instance\n"); + delete m_widgetControl; + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CButtonArrayTest::createGraphics: Failed to open background window\n"); + delete m_bgWindow; + m_bgWindow = (CBgWindow*)0; + return false; + } + + return true; +} + +// Create a CButtonArray instance + +CButtonArray *CButtonArrayTest::createButtonArray(void) +{ + // Get the width of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + message("CButtonArrayTest::createGraphics: Failed to get window size\n"); + return (CButtonArray *)NULL; + } + + // Pick an X/Y position such that the button array will be centered in the display + + nxgl_coord_t buttonArrayX; + if (BUTTONARRAY_WIDTH >= windowSize.w) + { + buttonArrayX = 0; + } + else + { + buttonArrayX = (windowSize.w - BUTTONARRAY_WIDTH) >> 1; + } + + nxgl_coord_t buttonArrayY; + if (BUTTONARRAY_HEIGHT >= windowSize.h) + { + buttonArrayY = 0; + } + else + { + buttonArrayY = (windowSize.h - BUTTONARRAY_HEIGHT) >> 1; + } + + // Now we have enough information to create the button array + + return new CButtonArray(m_widgetControl, + buttonArrayX, buttonArrayY, + BUTTONARRAY_NCOLUMNS, BUTTONARRAY_NROWS, + BUTTONARRAY_BUTTONWIDTH, BUTTONARRAY_BUTTONHEIGHT); +} + +// Draw the button array + +void CButtonArrayTest::showButton(CButtonArray *buttonArray) +{ + buttonArray->enable(); // Un-necessary, the widget is enabled by default + buttonArray->enableDrawing(); + buttonArray->redraw(); +} + +// Perform a simulated mouse click on a button in the array. This method injects +// the mouse click through the NX heirarchy just as would real mouse +// hardward. + +void CButtonArrayTest::click(CButtonArray *buttonArray, int column, int row) +{ + // nx_mousein is meant to be called by mouse handling software. + // Here we just inject a left-button click directly in the center of + // the selected button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // The the coorinates of the center of the button + + nxgl_coord_t buttonX = buttonArray->getX() + + column * BUTTONARRAY_BUTTONWIDTH + + BUTTONARRAY_BUTTONWIDTH/2; + nxgl_coord_t buttonY = buttonArray->getY() + + row * BUTTONARRAY_BUTTONHEIGHT + + BUTTONARRAY_BUTTONHEIGHT/2; + + // Then inject the mouse click + + (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_LEFTBUTTON); +} + +// The counterpart to click. This simulates a button release through +// the same mechanism. + +void CButtonArrayTest::release(CButtonArray *buttonArray, int column, int row) +{ + // nx_mousein is meant to be called by mouse handling software. + // Here we just inject a left-button click directly in the center of + // the button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // The the coorinates of the center of the button + + nxgl_coord_t buttonX = buttonArray->getX() + + column * BUTTONARRAY_BUTTONWIDTH + + BUTTONARRAY_BUTTONWIDTH/2; + nxgl_coord_t buttonY = buttonArray->getY() + + row * BUTTONARRAY_BUTTONHEIGHT + + BUTTONARRAY_BUTTONHEIGHT/2; + + // Then inject the mouse release + + (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_NOBUTTONS); +} + +// Widget events are normally handled in a modal loop (by calling goModal()). +// However, for this case we know when there should be press and release +// events so we don't have to poll. We can just perform a one pass poll +// then check if the event was processed corredly. + +void CButtonArrayTest::poll(CButtonArray *button) +{ + // Poll for mouse events + + m_widgetControl->pollEvents(button); +} + diff --git a/NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx b/NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx new file mode 100644 index 000000000..ef265efbf --- /dev/null +++ b/NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx @@ -0,0 +1,182 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CButtonArray/cbuttonarraytest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CBUTTONARRAY_CBUTTONARRAYTEST_HXX +#define __UNITTESTS_CBUTTONARRAY_CBUTTONARRAYTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cnxfont.hxx" +#include "cnxstring.hxx" +#include "cbuttonarray.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CBUTTONARRAYTEST_BGCOLOR +# define CONFIG_CBUTTONARRAYTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +#ifndef CONFIG_CBUTTONARRAYTEST_FONTCOLOR +# define CONFIG_CBUTTONARRAYTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME cbuttonarray_main +# define MAIN_STRING "cbuttonarray_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +// The geometry of the button array + +#define BUTTONARRAY_NCOLUMNS 4 +#define BUTTONARRAY_NROWS 7 +#define BUTTONARRAY_BUTTONWIDTH 60 +#define BUTTONARRAY_BUTTONHEIGHT 32 +#define BUTTONARRAY_WIDTH (BUTTONARRAY_BUTTONWIDTH * BUTTONARRAY_NCOLUMNS) +#define BUTTONARRAY_HEIGHT (BUTTONARRAY_BUTTONHEIGHT * BUTTONARRAY_NROWS) + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CButtonArrayTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The widget control for the window + CBgWindow *m_bgWindow; // Background window instance + +public: + // Constructor/destructors + + CButtonArrayTest(); + ~CButtonArrayTest(); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a CButtonArray instance. This method will show you how to create + // a CButtonArray widget + + CButtonArray *createButtonArray(void); + + // Draw the button array. This method illustrates how to draw the CButtonArray widget. + + void showButton(CButtonArray *buttonArray); + + // Perform a simulated mouse click on a button in the array. This method injects + // the mouse click through the NX heirarchy just as would real mouse + // hardward. + + void click(CButtonArray *buttonArray, int column, int row); + + // The counterpart to click. This simulates a button release through + // the same mechanism. + + void release(CButtonArray *buttonArray, int column, int row); + + // Widget events are normally handled in a model loop (by calling goModel()). + // However, for this case we know when there should be press and release + // events so we don't have to poll. We can just perform a one pass poll + // then check if the event was processed corredly. + + void poll(CButtonArray *buttonArray); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + + +#endif // __UNITTESTS_CBUTTONARRAY_CBUTTONARRAYTEST_HXX diff --git a/NxWidgets/UnitTests/CButtonArray/main.cxx b/NxWidgets/UnitTests/CButtonArray/main.cxx new file mode 100644 index 000000000..fa02413a4 --- /dev/null +++ b/NxWidgets/UnitTests/CButtonArray/main.cxx @@ -0,0 +1,327 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CButtonArray/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "cnxstring.hxx" +#include "cbuttonarraytest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static unsigned int g_mmInitial; +static unsigned int g_mmPrevious; +static unsigned int g_mmPeak; + +static FAR const char *g_buttonLabels[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" +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(unsigned int previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("%s: Before: %8d After: %8d Change: %8d\n", + msg, previous, mmcurrent.uordblks, mmcurrent.uordblks - previous); + + /* Set up for the next test */ + + g_mmPrevious = mmcurrent.uordblks; + if ((unsigned int)mmcurrent.uordblks > g_mmPeak) + { + g_mmPeak = mmcurrent.uordblks; + } +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mmInitial = mmcurrent.uordblks; + g_mmPrevious = mmcurrent.uordblks; + g_mmPeak = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Name: checkHighlighting +///////////////////////////////////////////////////////////////////////////// + +static void checkHighlighting(CButtonArray *buttonArray) +{ + // Turn highlighting on + + buttonArray->setCursorPosition(0, 0); + buttonArray->cursor(true); + + // Then test the cursor movement + + for (int row = 0; row < BUTTONARRAY_NROWS; row++) + { + for (int column = 0; column < BUTTONARRAY_NCOLUMNS; column++) + { + // Set cursor position + + buttonArray->setCursorPosition(column, row); + + // Check cursor position + + int checkColumn; + int checkRow; + if (buttonArray->isCursorPosition(checkColumn, checkRow)) + { + printf("ERROR: Not button selected\n"); + printf(" Expected (%d,%d)\n", column, row); + } + else if (checkColumn != column || checkRow != row) + { + printf("ERROR: Wrong button selected\n"); + printf(" Expected (%d,%d)\n", column, row); + printf(" Selected (%d,%d)\n", checkColumn, checkRow); + } + + // Wait a bit so that we can see the highlighting + + usleep(500*1000); + } + } + + // Turn highlighting off + + buttonArray->cursor(false); +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the button array test + + printf(MAIN_STRING "Create CButtonArrayTest instance\n"); + CButtonArrayTest *test = new CButtonArrayTest(); + updateMemoryUsage(g_mmPrevious, "After creating CButtonArrayTest"); + + // Connect the NX server + + printf(MAIN_STRING "Connect the CButtonArrayTest instance to the NX server\n"); + if (!test->connect()) + { + printf(MAIN_STRING "Failed to connect the CButtonArrayTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmPrevious, "After connecting to the server"); + + // Create a window to draw into + + printf(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + printf(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmPrevious, "After creating a window"); + + // Create a CButtonArray instance + + CButtonArray *buttonArray = test->createButtonArray(); + if (!buttonArray) + { + printf(MAIN_STRING "Failed to create a button array\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmPrevious, "After creating CButtonArray"); + + // Add the labels to each button + + FAR const char **ptr = g_buttonLabels; + for (int j = 0; j < BUTTONARRAY_NROWS; j++) + { + for (int i = 0; i < BUTTONARRAY_NCOLUMNS; i++) + { + printf(MAIN_STRING "Label (%d,%d): %s\n", i, j, *ptr); + CNxString string = *ptr++; + buttonArray->setText(i, j, string); + } + } + updateMemoryUsage(g_mmPrevious, "After adding labels to the buttons"); + + // Show the button array + + printf(MAIN_STRING "Show the button array\n"); + test->showButton(buttonArray); + sleep(1); + + // Verify that button highlighting works + + checkHighlighting(buttonArray); + updateMemoryUsage(g_mmPrevious, "After highliting"); + + // Then perform a simulated mouse click on a button in the array + + for (int j = 0; j < BUTTONARRAY_NROWS; j++) + { + for (int i = 0; i < BUTTONARRAY_NCOLUMNS; i++) + { + printf(MAIN_STRING "Click the button (%d,%d)\n", i, j); + test->click(buttonArray, i, j); + + // Poll for the mouse click event + + test->poll(buttonArray); + + // Is anything clicked? + + int clickColumn; + int clickRow; + if (buttonArray->isButtonClicked(clickColumn, clickRow)) + { + printf(MAIN_STRING "%s: Button (%d, %d) is clicked\n", + clickColumn == i && clickRow == j ? "OK" : "ERROR", + clickColumn, clickRow); + } + else + { + printf(MAIN_STRING "ERROR: No button is clicked\n"); + } + + // Wait a bit, then release the mouse button + + usleep(500*1000); + test->release(buttonArray, i, j); + + // Poll for the mouse release event (of course this can hang if something fails) + + test->poll(buttonArray); + if (buttonArray->isButtonClicked(clickColumn, clickRow)) + { + printf(MAIN_STRING "ERROR: Button (%d, %d) is clicked\n", + clickColumn, clickRow); + } + + usleep(500*1000); + } + } + updateMemoryUsage(g_mmPrevious, "After pushing buttons"); + + // Clean up and exit + + printf(MAIN_STRING "Clean-up and exit\n"); + delete buttonArray; + updateMemoryUsage(g_mmPrevious, "After deleting the button array"); + delete test; + updateMemoryUsage(g_mmPrevious, "After deleting the test"); + updateMemoryUsage(g_mmInitial, "Final memory usage"); + message("Peak memory usage: %8d\n", g_mmPeak - g_mmInitial); + return 0; +} + diff --git a/NxWidgets/UnitTests/CCheckBox/Makefile b/NxWidgets/UnitTests/CCheckBox/Makefile new file mode 100644 index 000000000..9dae246ce --- /dev/null +++ b/NxWidgets/UnitTests/CCheckBox/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CCheckBox/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx ccheckboxtest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = ccheckbox +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CCheckBox/ccheckboxtest.cxx b/NxWidgets/UnitTests/CCheckBox/ccheckboxtest.cxx new file mode 100644 index 000000000..90abf2e67 --- /dev/null +++ b/NxWidgets/UnitTests/CCheckBox/ccheckboxtest.cxx @@ -0,0 +1,297 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CCheckBox/ccheckboxtest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "cbgwindow.hxx" +#include "ccheckboxtest.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CCheckBoxTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CCheckBoxTest Constructor + +CCheckBoxTest::CCheckBoxTest() +{ + // Initialize state data + + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; + m_checkBox = (CCheckBox *)NULL; +} + +// CCheckBoxTest Descriptor + +CCheckBoxTest::~CCheckBoxTest(void) +{ + disconnect(); +} + +// Connect to the NX server + +bool CCheckBoxTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CCHECKBOXTEST_BGCOLOR)) + { + message("CCheckBoxTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CCheckBoxTest::disconnect(void) +{ + // Free the radiobutton group + + if (m_checkBox) + { + delete m_checkBox; + m_checkBox = (CCheckBox *)NULL; + } + + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + m_bgWindow = (CBgWindow *)NULL; + } + + // Free the widget control instance + + if (m_widgetControl) + { + delete m_widgetControl; + m_widgetControl = (CWidgetControl *)NULL; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CCheckBoxTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CCheckBoxTest::createWindow: Failed to create CBgWindow instance\n"); + disconnect(); + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CCheckBoxTest::createWindow: Failed to open background window\n"); + disconnect(); + return false; + } + + // Get the size of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + printf("CCheckBoxTest::createWindow: Failed to get window size\n"); + disconnect(); + return false; + } + + // Use the the size of the ON checkbox glyph. (adding twice the border thickness) + + nxgl_coord_t width = g_checkBoxOn.width + 2 * 1; + nxgl_coord_t height = g_checkBoxOn.height + 2 * 1; + + nxgl_coord_t checkboxX = (windowSize.w - width) >> 1; + nxgl_coord_t checkboxY = (windowSize.h - height) >> 1; + + // Create the checkbox + + m_checkBox = new CCheckBox(m_widgetControl, checkboxX, checkboxY, + width, height, (CWidgetStyle *)NULL); + if (!m_checkBox) + { + printf("CCheckBoxTest::createWindow: Failed to create CCheckBox\n"); + disconnect(); + return false; + } + + return true; +} + +// (Re-)draw the check box. + +void CCheckBoxTest::showCheckBox(void) +{ + m_checkBox->enable(); // Un-necessary, the widget is enabled by default + m_checkBox->enableDrawing(); + m_checkBox->redraw(); +} + +// Push the radio button + +void CCheckBoxTest::clickCheckBox(void) +{ + // Get the checkbox center coordinates + + nxgl_coord_t checkboxX = m_checkBox->getX() + (m_checkBox->getWidth() >> 1); + nxgl_coord_t checkboxY = m_checkBox->getY() + (m_checkBox->getHeight() >> 1); + + // Click the checkbox by calling nx_mousein. nx_mousein is meant to be + // called by mouse handling software. Here we just inject a left-button click + // directly in the center of the radio button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // Then inject the mouse click + + (void)nx_mousein(handle, checkboxX, checkboxY, NX_MOUSE_LEFTBUTTON); + + // Poll for mouse events + // + // Widget events are normally handled in a modal loop (by calling goModal()). + // However, for this case we know that we just pressed the mouse button + // so we don't have to poll. We can just perform a one pass poll then + // then check if the mouse event was processed corredly. + + m_widgetControl->pollEvents(m_checkBox); + + // Then inject the mouse release + + (void)nx_mousein(handle, checkboxX, checkboxY, 0); + + // And poll for more mouse events + + m_widgetControl->pollEvents(m_checkBox); + + // And re-draw the buttons (the mouse click event should have automatically + // triggered the re-draw) + // + // showCheckBox(); +} + +// Show the state of the radio button group + +void CCheckBoxTest::showCheckBoxState(void) +{ + CCheckBox::CheckBoxState state = m_checkBox->getState(); + switch (state) + { + case CCheckBox::CHECK_BOX_STATE_OFF: // Checkbox is unticked + message("CCheckBoxTest::showCheckBoxState Checkbox is in the unticked state\n"); + break; + + case CCheckBox::CHECK_BOX_STATE_ON: // Checkbox is ticked + message("CCheckBoxTest::showCheckBoxState Check is in the ticked state\n"); + break; + + default: + case CCheckBox::CHECK_BOX_STATE_MU: // Checkbox is in the third state + message("CCheckBoxTest::showCheckBoxState Checkbox is in the 3rd state\n"); + break; + } +} diff --git a/NxWidgets/UnitTests/CCheckBox/ccheckboxtest.hxx b/NxWidgets/UnitTests/CCheckBox/ccheckboxtest.hxx new file mode 100644 index 000000000..52371ab73 --- /dev/null +++ b/NxWidgets/UnitTests/CCheckBox/ccheckboxtest.hxx @@ -0,0 +1,152 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CCheckBox/ccheckboxtest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CCHECKBOX_CCHECKBOXTEST_HXX +#define __UNITTESTS_CCHECKBOX_CCHECKBOXTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "ccheckbox.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CCHECKBOXTEST_BGCOLOR +# define CONFIG_CCHECKBOXTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME ccheckbox_main +# define MAIN_STRING "ccheckbox_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CCheckBoxTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CBgWindow *m_bgWindow; // Background window instance + CCheckBox *m_checkBox; // Checkgox instance under test + +public: + // Constructor/destructors + + CCheckBoxTest(void); + ~CCheckBoxTest(void); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // (Re-)draw the checkbox. + + void showCheckBox(void); + + // Simulate pushing and releasing of the radio button + + void clickCheckBox(void); + + // Show the state of the radio button group + + void showCheckBoxState(void); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // __UNITTESTS_CCHECKBOX_CCHECKBOXTEST_HXX diff --git a/NxWidgets/UnitTests/CCheckBox/main.cxx b/NxWidgets/UnitTests/CCheckBox/main.cxx new file mode 100644 index 000000000..e9e8b516f --- /dev/null +++ b/NxWidgets/UnitTests/CCheckBox/main.cxx @@ -0,0 +1,209 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CCheckBox/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "crlepalettebitmap.hxx" +#include "glyphs.hxx" +#include "ccheckboxtest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static unsigned int g_mmInitial; +static unsigned int g_mmprevious; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(unsigned int previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("\n%s:\n", msg); + message(" Before: %8d After: %8d Change: %8d\n\n", + previous, mmcurrent.uordblks, mmcurrent.uordblks - previous); + + /* Set up for the next test */ + + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mmInitial = mmcurrent.uordblks; + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the checkbox test + + message(MAIN_STRING "Create CCheckBoxTest instance\n"); + CCheckBoxTest *test = new CCheckBoxTest(); + updateMemoryUsage(g_mmprevious, "After creating CCheckBoxTest"); + + // Connect the NX server + + message(MAIN_STRING "Connect the CCheckBoxTest instance to the NX server\n"); + if (!test->connect()) + { + message(MAIN_STRING "Failed to connect the CCheckBoxTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server"); + + // Create a window to draw into + + message(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + message(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window"); + + // Show the initial state of the checkbox + + test->showCheckBox(); + test->showCheckBoxState(); + sleep(1); + + // Now click the checkbox + + message(MAIN_STRING "Click 1\n"); + test->clickCheckBox(); + usleep(500*1000); + test->showCheckBoxState(); + updateMemoryUsage(g_mmprevious, "After click 1"); + usleep(500*1000); + + message(MAIN_STRING "Click 2\n"); + test->clickCheckBox(); + usleep(500*1000); + test->showCheckBoxState(); + updateMemoryUsage(g_mmprevious, "After click 2"); + usleep(500*1000); + + message(MAIN_STRING "Click 3\n"); + test->clickCheckBox(); + usleep(500*1000); + test->showCheckBoxState(); + updateMemoryUsage(g_mmprevious, "After click 3"); + sleep(2); + + // Clean up and exit + + message(MAIN_STRING "Clean-up and exit\n"); + delete test; + updateMemoryUsage(g_mmprevious, "After deleting the test"); + updateMemoryUsage(g_mmInitial, "Final memory usage"); + return 0; +} + diff --git a/NxWidgets/UnitTests/CGlyphButton/Makefile b/NxWidgets/UnitTests/CGlyphButton/Makefile new file mode 100644 index 000000000..527d882fa --- /dev/null +++ b/NxWidgets/UnitTests/CGlyphButton/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CGlyphButton/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx cglyphbuttontest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = cglyphbutton +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.cxx b/NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.cxx new file mode 100644 index 000000000..d44238c78 --- /dev/null +++ b/NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.cxx @@ -0,0 +1,307 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "cglyphbuttontest.hxx" +#include "cbgwindow.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CGlyphButtonTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CGlyphButtonTest Constructor + +CGlyphButtonTest::CGlyphButtonTest() +{ + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; + m_center.x = 0; + m_center.y = 0; +} + +// CGlyphButtonTest Descriptor + +CGlyphButtonTest::~CGlyphButtonTest() +{ + disconnect(); +} + +// Connect to the NX server + +bool CGlyphButtonTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CGLYPHBUTTONTEST_BGCOLOR)) + { + message("CGlyphButtonTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CGlyphButtonTest::disconnect(void) +{ + // Delete the widget control instance + + if (m_widgetControl) + { + delete m_widgetControl; + } + + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CGlyphButtonTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CGlyphButtonTest::createGraphics: Failed to create CBgWindow instance\n"); + delete m_widgetControl; + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CGlyphButtonTest::createGraphics: Failed to open background window\n"); + delete m_bgWindow; + m_bgWindow = (CBgWindow*)0; + return false; + } + + return true; +} + +// Create a CGlyphButton instance + +CGlyphButton *CGlyphButtonTest::createButton(FAR const struct SBitmap *clickGlyph, + FAR const struct SBitmap *unClickedGlyph) +{ + // Get the width of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + message("CGlyphButtonTest::createGraphics: Failed to get window size\n"); + return (CGlyphButton *)NULL; + } + + // Get the height and width of the glyph display area + + nxgl_coord_t glyphWidth = MAX(clickGlyph->width, unClickedGlyph->width); + nxgl_coord_t glyphHeight = MAX(clickGlyph->height, unClickedGlyph->height); + + // The default CGlyphButton has borders enabled with thickness of the border + // width. Add twice the thickness of the border to the width and height. (We + // could let CGlyphButton do this for us by calling + // CGlyphButton::getPreferredDimensions()) + + glyphWidth += 2 * 1; + glyphHeight += 2 * 1; + + // Pick an X/Y position such that the button will be centered in the display + + nxgl_coord_t buttonX; + if (glyphWidth >= windowSize.w) + { + buttonX = 0; + } + else + { + buttonX = (windowSize.w - glyphWidth) >> 1; + } + + nxgl_coord_t buttonY; + if (glyphHeight >= windowSize.h) + { + buttonY = 0; + } + else + { + buttonY = (windowSize.h - glyphHeight) >> 1; + } + + // Save the center position of the button for use by click and release + + m_center.x = buttonX + (glyphWidth >> 1); + m_center.y = buttonY + (glyphHeight >> 1); + + // Now we have enough information to create the button + + return new CGlyphButton(m_widgetControl, buttonX, buttonY, + glyphWidth, glyphHeight, + unClickedGlyph, clickGlyph); +} + +// Draw the button + +void CGlyphButtonTest::showButton(CGlyphButton *button) +{ + button->enable(); // Un-necessary, the widget is enabled by default + button->enableDrawing(); + button->redraw(); +} + +// Perform a simulated mouse click on the button. This method injects +// the mouse click through the NX heirarchy just as would real mouse +// hardward. + +void CGlyphButtonTest::click(void) +{ + // nx_mousein is meant to be called by mouse handling software. + // Here we just inject a left-button click directly in the center of + // the button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // Then inject the mouse click + + (void)nx_mousein(handle, m_center.x, m_center.y, NX_MOUSE_LEFTBUTTON); +} + +// The counterpart to click. This simulates a button release through +// the same mechanism. + +void CGlyphButtonTest::release(void) +{ + // nx_mousein is meant to be called by mouse handling software. + // Here we just inject a left-button click directly in the center of + // the button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // Then inject the mouse click + + (void)nx_mousein(handle, m_center.x, m_center.y, NX_MOUSE_NOBUTTONS); +} + +// Widget events are normally handled in a modal loop (by calling goModal()). +// However, for this case we know when there should be press and release +// events so we don't have to poll. We can just perform a one pass poll +// then check if the event was processed corredly. + +bool CGlyphButtonTest::poll(CGlyphButton *button) +{ + // Poll for mouse events + + m_widgetControl->pollEvents(button); + + // And return the button clicked state + + return button->isClicked(); +} + diff --git a/NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx b/NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx new file mode 100644 index 000000000..889ce21ca --- /dev/null +++ b/NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx @@ -0,0 +1,182 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CGlyphButton/cglyphbuttontest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CGLYPHBUTTON_CGLYPHBUTTONTEST_HXX +#define __UNITTESTS_CGLYPHBUTTON_CGLYPHBUTTONTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cnxfont.hxx" +#include "cnxstring.hxx" +#include "cglyphbutton.hxx" +#include "cbitmap.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CGLYPHBUTTONTEST_BGCOLOR +# define CONFIG_CGLYPHBUTTONTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +#ifndef CONFIG_CGLYPHBUTTONTEST_FONTCOLOR +# define CONFIG_CGLYPHBUTTONTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME cglyphbutton_main +# define MAIN_STRING "cglyphbutton_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +// Helper macros + +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CGlyphButtonTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CBgWindow *m_bgWindow; // Background window instance + struct nxgl_point_s m_center; // X, Y position the center of the button + +public: + // Constructor/destructors + + CGlyphButtonTest(); + ~CGlyphButtonTest(); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a CGlyphButton instance. This method will show you how to create + // a CGlyphButton widget + + CGlyphButton *createButton(FAR const struct SBitmap *clickGlyph, + FAR const struct SBitmap *unClickedGlyph); + + // Draw the button. This method illustrates how to draw the CGlyphButton widget. + + void showButton(CGlyphButton *button); + + // Perform a simulated mouse click on the button. This method injects + // the mouse click through the NX heirarchy just as would real mouse + // hardward. + + void click(void); + + // The counterpart to click. This simulates a button release through + // the same mechanism. + + void release(void); + + // Widget events are normally handled in a model loop (by calling goModel()). + // However, for this case we know when there should be press and release + // events so we don't have to poll. We can just perform a one pass poll + // then check if the event was processed corredly. + + bool poll(CGlyphButton *button); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + + +#endif // __UNITTESTS_CGLYPHBUTTON_CGLYPHBUTTONTEST_HXX diff --git a/NxWidgets/UnitTests/CGlyphButton/main.cxx b/NxWidgets/UnitTests/CGlyphButton/main.cxx new file mode 100644 index 000000000..7812fa9e9 --- /dev/null +++ b/NxWidgets/UnitTests/CGlyphButton/main.cxx @@ -0,0 +1,225 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CGlyphButton/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "cglyphbuttontest.hxx" +#include "glyphs.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static unsigned int g_mmInitial; +static unsigned int g_mmprevious; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(unsigned int previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("\n%s:\n", msg); + message(" Before: %8d After: %8d Change: %8d\n\n", + previous, mmcurrent.uordblks, mmcurrent.uordblks - previous); + + /* Set up for the next test */ + + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mmInitial = mmcurrent.uordblks; + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the font test + + message(MAIN_STRING "Create CGlyphButtonTest instance\n"); + CGlyphButtonTest *test = new CGlyphButtonTest(); + updateMemoryUsage(g_mmprevious, "After creating CGlyphButtonTest"); + + // Connect the NX server + + message(MAIN_STRING "Connect the CGlyphButtonTest instance to the NX server\n"); + if (!test->connect()) + { + message(MAIN_STRING "Failed to connect the CGlyphButtonTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, "After connecting to the server"); + + // Create a window to draw into + + message(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + message(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, "After creating a window"); + + // Create a CGlyphButton instance + + CGlyphButton *button = test->createButton(&g_arrowDown, &g_arrowUp); + if (!button) + { + message(MAIN_STRING "Failed to create a button\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, "After creating the glyph button"); + + // Show the button + + message(MAIN_STRING "Show the button\n"); + test->showButton(button); + updateMemoryUsage(g_mmprevious, "After showing the glyph button"); + + // Wait two seconds, then perform a simulated mouse click on the button + + sleep(2); + message(MAIN_STRING "Click the button\n"); + test->click(); + updateMemoryUsage(g_mmprevious, "After clicking glyph button"); + + // Poll for the mouse click event (of course this can hang if something fails) + + bool clicked = test->poll(button); + message(MAIN_STRING "Button is %s\n", clicked ? "clicked" : "released"); + + // Wait a second, then release the mouse buttone + + sleep(1); + test->release(); + updateMemoryUsage(g_mmprevious, "After releasing glyph button"); + + // Poll for the mouse release event (of course this can hang if something fails) + + clicked = test->poll(button); + message(MAIN_STRING "Button is %s\n", clicked ? "clicked" : "released"); + + // Wait a few more seconds so that the tester can ponder the result + + sleep(3); + + // Clean up and exit + + message(MAIN_STRING "Clean-up and exit\n"); + delete button; + updateMemoryUsage(g_mmprevious, "After deleting the glyph button"); + delete test; + updateMemoryUsage(g_mmprevious, "After deleting the test"); + updateMemoryUsage(g_mmInitial, "Final memory usage"); + return 0; +} + diff --git a/NxWidgets/UnitTests/CImage/Makefile b/NxWidgets/UnitTests/CImage/Makefile new file mode 100644 index 000000000..e248761e7 --- /dev/null +++ b/NxWidgets/UnitTests/CImage/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CImage/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx cimagetest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = cimage +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CImage/cimagetest.cxx b/NxWidgets/UnitTests/CImage/cimagetest.cxx new file mode 100644 index 000000000..48814c4ce --- /dev/null +++ b/NxWidgets/UnitTests/CImage/cimagetest.cxx @@ -0,0 +1,240 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CImage/cimagetest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "ibitmap.hxx" +#include "cbgwindow.hxx" +#include "cimagetest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CImageTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CImageTest Constructor + +CImageTest::CImageTest() +{ + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; +} + +// CImageTest Descriptor + +CImageTest::~CImageTest() +{ + disconnect(); +} + +// Connect to the NX server + +bool CImageTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CIMAGETEST_BGCOLOR)) + { + message("CImageTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CImageTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + } + + // Free the widget control instance + + if (m_widgetControl) + { + delete m_widgetControl; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CImageTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CImageTest::createGraphics: Failed to create CBgWindow instance\n"); + delete m_widgetControl; + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CImageTest::createGraphics: Failed to open background window\n"); + delete m_bgWindow; + m_bgWindow = (CBgWindow*)0; + return false; + } + + return true; +} + +// Create a CImage instance + +CImage *CImageTest::createImage(IBitmap *bitmap) +{ + // Get the width of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + message("CImageTest::createGraphics: Failed to get window size\n"); + return (CImage *)NULL; + } + + // Get the height and width of the image + + nxgl_coord_t imageWidth = bitmap->getWidth(); + nxgl_coord_t imageHeight = (nxgl_coord_t)bitmap->getHeight(); + + // The default CImage has borders enabled with thickness of the border + // width. Add twice the thickness of the border to the width and height. (We + // could let CImage do this for us by calling CImage::getPreferredDimensions()) + + imageWidth += 2 * 1; + imageHeight += 2 * 1; + + // Pick an X/Y position such that the image will be centered in the display + + nxgl_coord_t imageX; + if (imageWidth >= windowSize.w) + { + imageX = 0; + } + else + { + imageX = (windowSize.w - imageWidth) >> 1; + } + + nxgl_coord_t imageY; + if (imageHeight >= windowSize.h) + { + imageY = 0; + } + else + { + imageY = (windowSize.h - imageHeight) >> 1; + } + + // Now we have enough information to create the image + + return new CImage(m_widgetControl, imageX, imageY, imageWidth, imageHeight, bitmap); +} + +// Draw the image + +void CImageTest::showImage(CImage *image) +{ + image->enable(); + image->enableDrawing(); + image->redraw(); + image->disableDrawing(); +} diff --git a/NxWidgets/UnitTests/CImage/cimagetest.hxx b/NxWidgets/UnitTests/CImage/cimagetest.hxx new file mode 100644 index 000000000..8a8a55556 --- /dev/null +++ b/NxWidgets/UnitTests/CImage/cimagetest.hxx @@ -0,0 +1,150 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CImage/cimagetest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CIMAGE_CIMAGETEST_HXX +#define __UNITTESTS_CIMAGE_CIMAGETEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cnxfont.hxx" +#include "cnxstring.hxx" +#include "cimage.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CIMAGETEST_BGCOLOR +# define CONFIG_CIMAGETEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME cimage_main +# define MAIN_STRING "cimage_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CImageTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CBgWindow *m_bgWindow; // Background window instance + +public: + // Constructor/destructors + + CImageTest(void); + ~CImageTest(void); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a CImage instance. This method will show you how to create + // a CImage widget + + CImage *createImage(IBitmap *bitmap); + + // Draw the image. This method illustrates how to draw the CImage widget. + + void showImage(CImage *image); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // __UNITTESTS_CIMAGE_CIMAGETEST_HXX diff --git a/NxWidgets/UnitTests/CImage/main.cxx b/NxWidgets/UnitTests/CImage/main.cxx new file mode 100644 index 000000000..dd066b809 --- /dev/null +++ b/NxWidgets/UnitTests/CImage/main.cxx @@ -0,0 +1,222 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CImage/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "crlepalettebitmap.hxx" +#include "glyphs.hxx" +#include "cimagetest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static struct mallinfo g_mmInitial; +static struct mallinfo g_mmprevious; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: showMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void showMemoryUsage(FAR struct mallinfo *mmbefore, + FAR struct mallinfo *mmafter) +{ + message("VARIABLE BEFORE AFTER\n"); + message("======== ======== ========\n"); + message("arena %8d %8d\n", mmbefore->arena, mmafter->arena); + message("ordblks %8d %8d\n", mmbefore->ordblks, mmafter->ordblks); + message("mxordblk %8d %8d\n", mmbefore->mxordblk, mmafter->mxordblk); + message("uordblks %8d %8d\n", mmbefore->uordblks, mmafter->uordblks); + message("fordblks %8d %8d\n", mmbefore->fordblks, mmafter->fordblks); +} + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(FAR struct mallinfo *previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("\n%s:\n", msg); + showMemoryUsage(previous, &mmcurrent); + + /* Set up for the next test */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + g_mmprevious = mmcurrent; +#else + memcpy(&g_mmprevious, &mmcurrent, sizeof(struct mallinfo)); +#endif +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ +#ifdef CONFIG_CAN_PASS_STRUCTS + g_mmInitial = mallinfo(); + g_mmprevious = g_mmInitial; +#else + (void)mallinfo(&g_mmInitial); + memcpy(&g_mmprevious, &g_mmInitial, sizeof(struct mallinfo)); +#endif +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the font test + + message(MAIN_STRING "Create CImageTest instance\n"); + CImageTest *test = new CImageTest(); + updateMemoryUsage(&g_mmprevious, "After creating CImageTest"); + + // Connect the NX server + + message(MAIN_STRING "Connect the CImageTest instance to the NX server\n"); + if (!test->connect()) + { + message(MAIN_STRING "Failed to connect the CImageTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(&g_mmprevious, "After connecting to the server"); + + // Create a window to draw into + + message(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + message(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(&g_mmprevious, "After creating a window"); + + // Create an instance of the NuttX logo + + CRlePaletteBitmap *nuttxBitmap = new CRlePaletteBitmap(&g_nuttxBitmap); + updateMemoryUsage(&g_mmprevious, "After creating the bitmap"); + + // Create a CImage instance + + CImage *image = test->createImage(static_cast<IBitmap*>(nuttxBitmap)); + if (!image) + { + message(MAIN_STRING "Failed to create a image\n"); + delete test; + return 1; + } + updateMemoryUsage(&g_mmprevious, "After creating CImage"); + + // Show the image + + test->showImage(image); + updateMemoryUsage(&g_mmprevious, "After showing the image"); + sleep(5); + + // Clean up and exit + + message(MAIN_STRING "Clean-up and exit\n"); + delete image; + updateMemoryUsage(&g_mmprevious, "After deleting CImage"); + + delete nuttxBitmap; + updateMemoryUsage(&g_mmprevious, "After deleting the bitmap"); + + delete test; + updateMemoryUsage(&g_mmprevious, "After deleting the test"); + updateMemoryUsage(&g_mmInitial, "Final memory usage"); + return 0; +} + diff --git a/NxWidgets/UnitTests/CKeypad/Makefile b/NxWidgets/UnitTests/CKeypad/Makefile new file mode 100644 index 000000000..631be3b68 --- /dev/null +++ b/NxWidgets/UnitTests/CKeypad/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CKeyPad/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx ckeypadtest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = ckeypad +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CKeypad/ckeypadtest.cxx b/NxWidgets/UnitTests/CKeypad/ckeypadtest.cxx new file mode 100644 index 000000000..5d3eeda2a --- /dev/null +++ b/NxWidgets/UnitTests/CKeypad/ckeypadtest.cxx @@ -0,0 +1,458 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CKeypad/ckeypadtest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "ckeypadtest.hxx" +#include "cbgwindow.hxx" +#include "cnxstring.hxx" +#include "cnxfont.hxx" +#include "crect.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CKeypadTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CKeypadTest Constructor + +CKeypadTest::CKeypadTest() +{ + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; + m_buttonWidth = 0; + m_buttonHeight = 0; + m_displayHeight = 0; +} + +// CKeypadTest Descriptor + +CKeypadTest::~CKeypadTest() +{ + disconnect(); +} + +// Connect to the NX server + +bool CKeypadTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CKEYPADTEST_BGCOLOR)) + { + message("CKeypadTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CKeypadTest::disconnect(void) +{ + // Destroy the text box + + if (m_textbox) + { + delete m_textbox; + } + + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + } + + // Destroy the widget control + + if (m_widgetControl) + { + delete m_widgetControl; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CKeypadTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CKeypadTest::createGraphics: Failed to create CBgWindow instance\n"); + delete m_widgetControl; + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CKeypadTest::createGraphics: Failed to open background window\n"); + delete m_bgWindow; + m_bgWindow = (CBgWindow*)0; + return false; + } + + // Then determine the display size + + setDisplaySize(); + return true; +} + +// Pick size of the display + +void CKeypadTest::setDisplaySize(void) +{ + // Get the height and width of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + message("CKeypadTest::createGraphics: Failed to get window size\n"); + return; + } + + // Pick a height and width of a button. Here we use inside information + // that the number of rows and columns in the keypad. This should not matter in + // a "real" application. + + // Lets aim for a width of 4*60 = 240 + + if (windowSize.w > KEYPAD_NCOLUMNS*60) + { + m_buttonWidth = 60; + } + else + { + // Otherwise, let's use what we have + + m_buttonWidth = windowSize.w >> 2; + } + + // Lets aim for a height of 7*32 = 224. But lets bump up the number of rows + // to allow one for the text box. + + if (windowSize.h > (KEYPAD_NROWS+1)*32) + { + m_buttonHeight = 32; + m_displayHeight = (KEYPAD_NROWS+1)*32; + } + else + { + // Otherwise, let's use what we have + + m_buttonHeight = windowSize.h >> 3; + m_displayHeight = windowSize.h; + } +} + +// Create a CKeypad instance + +CKeypad *CKeypadTest::createKeypad(void) +{ + // Get the height and width of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + message("CKeypadTest::createGraphics: Failed to get window size\n"); + return (CKeypad *)NULL; + } + + // Pick a height and width. Here we use inside information that the number + // of rows in the keypad is 7. This should not matter in a "real" application. + + nxgl_coord_t keypadWidth = KEYPAD_NCOLUMNS * m_buttonWidth; + nxgl_coord_t keypadHeight = KEYPAD_NROWS * m_buttonHeight; + + // Pick an X/Y position such that the keypad will be centered in the display + + nxgl_coord_t keypadOffset = m_displayHeight - keypadHeight; + + nxgl_coord_t keypadX = (windowSize.w - keypadWidth) >> 1; + nxgl_coord_t keypadY = keypadOffset + ((windowSize.h - m_displayHeight) >> 1); + + // Now we have enough information to create the keypad + + CKeypad *keypad = new CKeypad(m_widgetControl, getServer(), keypadX, keypadY, + keypadWidth, keypadHeight); + if (keypad) + { + // Create a text box to catch the keyboard inputs + + m_textbox = createTextBox(); + if (!m_textbox) + { + delete keypad; + keypad = (CKeypad *)NULL; + } + else + { + // Always show the cursor and wrap the cursor if it goes past the end + + m_textbox->showCursor(SHOW_CURSOR_ALWAYS); + m_textbox->wrapCursor(true); + + // Align text on the left + + m_textbox->setTextAlignmentHoriz(CTextBox::TEXT_ALIGNMENT_HORIZ_LEFT); + + // Configure the text box to receive the keyboard input + + keypad->addWidgetEventHandler(m_textbox); + } + } + + return keypad; +} + +// Create a CTextBox instance so that we can see the keypad output + +CTextBox *CKeypadTest::createTextBox(void) +{ + // Get the height and width of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + message("CKeypadTest::createGraphics: Failed to get window size\n"); + return (CTextBox *)NULL; + } + + // Pick a height and width. Here we use inside information that the number + // of rows in the keypad is 7. This should not matter in a "real" application. + + nxgl_coord_t textboxWidth = KEYPAD_NCOLUMNS * m_buttonWidth; + nxgl_coord_t textboxHeight = m_displayHeight - KEYPAD_NROWS * m_buttonHeight; + + // Pick an X/Y position such that the keypad will be centered in the display + + nxgl_coord_t textboxX = (windowSize.w - textboxWidth) >> 1; + nxgl_coord_t textboxY = (windowSize.h - m_displayHeight) >> 1; + + // Now we have enough information to create the TextBox + + return new CTextBox(m_widgetControl, textboxX, textboxY, + textboxWidth, textboxHeight, ""); +} + +// Draw the keypad + +void CKeypadTest::showKeypad(CKeypad *keypad) +{ + // Re-draw the keypad + + keypad->enable(); // Un-necessary, the widget is enabled by default + keypad->enableDrawing(); + keypad->redraw(); + + // Then redraw the text box + + m_textbox->enable(); // Un-necessary, the widget is enabled by default + m_textbox->enableDrawing(); + m_textbox->redraw(); +} + +// Perform a simulated mouse click on a button in the array. This method injects +// the mouse click through the NX heirarchy just as would real mouse +// hardward. + +void CKeypadTest::click(CKeypad *keypad, int column, int row) +{ + // nx_mousein is meant to be called by mouse handling software. + // Here we just inject a left-button click directly in the center of + // the selected button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // The the coorinates of the center of the button + + nxgl_coord_t buttonX = keypad->getX() + column * m_buttonWidth + (m_buttonWidth >> 1); + nxgl_coord_t buttonY = keypad->getY() + row * m_buttonHeight + (m_buttonHeight >> 1); + + // Then inject the mouse click + + (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_LEFTBUTTON); +} + +// The counterpart to click. This simulates a button release through +// the same mechanism. + +void CKeypadTest::release(CKeypad *keypad, int column, int row) +{ + // nx_mousein is meant to be called by mouse handling software. + // Here we just inject a left-button click directly in the center of + // the button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // The the coorinates of the center of the button + + nxgl_coord_t buttonX = keypad->getX() + + column * m_buttonWidth + + m_buttonWidth/2; + nxgl_coord_t buttonY = keypad->getY() + + row * m_buttonHeight + + m_buttonHeight/2; + + // Then inject the mouse release + + (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_NOBUTTONS); +} + +// Widget events are normally handled in a modal loop (by calling goModal()). +// However, for this case we know when there should be press and release +// events so we don't have to poll. We can just perform a one pass poll +// then check if the event was processed corredly. + +void CKeypadTest::poll(CKeypad *button) +{ + // Poll for mouse events + + m_widgetControl->pollEvents(button); + + // Limit the amount of text in the TextBox + + reverseAlignment(); +} + +// Start with left text alignment. When the text reaches the right sice +// of the text box, switch to right text alignment. + +void CKeypadTest::reverseAlignment(void) +{ + // Get the current horizontal text alignment + + CTextBox::TextAlignmentHoriz hAlign = m_textbox->getTextAlignmentHoriz(); + + // Are we still using left text alignment? + + if (hAlign == CTextBox::TEXT_ALIGNMENT_HORIZ_LEFT) + { + // Yes.. Get the string in the text box + + CNxString string = m_textbox->getText(); + + // Get the font + + CNxFont *font = m_textbox->getFont(); + + // Get the TextBox bounding box + + CRect rect; + m_textbox->getRect(rect); + + // When the length of string approaches the width of the display + // region, then switch to right text alignment + + int mxWidth = font->getMaxWidth(); + if (font->getStringWidth(string) + mxWidth >= rect.getWidth()) + { + // Switch to right text alignment + + m_textbox->setTextAlignmentHoriz(CTextBox::TEXT_ALIGNMENT_HORIZ_RIGHT); + } + } +} + diff --git a/NxWidgets/UnitTests/CKeypad/ckeypadtest.hxx b/NxWidgets/UnitTests/CKeypad/ckeypadtest.hxx new file mode 100644 index 000000000..820113960 --- /dev/null +++ b/NxWidgets/UnitTests/CKeypad/ckeypadtest.hxx @@ -0,0 +1,192 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CKeypad/ckeypadtest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CKEYPAD_CKEYPADTEST_HXX +#define __UNITTESTS_CKEYPAD_CKEYPADTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cnxfont.hxx" +#include "cnxstring.hxx" +#include "ctextbox.hxx" +#include "ckeypad.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CKEYPADTEST_BGCOLOR +# define CONFIG_CKEYPADTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME ckeypad_main +# define MAIN_STRING "ckeypad_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +// This is the size of the keypad + +#define KEYPAD_NROWS 7 +#define KEYPAD_NCOLUMNS 4 + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CKeypadTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The widget control for the window + CBgWindow *m_bgWindow; // Background window instance + CTextBox *m_textbox; // TextBox to show the key presses + nxgl_coord_t m_buttonWidth; // The width of one button + nxgl_coord_t m_buttonHeight; // The height of one button + nxgl_coord_t m_displayHeight; // The height of the display + + // Pick size of the display + + void setDisplaySize(void); + + // Start with left text alignment. When the text reaches the right sice + // of the text box, switch to right text alignment. + + void reverseAlignment(void); + + // Create a CTextBox instance so that we can see the keypad output + + CTextBox *createTextBox(void); + +public: + + // Constructor/destructors + + CKeypadTest(); + ~CKeypadTest(); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a CKeypad instance. This method will show you how to create + // a CKeypad widget + + CKeypad *createKeypad(void); + + // Draw the keypad. This method illustrates how to draw the CKeypad widget. + + void showKeypad(CKeypad *keypad); + + // Perform a simulated mouse click on a button in the array. This method injects + // the mouse click through the NX heirarchy just as would real mouse + // hardward. + + void click(CKeypad *keypad, int column, int row); + + // The counterpart to click. This simulates a button release through + // the same mechanism. + + void release(CKeypad *keypad, int column, int row); + + // Widget events are normally handled in a model loop (by calling goModel()). + // However, for this case we know when there should be press and release + // events so we don't have to poll. We can just perform a one pass poll + // then check if the event was processed corredly. + + void poll(CKeypad *keypad); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // __UNITTESTS_CKEYPAD_CKEYPADTEST_HXX diff --git a/NxWidgets/UnitTests/CKeypad/main.cxx b/NxWidgets/UnitTests/CKeypad/main.cxx new file mode 100644 index 000000000..1c7679ee2 --- /dev/null +++ b/NxWidgets/UnitTests/CKeypad/main.cxx @@ -0,0 +1,274 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CKeypad/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "cnxstring.hxx" +#include "ckeypadtest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static unsigned int g_mmInitial; +static unsigned int g_mmPrevious; +static unsigned int g_mmPeak; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(unsigned int previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("%s: Before: %8d After: %8d Change: %8d\n", + msg, previous, mmcurrent.uordblks, mmcurrent.uordblks - previous); + + /* Set up for the next test */ + + g_mmPrevious = mmcurrent.uordblks; + if ((unsigned int)mmcurrent.uordblks > g_mmPeak) + { + g_mmPeak = mmcurrent.uordblks; + } +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mmInitial = mmcurrent.uordblks; + g_mmPrevious = mmcurrent.uordblks; + g_mmPeak = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Name: clickButtons +///////////////////////////////////////////////////////////////////////////// + +static void clickButtons(CKeypadTest *test, CKeypad *keypad) +{ + // Perform a simulated mouse click on a button in the keypad + + for (int j = 0; j < KEYPAD_NROWS; j++) + { + for (int i = 0; i < KEYPAD_NCOLUMNS; i++) + { + printf(MAIN_STRING "Click the button (%d,%d)\n", i, j); + test->click(keypad, i, j); + + // Poll for the mouse click event + + test->poll(keypad); + + // Is anything clicked? + + int clickColumn; + int clickRow; + if (keypad->isButtonClicked(clickColumn, clickRow)) + { + printf(MAIN_STRING "%s: Button (%d, %d) is clicked\n", + clickColumn == i && clickRow == j ? "OK" : "ERROR", + clickColumn, clickRow); + } + else + { + printf(MAIN_STRING "ERROR: No button is clicked\n"); + } + + // Wait a bit, then release the mouse button + + usleep(250*1000); + test->release(keypad, i, j); + + // Poll for the mouse release event (of course this can hang if something fails) + + test->poll(keypad); + if (keypad->isButtonClicked(clickColumn, clickRow)) + { + printf(MAIN_STRING "ERROR: Button (%d, %d) is clicked\n", + clickColumn, clickRow); + } + + usleep(500*1000); + } + } + updateMemoryUsage(g_mmPrevious, "After pushing buttons"); +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the keypad test + + printf(MAIN_STRING "Create CKeypadTest instance\n"); + CKeypadTest *test = new CKeypadTest(); + updateMemoryUsage(g_mmPrevious, "After creating CKeypadTest"); + + // Connect the NX server + + printf(MAIN_STRING "Connect the CKeypadTest instance to the NX server\n"); + if (!test->connect()) + { + printf(MAIN_STRING "Failed to connect the CKeypadTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmPrevious, "After connecting to the server"); + + // Create a window to draw into + + printf(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + printf(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmPrevious, "After creating a window"); + + // Create a CKeypad instance + + CKeypad *keypad = test->createKeypad(); + if (!keypad) + { + printf(MAIN_STRING "Failed to create a keypad\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmPrevious, "After creating CKeypad"); + + // Show the keypad in alphabetic mode + + printf(MAIN_STRING "Show the keypad in alphabetic mode\n"); + keypad->setKeypadMode(false); + test->showKeypad(keypad); + sleep(1); + + // Then click some buttons + + clickButtons(test, keypad); + sleep(1); + + // Show the keypad in numeric mode + + printf(MAIN_STRING "Show the keypad in numeric mode\n"); + keypad->setKeypadMode(true); + sleep(1); + + // Then click some buttons + + clickButtons(test, keypad); + sleep(1); + + // Clean up and exit + + printf(MAIN_STRING "Clean-up and exit\n"); + delete keypad; + updateMemoryUsage(g_mmPrevious, "After deleting the keypad"); + delete test; + updateMemoryUsage(g_mmPrevious, "After deleting the test"); + updateMemoryUsage(g_mmInitial, "Final memory usage"); + message("Peak memory usage: %8d\n", g_mmPeak - g_mmInitial); + return 0; +} + diff --git a/NxWidgets/UnitTests/CLabel/Makefile b/NxWidgets/UnitTests/CLabel/Makefile new file mode 100644 index 000000000..163d04175 --- /dev/null +++ b/NxWidgets/UnitTests/CLabel/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CLabel/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx clabeltest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = clabel +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CLabel/clabeltest.cxx b/NxWidgets/UnitTests/CLabel/clabeltest.cxx new file mode 100644 index 000000000..ef78cc3ce --- /dev/null +++ b/NxWidgets/UnitTests/CLabel/clabeltest.cxx @@ -0,0 +1,263 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CLabel/clabeltest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "clabeltest.hxx" +#include "cbgwindow.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CLabelTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CLabelTest Constructor + +CLabelTest::CLabelTest() +{ + m_bgWindow = (CBgWindow *)NULL; + m_nxFont = (CNxFont *)NULL; + m_text = (CNxString *)NULL; +} + +// CLabelTest Descriptor + +CLabelTest::~CLabelTest() +{ + disconnect(); +} + +// Connect to the NX server + +bool CLabelTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Create the default font instance + + m_nxFont = new CNxFont(NXFONT_DEFAULT, + CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR, + CONFIG_NXWIDGETS_TRANSPARENT_COLOR); + if (!m_nxFont) + { + printf("CLabelTest::connect: Failed to create the default font\n"); + } + + // Set the background color + + if (!setBackgroundColor(CONFIG_CLABELTEST_BGCOLOR)) + { + printf("CLabelTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CLabelTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + } + + // Free the display string + + if (m_text) + { + delete m_text; + m_text = (CNxString *)NULL; + } + + // Free the default font + + if (m_nxFont) + { + delete m_nxFont; + m_nxFont = (CNxFont *)NULL; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CLabelTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + printf("CLabelTest::createGraphics: Failed to create CBgWindow instance\n"); + delete m_widgetControl; + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + printf("CLabelTest::createGraphics: Failed to open background window\n"); + delete m_bgWindow; + m_bgWindow = (CBgWindow*)0; + return false; + } + + return true; +} + +// Create a CLabel instance + +CLabel *CLabelTest::createLabel(FAR const char *text) +{ + // Get the width of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + printf("CLabelTest::createGraphics: Failed to get window size\n"); + return (CLabel *)NULL; + } + + // Create a CNxString instance to contain the C string + + m_text = new CNxString(text); + + // Get the height and width of the text display area + + nxgl_coord_t stringWidth = m_nxFont->getStringWidth(*m_text); + nxgl_coord_t stringHeight = (nxgl_coord_t)m_nxFont->getHeight(); + + // The default CLabel has borders enabled with thickness of the border + // width. Add twice the thickness of the border to the width and height. (We + // could let CLabel do this for us by calling CLabel::getPreferredDimensions()) + + stringWidth += 2 * 1; + stringHeight += 2 * 1; + + // Pick an X/Y position such that the label will be centered in the display + + nxgl_coord_t labelX; + if (stringWidth >= windowSize.w) + { + labelX = 0; + } + else + { + labelX = (windowSize.w - stringWidth) >> 1; + } + + nxgl_coord_t labelY; + if (stringHeight >= windowSize.h) + { + labelY = 0; + } + else + { + labelY = (windowSize.h - stringHeight) >> 1; + } + + // Now we have enough information to create the label + + return new CLabel(m_widgetControl, labelX, labelY, stringWidth, stringHeight, *m_text); +} + +// Draw the label + +void CLabelTest::showLabel(CLabel *label) +{ + label->enable(); + label->enableDrawing(); + label->redraw(); + label->disableDrawing(); +} diff --git a/NxWidgets/UnitTests/CLabel/clabeltest.hxx b/NxWidgets/UnitTests/CLabel/clabeltest.hxx new file mode 100644 index 000000000..2d404b2df --- /dev/null +++ b/NxWidgets/UnitTests/CLabel/clabeltest.hxx @@ -0,0 +1,148 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CLabel/clabeltest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CLABEL_CLABELTEST_HXX +#define __UNITTESTS_CLABEL_CLABELTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cnxfont.hxx" +#include "cnxstring.hxx" +#include "clabel.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CLABELTEST_BGCOLOR +# define CONFIG_CLABELTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +#ifndef CONFIG_CLABELTEST_FONTCOLOR +# define CONFIG_CLABELTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME clabel_main +# define MAIN_STRING "clabel_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CLabelTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CNxFont *m_nxFont; // Default font + CBgWindow *m_bgWindow; // Background window instance + CNxString *m_text; // The label string + +public: + // Constructor/destructors + + CLabelTest(); + ~CLabelTest(); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a CLabel instance. This method will show you how to create + // a CLabel widget + + CLabel *createLabel(FAR const char *text); + + // Draw the label. This method illustrates how to draw the CLabel widget. + + void showLabel(CLabel *label); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + + +#endif // __UNITTESTS_CLABEL_CLABELTEST_HXX diff --git a/NxWidgets/UnitTests/CLabel/main.cxx b/NxWidgets/UnitTests/CLabel/main.cxx new file mode 100644 index 000000000..953e6afbc --- /dev/null +++ b/NxWidgets/UnitTests/CLabel/main.cxx @@ -0,0 +1,130 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CLabel/main.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 <nuttx/init.h> +#include <cstdio> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "clabeltest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static const char g_hello[] = "Hello, World!"; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Create an instance of the font test + + printf(MAIN_STRING "Create CLabelTest instance\n"); + CLabelTest *test = new CLabelTest(); + + // Connect the NX server + + printf(MAIN_STRING "Connect the CLabelTest instance to the NX server\n"); + if (!test->connect()) + { + printf(MAIN_STRING "Failed to connect the CLabelTest instance to the NX server\n"); + delete test; + return 1; + } + + // Create a window to draw into + + printf(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + printf(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + + // Create a CLabel instance + + CLabel *label = test->createLabel(g_hello); + if (!label) + { + printf(MAIN_STRING "Failed to create a label\n"); + delete test; + return 1; + } + + // Show the label + + test->showLabel(label); + sleep(5); + + // Clean up and exit + + printf(MAIN_STRING "Clean-up and exit\n"); + delete label; + delete test; + return 0; +} + diff --git a/NxWidgets/UnitTests/CLatchButton/Makefile b/NxWidgets/UnitTests/CLatchButton/Makefile new file mode 100644 index 000000000..ea6e7d662 --- /dev/null +++ b/NxWidgets/UnitTests/CLatchButton/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CLatchButton/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx clatchbuttontest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = clatchbutton +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CLatchButton/clatchbuttontest.cxx b/NxWidgets/UnitTests/CLatchButton/clatchbuttontest.cxx new file mode 100644 index 000000000..2b41eca63 --- /dev/null +++ b/NxWidgets/UnitTests/CLatchButton/clatchbuttontest.cxx @@ -0,0 +1,321 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CLatchButton/clatchbuttontest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "clatchbuttontest.hxx" +#include "cbgwindow.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CLatchButtonTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CLatchButtonTest Constructor + +CLatchButtonTest::CLatchButtonTest() +{ + m_bgWindow = (CBgWindow *)NULL; + m_nxFont = (CNxFont *)NULL; + m_text = (CNxString *)NULL; +} + +// CLatchButtonTest Descriptor + +CLatchButtonTest::~CLatchButtonTest() +{ + disconnect(); +} + +// Connect to the NX server + +bool CLatchButtonTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Create the default font instance + + m_nxFont = new CNxFont(NXFONT_DEFAULT, + CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR, + CONFIG_NXWIDGETS_TRANSPARENT_COLOR); + if (!m_nxFont) + { + printf("CLatchButtonTest::connect: Failed to create the default font\n"); + } + + // Set the background color + + if (!setBackgroundColor(CONFIG_CLATCHBUTTONTEST_BGCOLOR)) + { + printf("CLatchButtonTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CLatchButtonTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + } + + // Free the display string + + if (m_text) + { + delete m_text; + m_text = (CNxString *)NULL; + } + + // Free the default font + + if (m_nxFont) + { + delete m_nxFont; + m_nxFont = (CNxFont *)NULL; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CLatchButtonTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + printf("CLatchButtonTest::createGraphics: Failed to create CBgWindow instance\n"); + delete m_widgetControl; + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + printf("CLatchButtonTest::createGraphics: Failed to open background window\n"); + delete m_bgWindow; + m_bgWindow = (CBgWindow*)0; + return false; + } + + return true; +} + +// Create a CLatchButton instance + +CLatchButton *CLatchButtonTest::createButton(FAR const char *text) +{ + // Get the width of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + printf("CLatchButtonTest::createGraphics: Failed to get window size\n"); + return (CLatchButton *)NULL; + } + + // Create a CNxString instance to contain the C string + + m_text = new CNxString(text); + + // Get the height and width of the text display area + + nxgl_coord_t stringWidth = m_nxFont->getStringWidth(*m_text); + nxgl_coord_t stringHeight = (nxgl_coord_t)m_nxFont->getHeight(); + + // The default CLatchButton has borders enabled with thickness of the border + // width. Add twice the thickness of border the to the width and height. (We + // could let CLatchButton do this for us by calling + // CLatchButton::getPreferredDimensions()) + + stringWidth += 2 * 1; + stringHeight += 2 * 1; + + // Pick an X/Y position such that the button will be centered in the display + + nxgl_coord_t buttonX; + if (stringWidth >= windowSize.w) + { + buttonX = 0; + } + else + { + buttonX = (windowSize.w - stringWidth) >> 1; + } + + nxgl_coord_t buttonY; + if (stringHeight >= windowSize.h) + { + buttonY = 0; + } + else + { + buttonY = (windowSize.h - stringHeight) >> 1; + } + + // Save the center position of the button for use by click and release + + m_center.x = buttonX + (stringWidth >> 1); + m_center.y = buttonY + (stringHeight >> 1); + + // Now we have enough information to create the button + + return new CLatchButton(m_widgetControl, buttonX, buttonY, stringWidth, stringHeight, *m_text); +} + +// Draw the button + +void CLatchButtonTest::showButton(CLatchButton *button) +{ + button->enable(); // Un-necessary, the widget is enabled by default + button->enableDrawing(); + button->redraw(); +} + +// Perform a simulated mouse click on the button. This method injects +// the mouse click through the NX heirarchy just as would real mouse +// hardward. + +void CLatchButtonTest::click(void) +{ + // nx_mousein is meant to be called by mouse handling software. + // Here we just inject a left-button click directly in the center of + // the button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // Then inject the mouse click + + (void)nx_mousein(handle, m_center.x, m_center.y, NX_MOUSE_LEFTBUTTON); +} + +// The counterpart to click. This simulates a button release through +// the same mechanism. + +void CLatchButtonTest::release(void) +{ + // nx_mousein is meant to be called by mouse handling software. + // Here we just inject a left-button click directly in the center of + // the button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // Then inject the mouse click + + (void)nx_mousein(handle, m_center.x, m_center.y, NX_MOUSE_NOBUTTONS); +} + +// Widget events are normally handled in a modal loop (by calling goModal()). +// However, for this case we know when there should be press and release +// events so we don't have to poll. We can just perform a one pass poll. + +void CLatchButtonTest::poll(CLatchButton *button) +{ + // Poll for mouse events + + m_widgetControl->pollEvents(button); +} + diff --git a/NxWidgets/UnitTests/CLatchButton/clatchbuttontest.hxx b/NxWidgets/UnitTests/CLatchButton/clatchbuttontest.hxx new file mode 100644 index 000000000..22ded3d77 --- /dev/null +++ b/NxWidgets/UnitTests/CLatchButton/clatchbuttontest.hxx @@ -0,0 +1,165 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CLatchButton/clatchbuttontest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CLATCHBUTTON_CLATCHBUTTONTEST_HXX +#define __UNITTESTS_CLATCHBUTTON_CLATCHBUTTONTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cnxfont.hxx" +#include "cnxstring.hxx" +#include "clatchbutton.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CLATCHBUTTONTEST_BGCOLOR +# define CONFIG_CLATCHBUTTONTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +#ifndef CONFIG_CLATCHBUTTONTEST_FONTCOLOR +# define CONFIG_CLATCHBUTTONTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME clatchbutton_main +# define MAIN_STRING "clatchbutton_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CLatchButtonTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CNxFont *m_nxFont; // Default font + CBgWindow *m_bgWindow; // Background window instance + CNxString *m_text; // The button string + struct nxgl_point_s m_center; // X, Y position the center of the button + +public: + // Constructor/destructors + + CLatchButtonTest(void); + ~CLatchButtonTest(void); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a CLatchButton instance. This method will show you how to create + // a CLatchButton widget + + CLatchButton *createButton(FAR const char *text); + + // Draw the button. This method illustrates how to draw the CLatchButton widget. + + void showButton(CLatchButton *button); + + // Perform a simulated mouse click on the button. This method injects + // the mouse click through the NX heirarchy just as would real mouse + // hardward. + + void click(void); + + // The counterpart to click. This simulates a button release through + // the same mechanism. + + void release(void); + + // Widget events are normally handled in a model loop (by calling goModel()). + // However, for this case we know when there should be press and release + // events so we don't have to poll. We can just perform a one pass poll. + + void poll(CLatchButton *button); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // __UNITTESTS_CLATCHBUTTON_CLATCHBUTTONTEST_HXX diff --git a/NxWidgets/UnitTests/CLatchButton/main.cxx b/NxWidgets/UnitTests/CLatchButton/main.cxx new file mode 100644 index 000000000..d51f613c1 --- /dev/null +++ b/NxWidgets/UnitTests/CLatchButton/main.cxx @@ -0,0 +1,199 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CLatchButton/main.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 <nuttx/init.h> +#include <cstdio> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "clatchbuttontest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static const char g_pushme[] = "Push Me"; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: showButtonState +///////////////////////////////////////////////////////////////////////////// + +static void showButtonState(CLatchButton *button, bool &clicked, bool &latched) +{ + bool nowClicked = button->isClicked(); + bool nowLatched = button->isLatched(); + + printf(MAIN_STRING "Button state: %s and %s\n", + nowClicked ? "clicked" : "released", + nowLatched ? "latched" : "unlatched"); + + if (clicked != nowClicked || latched != nowLatched) + { + printf(MAIN_STRING "ERROR: Expected %s and %s\n", + clicked ? "clicked" : "released", + latched ? "latched" : "unlatched"); + + clicked = nowClicked; + latched = nowLatched; + } +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Create an instance of the font test + + printf(MAIN_STRING "Create CLatchButtonTest instance\n"); + CLatchButtonTest *test = new CLatchButtonTest(); + + // Connect the NX server + + printf(MAIN_STRING "Connect the CLatchButtonTest instance to the NX server\n"); + if (!test->connect()) + { + printf(MAIN_STRING "Failed to connect the CLatchButtonTest instance to the NX server\n"); + delete test; + return 1; + } + + // Create a window to draw into + + printf(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + printf(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + + // Create a CLatchButton instance + + CLatchButton *button = test->createButton(g_pushme); + if (!button) + { + printf(MAIN_STRING "Failed to create a button\n"); + delete test; + return 1; + } + + // Show the button + + printf(MAIN_STRING "Show the button\n"); + test->showButton(button); + + bool clicked = false; + bool latched = false; + showButtonState(button, clicked, latched); + + // Toggle the button state a few times + + for (int i = 0; i < 8; i++) + { + // Wait two seconds, then perform a simulated mouse click on the button + + sleep(2); + printf(MAIN_STRING "Click the button\n"); + test->click(); + test->poll(button); + + // Test the button state it should be clicked with the latch state + // toggled + + clicked = true; + latched = !latched; + showButtonState(button, clicked, latched); + + // And release the button after 0.5 seconds + + usleep(500 * 1000); + printf(MAIN_STRING "Release the button\n"); + test->release(); + test->poll(button); + + // Test the button state it should be unclicked with the latch state + // unchanged + + clicked = false; + showButtonState(button, clicked, latched); + fflush(stdout); + } + + // Wait a few more seconds so that the tester can ponder the result + + sleep(3); + + // Clean up and exit + + printf(MAIN_STRING "Clean-up and exit\n"); + delete button; + delete test; + return 0; +} + diff --git a/NxWidgets/UnitTests/CLatchButtonArray/Makefile b/NxWidgets/UnitTests/CLatchButtonArray/Makefile new file mode 100644 index 000000000..faa9d8fd9 --- /dev/null +++ b/NxWidgets/UnitTests/CLatchButtonArray/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CLatchButtonArray/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx clatchbuttonarraytest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = clatchbuttonarray +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.cxx b/NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.cxx new file mode 100644 index 000000000..5b1737e06 --- /dev/null +++ b/NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.cxx @@ -0,0 +1,301 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "clatchbuttonarraytest.hxx" +#include "cbgwindow.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CLatchButtonArrayTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CLatchButtonArrayTest Constructor + +CLatchButtonArrayTest::CLatchButtonArrayTest() +{ + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; +} + +// CLatchButtonArrayTest Descriptor + +CLatchButtonArrayTest::~CLatchButtonArrayTest() +{ + disconnect(); +} + +// Connect to the NX server + +bool CLatchButtonArrayTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CLATCHBUTTONARRAYTEST_BGCOLOR)) + { + message("CLatchButtonArrayTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CLatchButtonArrayTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + } + + // Destroy the widget control + + if (m_widgetControl) + { + delete m_widgetControl; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CLatchButtonArrayTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CLatchButtonArrayTest::createGraphics: Failed to create CBgWindow instance\n"); + delete m_widgetControl; + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CLatchButtonArrayTest::createGraphics: Failed to open background window\n"); + delete m_bgWindow; + m_bgWindow = (CBgWindow*)0; + return false; + } + + return true; +} + +// Create a CLatchButtonArray instance + +CLatchButtonArray *CLatchButtonArrayTest::createButtonArray(void) +{ + // Get the width of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + message("CLatchButtonArrayTest::createGraphics: Failed to get window size\n"); + return (CLatchButtonArray *)NULL; + } + + // Pick an X/Y position such that the button array will be centered in the display + + nxgl_coord_t buttonArrayX; + if (BUTTONARRAY_WIDTH >= windowSize.w) + { + buttonArrayX = 0; + } + else + { + buttonArrayX = (windowSize.w - BUTTONARRAY_WIDTH) >> 1; + } + + nxgl_coord_t buttonArrayY; + if (BUTTONARRAY_HEIGHT >= windowSize.h) + { + buttonArrayY = 0; + } + else + { + buttonArrayY = (windowSize.h - BUTTONARRAY_HEIGHT) >> 1; + } + + // Now we have enough information to create the button array + + return new CLatchButtonArray(m_widgetControl, + buttonArrayX, buttonArrayY, + BUTTONARRAY_NCOLUMNS, BUTTONARRAY_NROWS, + BUTTONARRAY_BUTTONWIDTH, BUTTONARRAY_BUTTONHEIGHT); +} + +// Draw the button array + +void CLatchButtonArrayTest::showButton(CLatchButtonArray *buttonArray) +{ + buttonArray->enable(); // Un-necessary, the widget is enabled by default + buttonArray->enableDrawing(); + buttonArray->redraw(); +} + +// Perform a simulated mouse click on a button in the array. This method injects +// the mouse click through the NX heirarchy just as would real mouse +// hardward. + +void CLatchButtonArrayTest::click(CLatchButtonArray *buttonArray, int column, int row) +{ + // nx_mousein is meant to be called by mouse handling software. + // Here we just inject a left-button click directly in the center of + // the selected button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // The the coorinates of the center of the button + + nxgl_coord_t buttonX = buttonArray->getX() + + column * BUTTONARRAY_BUTTONWIDTH + + BUTTONARRAY_BUTTONWIDTH/2; + nxgl_coord_t buttonY = buttonArray->getY() + + row * BUTTONARRAY_BUTTONHEIGHT + + BUTTONARRAY_BUTTONHEIGHT/2; + + // Then inject the mouse click + + (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_LEFTBUTTON); +} + +// The counterpart to click. This simulates a button release through +// the same mechanism. + +void CLatchButtonArrayTest::release(CLatchButtonArray *buttonArray, int column, int row) +{ + // nx_mousein is meant to be called by mouse handling software. + // Here we just inject a left-button click directly in the center of + // the button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // The the coorinates of the center of the button + + nxgl_coord_t buttonX = buttonArray->getX() + + column * BUTTONARRAY_BUTTONWIDTH + + BUTTONARRAY_BUTTONWIDTH/2; + nxgl_coord_t buttonY = buttonArray->getY() + + row * BUTTONARRAY_BUTTONHEIGHT + + BUTTONARRAY_BUTTONHEIGHT/2; + + // Then inject the mouse release + + (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_NOBUTTONS); +} + +// Widget events are normally handled in a modal loop (by calling goModal()). +// However, for this case we know when there should be press and release +// events so we don't have to poll. We can just perform a one pass poll +// then check if the event was processed corredly. + +void CLatchButtonArrayTest::poll(CLatchButtonArray *button) +{ + // Poll for mouse events + + m_widgetControl->pollEvents(button); +} + diff --git a/NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx b/NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx new file mode 100644 index 000000000..89ed242e7 --- /dev/null +++ b/NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx @@ -0,0 +1,182 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CLatchButtonArray/clatchbuttonarraytest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CLATCHBUTTONARRAY_CLATCHBUTTONARRAYTEST_HXX +#define __UNITTESTS_CLATCHBUTTONARRAY_CLATCHBUTTONARRAYTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cnxfont.hxx" +#include "cnxstring.hxx" +#include "clatchbuttonarray.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CLATCHBUTTONARRAYTEST_BGCOLOR +# define CONFIG_CLATCHBUTTONARRAYTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +#ifndef CONFIG_CLATCHBUTTONARRAYTEST_FONTCOLOR +# define CONFIG_CLATCHBUTTONARRAYTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME clatchbuttonarray_main +# define MAIN_STRING "clatchbuttonarray_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +// The geometry of the button array + +#define BUTTONARRAY_NCOLUMNS 4 +#define BUTTONARRAY_NROWS 7 +#define BUTTONARRAY_BUTTONWIDTH 60 +#define BUTTONARRAY_BUTTONHEIGHT 32 +#define BUTTONARRAY_WIDTH (BUTTONARRAY_BUTTONWIDTH * BUTTONARRAY_NCOLUMNS) +#define BUTTONARRAY_HEIGHT (BUTTONARRAY_BUTTONHEIGHT * BUTTONARRAY_NROWS) + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CLatchButtonArrayTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The widget control for the window + CBgWindow *m_bgWindow; // Background window instance + +public: + // Constructor/destructors + + CLatchButtonArrayTest(); + ~CLatchButtonArrayTest(); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a CLatchButtonArray instance. This method will show you how to create + // a CLatchButtonArray widget + + CLatchButtonArray *createButtonArray(void); + + // Draw the button array. This method illustrates how to draw the CLatchButtonArray widget. + + void showButton(CLatchButtonArray *buttonArray); + + // Perform a simulated mouse click on a button in the array. This method injects + // the mouse click through the NX heirarchy just as would real mouse + // hardward. + + void click(CLatchButtonArray *buttonArray, int column, int row); + + // The counterpart to click. This simulates a button release through + // the same mechanism. + + void release(CLatchButtonArray *buttonArray, int column, int row); + + // Widget events are normally handled in a model loop (by calling goModel()). + // However, for this case we know when there should be press and release + // events so we don't have to poll. We can just perform a one pass poll + // then check if the event was processed corredly. + + void poll(CLatchButtonArray *buttonArray); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + + +#endif // __UNITTESTS_CLATCHBUTTONARRAY_CLATCHBUTTONARRAYTEST_HXX diff --git a/NxWidgets/UnitTests/CLatchButtonArray/main.cxx b/NxWidgets/UnitTests/CLatchButtonArray/main.cxx new file mode 100644 index 000000000..d38651ae9 --- /dev/null +++ b/NxWidgets/UnitTests/CLatchButtonArray/main.cxx @@ -0,0 +1,301 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CLatchButtonArray/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "cnxstring.hxx" +#include "clatchbuttonarraytest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static unsigned int g_mmInitial; +static unsigned int g_mmPrevious; +static unsigned int g_mmPeak; + +static FAR const char *g_buttonLabels[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" +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: showButtonState +///////////////////////////////////////////////////////////////////////////// + +static void showButtonState(CLatchButtonArray *buttonArray, int i, int j, + bool &clicked, bool &latched) +{ + bool nowClicked = buttonArray->isThisButtonClicked(i,j); + bool nowLatched = buttonArray->isThisButtonLatched(i,j); + + printf(MAIN_STRING "Button(%d,%d) state: %s and %s\n", + i, j, + nowClicked ? "clicked" : "released", + nowLatched ? "latched" : "unlatched"); + + if (clicked != nowClicked || latched != nowLatched) + { + printf(MAIN_STRING "ERROR: Expected %s and %s\n", + clicked ? "clicked" : "released", + latched ? "latched" : "unlatched"); + + clicked = nowClicked; + latched = nowLatched; + } +} + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(unsigned int previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("%s: Before: %8d After: %8d Change: %8d\n", + msg, previous, mmcurrent.uordblks, mmcurrent.uordblks - previous); + + /* Set up for the next test */ + + g_mmPrevious = mmcurrent.uordblks; + if ((unsigned int)mmcurrent.uordblks > g_mmPeak) + { + g_mmPeak = mmcurrent.uordblks; + } +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mmInitial = mmcurrent.uordblks; + g_mmPrevious = mmcurrent.uordblks; + g_mmPeak = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the button array test + + printf(MAIN_STRING "Create CLatchButtonArrayTest instance\n"); + CLatchButtonArrayTest *test = new CLatchButtonArrayTest(); + updateMemoryUsage(g_mmPrevious, "After creating CLatchButtonArrayTest"); + + // Connect the NX server + + printf(MAIN_STRING "Connect the CLatchButtonArrayTest instance to the NX server\n"); + if (!test->connect()) + { + printf(MAIN_STRING "Failed to connect the CLatchButtonArrayTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmPrevious, "After connecting to the server"); + + // Create a window to draw into + + printf(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + printf(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmPrevious, "After creating a window"); + + // Create a CLatchButtonArray instance + + CLatchButtonArray *buttonArray = test->createButtonArray(); + if (!buttonArray) + { + printf(MAIN_STRING "Failed to create a button array\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmPrevious, "After creating CLatchButtonArray"); + + // Add the labels to each button + + FAR const char **ptr = g_buttonLabels; + for (int j = 0; j < BUTTONARRAY_NROWS; j++) + { + for (int i = 0; i < BUTTONARRAY_NCOLUMNS; i++) + { + printf(MAIN_STRING "Label (%d,%d): %s\n", i, j, *ptr); + CNxString string = *ptr++; + buttonArray->setText(i, j, string); + } + } + updateMemoryUsage(g_mmPrevious, "After adding labels to the buttons"); + + // Show the button array + + printf(MAIN_STRING "Show the button array\n"); + test->showButton(buttonArray); + sleep(1); + + // Then perform a simulated mouse click on a button in the array + + bool clicked = false; + bool latched = false; + + for (int j = 0; j < BUTTONARRAY_NROWS; j++) + { + for (int i = 0; i < BUTTONARRAY_NCOLUMNS; i++) + { + // Initially, this button should be neither clicked nor latched + + clicked = false; + latched = false; + showButtonState(buttonArray, i, j, clicked, latched); + + printf(MAIN_STRING "Click the button (%d,%d)\n", i, j); + test->click(buttonArray, i, j); + + // Poll for the mouse click event + + test->poll(buttonArray); + + // Now it should be clicked and latched + + clicked = true; + latched = true; + showButtonState(buttonArray, i, j, clicked, latched); + + // Wait a bit, then release the mouse button + + usleep(200*1000); + test->release(buttonArray, i, j); + + // Poll for the mouse release event (of course this can hang if something fails) + + test->poll(buttonArray); + + // Now it should be un-clicked and latched + + clicked = false; + latched = true; + showButtonState(buttonArray, i, j, clicked, latched); + + usleep(300*1000); + } + } + updateMemoryUsage(g_mmPrevious, "After pushing buttons"); + + // Clean up and exit + + printf(MAIN_STRING "Clean-up and exit\n"); + delete buttonArray; + updateMemoryUsage(g_mmPrevious, "After deleting the button array"); + delete test; + updateMemoryUsage(g_mmPrevious, "After deleting the test"); + updateMemoryUsage(g_mmInitial, "Final memory usage"); + message("Peak memory usage: %8d\n", g_mmPeak - g_mmInitial); + return 0; +} + diff --git a/NxWidgets/UnitTests/CListBox/Makefile b/NxWidgets/UnitTests/CListBox/Makefile new file mode 100644 index 000000000..9f3d5721d --- /dev/null +++ b/NxWidgets/UnitTests/CListBox/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CListBox/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx clistboxtest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = clistbox +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CListBox/clistboxtest.cxx b/NxWidgets/UnitTests/CListBox/clistboxtest.cxx new file mode 100644 index 000000000..cd41dacc7 --- /dev/null +++ b/NxWidgets/UnitTests/CListBox/clistboxtest.cxx @@ -0,0 +1,224 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CListBox/clistboxtest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "cbgwindow.hxx" +#include "clistboxtest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CListBoxTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CListBoxTest Constructor + +CListBoxTest::CListBoxTest() +{ + // Initialize state data + + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; +} + +// CListBoxTest Descriptor + +CListBoxTest::~CListBoxTest(void) +{ + disconnect(); +} + +// Connect to the NX server + +bool CListBoxTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CLISTBOXTEST_BGCOLOR)) + { + message("CListBoxTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CListBoxTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + m_bgWindow = (CBgWindow *)NULL; + } + + // Free the widget control instance + + if (m_widgetControl) + { + delete m_widgetControl; + m_widgetControl = (CWidgetControl *)NULL; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CListBoxTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CListBoxTest::createWindow: Failed to create CBgWindow instance\n"); + disconnect(); + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CListBoxTest::createWindow: Failed to open background window\n"); + disconnect(); + return false; + } + + return true; +} + +// Create a listbox in the center of the window + +CListBox *CListBoxTest::createListBox(void) +{ + // Get the size of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + printf("CListBoxTest::createListBox: Failed to get window size\n"); + disconnect(); + return false; + } + + // Put the listbox in the center of the display + + nxgl_coord_t listboxWidth = windowSize.w >> 1; + nxgl_coord_t listboxX = windowSize.w >> 2; + + nxgl_coord_t listboxHeight = windowSize.h >> 1; + nxgl_coord_t listboxY = windowSize.h >> 2; + + // Create the listbox + + CListBox *listbox = new CListBox(m_widgetControl, + listboxX, listboxY, + listboxWidth, listboxHeight); + if (!listbox) + { + printf("CListBoxTest::createListBox: Failed to create CListBox\n"); + disconnect(); + } + return listbox; +} + +// (Re-)draw the listbox. + +void CListBoxTest::showListBox(CListBox *listbox) +{ + listbox->enable(); // Un-necessary, the widget is enabled by default + listbox->enableDrawing(); + listbox->redraw(); +} diff --git a/NxWidgets/UnitTests/CListBox/clistboxtest.hxx b/NxWidgets/UnitTests/CListBox/clistboxtest.hxx new file mode 100644 index 000000000..5cc356849 --- /dev/null +++ b/NxWidgets/UnitTests/CListBox/clistboxtest.hxx @@ -0,0 +1,147 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CListBox/clistboxtest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CLISTBOX_CLISTBOXTEST_HXX +#define __UNITTESTS_CLISTBOX_CLISTBOXTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "clistbox.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CLISTBOXTEST_BGCOLOR +# define CONFIG_CLISTBOXTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME clistbox_main +# define MAIN_STRING "clistbox_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CListBoxTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CBgWindow *m_bgWindow; // Background window instance + +public: + // Constructor/destructors + + CListBoxTest(void); + ~CListBoxTest(void); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a listbox in the center of the window + + CListBox *createListBox(void); + + // (Re-)draw the listbox. + + void showListBox(CListBox *listbox); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // __UNITTESTS_CLISTBOX_CLISTBOXTEST_HXX diff --git a/NxWidgets/UnitTests/CListBox/main.cxx b/NxWidgets/UnitTests/CListBox/main.cxx new file mode 100644 index 000000000..5783e255d --- /dev/null +++ b/NxWidgets/UnitTests/CListBox/main.cxx @@ -0,0 +1,327 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CListBox/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "clistboxtest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static unsigned int g_mmInitial; +static unsigned int g_mmPrevious; +static unsigned int g_mmPeak; + +static FAR const char *g_options[] = +{ + "American groundnut (Apios americana)", + "Azuki bean (Vigna angularis)", + "Black-eyed pea (Vigna unguiculata subsp. unguiculata)", + "Chickpea (Cicer arietinum)", + "Common bean (Phaseolus vulgaris)", + "Drumstick (Moringa oleifera)", + "Dolichos bean (Lablab purpureus)", + "Fava bean (Vicia faba)", + "Garbanzo (Cicer arietinum)", + "Green bean (Phaseolus vulgaris)", + "Guar (Cyamopsis tetragonoloba)", + "Gumbo (Abelmoschus esculentus)", + "Horse gram (Macrotyloma uniflorum)", + "Indian pea (Lathyrus sativus)", + "Lentil (Lens culinaris)", + "Lima Bean (Phaseolus lunatus)", + "Moth bean (Vigna acontifolia)", + "Mung bean (Vigna radiata)", + "Okra (Abelmoschus esculentus)", + "Pea (Pisum sativum)", + "Peanut (Arachis hypogaea)", + "Pigeon pea (Cajanus cajan)", + "Ricebean (Vigna umbellata)", + "Runner bean (Phaseolus coccineus)", + "Soybean (Glycine max)", + "Tarwi (tarhui, chocho; Lupinus mutabilis)", + "Tepary bean (Phaseolus acutifolius)", + "Urad bean (Vigna mungo)", + "Velvet bean (Mucuna pruriens)", + "Winged bean (Psophocarpus tetragonolobus)", + "Yardlong bean (Vigna unguiculata subsp. sesquipedalis)" +}; +#define NOPTIONS (sizeof(g_options)/sizeof(FAR const char *)) + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(unsigned int previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("%s: Before: %8d After: %8d Change: %8d\n", + msg, previous, mmcurrent.uordblks, mmcurrent.uordblks - previous); + + /* Set up for the next test */ + + g_mmPrevious = mmcurrent.uordblks; + if ((unsigned int)mmcurrent.uordblks > g_mmPeak) + { + g_mmPeak = mmcurrent.uordblks; + } +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mmInitial = mmcurrent.uordblks; + g_mmPrevious = mmcurrent.uordblks; + g_mmPeak = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the listbox test + + message(MAIN_STRING "Create CListBoxTest instance\n"); + CListBoxTest *test = new CListBoxTest(); + updateMemoryUsage(g_mmPrevious, "After creating CListBoxTest"); + + // Connect the NX server + + message(MAIN_STRING "Connect the CListBoxTest instance to the NX server\n"); + if (!test->connect()) + { + message(MAIN_STRING "Failed to connect the CListBoxTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmPrevious, MAIN_STRING "After connecting to the server"); + + // Create a window to draw into + + message(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + message(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmPrevious, MAIN_STRING "After creating a window"); + + // Create a listbox + + message(MAIN_STRING "Create a ListBox\n"); + CListBox *listbox = test->createListBox(); + if (!listbox) + { + message(MAIN_STRING "Failed to create a listbox\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmPrevious, MAIN_STRING "After creating a listbox"); + + // Show the initial state of the listbox + + listbox->setAllowMultipleSelections(true); + test->showListBox(listbox); + sleep(1); + + // Now add items to the list box (in reverse alphabetical order) + + message(MAIN_STRING "Add options to the ListBox\n"); + for (int i = NOPTIONS - 1; i >= 0; i--) + { + listbox->addOption(g_options[i],i); + test->showListBox(listbox); + message(MAIN_STRING "%d. New option %s\n", i, g_options[i]); + usleep(500000); // The simulation needs this to let the X11 event loop run + } + updateMemoryUsage(g_mmPrevious, MAIN_STRING "After adding the listbox items"); + sleep(1); + + // Sort the list box + + message(MAIN_STRING "Sort the ListBox\n"); + listbox->sort(); + test->showListBox(listbox); + updateMemoryUsage(g_mmPrevious, MAIN_STRING "After sorting the listbox"); + sleep(1); + + // Select and remove items from the listbox + + srand(1978); + int nOptions; + while ((nOptions = listbox->getOptionCount()) > 0) + { + message(MAIN_STRING "Option count: %d\n", nOptions); + if (nOptions <= 5) + { + message(MAIN_STRING "Selecting all remaining options\n"); + listbox->selectAllOptions(); + test->showListBox(listbox); + updateMemoryUsage(g_mmPrevious, MAIN_STRING "After selecting all options"); + sleep(1); + + message(MAIN_STRING "Removing all remaining options\n"); + listbox->removeAllOptions(); + updateMemoryUsage(g_mmPrevious, MAIN_STRING "After removing all options"); + test->showListBox(listbox); + } + else + { + int selected[5]; + + message(MAIN_STRING "Selecting five options\n"); + for (int i = 0; i < 5; i++) + { + selected[i] = ((nOptions - 1) * rand()) / MAX_RAND; + message(MAIN_STRING "Selecting option %d\n", selected[i]); + listbox->removeOption(selected[i]); + test->showListBox(listbox); + usleep(500000); + } + updateMemoryUsage(g_mmPrevious, MAIN_STRING "After selecting five options"); + + message(MAIN_STRING "De-selecting options\n"); + int index; + int count = 0; + while ((index = listbox->getSelectedIndex()) >= 0) + { + message(MAIN_STRING "De-selecting option %d\n", index); + listbox->deselectOption(index); + test->showListBox(listbox); + count++; + usleep(500000); + } + + message(MAIN_STRING "%s: %d options de-selected\n", + count == 5 ? "OK" : "ERROR", count); + updateMemoryUsage(g_mmPrevious, MAIN_STRING "After de-selecting options"); + + message(MAIN_STRING "Removing the selected options\n"); + for (int i = 0; i < 5; i++) + { + message(MAIN_STRING "Removing option %d\n", selected[i]); + listbox->removeOption(selected[i]); + test->showListBox(listbox); + usleep(500000); + } + updateMemoryUsage(g_mmPrevious, MAIN_STRING "After removing five options"); + } + sleep(1); + } + updateMemoryUsage(g_mmPrevious, MAIN_STRING "After the listbox is empty again"); + sleep(1); + + // Clean up and exit + + message(MAIN_STRING "Clean-up and exit\n"); + delete listbox; + updateMemoryUsage(g_mmPrevious, "After deleting the listbox"); + delete test; + updateMemoryUsage(g_mmPrevious, "After deleting the test"); + updateMemoryUsage(g_mmInitial, "Final memory usage"); + message("Peak memory usage: %8d\n", g_mmPeak - g_mmInitial); + return 0; +} + diff --git a/NxWidgets/UnitTests/CProgressBar/Makefile b/NxWidgets/UnitTests/CProgressBar/Makefile new file mode 100644 index 000000000..53d66fefa --- /dev/null +++ b/NxWidgets/UnitTests/CProgressBar/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CProgressBar/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx cprogressbartest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = cprogressbar +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CProgressBar/cprogressbartest.cxx b/NxWidgets/UnitTests/CProgressBar/cprogressbartest.cxx new file mode 100644 index 000000000..60821d751 --- /dev/null +++ b/NxWidgets/UnitTests/CProgressBar/cprogressbartest.cxx @@ -0,0 +1,224 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/ProgressBar/cprogressbartest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "cbgwindow.hxx" +#include "cprogressbartest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CProgressBarTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CProgressBarTest Constructor + +CProgressBarTest::CProgressBarTest() +{ + // Initialize state data + + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; +} + +// CProgressBarTest Descriptor + +CProgressBarTest::~CProgressBarTest(void) +{ + disconnect(); +} + +// Connect to the NX server + +bool CProgressBarTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CPROGRESSBARTEST_BGCOLOR)) + { + message("CProgressBarTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CProgressBarTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + m_bgWindow = (CBgWindow *)NULL; + } + + // Free the widget control instance + + if (m_widgetControl) + { + delete m_widgetControl; + m_widgetControl = (CWidgetControl *)NULL; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CProgressBarTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CProgressBarTest::createWindow: Failed to create CBgWindow instance\n"); + disconnect(); + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CProgressBarTest::createWindow: Failed to open background window\n"); + disconnect(); + return false; + } + + return true; +} + +// Create a bar in the center of the window + +CProgressBar *CProgressBarTest::createProgressBar(void) +{ + // Get the size of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + printf("CProgressBarTest::createProgressBar: Failed to get window size\n"); + disconnect(); + return false; + } + + // Put the bar in the center of the display + + nxgl_coord_t barWidth = windowSize.w >> 1; + nxgl_coord_t barX = windowSize.w >> 2; + + nxgl_coord_t barHeight = 16; + nxgl_coord_t barY = (windowSize.h - barHeight) >> 1; + + // Create the bar + + CProgressBar *bar = new CProgressBar(m_widgetControl, + barX, barY, + barWidth, barHeight); + if (!bar) + { + printf("CProgressBarTest::createProgressBar: Failed to create CProgressBar\n"); + disconnect(); + } + return bar; +} + +// (Re-)draw the bar. + +void CProgressBarTest::showProgressBar(CProgressBar *bar) +{ + bar->enable(); // Un-necessary, the widget is enabled by default + bar->enableDrawing(); + bar->redraw(); +} diff --git a/NxWidgets/UnitTests/CProgressBar/cprogressbartest.hxx b/NxWidgets/UnitTests/CProgressBar/cprogressbartest.hxx new file mode 100644 index 000000000..f5058a0c4 --- /dev/null +++ b/NxWidgets/UnitTests/CProgressBar/cprogressbartest.hxx @@ -0,0 +1,147 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CProgressBar/cprogressbartest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CPROGRESSBAR_CPROGRESSBARTEST_HXX +#define __UNITTESTS_CPROGRESSBAR_CPROGRESSBARTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cprogressbar.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CPROGRESSBARTEST_BGCOLOR +# define CONFIG_CPROGRESSBARTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME cprogressbar_main +# define MAIN_STRING "cprogressbar_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CProgressBarTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CBgWindow *m_bgWindow; // Background window instance + +public: + // Constructor/destructors + + CProgressBarTest(void); + ~CProgressBarTest(void); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a progress bar in the center of the window + + CProgressBar *createProgressBar(void); + + // (Re-)draw the progress bar. + + void showProgressBar(CProgressBar *bar); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // __UNITTESTS_CPROGRESSBAR_CPROGRESSBARTEST_HXX diff --git a/NxWidgets/UnitTests/CProgressBar/main.cxx b/NxWidgets/UnitTests/CProgressBar/main.cxx new file mode 100644 index 000000000..525c509d3 --- /dev/null +++ b/NxWidgets/UnitTests/CProgressBar/main.cxx @@ -0,0 +1,238 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CProgressBar/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "cprogressbartest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +#define MAX_PROGRESSBAR 50 + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static unsigned int g_mmInitial; +static unsigned int g_mmprevious; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(unsigned int previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("\n%s:\n", msg); + message(" Before: %8d After: %8d Change: %8d\n\n", + previous, mmcurrent.uordblks, mmcurrent.uordblks - previous); + + /* Set up for the next test */ + + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mmInitial = mmcurrent.uordblks; + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the checkbox test + + message(MAIN_STRING "Create CProgressBarTest instance\n"); + CProgressBarTest *test = new CProgressBarTest(); + updateMemoryUsage(g_mmprevious, "After creating CProgressBarTest"); + + // Connect the NX server + + message(MAIN_STRING "Connect the CProgressBarTest instance to the NX server\n"); + if (!test->connect()) + { + message(MAIN_STRING "Failed to connect the CProgressBarTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server"); + + // Create a window to draw into + + message(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + message(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window"); + + // Create a progress bar + + message(MAIN_STRING "Create a ProgressBar\n"); + CProgressBar *bar = test->createProgressBar(); + if (!bar) + { + message(MAIN_STRING "Failed to create a progress bar\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a progress bar"); + + // Set the progress bar minimum and maximum values + + bar->setMinimumValue(0); + bar->setMaximumValue(MAX_PROGRESSBAR); + bar->setValue(0); + bar->hidePercentageText(); + message(MAIN_STRING "ProgressBar range %d->%d Initial value %d\n", + bar->getMinimumValue(), bar->getMaximumValue(), + bar->getValue()); + + // Show the initial state of the checkbox + + test->showProgressBar(bar); + sleep(1); + + // Now move the progress bar up from 0 to 100% (with percentages off) + + for (int i = 0; i <= MAX_PROGRESSBAR; i++) + { + bar->setValue(i); + test->showProgressBar(bar); + message(MAIN_STRING "%d. New value %d\n", i, bar->getValue()); + usleep(1000); // The simulation needs this to let the X11 event loop run + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the progress bar up #1"); + usleep(500*1000); + + // Now move the progress bar up from 0 to 100% (with percentages off) + + bar->showPercentageText(); + bar->setValue(0); + test->showProgressBar(bar); + usleep(500*1000); + + for (int i = 0; i <= MAX_PROGRESSBAR; i++) + { + bar->setValue(i); + test->showProgressBar(bar); + message(MAIN_STRING "%d. New value %d\n", i, bar->getValue()); + usleep(1000); // The simulation needs this to let the X11 event loop run + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the progress bar up #2"); + sleep(1); + + // Clean up and exit + + message(MAIN_STRING "Clean-up and exit\n"); + delete bar; + updateMemoryUsage(g_mmprevious, "After deleting the progress bar"); + delete test; + updateMemoryUsage(g_mmprevious, "After deleting the test"); + updateMemoryUsage(g_mmInitial, "Final memory usage"); + return 0; +} + diff --git a/NxWidgets/UnitTests/CRadioButton/Makefile b/NxWidgets/UnitTests/CRadioButton/Makefile new file mode 100644 index 000000000..0b4906dd8 --- /dev/null +++ b/NxWidgets/UnitTests/CRadioButton/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CRadioButton/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx cradiobuttontest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = cradiobutton +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CRadioButton/cradiobuttontest.cxx b/NxWidgets/UnitTests/CRadioButton/cradiobuttontest.cxx new file mode 100644 index 000000000..f97089ce7 --- /dev/null +++ b/NxWidgets/UnitTests/CRadioButton/cradiobuttontest.cxx @@ -0,0 +1,305 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CRadioButton/cradiobuttontest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "cbgwindow.hxx" +#include "cradiobuttontest.hxx" +#include "cbitmap.hxx" +#include "glyphs.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CRadioButtonTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CRadioButtonTest Constructor + +CRadioButtonTest::CRadioButtonTest() +{ + // Initialize state data + + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; + + // Peek at the radio button glyph to get a good estimate of the size + + m_size.w = g_radioButtonOn.width; + m_size.h = g_radioButtonOn.height; +} + +// CRadioButtonTest Descriptor + +CRadioButtonTest::~CRadioButtonTest(void) +{ + disconnect(); +} + +// Connect to the NX server + +bool CRadioButtonTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CRADIOBUTTONTEST_BGCOLOR)) + { + message("CRadioButtonTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CRadioButtonTest::disconnect(void) +{ + // Free the radiobutton group + + if (m_radioButtonGroup) + { + delete m_radioButtonGroup; + m_radioButtonGroup = (CRadioButtonGroup *)NULL; + } + + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + } + + // Free the widget control instance + + if (m_widgetControl) + { + delete m_widgetControl; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CRadioButtonTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CRadioButtonTest::createGraphics: Failed to create CBgWindow instance\n"); + delete m_widgetControl; + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CRadioButtonTest::createGraphics: Failed to open background window\n"); + delete m_bgWindow; + m_bgWindow = (CBgWindow*)0; + return false; + } + + return true; +} + +// Create a CRadioButton instance + +CRadioButton *CRadioButtonTest::newRadioButton(void) +{ + // Get the width of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + message("CRadioButtonTest::newRadioButton: Failed to get window size\n"); + return (CRadioButton *)NULL; + } + + // Create the radio button group, if we have not already done so + + if (!m_radioButtonGroup) + { + // Start the radio button group in the center of the upper, left + // quadrant. The initial size is 0,0 and the default style is used. + + nxgl_coord_t groupX = windowSize.w >> 2; + nxgl_coord_t groupY = windowSize.h >> 2; + + m_radioButtonGroup = new CRadioButtonGroup(m_widgetControl, groupX, groupY); + if (!m_radioButtonGroup) + { + message("CRadioButtonTest::newRadioButton: Failed to create the radio button group\n"); + return (CRadioButton *)NULL; + } + } + + // Create the new radio button at the botton of the radio button group and + // with the size of the ON radio button glyph (they all need to be the same + // size!). Note that coordinates are relative to the parent bounding box. + + nxgl_coord_t buttonX = 0; + nxgl_coord_t buttonY = m_radioButtonGroup->getHeight(); + + return m_radioButtonGroup->newRadioButton(buttonX, buttonY, m_size.w, m_size.h); +} + +// (Re-)draw the buttons. + +void CRadioButtonTest::showButtons(void) +{ + m_radioButtonGroup->enable(); // Un-necessary, the widget is enabled by default + m_radioButtonGroup->enableDrawing(); + m_radioButtonGroup->redraw(); +} + +// Push the radio button + +void CRadioButtonTest::pushButton(CRadioButton *button) +{ + // Get the button center coordinates + + nxgl_coord_t buttonX = button->getX() + (button->getWidth() >> 1); + nxgl_coord_t buttonY = button->getY() + (button->getHeight() >> 1); + + // Then push the button by calling nx_mousein. nx_mousein is meant to be + // called by mouse handling software. Here we just inject a left-button click + // directly in the center of the radio button. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level mouse interface + + NXHANDLE handle = getServer(); + + // Then inject the mouse click + + (void)nx_mousein(handle, buttonX, buttonY, NX_MOUSE_LEFTBUTTON); + + // Poll for mouse events + // + // Widget events are normally handled in a modal loop (by calling goModal()). + // However, for this case we know that we just pressed the mouse button + // so we don't have to poll. We can just perform a one pass poll then + // then check if the mouse event was processed corredly. + + m_widgetControl->pollEvents(m_radioButtonGroup); + + // Then inject the mouse release + + (void)nx_mousein(handle, buttonX, buttonY, 0); + + // And poll for more mouse events + + m_widgetControl->pollEvents(m_radioButtonGroup); + + // And re-draw the buttons (the mouse click event should have automatically + // triggered the re-draw) + // + // showButtons(); +} + +// Show the state of the radio button group + +void CRadioButtonTest::showButtonState(void) +{ + int index = m_radioButtonGroup->getSelectedIndex(); + if (index < 0) + { + message("CRadioButtonTest::showButtonState No button is pressed\n"); + } + else + { + message("CRadioButtonTest::showButtonState button%d is selected\n", index+1); + } +} diff --git a/NxWidgets/UnitTests/CRadioButton/cradiobuttontest.hxx b/NxWidgets/UnitTests/CRadioButton/cradiobuttontest.hxx new file mode 100644 index 000000000..563049dcf --- /dev/null +++ b/NxWidgets/UnitTests/CRadioButton/cradiobuttontest.hxx @@ -0,0 +1,162 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CRadioButton/cradiobuttontest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CRADIOBUTTON_CRADIOBUTTONTEST_HXX +#define __UNITTESTS_CRADIOBUTTON_CRADIOBUTTONTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cradiobutton.hxx" +#include "cradiobuttongroup.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CRADIOBUTTONTEST_BGCOLOR +# define CONFIG_CRADIOBUTTONTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME cradiobutton_main +# define MAIN_STRING "cradiobutton_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CRadioButtonTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CBgWindow *m_bgWindow; // Background window instance + CRadioButtonGroup *m_radioButtonGroup; // The radio button group + + // These are the dimensions that we will use for creating new radio buttons + + struct nxgl_size_s m_size; // The size of each radio button + +public: + // Constructor/destructors + + CRadioButtonTest(void); + ~CRadioButtonTest(void); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // (Re-)draw the buttons. + + void showButtons(void); + + // Create a CRadioButton instance. This method will show you how to create + // a CRadioButton widget + + CRadioButton *newRadioButton(void); + + // Simulate pushing and releasing of the radio button + + void pushButton(CRadioButton *button); + + // Show the state of the radio button group + + void showButtonState(void); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // __UNITTESTS_CRADIOBUTTON_CRADIOBUTTONTEST_HXX diff --git a/NxWidgets/UnitTests/CRadioButton/main.cxx b/NxWidgets/UnitTests/CRadioButton/main.cxx new file mode 100644 index 000000000..d53cd4a09 --- /dev/null +++ b/NxWidgets/UnitTests/CRadioButton/main.cxx @@ -0,0 +1,238 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CRadioButton/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "crlepalettebitmap.hxx" +#include "glyphs.hxx" +#include "cradiobuttontest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static unsigned int g_mmInitial; +static unsigned int g_mmprevious; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(unsigned int previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("\n%s:\n", msg); + message(" Before: %8d After: %8d Change: %8d\n\n", + previous, mmcurrent.uordblks, mmcurrent.uordblks - previous); + + /* Set up for the next test */ + + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mmInitial = mmcurrent.uordblks; + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the radio button test + + message(MAIN_STRING "Create CRadioButtonTest instance\n"); + CRadioButtonTest *test = new CRadioButtonTest(); + updateMemoryUsage(g_mmprevious, "After creating CRadioButtonTest"); + + // Connect the NX server + + message(MAIN_STRING "Connect the CRadioButtonTest instance to the NX server\n"); + if (!test->connect()) + { + message(MAIN_STRING "Failed to connect the CRadioButtonTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server"); + + // Create a window to draw into + + message(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + message(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window"); + + // Create three radio buttons + + CRadioButton *button1 = test->newRadioButton(); + if (!button1) + { + message(MAIN_STRING "Failed to create radio button 1\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating radio button 1"); + + CRadioButton *button2 = test->newRadioButton(); + if (!button2) + { + message(MAIN_STRING "Failed to create radio button 2\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating radio button 2"); + + CRadioButton *button3 = test->newRadioButton(); + if (!button3) + { + message(MAIN_STRING "Failed to create radio button 3\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating radio button 3"); + + // Show the initial state of the buttons + + test->showButtons(); + test->showButtonState(); + sleep(1); + + // Now push some buttons + + message(MAIN_STRING "Pushing button 1\n"); + test->pushButton(button1); + usleep(500*1000); + test->showButtonState(); + updateMemoryUsage(g_mmprevious, "After pushing button 1"); + usleep(500*1000); + + message(MAIN_STRING "Pushing button 2\n"); + test->pushButton(button2); + usleep(500*1000); + test->showButtonState(); + updateMemoryUsage(g_mmprevious, "After pushing button 2"); + usleep(500*1000); + + message(MAIN_STRING "Pushing button 3\n"); + test->pushButton(button3); + usleep(500*1000); + test->showButtonState(); + updateMemoryUsage(g_mmprevious, "After pushing button 3"); + sleep(2); + + // Clean up and exit + + message(MAIN_STRING "Clean-up and exit\n"); + delete test; + updateMemoryUsage(g_mmprevious, "After deleting the test"); + updateMemoryUsage(g_mmInitial, "Final memory usage"); + return 0; +} + diff --git a/NxWidgets/UnitTests/CScrollbarHorizontal/Makefile b/NxWidgets/UnitTests/CScrollbarHorizontal/Makefile new file mode 100644 index 000000000..6be8f7cd6 --- /dev/null +++ b/NxWidgets/UnitTests/CScrollbarHorizontal/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CScrollbarHorizontal/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx cscrollbarhorizontaltest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = cscrollbarhorizontal +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.cxx b/NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.cxx new file mode 100644 index 000000000..06673f080 --- /dev/null +++ b/NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.cxx @@ -0,0 +1,225 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "cbgwindow.hxx" +#include "cscrollbarhorizontaltest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CScrollbarHorizontalTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CScrollbarHorizontalTest Constructor + +CScrollbarHorizontalTest::CScrollbarHorizontalTest() +{ + // Initialize state data + + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; +} + +// CScrollbarHorizontalTest Descriptor + +CScrollbarHorizontalTest::~CScrollbarHorizontalTest(void) +{ + disconnect(); +} + +// Connect to the NX server + +bool CScrollbarHorizontalTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CSCROLLBARHORIZONTALTEST_BGCOLOR)) + { + message("CScrollbarHorizontalTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CScrollbarHorizontalTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + m_bgWindow = (CBgWindow *)NULL; + } + + // Free the widget control instance + + if (m_widgetControl) + { + delete m_widgetControl; + m_widgetControl = (CWidgetControl *)NULL; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CScrollbarHorizontalTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CScrollbarHorizontalTest::createWindow: Failed to create CBgWindow instance\n"); + disconnect(); + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CScrollbarHorizontalTest::createWindow: Failed to open background window\n"); + disconnect(); + return false; + } + + return true; +} + +// Create a scrollbar in the center of the window + +CScrollbarHorizontal *CScrollbarHorizontalTest::createScrollbar(void) +{ + // Get the size of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + printf("CScrollbarHorizontalTest::createScrollbar: Failed to get window size\n"); + disconnect(); + return false; + } + + // Put the scrollbar in the center of the display + + nxgl_coord_t scrollbarWidth = windowSize.w >> 1; + nxgl_coord_t scrollbarX = windowSize.w >> 2; + + nxgl_coord_t scrollbarHeight = 10; + nxgl_coord_t scrollbarY = (windowSize.h - scrollbarHeight) >> 1; + + // Create the scrollbar + + CScrollbarHorizontal *scrollbar = + new CScrollbarHorizontal(m_widgetControl, + scrollbarX, scrollbarY, + scrollbarWidth, scrollbarHeight); + if (!scrollbar) + { + printf("CScrollbarHorizontalTest::createScrollbar: Failed to create CScrollbarHorizontal\n"); + disconnect(); + } + return scrollbar; +} + +// (Re-)draw the scrollbar. + +void CScrollbarHorizontalTest::showScrollbar(CScrollbarHorizontal *scrollbar) +{ + scrollbar->enable(); // Un-necessary, the widget is enabled by default + scrollbar->enableDrawing(); + scrollbar->redraw(); +} diff --git a/NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx b/NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx new file mode 100644 index 000000000..feae319d0 --- /dev/null +++ b/NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx @@ -0,0 +1,147 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CScrollbarHorizontal/cscrollbarhorizontaltest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CSCROLLBARHORIZONTAL_CSCROLLBARHORIZONTALTEST_HXX +#define __UNITTESTS_CSCROLLBARHORIZONTAL_CSCROLLBARHORIZONTALTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cscrollbarhorizontal.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CSCROLLBARHORIZONTALTEST_BGCOLOR +# define CONFIG_CSCROLLBARHORIZONTALTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME cscrollbarhorizontal_main +# define MAIN_STRING "cscrollbarhorizontal_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CScrollbarHorizontalTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CBgWindow *m_bgWindow; // Background window instance + +public: + // Constructor/destructors + + CScrollbarHorizontalTest(void); + ~CScrollbarHorizontalTest(void); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a scrollbar in the center of the window + + CScrollbarHorizontal *createScrollbar(void); + + // (Re-)draw the scrollbar. + + void showScrollbar(CScrollbarHorizontal *scrollbar); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // __UNITTESTS_CSCROLLBARHORIZONTAL_CSCROLLBARHORIZONTALTEST_HXX diff --git a/NxWidgets/UnitTests/CScrollbarHorizontal/main.cxx b/NxWidgets/UnitTests/CScrollbarHorizontal/main.cxx new file mode 100644 index 000000000..a6a08cdbd --- /dev/null +++ b/NxWidgets/UnitTests/CScrollbarHorizontal/main.cxx @@ -0,0 +1,231 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CScrollbarHorizontal/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "cscrollbarhorizontaltest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +#define MAX_SCROLLBAR 50 + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static unsigned int g_mmInitial; +static unsigned int g_mmprevious; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(unsigned int previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("\n%s:\n", msg); + message(" Before: %8d After: %8d Change: %8d\n\n", + previous, mmcurrent.uordblks, mmcurrent.uordblks - previous); + + /* Set up for the next test */ + + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mmInitial = mmcurrent.uordblks; + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the checkbox test + + message(MAIN_STRING "Create CScrollbarHorizontalTest instance\n"); + CScrollbarHorizontalTest *test = new CScrollbarHorizontalTest(); + updateMemoryUsage(g_mmprevious, "After creating CScrollbarHorizontalTest"); + + // Connect the NX server + + message(MAIN_STRING "Connect the CScrollbarHorizontalTest instance to the NX server\n"); + if (!test->connect()) + { + message(MAIN_STRING "Failed to connect the CScrollbarHorizontalTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server"); + + // Create a window to draw into + + message(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + message(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window"); + + // Create a scrollbar + + message(MAIN_STRING "Create a Scrollbar\n"); + CScrollbarHorizontal *scrollbar = test->createScrollbar(); + if (!scrollbar) + { + message(MAIN_STRING "Failed to create a scrollbar\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a scrollbar"); + + // Set the scrollbar minimum and maximum values + + scrollbar->setMinimumValue(0); + scrollbar->setMaximumValue(MAX_SCROLLBAR); + scrollbar->setValue(0); + message(MAIN_STRING "Scrollbar range %d->%d Initial value %d\n", + scrollbar->getMinimumValue(), scrollbar->getMaximumValue(), + scrollbar->getValue()); + + // Show the initial state of the checkbox + + test->showScrollbar(scrollbar); + sleep(1); + + // Now move the scrollbar up + + for (int i = 0; i <= MAX_SCROLLBAR; i++) + { + scrollbar->setValue(i); + test->showScrollbar(scrollbar); + message(MAIN_STRING "%d. New value %d\n", i, scrollbar->getValue()); + usleep(1000); // The simulation needs this to let the X11 event loop run + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the scrollbar up"); + + // And move the scrollbar down + + for (int i = MAX_SCROLLBAR; i >= 0; i--) + { + scrollbar->setValue(i); + test->showScrollbar(scrollbar); + message(MAIN_STRING "%d. New value %d\n", i, scrollbar->getValue()); + usleep(1000); // The simulation needs this to let the X11 event loop run + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the scrollbar down"); + sleep(1); + + // Clean up and exit + + message(MAIN_STRING "Clean-up and exit\n"); + delete scrollbar; + updateMemoryUsage(g_mmprevious, "After deleting the scrollbar"); + delete test; + updateMemoryUsage(g_mmprevious, "After deleting the test"); + updateMemoryUsage(g_mmInitial, "Final memory usage"); + return 0; +} + diff --git a/NxWidgets/UnitTests/CScrollbarVertical/Makefile b/NxWidgets/UnitTests/CScrollbarVertical/Makefile new file mode 100644 index 000000000..a2c404aad --- /dev/null +++ b/NxWidgets/UnitTests/CScrollbarVertical/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CScrollbarVertical/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx cscrollbarverticaltest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = cscrollbarvertical +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.cxx b/NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.cxx new file mode 100644 index 000000000..df317adcd --- /dev/null +++ b/NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.cxx @@ -0,0 +1,225 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "cbgwindow.hxx" +#include "cscrollbarverticaltest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CScrollbarVerticalTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CScrollbarVerticalTest Constructor + +CScrollbarVerticalTest::CScrollbarVerticalTest() +{ + // Initialize state data + + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; +} + +// CScrollbarVerticalTest Descriptor + +CScrollbarVerticalTest::~CScrollbarVerticalTest(void) +{ + disconnect(); +} + +// Connect to the NX server + +bool CScrollbarVerticalTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CSCROLLBARVERTICALTEST_BGCOLOR)) + { + message("CScrollbarVerticalTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CScrollbarVerticalTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + m_bgWindow = (CBgWindow *)NULL; + } + + // Free the widget control instance + + if (m_widgetControl) + { + delete m_widgetControl; + m_widgetControl = (CWidgetControl *)NULL; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CScrollbarVerticalTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CScrollbarVerticalTest::createWindow: Failed to create CBgWindow instance\n"); + disconnect(); + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CScrollbarVerticalTest::createWindow: Failed to open background window\n"); + disconnect(); + return false; + } + + return true; +} + +// Create a scrollbar in the center of the window + +CScrollbarVertical *CScrollbarVerticalTest::createScrollbar(void) +{ + // Get the size of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + printf("CScrollbarVerticalTest::createScrollbar: Failed to get window size\n"); + disconnect(); + return false; + } + + // Put the scrollbar in the center of the display + + nxgl_coord_t scrollbarWidth = 10; + nxgl_coord_t scrollbarX = (windowSize.w - scrollbarWidth) >> 1; + + nxgl_coord_t scrollbarHeight = windowSize.h >> 1; + nxgl_coord_t scrollbarY = windowSize.h >> 2; + + // Create the scrollbar + + CScrollbarVertical *scrollbar = + new CScrollbarVertical(m_widgetControl, + scrollbarX, scrollbarY, + scrollbarWidth, scrollbarHeight); + if (!scrollbar) + { + printf("CScrollbarVerticalTest::createScrollbar: Failed to create CScrollbarVertical\n"); + disconnect(); + } + return scrollbar; +} + +// (Re-)draw the scrollbar. + +void CScrollbarVerticalTest::showScrollbar(CScrollbarVertical *scrollbar) +{ + scrollbar->enable(); // Un-necessary, the widget is enabled by default + scrollbar->enableDrawing(); + scrollbar->redraw(); +} diff --git a/NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx b/NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx new file mode 100644 index 000000000..874a851fd --- /dev/null +++ b/NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx @@ -0,0 +1,147 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CScrollbarVertical/cscrollbarverticaltest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CSCROLLBARVERTICAL_CSCROLLBARVERTICALTEST_HXX +#define __UNITTESTS_CSCROLLBARVERTICAL_CSCROLLBARVERTICALTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cscrollbarvertical.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CSCROLLBARVERTICALTEST_BGCOLOR +# define CONFIG_CSCROLLBARVERTICALTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME cscrollbarvertical_main +# define MAIN_STRING "cscrollbarvertical_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CScrollbarVerticalTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CBgWindow *m_bgWindow; // Background window instance + +public: + // Constructor/destructors + + CScrollbarVerticalTest(void); + ~CScrollbarVerticalTest(void); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a scrollbar in the center of the window + + CScrollbarVertical *createScrollbar(void); + + // (Re-)draw the scrollbar. + + void showScrollbar(CScrollbarVertical *scrollbar); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // __UNITTESTS_CSCROLLBARVERTICAL_CSCROLLBARVERTICALTEST_HXX diff --git a/NxWidgets/UnitTests/CScrollbarVertical/main.cxx b/NxWidgets/UnitTests/CScrollbarVertical/main.cxx new file mode 100644 index 000000000..16bd9eea6 --- /dev/null +++ b/NxWidgets/UnitTests/CScrollbarVertical/main.cxx @@ -0,0 +1,231 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CScrollbarVertical/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "cscrollbarverticaltest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +#define MAX_SCROLLBAR 20 + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static unsigned int g_mmInitial; +static unsigned int g_mmprevious; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(unsigned int previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("\n%s:\n", msg); + message(" Before: %8d After: %8d Change: %8d\n\n", + previous, mmcurrent.uordblks, mmcurrent.uordblks - previous); + + /* Set up for the next test */ + + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mmInitial = mmcurrent.uordblks; + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the checkbox test + + message(MAIN_STRING "Create CScrollbarVerticalTest instance\n"); + CScrollbarVerticalTest *test = new CScrollbarVerticalTest(); + updateMemoryUsage(g_mmprevious, "After creating CScrollbarVerticalTest"); + + // Connect the NX server + + message(MAIN_STRING "Connect the CScrollbarVerticalTest instance to the NX server\n"); + if (!test->connect()) + { + message(MAIN_STRING "Failed to connect the CScrollbarVerticalTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server"); + + // Create a window to draw into + + message(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + message(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window"); + + // Create a scrollbar + + message(MAIN_STRING "Create a Scrollbar\n"); + CScrollbarVertical *scrollbar = test->createScrollbar(); + if (!scrollbar) + { + message(MAIN_STRING "Failed to create a scrollbar\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a scrollbar"); + + // Set the scrollbar minimum and maximum values + + scrollbar->setMinimumValue(0); + scrollbar->setMaximumValue(MAX_SCROLLBAR); + scrollbar->setValue(0); + message(MAIN_STRING "Scrollbar range %d->%d Initial value %d\n", + scrollbar->getMinimumValue(), scrollbar->getMaximumValue(), + scrollbar->getValue()); + + // Show the initial state of the checkbox + + test->showScrollbar(scrollbar); + sleep(1); + + // Now move the scrollbar up + + for (int i = 0; i <= MAX_SCROLLBAR; i++) + { + scrollbar->setValue(i); + test->showScrollbar(scrollbar); + message(MAIN_STRING "%d. New value %d\n", i, scrollbar->getValue()); + usleep(1000); // The simulation needs this to let the X11 event loop run + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the scrollbar up"); + + // And move the scrollbar down + + for (int i = MAX_SCROLLBAR; i >= 0; i--) + { + scrollbar->setValue(i); + test->showScrollbar(scrollbar); + message(MAIN_STRING "%d. New value %d\n", i, scrollbar->getValue()); + usleep(5000); // The simulation needs this to let the X11 event loop run + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the scrollbar down"); + sleep(1); + + // Clean up and exit + + message(MAIN_STRING "Clean-up and exit\n"); + delete scrollbar; + updateMemoryUsage(g_mmprevious, "After deleting the scrollbar"); + delete test; + updateMemoryUsage(g_mmprevious, "After deleting the test"); + updateMemoryUsage(g_mmInitial, "Final memory usage"); + return 0; +} + diff --git a/NxWidgets/UnitTests/CSliderHorizonal/Makefile b/NxWidgets/UnitTests/CSliderHorizonal/Makefile new file mode 100644 index 000000000..b496bdda7 --- /dev/null +++ b/NxWidgets/UnitTests/CSliderHorizonal/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CSliderHorizontal/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx csliderhorizontaltest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = csliderhorizontal +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.cxx b/NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.cxx new file mode 100644 index 000000000..1687448db --- /dev/null +++ b/NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.cxx @@ -0,0 +1,224 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CSliderHorizontal/csliderhorizontaltest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "cbgwindow.hxx" +#include "csliderhorizontaltest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CSliderHorizontalTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CSliderHorizontalTest Constructor + +CSliderHorizontalTest::CSliderHorizontalTest() +{ + // Initialize state data + + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; +} + +// CSliderHorizontalTest Descriptor + +CSliderHorizontalTest::~CSliderHorizontalTest(void) +{ + disconnect(); +} + +// Connect to the NX server + +bool CSliderHorizontalTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CSLIDERHORIZONTALTEST_BGCOLOR)) + { + message("CSliderHorizontalTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CSliderHorizontalTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + m_bgWindow = (CBgWindow *)NULL; + } + + // Free the widget control instance + + if (m_widgetControl) + { + delete m_widgetControl; + m_widgetControl = (CWidgetControl *)NULL; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CSliderHorizontalTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CSliderHorizontalTest::createWindow: Failed to create CBgWindow instance\n"); + disconnect(); + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CSliderHorizontalTest::createWindow: Failed to open background window\n"); + disconnect(); + return false; + } + + return true; +} + +// Create a slider in the center of the window + +CSliderHorizontal *CSliderHorizontalTest::createSlider(void) +{ + // Get the size of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + printf("CSliderHorizontalTest::createSlider: Failed to get window size\n"); + disconnect(); + return false; + } + + // Put the slider in the center of the display + + nxgl_coord_t sliderWidth = windowSize.w >> 1; + nxgl_coord_t sliderX = windowSize.w >> 2; + + nxgl_coord_t sliderHeight = 10; + nxgl_coord_t sliderY = (windowSize.h - sliderHeight) >> 1; + + // Create the slider + + CSliderHorizontal *slider = new CSliderHorizontal(m_widgetControl, + sliderX, sliderY, + sliderWidth, sliderHeight); + if (!slider) + { + printf("CSliderHorizontalTest::createSlider: Failed to create CSliderHorizontal\n"); + disconnect(); + } + return slider; +} + +// (Re-)draw the slider. + +void CSliderHorizontalTest::showSlider(CSliderHorizontal *slider) +{ + slider->enable(); // Un-necessary, the widget is enabled by default + slider->enableDrawing(); + slider->redraw(); +} diff --git a/NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.hxx b/NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.hxx new file mode 100644 index 000000000..1dde688a8 --- /dev/null +++ b/NxWidgets/UnitTests/CSliderHorizonal/csliderhorizontaltest.hxx @@ -0,0 +1,147 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CSliderHorizontal/csliderhorizontaltest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CSLIDERHORIZONTAL_CSLIDERHORIZONTALTEST_HXX +#define __UNITTESTS_CSLIDERHORIZONTAL_CSLIDERHORIZONTALTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "csliderhorizontal.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CSLIDERHORIZONTALTEST_BGCOLOR +# define CONFIG_CSLIDERHORIZONTALTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME csliderhorizontal_main +# define MAIN_STRING "csliderhorizontal_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CSliderHorizontalTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CBgWindow *m_bgWindow; // Background window instance + +public: + // Constructor/destructors + + CSliderHorizontalTest(void); + ~CSliderHorizontalTest(void); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a slider in the center of the window + + CSliderHorizontal *createSlider(void); + + // (Re-)draw the slider. + + void showSlider(CSliderHorizontal *slider); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // __UNITTESTS_CSLIDERHORIZONTAL_CSLIDERHORIZONTALTEST_HXX diff --git a/NxWidgets/UnitTests/CSliderHorizonal/main.cxx b/NxWidgets/UnitTests/CSliderHorizonal/main.cxx new file mode 100644 index 000000000..b99d1c547 --- /dev/null +++ b/NxWidgets/UnitTests/CSliderHorizonal/main.cxx @@ -0,0 +1,231 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CSliderHorizontal/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "csliderhorizontaltest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +#define MAX_SLIDER 50 + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static unsigned int g_mmInitial; +static unsigned int g_mmprevious; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(unsigned int previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("\n%s:\n", msg); + message(" Before: %8d After: %8d Change: %8d\n\n", + previous, mmcurrent.uordblks, mmcurrent.uordblks - previous); + + /* Set up for the next test */ + + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mmInitial = mmcurrent.uordblks; + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the checkbox test + + message(MAIN_STRING "Create CSliderHorizontalTest instance\n"); + CSliderHorizontalTest *test = new CSliderHorizontalTest(); + updateMemoryUsage(g_mmprevious, "After creating CSliderHorizontalTest"); + + // Connect the NX server + + message(MAIN_STRING "Connect the CSliderHorizontalTest instance to the NX server\n"); + if (!test->connect()) + { + message(MAIN_STRING "Failed to connect the CSliderHorizontalTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server"); + + // Create a window to draw into + + message(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + message(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window"); + + // Create a slider + + message(MAIN_STRING "Create a Slider\n"); + CSliderHorizontal *slider = test->createSlider(); + if (!slider) + { + message(MAIN_STRING "Failed to create a slider\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a slider"); + + // Set the slider minimum and maximum values + + slider->setMinimumValue(0); + slider->setMaximumValue(MAX_SLIDER); + slider->setValue(0); + message(MAIN_STRING "Slider range %d->%d Initial value %d\n", + slider->getMinimumValue(), slider->getMaximumValue(), + slider->getValue()); + + // Show the initial state of the checkbox + + test->showSlider(slider); + sleep(1); + + // Now move the slider up + + for (int i = 0; i <= MAX_SLIDER; i++) + { + slider->setValue(i); + test->showSlider(slider); + message(MAIN_STRING "%d. New value %d\n", i, slider->getValue()); + usleep(1000); // The simulation needs this to let the X11 event loop run + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the slider up"); + + // And move the slider down + + for (int i = MAX_SLIDER; i >= 0; i--) + { + slider->setValue(i); + test->showSlider(slider); + message(MAIN_STRING "%d. New value %d\n", i, slider->getValue()); + usleep(1000); // The simulation needs this to let the X11 event loop run + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the slider down"); + sleep(1); + + // Clean up and exit + + message(MAIN_STRING "Clean-up and exit\n"); + delete slider; + updateMemoryUsage(g_mmprevious, "After deleting the slider"); + delete test; + updateMemoryUsage(g_mmprevious, "After deleting the test"); + updateMemoryUsage(g_mmInitial, "Final memory usage"); + return 0; +} + diff --git a/NxWidgets/UnitTests/CSliderVertical/Makefile b/NxWidgets/UnitTests/CSliderVertical/Makefile new file mode 100644 index 000000000..5d5e590f1 --- /dev/null +++ b/NxWidgets/UnitTests/CSliderVertical/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CSliderVertical/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx csliderverticaltest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = cslidervertical +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.cxx b/NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.cxx new file mode 100644 index 000000000..d0691c52d --- /dev/null +++ b/NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.cxx @@ -0,0 +1,225 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.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. +// modify this software without notice. +// +////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "cbgwindow.hxx" +#include "csliderverticaltest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CSliderVerticalTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CSliderVerticalTest Constructor + +CSliderVerticalTest::CSliderVerticalTest() +{ + // Initialize state data + + m_widgetControl = (CWidgetControl *)NULL; + m_bgWindow = (CBgWindow *)NULL; +} + +// CSliderVerticalTest Descriptor + +CSliderVerticalTest::~CSliderVerticalTest(void) +{ + disconnect(); +} + +// Connect to the NX server + +bool CSliderVerticalTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Set the background color + + if (!setBackgroundColor(CONFIG_CSLIDERVERTICALTEST_BGCOLOR)) + { + message("CSliderVerticalTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CSliderVerticalTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + m_bgWindow = (CBgWindow *)NULL; + } + + // Free the widget control instance + + if (m_widgetControl) + { + delete m_widgetControl; + m_widgetControl = (CWidgetControl *)NULL; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CSliderVerticalTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + message("CSliderVerticalTest::createWindow: Failed to create CBgWindow instance\n"); + disconnect(); + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + message("CSliderVerticalTest::createWindow: Failed to open background window\n"); + disconnect(); + return false; + } + + return true; +} + +// Create a slider in the center of the window + +CSliderVertical *CSliderVerticalTest::createSlider(void) +{ + // Get the size of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + printf("CSliderVerticalTest::createSlider: Failed to get window size\n"); + disconnect(); + return false; + } + + // Put the slider in the center of the display + + nxgl_coord_t sliderWidth = 10; + nxgl_coord_t sliderX = (windowSize.w - sliderWidth) >> 1; + + nxgl_coord_t sliderHeight = windowSize.h >> 1; + nxgl_coord_t sliderY = windowSize.h >> 2; + + // Create the slider + + CSliderVertical *slider = new CSliderVertical(m_widgetControl, + sliderX, sliderY, + sliderWidth, sliderHeight); + if (!slider) + { + printf("CSliderVerticalTest::createSlider: Failed to create CSliderVertical\n"); + disconnect(); + } + return slider; +} + +// (Re-)draw the slider. + +void CSliderVerticalTest::showSlider(CSliderVertical *slider) +{ + slider->enable(); // Un-necessary, the widget is enabled by default + slider->enableDrawing(); + slider->redraw(); +} diff --git a/NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx b/NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx new file mode 100644 index 000000000..e8d506db9 --- /dev/null +++ b/NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx @@ -0,0 +1,147 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CSliderVertical/csliderverticaltest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CSLIDERVERTICAL_CSLIDERVERTICALTEST_HXX +#define __UNITTESTS_CSLIDERVERTICAL_CSLIDERVERTICALTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cslidervertical.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CSLIDERVERTICALTEST_BGCOLOR +# define CONFIG_CSLIDERVERTICALTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME cslidervertical_main +# define MAIN_STRING "cslidervertical_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +// If debug is enabled, use the debug function, lib_rawprintf() instead +// of printf() so that the output is synchronized. + +#ifdef CONFIG_DEBUG +# define message lib_lowprintf +#else +# define message printf +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CSliderVerticalTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CBgWindow *m_bgWindow; // Background window instance + +public: + // Constructor/destructors + + CSliderVerticalTest(void); + ~CSliderVerticalTest(void); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a slider in the center of the window + + CSliderVertical *createSlider(void); + + // (Re-)draw the slider. + + void showSlider(CSliderVertical *slider); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +#endif // __UNITTESTS_CSLIDERVERTICAL_CSLIDERVERTICALTEST_HXX diff --git a/NxWidgets/UnitTests/CSliderVertical/main.cxx b/NxWidgets/UnitTests/CSliderVertical/main.cxx new file mode 100644 index 000000000..f5a53f018 --- /dev/null +++ b/NxWidgets/UnitTests/CSliderVertical/main.cxx @@ -0,0 +1,231 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CSliderVertical/main.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 <nuttx/init.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "csliderverticaltest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +#define MAX_SLIDER 50 + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static unsigned int g_mmInitial; +static unsigned int g_mmprevious; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Private Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: updateMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void updateMemoryUsage(unsigned int previous, + FAR const char *msg) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + /* Show the change from the previous time */ + + message("\n%s:\n", msg); + message(" Before: %8d After: %8d Change: %8d\n\n", + previous, mmcurrent.uordblks, mmcurrent.uordblks - previous); + + /* Set up for the next test */ + + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Name: initMemoryUsage +///////////////////////////////////////////////////////////////////////////// + +static void initMemoryUsage(void) +{ + struct mallinfo mmcurrent; + + /* Get the current memory usage */ + +#ifdef CONFIG_CAN_PASS_STRUCTS + mmcurrent = mallinfo(); +#else + (void)mallinfo(&mmcurrent); +#endif + + g_mmInitial = mmcurrent.uordblks; + g_mmprevious = mmcurrent.uordblks; +} + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Name: user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Initialize memory monitor logic + + initMemoryUsage(); + + // Create an instance of the checkbox test + + message(MAIN_STRING "Create CSliderVerticalTest instance\n"); + CSliderVerticalTest *test = new CSliderVerticalTest(); + updateMemoryUsage(g_mmprevious, "After creating CSliderVerticalTest"); + + // Connect the NX server + + message(MAIN_STRING "Connect the CSliderVerticalTest instance to the NX server\n"); + if (!test->connect()) + { + message(MAIN_STRING "Failed to connect the CSliderVerticalTest instance to the NX server\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After connecting to the server"); + + // Create a window to draw into + + message(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + message(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a window"); + + // Create a slider + + message(MAIN_STRING "Create a Slider\n"); + CSliderVertical *slider = test->createSlider(); + if (!slider) + { + message(MAIN_STRING "Failed to create a slider\n"); + delete test; + return 1; + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After creating a slider"); + + // Set the slider minimum and maximum values + + slider->setMinimumValue(0); + slider->setMaximumValue(MAX_SLIDER); + slider->setValue(0); + message(MAIN_STRING "Slider range %d->%d Initial value %d\n", + slider->getMinimumValue(), slider->getMaximumValue(), + slider->getValue()); + + // Show the initial state of the checkbox + + test->showSlider(slider); + sleep(1); + + // Now move the slider up + + for (int i = 0; i <= MAX_SLIDER; i++) + { + slider->setValue(i); + test->showSlider(slider); + message(MAIN_STRING "%d. New value %d\n", i, slider->getValue()); + usleep(1000); // The simulation needs this to let the X11 event loop run + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the slider up"); + + // And move the slider down + + for (int i = MAX_SLIDER; i >= 0; i--) + { + slider->setValue(i); + test->showSlider(slider); + message(MAIN_STRING "%d. New value %d\n", i, slider->getValue()); + usleep(1000); // The simulation needs this to let the X11 event loop run + } + updateMemoryUsage(g_mmprevious, MAIN_STRING "After moving the slider down"); + sleep(1); + + // Clean up and exit + + message(MAIN_STRING "Clean-up and exit\n"); + delete slider; + updateMemoryUsage(g_mmprevious, "After deleting the slider"); + delete test; + updateMemoryUsage(g_mmprevious, "After deleting the test"); + updateMemoryUsage(g_mmInitial, "Final memory usage"); + return 0; +} + diff --git a/NxWidgets/UnitTests/CTextBox/Makefile b/NxWidgets/UnitTests/CTextBox/Makefile new file mode 100644 index 000000000..3fe0fa43e --- /dev/null +++ b/NxWidgets/UnitTests/CTextBox/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/UnitTests/CTextBox/Makefile +# +# 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. +# +################################################################################# + +TESTDIR := ${shell pwd | sed -e 's/ /\\ /g'} + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Add the path to the NXWidget include directory to the CFLAGS + +NXWIDGETS_DIR="$(TESTDIR)/../../NXWidgets/libnxwidgets" +NXWIDGETS_INC="$(NXWIDGETS_DIR)/include" +NXWIDGETS_LIB="$(NXWIDGETS_DIR)/libnxwidgets$(LIBEXT)" + +INCDIR=$(TOPDIR)/tools/incdir.sh +ifeq ($(WINTOOL),y) + CFLAGS += ${shell $(INCDIR) -w "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) -w "$(CXX)" "$(NXWIDGETS_INC)"} +else + CFLAGS += ${shell $(INCDIR) "$(CC)" "$(NXWIDGETS_INC)"} + CXXFLAGS += ${shell $(INCDIR) "$(CXX)" "$(NXWIDGETS_INC)"} +endif + +# Get the path to the archiver tool + +TESTTOOL_DIR="$(TESTDIR)/../tools" +ARCHIVER=$(TESTTOOL_DIR)/addobjs.sh + +# Hello, World! C++ Example + +ASRCS = +CSRCS = +CXXSRCS = main.cxx ctextboxtest.cxx + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) +OBJS = $(AOBJS) $(COBJS) $(CXXOBJS) + +POSIX_BIN = "$(APPDIR)/libapps$(LIBEXT)" +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(POSIX_BIN)}" +else + BIN = $(POSIX_BIN) +endif + +ROOTDEPPATH = --dep-path . + +# helloxx built-in application info + +APPNAME = ctextbox +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 2048 + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend context disclean chkcxx chklib + +# Object file creation targets + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +$(CXXOBJS): %$(OBJEXT): %.cxx + $(call COMPILEXX, $<, $@) + +# Verify that the NuttX configuration is setup to support C++ + +chkcxx: +ifneq ($(CONFIG_HAVE_CXX),y) + @echo "" + @echo "In order to use this example, you toolchain must support must" + @echo "" + @echo " (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support" + @echo " (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file" + @echo " of the configuration that you are using." + @echo "" + @exit 1 +endif + +# Verify that the NXWidget library has been built + +chklib: + @( \ + if [ ! -e "$(NXWIDGETS_LIB)" ]; then \ + echo "$(NXWIDGETS_LIB) does not exist."; \ + echo "Please go to $(NXWIDGETS_DIR)"; \ + echo "and rebuild the library"; \ + exit 1; \ + fi; \ + ) + +# Library creation targets + +$(NXWIDGETS_LIB): # Just to keep make happy. chklib does the work. + +.built: chkcxx chklib $(OBJS) $(NXWIDGETS_LIB) + @( for obj in $(OBJS) ; do \ + $(call ARCHIVE, $(BIN), $${obj}); \ + done ; ) +ifeq ($(WINTOOL),y) + @$(ARCHIVER) -w -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +else + @$(ARCHIVER) -p "$(CROSSDEV)" $(BIN) $(NXWIDGETS_DIR) +endif + @touch .built + +# Standard housekeeping targets + +.context: +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main) +endif + @touch $@ + +context: .context + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) $(CXX) -- $(CXXFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + @rm -f *.o *~ .*.swp .built + $(call CLEAN) + +distclean: clean + @rm -f Make.dep .depend + +-include Make.dep diff --git a/NxWidgets/UnitTests/CTextBox/ctextboxtest.cxx b/NxWidgets/UnitTests/CTextBox/ctextboxtest.cxx new file mode 100644 index 000000000..e54bd4e6a --- /dev/null +++ b/NxWidgets/UnitTests/CTextBox/ctextboxtest.cxx @@ -0,0 +1,287 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CTextBox/ctextboxtest.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 <nuttx/init.h> +#include <cstdio> +#include <cerrno> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> +#include <nuttx/nx/nxfonts.h> + +#include "nxconfig.hxx" +#include "ctextboxtest.hxx" +#include "cbgwindow.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// CTextBoxTest Method Implementations +///////////////////////////////////////////////////////////////////////////// + +// CTextBoxTest Constructor + +CTextBoxTest::CTextBoxTest() +{ + m_bgWindow = (CBgWindow *)NULL; + m_nxFont = (CNxFont *)NULL; + m_text = (CNxString *)NULL; +} + +// CTextBoxTest Descriptor + +CTextBoxTest::~CTextBoxTest() +{ + disconnect(); +} + +// Connect to the NX server + +bool CTextBoxTest::connect(void) +{ + // Connect to the server + + bool nxConnected = CNxServer::connect(); + if (nxConnected) + { + // Create the default font instance + + m_nxFont = new CNxFont(NXFONT_DEFAULT, + CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR, + CONFIG_NXWIDGETS_TRANSPARENT_COLOR); + if (!m_nxFont) + { + printf("CTextBoxTest::connect: Failed to create the default font\n"); + } + + // Set the background color + + if (!setBackgroundColor(CONFIG_CTEXTBOXTEST_BGCOLOR)) + { + printf("CTextBoxTest::connect: setBackgroundColor failed\n"); + } + } + + return nxConnected; +} + +// Disconnect from the NX server + +void CTextBoxTest::disconnect(void) +{ + // Close the window + + if (m_bgWindow) + { + delete m_bgWindow; + } + + // Free the display string + + if (m_text) + { + delete m_text; + m_text = (CNxString *)NULL; + } + + // Free the default font + + if (m_nxFont) + { + delete m_nxFont; + m_nxFont = (CNxFont *)NULL; + } + + // And disconnect from the server + + CNxServer::disconnect(); +} + +// Create the background window instance. This function illustrates +// the basic steps to instantiate any window: +// +// 1) Create a dumb CWigetControl instance +// 2) Pass the dumb CWidgetControl instance to the window constructor +// that inherits from INxWindow. This will "smarten" the CWidgetControl +// instance with some window knowlede +// 3) Call the open() method on the window to display the window. +// 4) After that, the fully smartened CWidgetControl instance can +// be used to generate additional widgets by passing it to the +// widget constructor + +bool CTextBoxTest::createWindow(void) +{ + // Initialize the widget control using the default style + + m_widgetControl = new CWidgetControl((CWidgetStyle *)NULL); + + // Get an (uninitialized) instance of the background window as a class + // that derives from INxWindow. + + m_bgWindow = getBgWindow(m_widgetControl); + if (!m_bgWindow) + { + printf("CTextBoxTest::createGraphics: Failed to create CBgWindow instance\n"); + delete m_widgetControl; + return false; + } + + // Open (and initialize) the window + + bool success = m_bgWindow->open(); + if (!success) + { + printf("CTextBoxTest::createGraphics: Failed to open background window\n"); + delete m_bgWindow; + m_bgWindow = (CBgWindow*)0; + return false; + } + + return true; +} + +// Create a CTextBox instance + +CTextBox *CTextBoxTest::createTextBox(void) +{ + // Get the width of the display + + struct nxgl_size_s windowSize; + if (!m_bgWindow->getSize(&windowSize)) + { + printf("CTextBoxTest::createGraphics: Failed to get window size\n"); + return (CTextBox *)NULL; + } + + // Create an empty CNxString instance to contain the C string + + m_text = new CNxString(); + + // Get the height and width of the text display area. The width + // is half of the display width and the height is optimized for + // the font height + + nxgl_coord_t textBoxWidth = windowSize.w >> 1; + nxgl_coord_t textBoxHeight = (nxgl_coord_t)m_nxFont->getHeight(); + + // The default CTextBox has borders enabled with thickness of one. + // Add twice the thickness of the border to the height. + + textBoxHeight += 2 * 1; + + // Pick an X/Y position such that the label will be centered in the display + + nxgl_coord_t labelX = windowSize.w >> 2; + nxgl_coord_t labelY = (windowSize.h - textBoxHeight) >> 1; + + // Now we have enough information to create the label + + return new CTextBox(m_widgetControl, labelX, labelY, textBoxWidth, textBoxHeight, *m_text); +} + +// Draw the label + +void CTextBoxTest::showTextBox(CTextBox *label) +{ + label->enable(); + label->enableDrawing(); + label->redraw(); +} + +// Inject simulated keyboard characters into NX. + +void CTextBoxTest::injectChars(CTextBox *textbox, int nCh, FAR const uint8_t *string) +{ + // nx_kbdin is meant to be called by keyboard handling software. + // Here we just inject the string under unit test control. + + // First, get the server handle. Graphics software will never care + // about the server handle. Here we need it to get access to the + // low-level keyboard interface + + NXHANDLE handle = getServer(); + + // The widget must have focus to receive keyboard input + + m_widgetControl->setFocusedWidget(textbox); + + // Inject the string one character at a time to get a more realistic + // simulation of keyboard behavior. Note the API nx_kbdin() could + // be used to inject the string in its entirety. + + for (int i = 0; i < nCh; i++) + { + // Inject the next character + + (void)nx_kbdchin(handle, string[i]); + + // Widget events are normally handled in a modal loop (by calling goModal()). + // However, for this case we know when there should be keyboard events pending, + // events so we don't have to poll repeatedly. We can just perform a one pass + // poll + + m_widgetControl->pollEvents(textbox); + + // Sleep a bit, just for the effect (this also gives the X server loop a + // chance to run in the simulated environment. + + usleep(500*1000); + } +} diff --git a/NxWidgets/UnitTests/CTextBox/ctextboxtest.hxx b/NxWidgets/UnitTests/CTextBox/ctextboxtest.hxx new file mode 100644 index 000000000..2a839b06d --- /dev/null +++ b/NxWidgets/UnitTests/CTextBox/ctextboxtest.hxx @@ -0,0 +1,152 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CTextBox/ctextboxtest.hxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt <gnutt@nuttx.org> +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX, NxWidgets, nor the names of its contributors +// me be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef __UNITTESTS_CTEXTBOX_CTEXTBOXTEST_HXX +#define __UNITTESTS_CTEXTBOX_CTEXTBOXTEST_HXX + +///////////////////////////////////////////////////////////////////////////// +// Included Files +///////////////////////////////////////////////////////////////////////////// + +#include <nuttx/config.h> + +#include <nuttx/init.h> +#include <cstdio> +#include <semaphore.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "nxconfig.hxx" +#include "cwidgetcontrol.hxx" +#include "ccallback.hxx" +#include "cbgwindow.hxx" +#include "cnxserver.hxx" +#include "cnxfont.hxx" +#include "cnxstring.hxx" +#include "ctextbox.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// +// Configuration //////////////////////////////////////////////////////////// + +#ifndef CONFIG_HAVE_CXX +# error "CONFIG_HAVE_CXX must be defined" +#endif + +#ifndef CONFIG_CTEXTBOXTEST_BGCOLOR +# define CONFIG_CTEXTBOXTEST_BGCOLOR CONFIG_NXWIDGETS_DEFAULT_BACKCOLOR +#endif + +#ifndef CONFIG_CTEXTBOXTEST_FONTCOLOR +# define CONFIG_CTEXTBOXTEST_FONTCOLOR CONFIG_NXWIDGETS_DEFAULT_FONTCOLOR +#endif + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME ctextbox_main +# define MAIN_STRING "ctextbox_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +///////////////////////////////////////////////////////////////////////////// +// Public Classes +///////////////////////////////////////////////////////////////////////////// + +using namespace NXWidgets; + +class CTextBoxTest : public CNxServer +{ +private: + CWidgetControl *m_widgetControl; // The controlling widget for the window + CNxFont *m_nxFont; // Default font + CBgWindow *m_bgWindow; // Background window instance + CNxString *m_text; // The label string + +public: + // Constructor/destructors + + CTextBoxTest(); + ~CTextBoxTest(); + + // Initializer/unitializer. These methods encapsulate the basic steps for + // starting and stopping the NX server + + bool connect(void); + void disconnect(void); + + // Create a window. This method provides the general operations for + // creating a window that you can draw within. + // + // Those general operations are: + // 1) Create a dumb CWigetControl instance + // 2) Pass the dumb CWidgetControl instance to the window constructor + // that inherits from INxWindow. This will "smarten" the CWidgetControl + // instance with some window knowlede + // 3) Call the open() method on the window to display the window. + // 4) After that, the fully smartened CWidgetControl instance can + // be used to generate additional widgets by passing it to the + // widget constructor + + bool createWindow(void); + + // Create a CTextBox instance. This method will show you how to create + // a CTextBox widget + + CTextBox *createTextBox(void); + + // Draw the label. This method illustrates how to draw the CTextBox widget. + + void showTextBox(CTextBox *label); + + // Inject simulated keyboard characters into NX. + + void injectChars(CTextBox *textbox, int nCh, FAR const uint8_t *string); +}; + +///////////////////////////////////////////////////////////////////////////// +// Public Data +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + + +#endif // __UNITTESTS_CTEXTBOX_CTEXTBOXTEST_HXX diff --git a/NxWidgets/UnitTests/CTextBox/main.cxx b/NxWidgets/UnitTests/CTextBox/main.cxx new file mode 100644 index 000000000..b5b8ec4d5 --- /dev/null +++ b/NxWidgets/UnitTests/CTextBox/main.cxx @@ -0,0 +1,141 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/CTextBox/main.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 <nuttx/init.h> +#include <cstdio> +#include <unistd.h> +#include <debug.h> + +#include <nuttx/nx/nx.h> + +#include "ctextboxtest.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Definitions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Classes +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static const char string1[] = "Johhn "; +static const char string2[] = "\b\b\bn Doe\r"; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// user_start/nxheaders_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Create an instance of the font test + + printf(MAIN_STRING "Create CTextBoxTest instance\n"); + CTextBoxTest *test = new CTextBoxTest(); + + // Connect the NX server + + printf(MAIN_STRING "Connect the CTextBoxTest instance to the NX server\n"); + if (!test->connect()) + { + printf(MAIN_STRING "Failed to connect the CTextBoxTest instance to the NX server\n"); + delete test; + return 1; + } + + // Create a window to draw into + + printf(MAIN_STRING "Create a Window\n"); + if (!test->createWindow()) + { + printf(MAIN_STRING "Failed to create a window\n"); + delete test; + return 1; + } + + // Create a CTextBox instance + + CTextBox *textbox = test->createTextBox(); + if (!textbox) + { + printf(MAIN_STRING "Failed to create a text box\n"); + delete test; + return 1; + } + + // Show the text box + + test->showTextBox(textbox); + + // Wait a bit, then inject a string with a typo + + sleep(1); + test->injectChars(textbox, sizeof(string1), (FAR const uint8_t*)string1); + + // Now fix the string with backspaces and finish it correctly + + usleep(500*1000); + test->injectChars(textbox, sizeof(string2), (FAR const uint8_t*)string2); + + // Clean up and exit + + sleep(2); + printf(MAIN_STRING "Clean-up and exit\n"); + delete textbox; + delete test; + return 0; +} + diff --git a/NxWidgets/UnitTests/README.txt b/NxWidgets/UnitTests/README.txt new file mode 100644 index 000000000..b0f3c9aab --- /dev/null +++ b/NxWidgets/UnitTests/README.txt @@ -0,0 +1,394 @@ +README +====== + +This directory contains a collection of Unit Tests that can be used to verify +NXWidgets.: + +Contents +======== + o Installing and Building the Unit Tests + 1. Setup NuttX + a) Configure NuttX + b) Enable C++ Support + c) Enable Debug Options + d) Other Possible nuttx/.config changes + e) Other Possible apps/.config changes + 2. Configure in the Selected Unit Test + o Work-Arounds + 1. Build Issues + 2. Stack Size Issues with the X11 Simulation + o Theory of Operation + o Unit Test Directories + o Example + +Installing and Building the Unit Tests +====================================== + +1. Setup NuttX + + a) Configure NuttX + + Configure NuttX to run one of the target configurations. For example, + let's assume that you are using the sim/nsh2 configuration. The sim/nsh2 + configuration was specially created for use NXWidgets on the simulation + platform. A similar, special configuration stm3210e-eval/nsh2 is also + for the STM3210E-EVAL available. However, the unit test can be run on + other configurations (see steps d and e below). + + We will assume the sim/nsh2 configuration in this discussion. The + sim/nsh2 configuration is installed as follows: + + cd <nuttx-directory-path> + make distclean + cd tools + ./configure.sh sim/nsh2 + + Where: + + <nuttx-directory-path> is the full, absolute path to the NuttX build directory + + If you are using the sim/nsh2 or stm3210e-eval configurations, then skip + to step 2. + + There may be certain requirements for the configuration that you select... + for example, certain widget tests may require touchscreen support or special + font selections. These test-specific requirements are addressed below under + "Unit Test Directories" + + b) Enable C++ Support + + If you are not using the sim/nsh2 or stm3210e-eval, you will need to add + the following definitions to the nuttx configuration at nuttx/.config to + enable C++ support: + + CONFIG_HAVE_CXX=y + + Check first, some configurations already have C++ support enabled (As of this + writing *ONLY* the sim/nsh2 and stm321-e-eval configurations have C++ support + pre-enabled). + + c) Enable Debug Options + + If you are running on a simulated target, then you might also want to + enable debug symbols: + + CONFIG_DEBUG_SYMBOLS=y + + Then you can run the simulation using GDB or DDD which is a very powerful + debugging environment! + + d) Other nuttx/.config changes -- NSH configurations only. + + If the configuration that you are using supports NSH and NSH built-in tasks + then all is well. If it is an NSH configuration, then you will have to define + the following in your nuttx/.config file as well (if it is not already defined): + + CONFIG_NSH_BUILTIN_APPS=y + + sim/nsh2 and stm3210e-eval/nsh2 already has this setting. You do not need + to change anything further in the nuttx/.config file if you are using either + of these configurations. + + e) Other apps/.config changes -- NON-NSH configurations only. + + For non-NSH configurations (such as the sim/touchscreen) you will have to + remove the CONFIGURED_APPS seting that contains the user_start function so + that you use the user_start in the unit test code instead. So, for example, + with the sim/touchscreen configuration you need to remove the following from + the apps/.config file: + + CONFIGURED_APPS += examples/<example> ## REMOVE + + The following step will then install the new, correct directory containing + the user_start function for the selected unit test. If you see that NSH + is configured: + + CONFIGURED_APPS += examples/nsh ## DO NOT REMOVE + + Then DO NOT REMOVE the CONFIGURED_APPS setting. Go back and re-read c) + above. Do either c) or d). Don't do both! + + sim/nsh2 and stm3210e-eval/nsh2 both NSH configurations. You do not need + to change anything further in the apps/.config file for any NSH configuration. + +2. Configure/Install the Selected Unit Test + + Then reconfigure that to use the Unit Test of your choice: + + cd <raztek-nxwidgets-directory>/trunk/UnitTests/tools + ./install.sh <apps-directory-path> <test-sub-directory> + + Where: + + <apps-directory-path> is the full, absolute path to the NuttX apps/ directory + <test-sub-directory> is the name of a sub-directory in the UnitTests directory + +3. Instantiate the Configuration + + Before we can make the NXWidgets Library, we have to instantiate the NuttX + configuration with the installed unit test: + + cd <nuttx-directory-path> + . ./setenv.sh + make context + + This will create auto-generated files and will setup symbolic links needed + in order to build the NXWidgets Library. + +4. Adjust the Stack Size + + If using an simulation configuration (like sim/nsh2) and your unit test + uses X11 as its display device, then you would have to increase the size + of unit test stack as described below under "Stack Size Issues with the + X11 Simulation." + +5. Build the NXWidgets Library + + cd <raztek-nxwidgets-directory>/trunk/NXWidgets/libnxwidgets + make TOPDIR=<nuttx-directory-path> + +6. Build NuttX including the unit test and the NXWidget library + + cd <nuttx-directory-path> + . ./setenv.sh + make + +Work-Arounds +============ + +Build Issues +------------ +1. I have seen this error on Cygwin building C++ code: + + LD: nuttx.rel + ld: skipping incompatible /home/patacongo/projects/nuttx/nuttx/trunk/nuttx/libxx//liblibxx.a when searching for -llibxx + ld: cannot find -llibxx + + The problem seems to be caused because gcc build code for 32-bit mode and g++ builds code for 64-bit mode. Add the -m32 option to the g++ command line seems to fix the problem. In Make.defs: + + CXXFLAGS = -m32 $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) \ + $(ARCHCPUFLAGSXX) $(ARCHINCLUDESXX) $(ARCHDEFINES) $(EXTRADEFINES) -pipe + +2. Stack Size Issues with the X11 Simulation + + When you run the NuttX simulation, it uses stacks allocated by NuttX from the + NuttX heap. The memory management model is exactly the same in the simulation + as it is real, target system. This is good because this produces a higher + fidelity simulation. + + However, when the simulation calls into Linux/Cygwin libraries, it will still + use these small simulation stacks. This happens, for example, when you call + into the system to get and put characters to the console window or when you + make x11 calls into the system. The programming model within those libraries + will assume a Linux/Cygwin environment where the stack size grows dynamically + + As a consequence, those system libraries may allocate large data structures + on the stack and overflow the small NuttX stacks. X11, in particular, + requires large stacks. If you are using X11 in the simulation, make sure + that you set aside a "lot" of stack for the X11 system calls (maybe 8 or 16Kb). + The stack size for the thread that begins with user start is controlled + by the configuration setting CONFIG_USERMAIN_STACKSIZE; you may need to + increase this value to larger number to survive the X11 system calls. + + If you are running X11 applications as NSH add-on programs, then the stack + size of the add-on program is controlled in another way. Here are the + steps for increasing the stack size in that case: + + cd ../apps/namedapps # Go to the namedapps directory + vi namedapps_list.h # Edit this file and increase the stack size of the add-on + rm .built *.o # This will force the namedapps logic to rebuild + +Theory Of Operation +=================== + +The NuttX application Makefile at apps/Makefile has some special hooks for +building "external" applications. In particular, it will automatically +build in the contents any directory call "external/" that may appear in the +apps/ directory. There is no external/ directory in the repository. Rather, +this directory may be provided by the user (possibly as a symbolic link) to +add libraries and applications to the standard build from the repository. + +The script at tools/install.sh, then, just does a lot of careful validation and +sanity checking. Then it installs the UnitTest test sub-directory in the apps/ +directory by creating a symbolic link in the apps/ directory call "external". +That symbolic link will refer to the selected UnitTest sub-directory. + +UnitTests +========= + +The following provide simple unit tests for each of the NXWidgets. In +addition, these unit tests provide examples for the use of each widget +type. + +CButton + Exercises the CButton widget + Depends on CLabel + +CButtonArray + Exercises the CButtonArray widget + +CCheckBox + Exercises the CCheckBox widget + Depends on CLabel and CButton. + +CGlyphButton + Exercises the CGlyphButton widget. + Depends on CLabel and CButton. + +CImage + Exercises the CImage widget + +CLabel + Exercises the CLabel widget + +CProgressBar + Exercises the CProgressBar widget + +CRadioButton + Exercises the CRadioButton and CRadioButtonGroup widgets. + Depends on CLabel and CButton + +CScrollBarHorizontal + Exercises the ScrollbarHorizontal + Depends on CSliderHorizontal and CGlyphButton + +CScrollBarVertical + Exercises the ScrollbarHorizontal + Depends on CSliderVertical and CGlyphButton + +CSliderHorizontal + Exercises the CSliderHorizontal + Depends on CSliderHorizontalGrip + +CSliderVertical + Exercises the CSliderVertical + Depends on CSliderVerticalGrip + +CTextBox + Exercises the CTextBox widget + Depends on CLabel + +Example +======= + +1. Configure sim/nsh2 + Where: nuttx and nuttx/tools directory + + $ cd tools/ + $ ./configure.sh sim/nsh2 + $ cd - + +2. Edit nuttx/.config to enable C++ support + + Do nothing... sim/nsh2 already has C++ support enabled. + +3. Install the CButton C++ application (for example) + Where: NXWidgets/trunk/UnitTests/tool + + $ ./install.sh ~/projects/nuttx/nuttx/trunk/apps/ CButton + /home/patacongo/projects/nuttx/nuttx/trunk/apps//external already exists... + Removing the old symbolic link. + Creating symbolic link + - To /home/patacongo/projects/nuttx/gui/raztek-nxwidgets/trunk/UnitTests/tools/../CButton + - At /home/patacongo/projects/nuttx/nuttx/trunk/apps//external + +4. Instantiate the Configuration + Where: nuttx directory + + $ cd /home/patacongo/projects/nuttx/nuttx/trunk/nuttx + $ . ./setenv.sh + $ make context + + This will create auto-generated files and will setup symbolic links needed + in order to build the NXWidgets Library. + +6. Adjust the Stack Size + + If using an simulation configuration (like sim/nsh2) and your unit test + uses X11 as its display device, then you would have to increase the size + of unit test stack as described above under "Stack Size Issues." + +7. Build the NXWdigets Library + Where XWidgets/trunk/NXWidgets/libnxwidgets + + $ cd /home/patacongo/projects/nuttx/gui/raztek-nxwidgets/trunkXWidgets/libnxwidgets + $ make TOPDIR=/home/patacongo/projects/nuttx/nuttx/trunk/nuttx + +8. Build NuttX + Where: nuttx directory + + $ cd /home/patacongo/projects/nuttx/nuttx/trunk/nuttx + $ make + ... + +8. Run the "bringup" task: + + a. Start NuttX + Where: nuttx directory + + ./nuttx + + NuttShell (NSH) NuttX-6.9 + nsh> + + b. Execute NuttX + Where: NSH command prompt + + NOTE that when you run NSH as a simulation, the commands are echoed + twice -- once by Linux/Cygwin and once by NuttX: + + nsh> help + help + ... + Builtin Apps: + nx + nxhello + tc + bringup + nsh> bringup + bringup + bringup [2:128] + + c. Then do a kludgy thing + Where: NSH command prompt + + The I/O with the Linux/Cygwin simulation is blocking. So while NSH is + waiting for input nothing can run (see configs/sim/README.txt for more info). + One way to make NSH stop asking for input is to sleep. + + nsh> sleep 10 + sleep 10 + + NOTE 1: This is not a problem if CONFIG_SCHED_WAITPID is defined in the + configuration file. If CONFIG_SCHED_WAITPID is defined, NSH will wait + for the unit test to complete and it will not be necessary to sleep. + + NOTE 2: CONFIG_SCHED_WAITPID is defined in the sim/nsh2 configuration + so you can probably ignore this kludgy thing. + + d. The Unit Test runs + + As soon as NSH sleeps, the unit test will run: + + bringup_main: Saying hello from the dynamically constructed instance + CHelloWorld::HelloWorld: Hello, World!! + bringup_main: Saying hello from the instance constructed on the stack + CHelloWorld::HelloWorld: Hello, World!! + bringup_main: Saying hello from the statically constructed instance + CHelloWorld::HelloWorld: Hello, World!! + +8. Debugging + Where: nuttx directory + + In the simulation (only) you can use GDB or, better, the graphic + front-end DDD to debug the code. Most embedded targets do not + have good debugging capabilities. + + In order to debug, you have to have build with CONFIG_DEBUG_SYMBOLS=y. + This setting is preselected in the sim/nsh2 configuration so that + you don't have to do anything. + + Then under Linux or in a Cygwin X11 window, you can start the graphic + debugger like: + + ddd nuttx & diff --git a/NxWidgets/UnitTests/tools/addobjs.sh b/NxWidgets/UnitTests/tools/addobjs.sh new file mode 100755 index 000000000..e998cfc64 --- /dev/null +++ b/NxWidgets/UnitTests/tools/addobjs.sh @@ -0,0 +1,141 @@ +#!/bin/bash +################################################################################# +# NxWidgets/UnitTests/tools/addobjs.sh +# +# 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. +# +################################################################################# + +# set -x + +# Get input parameters + +usage="Usage: $0 [OPTIONS] <lib-path> <obj-dir>" +advice="Try '$0 -h' for more information" + +unset prefix +wintool=n + +while [ ! -z "$1" ]; do + case $1 in + -d ) + set -x + ;; + -p ) + shift + prefix=$1 + ;; + -w ) + wintool=y + ;; + -h ) + echo "$0 will add all object (.o) files in directory to an archive." + echo "" + echo $usage + echo "" + echo "Where:" + echo " <alib-path> is the full, absolute path to the library to use" + echo " <obj-dir> is full path to the directory containing the object files to be added" + echo "OPTIONS include:" + echo " -p Prefix to use. For example, to use arm-elf-ar, add '-p arm-elf-'" + echo " -w Use Windows style paths insted of POSIX paths" + echo " -d Enable script debug" + echo " -h Show this usage information" + exit 0 + ;; + * ) + break; + ;; + esac + shift +done + +libpath=$1 +objdir=$2 +archiver="${prefix}"ar + +# Verify input parameters + +if [ -z "${libpath}" ]; then + echo "Missing required arguments" + echo "" + echo $usage + echo $advice + exit 1 +fi + +if [ -z "${objdir}" ]; then + echo "Missing required argument <obj-dir>" + echo "" + echo $usage + echo $advice + exit 1 +fi + +if [ ! -w ${libpath} ]; then + if [ -e ${libpath} ]; then + echo "${libpath} exists but is not a write-able file" + echo $advice + else + echo "${libpath} does not exist" + echo $advice + fi + exit 1 +fi + +if [ ! -d ${objdir} ]; then + if [ -e ${objdir} ]; then + echo "${objdir} exists but is not a directory" + echo $advice + else + echo "${objdir} does not exist" + echo $advice + fi + exit 1 +fi + +# Add each object file in <obj-dir> to the archive at <lib-path> + +for obj in `ls "${objdir}"/*.o`; do + name=`basename "${obj}"` + if [ "X${wintool}" = "Xy" ]; then + objpath=`cygpath -w "${obj}"` + else + objpath=${obj} + fi + echo "AR: ${name}" + ${archiver} rcs ${libpath} ${objpath} || \ + { echo "Failed to archive the object file:"; \ + echo " Archive: ${libpath}"; \ + echo " Object: ${obj}"; \ + exit 1; \ + } +done
\ No newline at end of file diff --git a/NxWidgets/UnitTests/tools/install.sh b/NxWidgets/UnitTests/tools/install.sh new file mode 100755 index 000000000..3ba086aff --- /dev/null +++ b/NxWidgets/UnitTests/tools/install.sh @@ -0,0 +1,152 @@ +#!/bin/bash +################################################################################# +# NxWidgets/UnitTests/tools/install.sh +# +# 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. +# +################################################################################# +# +# set -x +# Functions + +function ShowUsage() +{ + echo "" + echo "USAGE: $0 <apps-directory-path> <test-sub-directory>" + echo "" + echo "Where:" + echo " <apps-directory-path> is the full, absolute path to the NuttX apps/ directory" + echo " <test-sub-directory> is the name of a sub-directory in the UnitTests directory" + echo "" +} + +function ShowTests() +{ + for testdir in ${UNITTEST_DIRPATH}/*; do + subdir=`basename ${testdir}` + if [ -d "${UNITTEST_DIRPATH}/${subdir}" ]; then + if [ -f "${UNITTEST_DIRPATH}/${subdir}/Makefile" ]; then + echo $subdir + fi + fi + done +} + +# Input parameters + +APPS_DIRPATH=$1 +TEST_SUBDIR=$2 + +if [ -z "${APPS_DIRPATH}" ]; then + echo "Missing required arguments" + ShowUsage + exit 1 +fi + +if [ -z "${TEST_SUBDIR}" ]; then + echo "Missing required argument <test-sub-directory>" + ShowUsage + exit 1 +fi + +# Make sure that we know where we are and where we are going + +WD=`pwd` +if [ -x install.sh ]; then + UNITTEST_DIRPATH="${WD}/.." + TOOLS_DIRPATH="${WD}" +else + if [ -x tools/install.sh ]; then + UNITTEST_DIRPATH="${WD}" + TOOLS_DIRPATH="${WD}/tools" + else + echo "This script must be executed in the UnitTest or UnitTest/tools directory" + ShowUsage + exit 1 + fi +fi + +if [ ! -d "${APPS_DIRPATH}" ]; then + echo "Directory ${APPS_DIRPATH} does not exist" + ShowUsage + exit 1 +fi + +if [ ! -f "${APPS_DIRPATH}/Makefile" ]; then + echo "Directory ${APPS_DIRPATH} does not look like a NuttX apps directory" + ShowUsage + exit 1 +fi + +TEST_PATH="${UNITTEST_DIRPATH}/${TEST_SUBDIR}" +if [ ! -d "${TEST_PATH}" ]; then + echo "Directory ${TEST_PATH} does not exist" + ShowUsage + ShowTests + exit 1 +fi + +if [ ! -f "${TEST_PATH}/Makefile" ]; then + echo "Directory ${TEST_PATH} does not look like a unit test directory" + ShowUsage + ShowTests + exit 1 +fi + +# Check if the symbolic link "external" exists in the NuttX apps directory + +if [ -e "${APPS_DIRPATH}/external" ]; then + echo "${APPS_DIRPATH}/external already exists..." + if [ -h "${APPS_DIRPATH}/external" ]; then + echo " Removing the old symbolic link." + rm "${APPS_DIRPATH}/external" || \ + { echo " ERROR: Failed to remove old symbolic link"; \ + exit 1; + } + else + echo " ERROR: But it is not a symbolic link!" + echo " Please remove ${APPS_DIRPATH}/external" + echo " and run this script again" + fi +fi + +# Then set up the symbolic link "external" in the NuttX apps to point to the +# UnitTest subdirectory + +echo "Creating symbolic link" +echo " - To ${TEST_PATH}" +echo " - At ${APPS_DIRPATH}/external" + +ln -s "${TEST_PATH}" "${APPS_DIRPATH}/external" || \ + { echo "Failed to create symbollic link"; \ + exit 1; + } + |