From 9384da7066d128ab6a0fb7616a671047c374cd4a Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 30 Apr 2012 20:38:44 +0000 Subject: Completes first cut at task bar git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4678 42af7a65-404d-4744-a932-0658087f49c3 --- NxWidgets/ChangeLog.txt | 4 +- NxWidgets/UnitTests/nxwm/Makefile | 172 +++++++ NxWidgets/UnitTests/nxwm/main.cxx | 262 +++++++++++ NxWidgets/nxwm/include/capplicationwindow.hxx | 13 +- NxWidgets/nxwm/include/cbackgroundimage.hxx | 88 ---- NxWidgets/nxwm/include/cstartwindow.hxx | 5 +- NxWidgets/nxwm/include/ctaskbar.hxx | 142 +++++- NxWidgets/nxwm/include/iapplication.hxx | 61 ++- NxWidgets/nxwm/include/nxwmconfig.hxx | 51 ++- NxWidgets/nxwm/include/nxwmglyphs.hxx | 1 + NxWidgets/nxwm/src/ctaskbar.cxx | 618 ++++++++++++++++++++++++-- 11 files changed, 1252 insertions(+), 165 deletions(-) create mode 100644 NxWidgets/UnitTests/nxwm/Makefile create mode 100644 NxWidgets/UnitTests/nxwm/main.cxx delete mode 100644 NxWidgets/nxwm/include/cbackgroundimage.hxx (limited to 'NxWidgets') diff --git a/NxWidgets/ChangeLog.txt b/NxWidgets/ChangeLog.txt index 8064137e0..d9dfda7b2 100755 --- a/NxWidgets/ChangeLog.txt +++ b/NxWidgets/ChangeLog.txt @@ -11,5 +11,5 @@ * CImage: If selected, uses different LUTs based, different borders. CImage is now basically a button type. * CImage: Add logic to hightlight an CImage (using the selected LUT). -* nxwm: This directory will, hopefully, eventually hold the NX tiny - desktop (NxWM). +* nxwm: The tiny NX window manager (NxWM) is being developed in this directory. +* UnitTests/nxwm: A unit test for the NX window manager. diff --git a/NxWidgets/UnitTests/nxwm/Makefile b/NxWidgets/UnitTests/nxwm/Makefile new file mode 100644 index 000000000..d9cf2d051 --- /dev/null +++ b/NxWidgets/UnitTests/nxwm/Makefile @@ -0,0 +1,172 @@ +################################################################################# +# NxWidgets/Unitests/nxwm/Makefile +# +# Copyright (C) 2012 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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)/../../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 + +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 = nxwm +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/nxwm/main.cxx b/NxWidgets/UnitTests/nxwm/main.cxx new file mode 100644 index 000000000..dffa7b600 --- /dev/null +++ b/NxWidgets/UnitTests/nxwm/main.cxx @@ -0,0 +1,262 @@ +///////////////////////////////////////////////////////////////////////////// +// NxWidgets/UnitTests/nxwm/main.cxx +// +// Copyright (C) 2012 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// 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 + +#include "ctaskbar.hxx" +#include "cstartwindow.hxx" + +///////////////////////////////////////////////////////////////////////////// +// Pre-processor Definitions +///////////////////////////////////////////////////////////////////////////// + +// What is the entry point called? + +#ifdef CONFIG_NSH_BUILTIN_APPS +# define MAIN_NAME nxwm_main +# define MAIN_STRING "nxwm_main: " +#else +# define MAIN_NAME user_start +# define MAIN_STRING "user_start: " +#endif + +///////////////////////////////////////////////////////////////////////////// +// Private Types +///////////////////////////////////////////////////////////////////////////// + +struct nxwm_test_s +{ + NxWM::CTaskbar *taskbar; // The task bar + NxWM::CStartWindow *startwindow; // The start window +}; + +///////////////////////////////////////////////////////////////////////////// +// Private Data +///////////////////////////////////////////////////////////////////////////// + +static struct nxwm_test_s g_nxwmtest; + +///////////////////////////////////////////////////////////////////////////// +// Public Function Prototypes +///////////////////////////////////////////////////////////////////////////// + +// Suppress name-mangling + +extern "C" int MAIN_NAME(int argc, char *argv[]); + +///////////////////////////////////////////////////////////////////////////// +// Public Functions +///////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////// +// user_start/nxwm_main +///////////////////////////////////////////////////////////////////////////// + +int MAIN_NAME(int argc, char *argv[]) +{ + // Create an instance of the Task Bar. + // + // The general sequence for initializing the task bar is: + // + // 1. Create the CTaskbar instance, + // 2. Call the CTaskbar::connect() method to connect to the NX server (CTaskbar + // inherits the connect method from CNxServer), + // 3. Call the CTaskbar::initWindowManager() method to initialize the task bar. + // 3. Call CTaskBar::startApplication repeatedly to add applications to the task bar + // 4. Call CTaskBar::startWindowManager to start the display with applications in place + + printf(MAIN_STRING "Create CTaskbar instance\n"); + g_nxwmtest.taskbar = new CTaskbar(); + if (!g_nxwmtest.taskbar) + { + printf(MAIN_STRING "ERROR: Failed to instantiate CTaskbar\n"); + return EXIT_FAILURE; + } + + // Connect to the NX server + + printf(MAIN_STRING "Connect the CTaskbar instance to the NX server\n"); + if (!g_nxwmtest.taskbar->connect()) + { + printf(MAIN_STRING "ERROR: Failed to connect the CTaskbar instance to the NX server\n"); + delete g_nxwmtest.taskbar; + return EXIT_FAILURE; + } + + // Initialize the task bar + // + // Taskbar::initWindowManager() prepares the task bar to receive applications. + // CTaskBar::startWindowManager() brings the window manager up with those applications + // in place. + + printf(MAIN_STRING "Initialize the CTaskbar instance\n"); + if (!g_nxwmtest.taskbar->initWindowManager()) + { + printf(MAIN_STRING "ERROR: Failed to intialize the CTaskbar instance\n"); + delete g_nxwmtest.taskbar; + return EXIT_FAILURE; + } + + // Create the start window. The general sequence for setting up the start window is: + // + // 1. Call CTaskBar::openApplicationWindow to create a window for the start window, + // 2. Use the window to instantiate Cstartwindow + // 3. Call Cstartwindow::addApplication numerous times to install applications + // in the start window. + // 4. Call CTaskBar::startApplication (initially minimized) to start the start + // window application. + + printf(MAIN_STRING "Opening the start window application window\n"); + CApplicationWindow *window = g_nxwmtest.taskbar->openApplicationWindow(); + if (!window) + { + printf(MAIN_STRING "ERROR: Failed to create CApplicationWindow for the start window\n"); + delete g_nxwmtest.taskbar; + return EXIT_FAILURE; + } + + printf(MAIN_STRING "Creating the start window application\n"); + g_nxwmtest.startwindow = new NxWM::CStartWindow(g_nxwmtest.taskbar, window); + if (!g_nxwmtest.taskbar) + { + printf(MAIN_STRING "ERROR: Failed to instantiate CStartWindow\n"); + delete window; + delete g_nxwmtest.taskbar; + return EXIT_FAILURE; + } + + // Add the NxConsole application to the start window + +#if 0 + printf(MAIN_STRING "Opening the NxConsole application window\n"); + window = g_nxwmtest.taskbar->openApplicationWindow(); + if (!window) + { + printf(MAIN_STRING "ERROR: Failed to create CApplicationWindow for the NxConsole\n"); + goto noconsole; + } + + printf(MAIN_STRING "Creating the NxConsole application\n"); + NxWM::CNxConsole *console = new CNxConsole(window); + if (!console) + { + printf(MAIN_STRING "ERROR: Failed to instantiate CNxConsole\n"); + delete window; + goto noconsole; + } + + printf(MAIN_STRING "Adding the NxConsole application to the start window\n"); + if (!g_nxwmtest.startwindow->addApplication(console)) + { + printf(MAIN_STRING "ERROR: Failed to add CNxConsole to the start menu\n"); + delete window; + } + +noconsole: +#endif + + // Add the calculator application to the start window + +#if 0 + printf(MAIN_STRING "Opening the calculator application window\n"); + window = g_nxwmtest.taskbar->openApplicationWindow(); + if (!window) + { + printf(MAIN_STRING "ERROR: Failed to create CApplicationWindow for the calculator\n"); + goto nocalculator; + } + + printf(MAIN_STRING "Creating the calculator application\n"); + NxWM::CCalculator *calculator = new CCalculator(window); + if (!calculator) + { + printf(MAIN_STRING "ERROR: Failed to instantiate calculator\n"); + delete window; + goto nocalculator; + } + + printf(MAIN_STRING "Adding the calculator application to the start window\n"); + if (!g_nxwmtest.startwindow->addApplication(calculator)) + { + printf(MAIN_STRING "ERROR: Failed to add calculator to the start menu\n"); + delete window; + } + +nocalculator: +#endif + + // Call CTaskBar::startApplication to start the start window application. The initial + // state of the start window is minimized. + + printf(MAIN_STRING "Start the start window application\n"); + if (!g_nxwmtest.taskbar->startApplication(g_nxwmtest.startwindow, true)) + { + printf(MAIN_STRING "ERROR: Failed to start the start window application\n"); + + // Delete the task bar then the start window. the order is important because + // we must bet all of the application references out of the task bar before + // deleting the start window. When the start window is deleted, it will + // also delete of of the resouces contained within the start window. + + delete g_nxwmtest.taskbar; + delete g_nxwmtest.startwindow; + return EXIT_FAILURE; + } + + // Call CTaskBar::startWindowManager to start the display with applications in place. + // This method will not return but will enter the task bar's modal loop. + + printf(MAIN_STRING "Start the window manager\n"); + if (!g_nxwmtest.taskbar->startWindowManager()) + { + printf(MAIN_STRING "ERROR: Failed to start the window manager\n"); + + // Delete the task bar then the start window. the order is important because + // we must bet all of the application references out of the task bar before + // deleting the start window. When the start window is deleted, it will + // also delete of of the resouces contained within the start window. + + delete g_nxwmtest.taskbar; + delete g_nxwmtest.startwindow; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + diff --git a/NxWidgets/nxwm/include/capplicationwindow.hxx b/NxWidgets/nxwm/include/capplicationwindow.hxx index 805df4184..3d868e576 100644 --- a/NxWidgets/nxwm/include/capplicationwindow.hxx +++ b/NxWidgets/nxwm/include/capplicationwindow.hxx @@ -110,23 +110,22 @@ namespace NxWM void handleClickEvent(const NXWidgets::CWidgetEventArgs &e); - /** - * CApplicationWindow Destructor - */ - - ~CApplicationWindow(void); - public: /** * CApplicationWindow Constructor * - * @param taskbar. A pointer to the parent task bar instance * @param window. The window to be used by this application. */ CApplicationWindow(NXWidgets::CNxTkWindow *window); + /** + * CApplicationWindow Destructor + */ + + ~CApplicationWindow(void); + /** * Initialize window. Window initialization is separate from * object instantiation so that failures can be reported. diff --git a/NxWidgets/nxwm/include/cbackgroundimage.hxx b/NxWidgets/nxwm/include/cbackgroundimage.hxx deleted file mode 100644 index 89ca469cd..000000000 --- a/NxWidgets/nxwm/include/cbackgroundimage.hxx +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** - * NxWidgets/nxwm/include/cnxbackimage.hxx - * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * 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 __NXWM_INCLUDE_CBACKGROUNDIMAGE_HXX -#define __NXWM_INCLUDE_CBACKGROUNDIMAGE_HXX - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include "nxconfig.hxx" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Implementation Class Definition - ****************************************************************************/ - -#if defined(__cplusplus) - -namespace NxWM -{ - /** - * This class describes the NX windo manager's background image. - */ - - class CBackgroundImage : public NXWidgets::CImage - { - private: - NXWidgets::CWidgetControl *m_widgetControl; // The controlling widget for the window - - public: - /** - * CBackgroundImage Constructor - */ - - CBackgroundImage(void); - - /** - * CBackgroundImage Destructor - */ - - ~CBackgroundImage(void); - }; -} - -#endif // __cplusplus -#endif // __NXWM_INCLUDE_CBACKGROUNDIMAGE_HXX diff --git a/NxWidgets/nxwm/include/cstartwindow.hxx b/NxWidgets/nxwm/include/cstartwindow.hxx index c47b85d83..2a1dac088 100644 --- a/NxWidgets/nxwm/include/cstartwindow.hxx +++ b/NxWidgets/nxwm/include/cstartwindow.hxx @@ -125,9 +125,10 @@ namespace NxWM * setting up the start window is: * * 1. Call CTaskBar::openApplicationWindow to create a window for the start window, - * 2. Call CStartMenu::addApplication numerous times to install applications + * 2. Use the window to instantiate CStartMenu + * 3. Call CStartMenu::addApplication numerous times to install applications * in the start window. - * 3. Call CTaskBar::startApplication (initially minimized) to start the start + * 4. Call CTaskBar::startApplication (initially minimized) to start the start * window application. * * @param application. The new application to add to the start window diff --git a/NxWidgets/nxwm/include/ctaskbar.hxx b/NxWidgets/nxwm/include/ctaskbar.hxx index 0c420a0e2..ef25fd563 100644 --- a/NxWidgets/nxwm/include/ctaskbar.hxx +++ b/NxWidgets/nxwm/include/ctaskbar.hxx @@ -44,7 +44,7 @@ #include "nxconfig.hxx" #include "tnxarray.hxx" -#include "inxwindow.hxx" +#include "cnxwindow.hxx" #include "cnxserver.hxx" #include "cwidgeteventhandler.hxx" #include "cwidgeteventargs.hxx" @@ -64,15 +64,41 @@ namespace NxWM { /** - * This class describes the NX window manager's task bar + * This class describes the NX window manager's task bar. That task bar is, + * of course, used to dock active applications. But in NxWM, it is also + * the heart of the window manager: It inherits for CNxServer and, hence, + * represents the NX server itself. It also then serves as the NxWM + * window factory. + * + * Why do it this way? The only reason is so that if you have an instance + * of CTaskbar, you have everything you need to manage new applications. + * It might have been a better decision to separate the window factory into + * a separate class instead of making the task bar of such central importance + * (and I may still do that someday) */ class CTaskbar : public NXWidgets::CNxServer, private NXWidgets::CWidgetEventHandler { private: - NXWidgets::INxWindow *m_taskbar; /**< The toolbar window */ - NXWidgets::INxWindow *m_background; /**< The background window */ - TNxArray m_applications; /**< List of apps in the task bar */ + /** + * This structgure represents an application and its associated icon image + */ + + struct STaskbarSlot + { + IApplication *app; /**< A reference to the icon */ + NXWidgets::CImage *image; /**< The icon image that goes with the application */ + }; + + /** + * Taskbar state + */ + + NXWidgets::CNxWindow *m_taskbar; /**< The task bar window */ + NXWidgets::CNxWindow *m_background; /**< The background window */ + NXWidgets::CImage *m_backImage; /**< The background image */ + IApplication *m_topapp; /**< The top application in the hierarchy */ + TNxArray m_slots; /**< List of application slots in the task bar */ /** * Connect to the server @@ -120,12 +146,12 @@ namespace NxWM void setApplicationGeometry(NXWidgets::INxWindow *window); /** - * Create the toolbar window. + * Create the task bar window. * * @return true on success */ - bool createToolbarWindow(void); + bool createTaskbarWindow(void); /** * Create the background window. @@ -135,6 +161,38 @@ namespace NxWM bool createBackgroundWindow(void); + /** + * Create the background image. + * + * @return true on success + */ + + bool createBackgroundImage(void); + + /** + * (Re-)draw the task bar window. + * + * @return true on success + */ + + bool redrawTaskbarWindow(void); + + /** + * (Re-)draw the background window. + * + * @return true on success + */ + + bool redrawBackgroundWindow(void); + + /** + * Redraw the last application in the list of application maintained by + * the task bar. + * + * @return true on success + */ + + bool redrawApplicationWindow(void); /** * Handle a mouse button click event. @@ -159,16 +217,46 @@ namespace NxWM CTaskbar(void); + /** + * Initialize task bar. Task bar initialization is separate from + * object instantiation so that failures can be reported. The window + * manager start-up sequence is: + * + * 1. Create the CTaskbar instance, + * 2. Call the CTaskbar::connect() method to connect to the NX server (CTaskbar + * inherits the connect method from CNxServer), + * 3. Call the CTaskbar::initWindowManager() method to initialize the task bar. + * 4. Call CTaskBar::startApplication repeatedly to add applications to the task bar + * 5. Call CTaskBar::startWindowManager() to start the display with applications in place + * + * CTaskbar::initWindowManager() prepares the task bar to receive applications. + * CTaskBar::startWindowManager() brings the window manager up with those applications + * in place. + * + * @return True if the window was successfully initialized. + */ + + bool initWindowManager(void); + /** * Start the window manager and present the initial displays. The window * manager start-up sequence is: * * 1. Create the CTaskbar instance, - * 2. Call CTaskBar::startApplication repeatedly to add applications to the task bar - * 3. Call CTaskBar::startWindowManager to start the display with applications in place + * 2. Call the CTaskbar::connect() method to connect to the NX server (CTaskbar + * inherits the connect method from CNxServer), + * 3. Call the CTaskbar::initWindowManager() method to initialize the task bar. + * 4. Call CTaskBar::startApplication repeatedly to add applications to the task bar + * 5. Call CTaskBar::startWindowManager to start the display with applications in place * - * startWindowManager will present the taskar and the background image. The - * initial taskbar will contain only the start window icon. + * CTaskbar::initWindowManager() prepares the task bar to receive applications. + * CTaskBar::startWindowManager() brings the window manager up with those applications + * in place. + * + * CTaskBar::startWindowManager() will present the task bar and the background image. + * The The initial taskbar will contain only the start window icon. + * + * @return true on success */ bool startWindowManager(void); @@ -214,23 +302,45 @@ namespace NxWM bool startApplication(IApplication *app, bool minimized); /** - * Hide an application by moving its window to the bottom. + * Move window to the top of the hierarchy and re-draw it. This method + * does nothing if the application is minimized. * - * @param application. The new application to add to the task bar + * @param app. The new application to show + * @return true on success + */ + + bool topApplication(IApplication *app); + + /** + * Maximize an application by moving its window to the top of the hierarchy + * and re-drawing it. If the application was already maximized, then this + * method is equivalent to topApplication(). + * + * @param app. The new application to add to the task bar + * @return true on success + */ + + bool maximizeApplication(IApplication *app); + + /** + * Minimize an application by moving its window to the bottom of the + * and redrawing the next visible appliation. + * + * @param app. The new application to add to the task bar * @return true on success */ - bool hideApplication(IApplication *application); + bool minimizeApplication(IApplication *app); /** * Destroy an application. Move its window to the bottom and remove its * icon from the task bar. * - * @param application. The new application to remove from the task bar + * @param app. The new application to remove from the task bar * @return true on success */ - bool stopApplication(IApplication *application); + bool stopApplication(IApplication *app); }; } diff --git a/NxWidgets/nxwm/include/iapplication.hxx b/NxWidgets/nxwm/include/iapplication.hxx index 1056e18c0..88583d4c5 100644 --- a/NxWidgets/nxwm/include/iapplication.hxx +++ b/NxWidgets/nxwm/include/iapplication.hxx @@ -64,6 +64,14 @@ namespace NxWM class IApplication { + protected: + // These values (and the accessors that go with them) violate the "purity" + // of the base class. These are really part of the task bar implementation: + // Each application provides this state information needed by the taskbar. + + bool m_minimized; /**< True if the application is minimized */ + bool m_topapp; /**< True if this application is at the top in the hiearchy */ + public: /** * Each implementation of IApplication must provide a method to recover @@ -91,7 +99,7 @@ namespace NxWM virtual NXWidgets::CNxString getName(void) = 0; /** - * Start the application. + * Start the application (pehaps in the minimized state). */ virtual void run(void) = 0; @@ -101,6 +109,57 @@ namespace NxWM */ virtual void stop(void) = 0; + + /** + * Re-draw the application window. This method is call from CTaskbar + * when the application window must be displayed + */ + + virtual void redraw(void) = 0; + + /** + * Set the application's minimized state + * + * @param minimized. True if the application is minimized + */ + + inline void setMinimized(bool minimized) + { + m_minimized = minimized; + } + + /** + * Set the application's top state + * + * @param topapp. True if the application is the new top application + */ + + inline void setTopApplication(bool topapp) + { + m_topapp = topapp; + } + + /** + * Get the application's minimized state + * + * @return True if the application is minimized + */ + + inline bool isMinimized(void) const + { + return m_minimized; + } + + /** + * Return true if this is the top application + * + * @return True if the application is the new top application + */ + + inline bool isTopApplication(void) const + { + return m_topapp; + } }; } diff --git a/NxWidgets/nxwm/include/nxwmconfig.hxx b/NxWidgets/nxwm/include/nxwmconfig.hxx index 178cc37a2..d416bf8f0 100644 --- a/NxWidgets/nxwm/include/nxwmconfig.hxx +++ b/NxWidgets/nxwm/include/nxwmconfig.hxx @@ -91,13 +91,25 @@ #endif /** - * Default selected forecround color + * Default selected foreground color */ #ifndef CONFIG_NXWM_DEFAULT_SELECTEDFOREGROUNDCOLOR # define CONFIG_NXWM_DEFAULT_SELECTEDFOREGROUNDCOLOR MKRGB(248,248,248) #endif +/** + * Border colors + */ + +#ifndef CONFIG_NXWM_DEFAULT_SHINEEDGECOLOR +# define CONFIG_NXWM_DEFAULT_SHINEEDGECOLOR MKRGB(248,248,248) +#endif + +#ifndef CONFIG_NXWM_DEFAULT_SHADOWEDGECOLOR +# define CONFIG_NXWM_DEFAULT_SHADOWEDGECOLOR MKRGB(0,0,0) +#endif + /** * The default font color */ @@ -115,15 +127,21 @@ #endif /* Task Bar Configuation ***************************************************/ -/* At present, all icons are 25 pixels in "widgth" and, hence require a - * task bar of at least that size. +/** + * Horizontal and vertical spacing of icons in the task bar. */ -#ifndef CONFIG_NXWM_TASKBAR_WIDTH -# define CONFIG_NXWM_TASKBAR_WIDTH (25+2*2) +#ifndef CONFIG_NXWM_TASKBAR_VSPACING +# define CONFIG_NXWM_TASKBAR_VSPACING (2) #endif -/* Check task bar location */ +#ifndef CONFIG_NXWM_TASKBAR_HSPACING +# define CONFIG_NXWM_TASKBAR_HSPACING (2) +#endif + +/** + * Check task bar location + */ #if defined(CONFIG_NXWM_TASKBAR_TOP) # if defined(CONFIG_NXWM_TASKBAR_BOTTOM) || defined (CONFIG_NXWM_TASKBAR_LEFT) || defined (CONFIG_NXWM_TASKBAR_RIGHT) @@ -142,12 +160,29 @@ # define CONFIG_NXWM_TASKBAR_TOP 1 #endif +/** + * At present, all icons are 25 pixels in "widgth" and, hence require a + * task bar of at least that size. + */ + +#ifndef CONFIG_NXWM_TASKBAR_WIDTH +# if defined(CONFIG_NXWM_TASKBAR_TOP) || defined(CONFIG_NXWM_TASKBAR_BOTTOM) +# define CONFIG_NXWM_TASKBAR_WIDTH (25+2*CONFIG_NXWM_TASKBAR_HSPACING) +# else +# define CONFIG_NXWM_TASKBAR_WIDTH (25+2*CONFIG_NXWM_TASKBAR_VSPACING) +# endif +#endif + +/* Background Image **********************************************************/ + +#ifndef CONFIG_NXWM_BACKGROUND_IMAGE +# define CONFIG_NXWM_BACKGROUND_IMAGE NXWidgets::g_nuttxBitmap +#endif + /* Tool Bar Configuration ***************************************************/ #ifndef CONFIG_NXWM_TOOLBAR_HEIGHT # define CONFIG_NXWM_TOOLBAR_HEIGHT CONFIG_NXWM_TASKBAR_WIDTH #endif -/* Colors *******************************************************************/ - #endif // __INCLUDE_NXWMCONFIG_HXX diff --git a/NxWidgets/nxwm/include/nxwmglyphs.hxx b/NxWidgets/nxwm/include/nxwmglyphs.hxx index bacd35891..198fe9f26 100644 --- a/NxWidgets/nxwm/include/nxwmglyphs.hxx +++ b/NxWidgets/nxwm/include/nxwmglyphs.hxx @@ -43,6 +43,7 @@ #include #include "nxconfig.hxx" +#include "glyphs.hxx" /**************************************************************************** * Pre-Processor Definitions diff --git a/NxWidgets/nxwm/src/ctaskbar.cxx b/NxWidgets/nxwm/src/ctaskbar.cxx index 407396ee5..42cb41087 100644 --- a/NxWidgets/nxwm/src/ctaskbar.cxx +++ b/NxWidgets/nxwm/src/ctaskbar.cxx @@ -46,6 +46,7 @@ #include "cnxtkwindow.hxx" #include "nxwmconfig.hxx" +#include "nxwmglyphs.hxx" #include "ctaskbar.hxx" /******************************************************************************************** @@ -66,8 +67,10 @@ using namespace NxWM; CTaskbar::CTaskbar(void) { - m_taskbar = (NXWidgets::INxWindow *)0; - m_background = (NXWidgets::INxWindow *)0; + m_taskbar = (NXWidgets::CNxWindow *)0; + m_background = (NXWidgets::CNxWindow *)0; + m_backImage = (NXWidgets::CImage *)0; + m_topapp = (IApplication *)0; } /** @@ -79,6 +82,51 @@ CTaskbar::~CTaskbar(void) disconnect(); } +/** + * Initialize task bar. Task bar initialization is separate from + * object instantiation so that failures can be reported. The window + * manager start-up sequence is: + * + * 1. Create the CTaskbar instance, + * 2. Call the CTaskbar::connect() method to connect to the NX server (CTaskbar + * inherits the connect method from CNxServer), + * 3. Call the CTaskbar::initWindowManager() method to initialize the task bar. + * 4. Call CTaskBar::startApplication repeatedly to add applications to the task bar + * 5. Call CTaskBar::startWindowManager to start the display with applications in place + * + * CTaskbar::initWindowManager() prepares the task bar to receive applications. + * CTaskBar::startWindowManager() brings the window manager up with those applications + * in place. + * + * @return True if the window was successfully initialized. + */ + +bool CTaskbar::initWindowManager(void) +{ + // Create the taskbar window + + if (!createTaskbarWindow()) + { + return false; + } + + // Create the background window + + if (!createBackgroundWindow()) + { + return false; + } + + // Create the background image + + if (!createBackgroundImage()) + { + return false; + } + + return true; +} + /** * Start the window manager and present the initial displays. The window * manager start-up sequence is: @@ -87,17 +135,28 @@ CTaskbar::~CTaskbar(void) * 2. Call startApplication repeatedly to add applications to the task bar * 3. Call startWindowManager to start the display with applications in place * - * startWindowManager will present the taskar and the background image. The + * CTaskbar::initWindowManager() prepares the task bar to receive applications. + * CTaskBar::startWindowManager() brings the window manager up with those applications + * in place. + * + * startWindowManager will present the task bar and the background image. The * initial taskbar will contain only the start window icon. * - * @param application. The new application to add to the start window * @return true on success */ bool CTaskbar::startWindowManager(void) { -#warning "Missing logic" - return false; + // Draw the taskbar + + if (!redrawTaskbarWindow()) + { + return false; + } + + // Draw the application window + + return redrawApplicationWindow(); } /** @@ -117,8 +176,27 @@ bool CTaskbar::startWindowManager(void) CApplicationWindow *CTaskbar::openApplicationWindow(void) { -#warning "Missing logic" - return (CApplicationWindow *)0; + // Create a framed window for the application + + NXWidgets::CNxTkWindow *window = openFramedWindow(); + if (!window) + { + return (CApplicationWindow *)0; + } + + // Set size and position of a window in the application area. + + setApplicationGeometry(window); + + // Use this window to instantiate the application window + + CApplicationWindow *appwindow = new CApplicationWindow(window); + if (!appwindow) + { + delete window; + } + + return appwindow; } /** @@ -142,48 +220,204 @@ CApplicationWindow *CTaskbar::openApplicationWindow(void) bool CTaskbar::startApplication(IApplication *app, bool minimized) { -#warning "Missing logic" + // Get the widget control associated with the task bar window + + NXWidgets::CWidgetControl *control = m_taskbar->getWidgetControl(); + + // Get the bitmap icon that goes with this application + + NXWidgets::IBitmap *bitmap = app->getIcon(); + + // Create a CImage instance to manage the applications icon + + NXWidgets::CImage *image = + new NXWidgets::CImage(control, 0, 0, bitmap->getWidth(), + bitmap->getHeight(), bitmap, 0); + if (!image) + { + return false; + } + + // Configure the image, disabling drawing for now + + image->setBorderless(true); + image->disableDrawing(); + + // Register to get events from the mouse clicks on the image + + image->addWidgetEventHandler(this); + + // Add the application to end of the list of applications managed by + // the task bar + + struct STaskbarSlot slot; + slot.app = app; + slot.image = image; + m_slots.push_back(slot); + + // Mark the application as minimized (or not) + + app->setMinimized(minimized); + + // Assume for now that this is not the top application (we will + // know when drawApplicationWindow() runs. + + app->setTopApplication(false); + + // Then start the application (whatever that means) + + app->run(); + return true; +} + +/** + * Move window to the top of the hierarchy and re-draw it. This method + * does nothing if the application is minimized. + * + * @param app. The new application to show + * @return true on success + */ + +bool CTaskbar::topApplication(IApplication *app) +{ + // Verify that the application is not minimized + + if (!app->isMinimized()) + { + // Every application provides a method to obtain its application window + + CApplicationWindow *appWindow = app->getWindow(); + + // Each application window provides a method to get the underlying NX window + + NXWidgets::CNxTkWindow *window = appWindow->getWindow(); + + // Mark the window as the top application + + m_topapp = app; + app->setTopApplication(true); + + // Raise the window to the top of the hierarchy + + window->raise(); + + // And re-draw it + + app->redraw(); + return true; + } + return false; } /** - * Hide an application by moving its window to the bottom. + * Maximize an application by moving its window to the top of the hierarchy + * and re-drawing it. If the application was already maximized, then this + * method is equivalent to topApplication(). + * + * @param app. The new application to add to the task bar + * @return true on success + */ + +bool CTaskbar::maximizeApplication(IApplication *app) +{ + // Mark that the application is no longer minimized + + app->setMinimized(false); + + // Then bring the appliation to the top of the hieararchy + + return topApplication(app); +} + +/** + * Minimize an application by moving its window to the bottom of the and + * redrawing the next visible appliation. * - * @param application. The new application to add to the task bar + * @param app. The new application to add to the task bar * @return true on success */ -bool CTaskbar::hideApplication(IApplication *application) +bool CTaskbar::minimizeApplication(IApplication *app) { - // Every application provides a method to obtain its applicatin window + // Verify that the application is not already minimized - CApplicationWindow *appWindow = application->getWindow(); + if (!app->isMinimized()) + { + // Every application provides a method to obtain its application window - // Each application window provides a method to get the underlying NX window + CApplicationWindow *appWindow = app->getWindow(); - NXWidgets::CNxTkWindow *window = appWindow->getWindow(); + // Each application window provides a method to get the underlying NX window - // Lower the window + NXWidgets::CNxTkWindow *window = appWindow->getWindow(); - window->lower(); + // Mark the window as minimized - // Grey out the image in task bar -#warning "Missing logic" - return true; + app->setMinimized(true); + + // And it certainly is no longer the top application. If it was before + // then redrawApplicationWindow() will pick a new one (rather arbitrarily). + + if (app->isTopApplication()) + { + m_topapp = (IApplication *)0; + app->setTopApplication(false); + } + + // Lower the window to the bottom of the hierarchy + + window->lower(); + + // And re-draw the next non-minimized application + + return redrawApplicationWindow(); + } + + return false; } /** * Destroy an application. Move its window to the bottom and remove its * icon from the task bar. * - * @param application. The new application to remove from the task bar + * @param app. The new application to remove from the task bar * @return true on success */ -bool CTaskbar::stopApplication(IApplication *application) +bool CTaskbar::stopApplication(IApplication *app) { -#warning "Missing logic" - return false; + // First, minimize the application. That will move the application + // to the bottom of the hiearachy and redraw the next application + // (If the application is already minimized, it does nothing) + + minimizeApplication(app); + + // Stop the appliation + + app->stop(); + + // Find the application in the list of applications + + for (int i = 0; i < m_slots.size(); i++) + { + // Is this it? + + IApplication *candidate = m_slots.at(i).app; + if (candidate == app) + { + // Yes.. found it. Delete the icon image and remove it + // from the list of applications + + delete m_slots.at(i).image; + m_slots.erase(i); + break; + } + } + + // And redraw the task bar (without the icon for this task) + + return redrawTaskbarWindow(); } /** @@ -218,9 +452,9 @@ void CTaskbar::disconnect(void) // are some ordering issues here... On an orderly system shutdown, disconnection // should really occur priority to deleting instances - while (!m_applications.empty()) + while (!m_slots.empty()) { - IApplication *app = m_applications.at(0); + IApplication *app = m_slots.at(0).app; stopApplication(app); } @@ -238,7 +472,7 @@ void CTaskbar::disconnect(void) delete control; } - // Then delete the toolbar + // Then delete the task bar window delete m_taskbar; } @@ -353,7 +587,7 @@ NXWidgets::CNxTkWindow *CTaskbar::openFramedWindow(void) void CTaskbar::setApplicationGeometry(NXWidgets::INxWindow *window) { - // Get the widget control from the toolbar window. The physical window geometry + // Get the widget control from the task bar window. The physical window geometry // should be the same for all windows. NXWidgets::CWidgetControl *control = m_taskbar->getWidgetControl(); @@ -363,7 +597,7 @@ void CTaskbar::setApplicationGeometry(NXWidgets::INxWindow *window) NXWidgets::CRect rect = control->getWindowBoundingBox(); // Now position and size the application. This will depend on the position and - // orientation of the toolbar. + // orientation of the task bar. struct nxgl_point_s pos; struct nxgl_size_s size; @@ -405,14 +639,14 @@ void CTaskbar::setApplicationGeometry(NXWidgets::INxWindow *window) } /** - * Create the toolbar window. + * Create the task bar window. * * @return true on success */ -bool CTaskbar::createToolbarWindow(void) +bool CTaskbar::createTaskbarWindow(void) { - // Create a raw window to present the toolbar + // Create a raw window to present the task bar m_taskbar = openRawWindow(); if (!m_taskbar) @@ -428,8 +662,8 @@ bool CTaskbar::createToolbarWindow(void) NXWidgets::CRect rect = control->getWindowBoundingBox(); - // Now position and size the toolbar. This will depend on the position and - // orientation of the toolbar. + // Now position and size the task bar. This will depend on the position and + // orientation of the task bar. struct nxgl_point_s pos; struct nxgl_size_s size; @@ -472,9 +706,6 @@ bool CTaskbar::createToolbarWindow(void) /* And raise the window to the top of the display */ m_taskbar->raise(); - - // Add the start menu's icon to the toolbar -#warning "Missing logic" return true; } @@ -498,13 +729,285 @@ bool CTaskbar::createBackgroundWindow(void) setApplicationGeometry(static_cast(m_background)); - /* And lower the background window to the bottom of the display */ + /* The background window starts at the top display */ - m_background->lower(); + m_background->raise(); + return true; +} + +/** + * Create the background image. + * + * @return true on success + */ + +bool CTaskbar::createBackgroundImage(void) +{ + // Get the size of the display + + struct nxgl_size_s windowSize; + if (!m_background->getSize(&windowSize)) + { + return false; + } + // Get the widget control from the background window + + NXWidgets::CWidgetControl *control = m_background->getWidgetControl(); + + // Create the bitmap object + + NXWidgets::CRlePaletteBitmap *bitmap = + new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_BACKGROUND_IMAGE); + + if (!bitmap) + { + return false; + } + + // Get the size of the bitmap image + + struct nxgl_size_s imageSize; + imageSize.w = bitmap->getWidth(); + imageSize.h = (nxgl_coord_t)bitmap->getHeight(); + + // Pick an X/Y position such that the image will be centered in the display + + struct nxgl_point_s imagePos; + if (imageSize.w >= windowSize.w) + { + imagePos.x = 0; + } + else + { + imagePos.x = (windowSize.w - imageSize.w) >> 1; + } + + if (imageSize.h >= windowSize.h) + { + imagePos.y = 0; + } + else + { + imagePos.y = (windowSize.h - imageSize.h) >> 1; + } + + // Now we have enough information to create the image + + m_backImage = new NXWidgets::CImage(control, imagePos.x, imagePos.y, + imageSize.w, imageSize.h, bitmap); + if (!m_backImage) + { + delete bitmap; + return false; + } + + // Configure the background image + + m_backImage->setBorderless(true); + m_backImage->setRaisesEvents(false); + return true; +} + +/** + * (Re-)draw the task bar window. + * + * @return true on success + */ + +bool CTaskbar::redrawTaskbarWindow(void) +{ + // Get the widget control from the task bar + + NXWidgets::CWidgetControl *control = m_taskbar->getWidgetControl(); + + // Get the graphics port for drawing on the background window + + NXWidgets::CGraphicsPort *port = control->getGraphicsPort(); + + // Get the size of the window + + struct nxgl_size_s windowSize; + if (!m_taskbar->getSize(&windowSize)) + { + return false; + } + + // Fill the entire window with the background color + + port->drawFilledRect(0, 0, windowSize.w, windowSize.h, + CONFIG_NXWM_DEFAULT_BACKGROUNDCOLOR); + + // Add a border to the task bar to delineate it from the background window + + port->drawBevelledRect(0, 0, windowSize.w, windowSize.h, + CONFIG_NXWM_DEFAULT_SHINEEDGECOLOR, + CONFIG_NXWM_DEFAULT_SHADOWEDGECOLOR); + + // Begin adding icons in the upper left corner + + struct nxgl_point_s taskbarPos; +#if defined(CONFIG_NXWM_TASKBAR_TOP) || defined(CONFIG_NXWM_TASKBAR_BOTTOM) + taskbarPos.x = CONFIG_NXWM_TASKBAR_HSPACING; + taskbarPos.y = 0; +#else + taskbarPos.x = 0; + taskbarPos.y = CONFIG_NXWM_TASKBAR_VSPACING; +#endif + + // Add each icon in the list of applications + + for (int i = 0; i < m_slots.size(); i++) + { + // Get the icon associated with this application + + NXWidgets::CImage *image = m_slots.at(i).image; + + // Disable drawing of the icon image + + image->disableDrawing(); + + // Get the size of the icon image + + NXWidgets::CRect rect; + image->getPreferredDimensions(rect); + + // Position the icon + + struct nxgl_point_s iconPos; + +#if defined(CONFIG_NXWM_TASKBAR_TOP) || defined(CONFIG_NXWM_TASKBAR_BOTTOM) + // For horizontal task bars, the icons will be aligned at the top of + // the task bar + + iconPos.x = taskbarPos.x; + iconPos.y = taskbarPos.y + CONFIG_NXWM_TASKBAR_VSPACING; +#else + // For vertical task bars, the icons will be centered horizontally + + iconPos.x = (windowSize.w - rect.getWidth()) >> 1; + iconPos.y = taskbarPos.y +#endif + + // Set the position of the icon bitmap + + (void)image->moveTo(iconPos.x, iconPos.y); + + // Then re-draw the icon at the new position + + (void)image->enableDrawing(); + (void)image->redraw(); + + // Do we add icons left-to-right? Or top-to-bottom? + + bool moveTo(nxgl_coord_t x, nxgl_coord_t y); +#if defined(CONFIG_NXWM_TASKBAR_TOP) || defined(CONFIG_NXWM_TASKBAR_BOTTOM) + // left-to-right ... increment the X display position + + taskbarPos.x += rect.getWidth() + CONFIG_NXWM_TASKBAR_HSPACING; + if (taskbarPos.x > windowSize.w) + { + break; + } +#else + // top-to-bottom ... increment the Y display position + + taskbarPos.y += rect.getHeight() + CONFIG_NXWM_TASKBAR_VSPACING; + if (taskbarPos.y > windowSize.h) + { + break; + } +#endif + } + + return true; +} + +/** + * (Re-)draw the background window. + * + * @return true on success + */ + +bool CTaskbar::redrawBackgroundWindow(void) +{ + // Get the widget control from the background window + + NXWidgets::CWidgetControl *control = m_background->getWidgetControl(); + + // Get the graphics port for drawing on the background window + + NXWidgets::CGraphicsPort *port = control->getGraphicsPort(); + + // Get the size of the window + + struct nxgl_size_s windowSize; + if (!m_background->getSize(&windowSize)) + { + return false; + } + + // Fill the entire window with the background color + + port->drawFilledRect(0, 0, windowSize.w, windowSize.h, + CONFIG_NXWM_DEFAULT_BACKGROUNDCOLOR); + + // Then re-draw the background image on the window + + m_backImage->redraw(); return true; } +/** + * Redraw the last application in the list of application maintained by + * the task bar. + * + * @return true on success + */ + +bool CTaskbar::redrawApplicationWindow(void) +{ + // Check if there is already a top application + + IApplication *app = m_topapp; + if (!app) + { + // No.. Search for that last, non-minimized application + + for (int i = m_slots.size() - 1; i > 0; i--) + { + IApplication *candidate = m_slots.at(i).app; + if (!candidate->isMinimized()) + { + app = candidate; + break; + } + } + } + + // Did we find one? + + if (app) + { + // Yes.. Then this is the new top application + + m_topapp = app; + app->setTopApplication(true); + + // And.. Draw the application + + app->redraw(); + return true; + } + else + { + // Otherwise, re-draw the background + + m_topapp = (IApplication *)0; + return redrawBackgroundWindow(); + } +} + /** * Handle a mouse button click event. * @@ -513,7 +1016,40 @@ bool CTaskbar::createBackgroundWindow(void) void CTaskbar::handleClickEvent(const NXWidgets::CWidgetEventArgs &e) { -#warning "Missing logic" + // icon was clicked? + + for (int i = 0; i < m_slots.size(); i++) + { + // Is this it? + + NXWidgets::CImage *image = m_slots.at(i).image; + if (image->isClicked()) + { + // Was the icon minimized + + IApplication *app = m_slots.at(i).app; + if (app->isMinimized()) + { + // Maximize the application by moving its window to the top of + // the hierarchy and re-drawing it. + + (void)maximizeApplication(app); + } + + // No, it is not minimized. Is it already the top application? + + else if (!app->isTopApplication()) + { + /* Move window to the top of the hierarchy and re-draw it. */ + + (void)topApplication(app); + } + + // Then break out of the loop + + break; + } + } } -- cgit v1.2.3