NXWidgets  1.19
ctaskbar.cxx
Go to the documentation of this file.
1 /********************************************************************************************
2  * NxWidgets/nxwm/src/ctaskbar.cxx
3  *
4  * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
5  * Author: Gregory Nutt <gnutt@nuttx.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  * 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
18  * me be used to endorse or promote products derived from this software
19  * without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  ********************************************************************************************/
35 
36 /********************************************************************************************
37  * Included Files
38  ********************************************************************************************/
39 
40 #include <nuttx/config.h>
41 
42 #include <debug.h>
43 
44 #include <nuttx/nx/nxglib.h>
45 
46 #include "crect.hxx"
47 #include "cwidgetcontrol.hxx"
48 #include "cnxtkwindow.hxx"
49 #include "cscaledbitmap.hxx"
50 
51 #include "cwindowmessenger.hxx"
52 #include "ctaskbar.hxx"
53 
54 /********************************************************************************************
55  * Pre-Processor Definitions
56  ********************************************************************************************/
57 
58 /********************************************************************************************
59  * CNxTerm Method Implementations
60  ********************************************************************************************/
61 
62 using namespace NxWM;
63 
64 /**
65  * CTaskbar Constructor
66  *
67  * @param hWnd - NX server handle
68  */
69 
71 {
75  m_topApp = (IApplication *)0;
76  m_started = false;
77 }
78 
79 /**
80  * CTaskbar Destructor
81  */
82 
84 {
85  // The disconnect,putting the instance back in the state that it
86  // was before it was constructed.
87 
88  disconnect();
89 }
90 
91 /**
92  * Connect to the server
93  */
94 
96 {
97  // Connect to the server
98 
99  bool nxConnected = CNxServer::connect();
100  if (nxConnected)
101  {
102  // Set the background color
103 
104  if (!setBackgroundColor(CONFIG_NXWM_DEFAULT_BACKGROUNDCOLOR))
105  {
106  // Failed
107  }
108  }
109 
110  return nxConnected;
111 }
112 
113 /**
114  * Disconnect from the server. This method restores the taskbar to the
115  * same state that it was in when it was constructed.
116  */
117 
119 {
120  // Stop all applications and remove them from the task bar. Clearly, there
121  // are some ordering issues here... On an orderly system shutdown, disconnection
122  // should really occur priority to deleting instances
123 
124  while (!m_slots.empty())
125  {
126  IApplication *app = m_slots.at(0).app;
127  stopApplication(app);
128  }
129 
130  // Close the windows
131 
132  NXWidgets::CWidgetControl *control;
133  if (m_taskbar)
134  {
135  // Get the contained widget control
136 
137  control = m_taskbar->getWidgetControl();
138 
139  // Delete the widget control. We are responsible for it because we created it
140 
141  if (control)
142  {
143  delete control;
144  }
145 
146  // Then delete the task bar window
147 
148  delete m_taskbar;
150  }
151 
152  if (m_background)
153  {
154  // Delete the contained widget control. We are responsible for it
155  // because we created it
156 
157  control = m_background->getWidgetControl();
158  if (control)
159  {
160  delete control;
161  }
162 
163  // Then delete the background
164 
165  delete m_background;
167  }
168 
169  // Delete the background image
170 
171  if (m_backImage)
172  {
173  delete m_backImage;
175  }
176 
177  // Reset other variables
178 
179  m_topApp = (IApplication *)0;
180  m_started = false;
181 
182  // And disconnect from the server
183 
184  CNxServer::disconnect();
185 }
186 
187 /**
188  * Initialize task bar. Task bar initialization is separate from
189  * object instantiation so that failures can be reported. The window
190  * manager start-up sequence is:
191  *
192  * 1. Create the CTaskbar instance,
193  * 2. Call the CTaskbar::connect() method to connect to the NX server (CTaskbar
194  * inherits the connect method from CNxServer),
195  * 3. Call the CTaskbar::initWindowManager() method to initialize the task bar.
196  * 4. Call CTaskBar::startApplication repeatedly to add applications to the task bar
197  * 5. Call CTaskBar::startWindowManager to start the display with applications in place
198  *
199  * CTaskbar::initWindowManager() prepares the task bar to receive applications.
200  * CTaskBar::startWindowManager() brings the window manager up with those applications
201  * in place.
202  *
203  * @return True if the window was successfully initialized.
204  */
205 
207 {
208  // Create the taskbar window
209 
210  if (!createTaskbarWindow())
211  {
212  return false;
213  }
214 
215  // Create the background window
216 
217  if (!createBackgroundWindow())
218  {
219  return false;
220  }
221 
222  // Create the background image
223 
224  if (!createBackgroundImage())
225  {
226  return false;
227  }
228 
229  return true;
230 }
231 
232 /**
233  * Start the window manager and present the initial displays. The window
234  * manager start-up sequence is:
235  *
236  * 1. Create the CTaskbar instance,
237  * 2. Call startApplication repeatedly to add applications to the task bar
238  * 3. Call startWindowManager to start the display with applications in place
239  *
240  * CTaskbar::initWindowManager() prepares the task bar to receive applications.
241  * CTaskBar::startWindowManager() brings the window manager up with those applications
242  * in place.
243  *
244  * startWindowManager will present the task bar and the background image. The
245  * initial taskbar will contain only the start window icon.
246  *
247  * @return true on success
248  */
249 
251 {
252  // Have we already been started
253 
254  if (!m_started)
255  {
256  // We are now started
257 
258  m_started = true;
259 
260  // Decide which application will be the initial 'top' application
261 
262  m_topApp = (IApplication *)0;
263  int topIndex = -1;
264 
265  // No.. Search for that last, non-minimized application (there might not be one)
266 
267  for (int i = m_slots.size() - 1; i >= 0; i--)
268  {
269  IApplication *candidate = m_slots.at(i).app;
270  if (!candidate->isMinimized())
271  {
272  m_topApp = candidate;
273  topIndex = i;
274  break;
275  }
276  }
277  ginfo("m_topApp=%p topIndex=%d\n", m_topApp, topIndex);
278 
279  // Now start each application (whatever that means to the application)
280 
281  for (int i = 0; i < m_slots.size(); )
282  {
283  IApplication *app = m_slots.at(i).app;
284 
285  ginfo("Starting app[%d]\n", i);
286  if (!app->run())
287  {
288  // Call stopApplication on a failure to start. This will call
289  // app->stop() (which is probably not necesary for the application
290  // but it should be prepared/ to handle it). stopApplication()
291  // will also removed the icon image from the list and delete it.
292 
293  stopApplication(app);
294 
295  // Then continue with the next application. Notice that i is
296  // not incremented in this case and we will continue with the
297  // next application which will not be at this same index
298 
299  continue;
300  }
301 
302  // Hide all applications except for the top application. NOTE:
303  // topIndex may still be -1, meaning that there is no application
304  // and that all applications should be hidden.
305 
306  if (i != topIndex)
307  {
308  // Bring the application up in the non-visible state (the
309  // application may or may not be minimized, but it is not
310  // visible now).
311 
312  ginfo("Hiding app[%d]\n", i);
314  }
315  else
316  {
317  // Bring up the application as the new top application
318 
319  ginfo("Showing app[%d]\n", i);
320  topApplication(app);
321  }
322 
323  // The application was successfully initialized.. index to the next application
324 
325  i++;
326  }
327 
328  // If there is no top appliation (i.e., no applications or all applications
329  // are minimized), then draw the background image
330 
331  if (!m_topApp)
332  {
333  if (!redrawBackgroundWindow())
334  {
335  return false;
336  }
337  }
338 
339  // Draw the taskbar. It will be draw at a higher level than the application.
340 
341  return redrawTaskbarWindow();
342  }
343 
344  return false;
345 }
346 
347 /**
348  * Create an normal application window. Creating a normal application in the
349  * start window requires three steps:
350  *
351  * 1. Call CTaskBar::openApplicationWindow to create a window for the application,
352  * 2. Instantiate the application, providing the window to the application's
353  * constructor,
354  * 3. Then call CStartWindow::addApplication to add the application to the
355  * start window.
356  *
357  * When the application is selected from the start window:
358  *
359  * 4. Call CTaskBar::startApplication start the application and bring its window to
360  * the top.
361  *
362  * @param flags. CApplicationWindow flugs for window customization.
363  */
364 
366 {
367  // Get a framed window for the application
368 
370  if (!window)
371  {
372  return (CApplicationWindow *)0;
373  }
374 
375  // Set size and position of a window in the application area.
376 
377  setApplicationGeometry(window, false);
378 
379  // Use this window to instantiate the application window
380 
381  CApplicationWindow *appWindow = new CApplicationWindow(window, flags);
382  if (!appWindow)
383  {
384  delete window;
385  }
386 
387  return appWindow;
388 }
389 
390 /**
391  * Create a full screen application window. Creating a new full screen application
392  * requires three steps:
393  *
394  * 1. Call CTaskBar::FullScreenWindow to create a window for the application,
395  * 2. Instantiate the application, providing the window to the application's
396  * constructor,
397  * 3. Then call CStartWindow::addApplication to add the application to the
398  * start window.
399  *
400  * When the application is selected from the start window:
401  *
402  * 4. Call CTaskBar::startApplication start the application and bring its window to
403  * the top.
404  */
405 
407 {
408  // Get a raw window for the application
409 
411  if (!window)
412  {
413  return (CFullScreenWindow *)0;
414  }
415 
416  // Set size and position of a window in the application area.
417 
418  setApplicationGeometry(window, true);
419 
420  // Use this window to instantiate the generia application window
421 
422  CFullScreenWindow *appWindow = new CFullScreenWindow(window);
423  if (!appWindow)
424  {
425  delete window;
426  }
427 
428  return appWindow;
429 }
430 
431 /**
432  * Start an application and add its icon to the taskbar. The applications's
433  * window is brought to the top. Creating a new application in the start
434  * window requires three steps:
435  *
436  * 1. Create the CTaskbar instance,
437  * 2. Call startApplication repeatedly to add applications to the task bar
438  * 3. Call startWindowManager to start the display with applications in place
439  *
440  * When the application is selected from the start window:
441  *
442  * 4. Call startApplication start the application and bring its window to
443  * the top.
444  *
445  * @param app. The new application to add to the task bar
446  * @param minimized. The new application starts in the minimized state
447  * @return true on success
448  */
449 
450 bool CTaskbar::startApplication(IApplication *app, bool minimized)
451 {
452  // Get the widget control associated with the task bar window
453 
455 
456  // Get the bitmap icon that goes with this application
457 
459 
460 #ifdef CONFIG_NXWM_TASKBAR_ICONSCALE
461  // Create a CScaledBitmap to scale the bitmap icon
462 
464  if (bitmap)
465  {
466  // Create a CScaledBitmap to scale the bitmap icon
467 
468  struct nxgl_size_s iconSize;
469  iconSize.w = CONFIG_NXWM_TASKBAR_ICONWIDTH;
470  iconSize.h = CONFIG_NXWM_TASKBAR_ICONHEIGHT;
471 
472  scaler = new NXWidgets::CScaledBitmap(bitmap, iconSize);
473  if (!scaler)
474  {
475  return false;
476  }
477  }
478 #endif
479 
480  // Create a CImage instance to manage the applications icon. Assume the
481  // minimum size in case no bitmap is provided (bitmap == NULL)
482 
483  int w = 1;
484  int h = 1;
485 
486 #ifdef CONFIG_NXWM_TASKBAR_ICONSCALE
487  if (scaler)
488  {
489  w = scaler->getWidth();
490  h = scaler->getHeight();
491  }
492 
493  NXWidgets::CImage *image =
494  new NXWidgets::CImage(control, 0, 0, w, h, scaler, 0);
495 
496 #else
497  if (bitmap)
498  {
499  w = bitmap->getWidth();
500  h = bitmap->getHeight();
501  }
502 
503  NXWidgets::CImage *image =
504  new NXWidgets::CImage(control, 0, 0, w, h, bitmap, 0);
505 
506 #endif
507 
508  if (!image)
509  {
510  return false;
511  }
512 
513  // Configure the image, disabling drawing for now
514 
515  image->setBorderless(true);
516  image->disableDrawing();
517  image->setRaisesEvents(false);
518 
519  // Register to get events from the mouse clicks on the image
520 
521  image->addWidgetEventHandler(this);
522 
523  // Add the application to end of the list of applications managed by
524  // the task bar
525 
526  struct STaskbarSlot slot;
527  slot.app = app;
528  slot.image = image;
529  m_slots.push_back(slot);
530 
531  // Initialize the application states
532 
533  app->setTopApplication(false);
534  app->setMinimized(minimized);
535 
536  // Has the window manager been started?
537 
538  if (m_started)
539  {
540  // Yes.. Start the application (whatever that means).
541 
542  if (!app->run())
543  {
544  // Call stopApplication on a failure to start. This will call
545  // app->stop() (which is probably not necesary for the application
546  // but it should be prepared/ to handle it). stopApplication()
547  // will also removed the icon image from the list and delete it.
548 
549  stopApplication(app);
550  return false;
551  }
552 
553  // Were we ask to start the application minimized?
554 
555  if (minimized)
556  {
557  // Bring the minimized application up in non-visible state
558 
560  }
561  else
562  {
563  // Bring up the application as the new top application if we are running
564  // If not, we will select and bring up the top application when the
565  // window manager is started
566 
567  topApplication(app);
568  }
569 
570  // Redraw the task bar with the new icon (if we have been started)
571 
573  }
574 
575  return true;
576 }
577 
578 /**
579  * Move window to the top of the hierarchy and re-draw it. This method
580  * does nothing if the application is minimized.
581  *
582  * @param app. The new application to show
583  * @return true on success
584  */
585 
587 {
588  // Verify that the application is not minimized and is not already the top application
589 
590  if (!app->isMinimized() && !app->isTopApplication())
591  {
592  // It is not minimized. We are going to bring it to the top of the display.
593  // Is there already a top application?
594 
595  if (m_topApp)
596  {
597  // Yes.. make the application non-visible (it is still maximized and
598  // will reappear when the window above it is minimized or closed).
599 
601  }
602 
603  // Make the application the top application and redraw it
604 
605  return redrawApplicationWindow(app);
606  }
607 
608  return false;
609 }
610 
611 /**
612  * Maximize an application by moving its window to the top of the hierarchy
613  * and re-drawing it. If the application was already maximized, then this
614  * method is equivalent to topApplication().
615  *
616  * @param app. The new application to add to the task bar
617  * @return true on success
618  */
619 
621 {
622  // Mark that the application is no longer minimized
623 
624  app->setMinimized(false);
625 
626  // Then bring the application to the top of the hierarchy
627 
628  return topApplication(app);
629 }
630 
631 /**
632  * Minimize an application by moving its window to the bottom of the and
633  * redrawing the next visible appliation.
634  *
635  * @param app. The new application to add to the task bar
636  * @return true on success
637  */
638 
640 {
641  // Verify that the application is not already minimized
642 
643  if (!app->isMinimized())
644  {
645  // No, then we are going to minimize it but disabling its components,
646  // marking it as minimized, then raising a new window to the top window.
647 
648  app->setMinimized(true);
650 
651  // Re-draw the new top, non-minimized application
652 
653  return redrawTopApplication();
654  }
655 
656  return false;
657 }
658 
659 /**
660  * Destroy an application. Move its window to the bottom and remove its
661  * icon from the task bar.
662  *
663  * @param app. The new application to remove from the task bar
664  * @return true on success
665  */
666 
668 {
669  // Make the application minimized and make sure that it is not the top
670  // application.
671 
672  app->setMinimized(true);
673  if (app->isTopApplication())
674  {
675  app->setTopApplication(false);
676  m_topApp = (IApplication *)0;
677  }
678 
679  // Hide the application window. That will move the application to the
680  // bottom of the hiearachy.
681 
683 
684  // Stop the application (whatever this means to the application). We
685  // separate stopping from destroying to get the application a chance
686  // to put things in order before being destroyed.
687 
688  app->stop();
689 
690  // Find the application in the list of applications
691 
692  for (int i = 0; i < m_slots.size(); i++)
693  {
694  // Is this it?
695 
696  IApplication *candidate = m_slots.at(i).app;
697  if (candidate == app)
698  {
699  // Yes.. found it. Delete the icon image and remove the entry
700  // from the list of applications
701 
702  delete m_slots.at(i).image->getBitmap();
703  delete m_slots.at(i).image;
704  m_slots.erase(i);
705  break;
706  }
707  }
708 
709  // Destroy the application (actually, this just sets up the application for
710  // later destruction.
711 
712  app->destroy();
713 
714  // Re-draw the new top, non-minimized application
715 
716  bool ret = redrawTopApplication();
717  if (ret)
718  {
719  // And redraw the task bar (without the icon for this task)
720 
721  ret = redrawTaskbarWindow();
722  }
723  return ret;
724 }
725 
726 /**
727  * Get the size of the physical display device as it is known to the task
728  * bar.
729  *
730  * @return The size of the display
731  */
732 
733 void CTaskbar::getDisplaySize(FAR struct nxgl_size_s &size)
734 {
735  // Get the widget control from the task bar window. The physical window geometry
736  // should be the same for all windows.
737 
739 
740  // Get the window bounding box from the widget control
741 
742  NXWidgets::CRect rect = control->getWindowBoundingBox();
743 
744  // And return the size of the window
745 
746  rect.getSize(size);
747 }
748 
749 /**
750  * Simulate a mouse click or release on the icon at index. This method
751  * is only available during automated testing of NxWM.
752  *
753  * @param index. Selects the icon in the start window
754  * @param click. True to click and false to release
755  */
756 
757 #if defined(CONFIG_NXWM_UNITTEST) && !defined(CONFIG_NXWM_TOUCHSCREEN)
758 void CTaskbar::clickIcon(int index, bool click)
759 {
760  if (index < m_slots.size())
761  {
762  // Get the image widget at this index
763 
764  NXWidgets::CImage *image = m_slots.at(index).image;
765 
766  // Get the size and position of the widget
767 
768  struct nxgl_size_s imageSize;
769  image->getSize(imageSize);
770 
771  struct nxgl_point_s imagePos;
772  image->getPos(imagePos);
773 
774  // And click or release the image at its center
775 
776  if (click)
777  {
778  image->click(imagePos.x + (imageSize.w >> 1),
779  imagePos.y + (imageSize.h >> 1));
780  }
781  else
782  {
783  image->release(imagePos.x + (imageSize.w >> 1),
784  imagePos.y + (imageSize.h >> 1));
785  }
786  }
787 }
788 #endif
789 
790 /**
791  * Create a raw window.
792  *
793  * 1) Create a dumb CWigetControl instance (see note below)
794  * 2) Pass the dumb CWidgetControl instance to the window constructor
795  * that inherits from INxWindow. This will "smarten" the CWidgetControl
796  * instance with some window knowlede
797  * 3) Call the open() method on the window to display the window.
798  * 4) After that, the fully smartened CWidgetControl instance can
799  * be used to generate additional widgets by passing it to the
800  * widget constructor
801  *
802  * NOTE: Actually, NxWM uses the CWindowMessenger class that inherits from
803  * CWidgetControl. That class just adds some unrelated messaging capability;
804  * It cohabitates with CWidgetControl only becuase it needs the CWidgetControl
805  * this point.
806  */
807 
809 {
810  // Create the widget control (with the window messenger) using the default style
811 
813 
814  // Get an (uninitialized) instance of the background window as a class
815  // that derives from INxWindow.
816 
817  NXWidgets::CNxWindow *window = createRawWindow(control);
818  if (!window)
819  {
820  delete control;
821  return NULL;
822  }
823 
824  // Open (and initialize) the window
825 
826  bool success = window->open();
827  if (!success)
828  {
829  delete window;
830  window = (NXWidgets::CNxWindow *)0;
831  return NULL;
832  }
833 
834  return window;
835 }
836 
837 /**
838  * Create a framed application window
839  *
840  * This may be used to provide the window parater to the IApplication constructor
841  *
842  * @return A partially initialized application window instance.
843  */
844 
846 {
847  // Create the widget control (with the window messenger) using the default style
848 
850 
851  // Get an (uninitialized) instance of the framed window as a class
852  // that derives from INxWindow.
853 
854  NXWidgets::CNxTkWindow *window = createFramedWindow(control);
855  if (!window)
856  {
857  delete control;
858  return (NXWidgets::CNxTkWindow *)0;
859  }
860 
861  // Open (and initialize) the window
862 
863  bool success = window->open();
864  if (!success)
865  {
866  delete window;
867  window = (NXWidgets::CNxTkWindow *)0;
868  }
869 
870  return window;
871 }
872 
873 /**
874  * Set size and position of a window in the application area.
875  *
876  * @param window. The window to be resized and repositioned
877  * @param fullscreen. True: Use full screen
878  *
879  * @return true on success
880  */
881 
883 {
884  // Get the physical size of the display
885 
886  struct nxgl_size_s displaySize;
887  getDisplaySize(displaySize);
888 
889  // Now position and size the application. This will depend on the position and
890  // orientation of the task bar.
891 
892  struct nxgl_point_s pos;
893  struct nxgl_size_s size;
894 
895  // In fullscreen mode, the application window gets everything
896 
897  if (fullscreen)
898  {
899  pos.x = 0;
900  pos.y = 0;
901 
902  size.w = displaySize.w;
903  size.h = displaySize.h;
904  }
905  else
906  {
907 #if defined(CONFIG_NXWM_TASKBAR_TOP)
908  pos.x = 0;
909  pos.y = CONFIG_NXWM_TASKBAR_WIDTH;
910 
911  size.w = displaySize.w;
912  size.h = displaySize.h - CONFIG_NXWM_TASKBAR_WIDTH;
913 #elif defined(CONFIG_NXWM_TASKBAR_BOTTOM)
914  pos.x = 0;
915  pos.y = 0;
916 
917  size.w = displaySize.w;
918  size.h = displaySize.h - CONFIG_NXWM_TASKBAR_WIDTH;
919 #elif defined(CONFIG_NXWM_TASKBAR_LEFT)
920  pos.x = CONFIG_NXWM_TASKBAR_WIDTH;
921  pos.y = 0;
922 
923  size.w = displaySize.w - CONFIG_NXWM_TASKBAR_WIDTH;
924  size.h = displaySize.h;
925 #else
926  pos.x = 0;
927  pos.y = 0;
928 
929  size.w = displaySize.w - CONFIG_NXWM_TASKBAR_WIDTH;
930  size.h = displaySize.h;
931 #endif
932  }
933 
934  /* Set the size and position the window.
935  *
936  * @param pPos The new position of the window.
937  * @return True on success, false on failure.
938  */
939 
940  window->setPosition(&pos);
941  window->setSize(&size);
942 }
943 
944 /**
945  * Create the task bar window.
946  *
947  * @return true on success
948  */
949 
951 {
952  // Create a raw window to present the task bar
953 
955  if (!m_taskbar)
956  {
957  return false;
958  }
959 
960  // Get the size of the physical display
961 
962  struct nxgl_size_s displaySize;
963  getDisplaySize(displaySize);
964 
965  // Now position and size the task bar. This will depend on the position and
966  // orientation of the task bar.
967 
968  struct nxgl_point_s pos;
969  struct nxgl_size_s size;
970 
971 #if defined(CONFIG_NXWM_TASKBAR_TOP)
972  pos.x = 0;
973  pos.y = 0;
974 
975  size.w = displaySize.w;
976  size.h = CONFIG_NXWM_TASKBAR_WIDTH;
977 #elif defined(CONFIG_NXWM_TASKBAR_BOTTOM)
978  pos.x = 0;
979  pos.y = displaySize.h - CONFIG_NXWM_TASKBAR_WIDTH;
980 
981  size.w = displaySize.w;
982  size.h = CONFIG_NXWM_TASKBAR_WIDTH;
983 #elif defined(CONFIG_NXWM_TASKBAR_LEFT)
984  pos.x = 0;
985  pos.y = 0;
986 
987  size.w = CONFIG_NXWM_TASKBAR_WIDTH;
988  size.h = displaySize.h;
989 #else
990  pos.x = rect.getWidgth() - CONFIG_NXWM_TASKBAR_WIDTH;
991  pos.y = 0;
992 
993  size.w = CONFIG_NXWM_TASKBAR_WIDTH;
994  size.h = displaySize.h;
995 #endif
996 
997  /* Set the size and position the window.
998  *
999  * @param pPos The new position of the window.
1000  * @return True on success, false on failure.
1001  */
1002 
1003  m_taskbar->setPosition(&pos);
1004  m_taskbar->setSize(&size);
1005  return true;
1006 }
1007 
1008 /**
1009  * Create the background window.
1010  *
1011  * @return true on success
1012  */
1013 
1015 {
1016  // Create a raw window to present the background image
1017 
1019  if (!m_background)
1020  {
1021  return false;
1022  }
1023 
1024  // Set the geometry to fit in the application window space
1025 
1026  setApplicationGeometry(static_cast<NXWidgets::INxWindow*>(m_background), false);
1027  return true;
1028 }
1029 
1030 /**
1031  * Create the background image.
1032  *
1033  * @return true on success
1034  */
1035 
1037 {
1038 #ifndef CONFIG_NXWM_DISABLE_BACKGROUND_IMAGE
1039  // Get the size of the display
1040 
1041  struct nxgl_size_s windowSize;
1042  if (!m_background->getSize(&windowSize))
1043  {
1044  return false;
1045  }
1046 
1047  // Get the widget control from the background window
1048 
1050 
1051  // Create the bitmap object
1052 
1054  new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_BACKGROUND_IMAGE);
1055 
1056  if (!bitmap)
1057  {
1058  return false;
1059  }
1060 
1061  // Get the size of the bitmap image
1062 
1063  struct nxgl_size_s imageSize;
1064  imageSize.w = bitmap->getWidth();
1065  imageSize.h = (nxgl_coord_t)bitmap->getHeight();
1066 
1067  // Pick an X/Y position such that the image will be centered in the display
1068 
1069  struct nxgl_point_s imagePos;
1070  if (imageSize.w >= windowSize.w)
1071  {
1072  imagePos.x = 0;
1073  }
1074  else
1075  {
1076  imagePos.x = (windowSize.w - imageSize.w) >> 1;
1077  }
1078 
1079  if (imageSize.h >= windowSize.h)
1080  {
1081  imagePos.y = 0;
1082  }
1083  else
1084  {
1085  imagePos.y = (windowSize.h - imageSize.h) >> 1;
1086  }
1087 
1088  // Now we have enough information to create the image
1089 
1090  m_backImage = new NXWidgets::CImage(control, imagePos.x, imagePos.y,
1091  imageSize.w, imageSize.h, bitmap);
1092  if (!m_backImage)
1093  {
1094  delete bitmap;
1095  return false;
1096  }
1097 
1098  // Configure the background image
1099 
1100  m_backImage->setBorderless(true);
1101  m_backImage->setRaisesEvents(false);
1102 #endif
1103 
1104  return true;
1105 }
1106 
1107 /**
1108  * (Re-)draw the task bar window.
1109  *
1110  * @return true on success
1111  */
1112 
1114 {
1115  // Only redraw the task bar if (1) the window manager has been started, AND
1116  // (2) there is no top window (i.e., we are showing the background image), OR
1117  // (3) there is a top window, but it is not full screen
1118 
1119  if (m_started && (!m_topApp || !m_topApp->isFullScreen()))
1120  {
1121  // Get the widget control from the task bar
1122 
1124 
1125  // Get the graphics port for drawing on the background window
1126 
1127  NXWidgets::CGraphicsPort *port = control->getGraphicsPort();
1128 
1129  // Get the size of the window
1130 
1131  struct nxgl_size_s windowSize;
1132  if (!m_taskbar->getSize(&windowSize))
1133  {
1134  return false;
1135  }
1136 
1137  // Raise the task bar to the top of the display. This is only necessary
1138  // after stopping a full screen application. Other applications do not
1139  // overlap the task bar and, hence, do not interfere.
1140 
1141  m_taskbar->raise();
1142 
1143  // Fill the entire window with the background color
1144 
1145  port->drawFilledRect(0, 0, windowSize.w, windowSize.h,
1146  CONFIG_NXWM_DEFAULT_BACKGROUNDCOLOR);
1147 
1148 #ifndef CONFIG_NXWM_TASKBAR_NO_BORDER
1149  // Add a border to the task bar to delineate it from the background window
1150 
1151  port->drawBevelledRect(0, 0, windowSize.w, windowSize.h,
1152  CONFIG_NXWM_DEFAULT_SHINEEDGECOLOR,
1153  CONFIG_NXWM_DEFAULT_SHADOWEDGECOLOR);
1154 #endif
1155 
1156  // Begin adding icons in the upper left corner
1157 
1158  struct nxgl_point_s taskbarPos;
1159 #if defined(CONFIG_NXWM_TASKBAR_TOP) || defined(CONFIG_NXWM_TASKBAR_BOTTOM)
1160  taskbarPos.x = CONFIG_NXWM_TASKBAR_HSPACING;
1161  taskbarPos.y = 0;
1162 #else
1163  taskbarPos.x = 0;
1164  taskbarPos.y = CONFIG_NXWM_TASKBAR_VSPACING;
1165 #endif
1166 
1167  // Add each icon in the list of applications
1168 
1169  for (int i = 0; i < m_slots.size(); i++)
1170  {
1171  // Get the icon associated with this application
1172 
1173  NXWidgets::CImage *image = m_slots.at(i).image;
1174 
1175  // Disable drawing of the icon image; disable events from the icon
1176 
1177  image->disableDrawing();
1178  image->setRaisesEvents(false);
1179 
1180  // Highlight the icon for the top-most window
1181 
1182  image->highlight(m_slots.at(i).app == m_topApp);
1183 
1184  // Get the size of the icon image
1185 
1186  NXWidgets::CRect rect;
1187  image->getPreferredDimensions(rect);
1188 
1189  // Position the icon
1190 
1191  struct nxgl_point_s iconPos;
1192 
1193 #if defined(CONFIG_NXWM_TASKBAR_TOP) || defined(CONFIG_NXWM_TASKBAR_BOTTOM)
1194  // For horizontal task bars, the icons will be aligned along the top of
1195  // the task bar
1196 
1197  iconPos.x = taskbarPos.x;
1198  iconPos.y = taskbarPos.y + CONFIG_NXWM_TASKBAR_VSPACING;
1199 #else
1200  // For vertical task bars, the icons will be centered horizontally
1201 
1202  iconPos.x = (windowSize.w - rect.getWidth()) >> 1;
1203  iconPos.y = taskbarPos.y;
1204 #endif
1205 
1206  // Set the position of the icon bitmap
1207 
1208  (void)image->moveTo(iconPos.x, iconPos.y);
1209 
1210  // Then re-draw the icon at the new position
1211 
1212  image->enableDrawing();
1213  image->redraw();
1214  image->setRaisesEvents(true);
1215 
1216  // Do we add icons left-to-right? Or top-to-bottom?
1217 
1218 #if defined(CONFIG_NXWM_TASKBAR_TOP) || defined(CONFIG_NXWM_TASKBAR_BOTTOM)
1219  // left-to-right ... increment the X display position
1220 
1221  taskbarPos.x += rect.getWidth() + CONFIG_NXWM_TASKBAR_HSPACING;
1222  if (taskbarPos.x > windowSize.w)
1223  {
1224  break;
1225  }
1226 #else
1227  // top-to-bottom ... increment the Y display position
1228 
1229  taskbarPos.y += rect.getHeight() + CONFIG_NXWM_TASKBAR_VSPACING;
1230  if (taskbarPos.y > windowSize.h)
1231  {
1232  break;
1233  }
1234 #endif
1235  }
1236 
1237  // If there is a top application then we must now raise it above the task
1238  // bar so that itwill get the keyboard input.
1239 
1241  }
1242 
1243  // Return success (it is not a failure if the window manager is not started
1244  // or the task bar is occluded by a full screen window.
1245 
1246  return true;
1247 }
1248 
1249 /**
1250  * Redraw the window at the top of the heirarchy.
1251  *
1252  * @return true on success
1253  */
1254 
1256 {
1257  // Check if there is already a top application
1258 
1259  IApplication *app = m_topApp;
1260  if (!app)
1261  {
1262  // No.. Search for that last, non-minimized application
1263 
1264  for (int i = m_slots.size() - 1; i >= 0; i--)
1265  {
1266  IApplication *candidate = m_slots.at(i).app;
1267  if (!candidate->isMinimized())
1268  {
1269  app = candidate;
1270  break;
1271  }
1272  }
1273  }
1274 
1275  // Did we find one?
1276 
1277  if (app)
1278  {
1279  // Yes.. make it the top application window and redraw it
1280 
1281  return redrawApplicationWindow(app);
1282  return true;
1283  }
1284  else
1285  {
1286  // Otherwise, there is no top application. Re-draw the background image.
1287 
1288  m_topApp = (IApplication *)0;
1289  return redrawBackgroundWindow();
1290  }
1291 }
1292 
1293 /**
1294  * Raise the top window to the top of the NXheirarchy.
1295  *
1296  * @return true on success
1297  */
1298 
1300 {
1301  if (m_topApp)
1302  {
1303  // Every application provides a method to obtain its application window
1304 
1305  IApplicationWindow *appWindow = m_topApp->getWindow();
1306 
1307  // Each application window provides a method to get the underlying NX window
1308 
1309  NXWidgets::INxWindow *window = appWindow->getWindow();
1310 
1311  // Raise the application window to the top of the hierarchy
1312 
1313  window->raise();
1314  }
1315 }
1316 
1317 /**
1318  * (Re-)draw the background window.
1319  *
1320  * @return true on success
1321  */
1322 
1324 {
1325  // Get the widget control from the background window
1326 
1328 
1329  // Get the graphics port for drawing on the background window
1330 
1331  NXWidgets::CGraphicsPort *port = control->getGraphicsPort();
1332 
1333  // Get the size of the window
1334 
1335  struct nxgl_size_s windowSize;
1336  if (!m_background->getSize(&windowSize))
1337  {
1338  return false;
1339  }
1340 
1341  // Raise the background window to the top of the hierarchy
1342 
1343  m_background->raise();
1344 
1345  // Fill the entire window with the background color
1346 
1347  port->drawFilledRect(0, 0, windowSize.w, windowSize.h,
1348  CONFIG_NXWM_DEFAULT_BACKGROUNDCOLOR);
1349 
1350  // Add a border to the task bar to delineate it from the task bar
1351 
1352  port->drawBevelledRect(0, 0, windowSize.w, windowSize.h,
1353  CONFIG_NXWM_DEFAULT_SHINEEDGECOLOR,
1354  CONFIG_NXWM_DEFAULT_SHADOWEDGECOLOR);
1355 
1356  // Then re-draw the background image on the window
1357 
1358  if (m_backImage)
1359  {
1361  m_backImage->redraw();
1362  }
1363 
1364  return true;
1365 }
1366 
1367 /**
1368  * Redraw the last application in the list of application maintained by
1369  * the task bar.
1370  *
1371  * @param app. The new top application to draw
1372  * @return true on success
1373  */
1374 
1376 {
1377  // Mark the window as the top application
1378 
1379  m_topApp = app;
1380  app->setTopApplication(true);
1381 
1382  // Disable drawing of the background image.
1383 
1385 
1386  // Raise to top application to the top of the NX window heirarchy
1387 
1389 
1390  // Redraw taskbar
1391 
1393 
1394  // Every application provides a method to obtain its application window
1395 
1396  IApplicationWindow *appWindow = app->getWindow();
1397 
1398  // Re-draw the application window toolbar
1399 
1400  appWindow->redraw();
1401 
1402  // And re-draw the application window itself
1403 
1404  app->redraw();
1405  return true;
1406 }
1407 
1408 /**
1409  * The application window is hidden (either it is minimized or it is
1410  * maximized, but not at the top of the hierarchy)
1411  *
1412  * @param app. The application to hide
1413  */
1414 
1416 {
1417  // The hidden window is certainly not the top application any longer
1418  // If it was before then redrawTopApplication() will pick a new one (rather
1419  // arbitrarily).
1420 
1421  if (app->isTopApplication())
1422  {
1423  m_topApp = (IApplication *)0;
1424  app->setTopApplication(false);
1425  }
1426 
1427  // We do not need to lower the application to the back.. the new top
1428  // window will be raised instead.
1429  //
1430  // So all that we really have to do is to make sure that all of the
1431  // components of the hidden window are inactive.
1432 
1433  // Every application provides a method to obtain its application window
1434 
1435  IApplicationWindow *appWindow = app->getWindow();
1436 
1437  // Hide the application window toolbar
1438 
1439  appWindow->hide();
1440 
1441  // The hide the application window itself
1442 
1443  app->hide();
1444 }
1445 
1446 /**
1447  * Handle a widget action event. For CImage, this is a mouse button pre-release event.
1448  *
1449  * @param e The event data.
1450  */
1451 
1453 {
1454  // Was a n ICON clicked?
1455 
1456  for (int i = 0; i < m_slots.size(); i++)
1457  {
1458  // Is this it?
1459 
1460  NXWidgets::CImage *image = m_slots.at(i).image;
1461  if (image->isClicked())
1462  {
1463  // Was the icon minimized
1464 
1465  IApplication *app = m_slots.at(i).app;
1466  if (app->isMinimized())
1467  {
1468  // Maximize the application by moving its window to the top of
1469  // the hierarchy and re-drawing it.
1470 
1471  (void)maximizeApplication(app);
1472  }
1473 
1474  // No, it is not minimized. Is it already the top application?
1475 
1476  else if (!app->isTopApplication())
1477  {
1478  /* Move window to the top of the hierarchy and re-draw it. */
1479 
1480  (void)topApplication(app);
1481  }
1482 
1483  // Then break out of the loop
1484 
1485  break;
1486  }
1487  }
1488 }
bool getSize(FAR struct nxgl_size_s *pSize)
Definition: cnxwindow.cxx:159
void handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
Definition: ctaskbar.cxx:1452
virtual void hide(void)=0
bool isClicked(void) const
Definition: cnxwidget.hxx:560
virtual bool redrawBackgroundWindow(void)
Definition: ctaskbar.cxx:1323
NXWidgets::CImage * image
Definition: ctaskbar.hxx:96
const nxgl_coord_t getHeight(void) const
bool startWindowManager(void)
Definition: ctaskbar.cxx:250
nxgl_coord_t getHeight(void) const
Definition: crect.hxx:204
CGraphicsPort * getGraphicsPort(void)
bool topApplication(IApplication *app)
Definition: ctaskbar.cxx:586
bool moveTo(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:990
void raiseTopApplication(void)
Definition: ctaskbar.cxx:1299
void disableDrawing(void)
Definition: cnxwidget.hxx:908
void setRaisesEvents(bool raises)
Definition: cnxwidget.hxx:887
nxgl_coord_t getWidth(void) const
Definition: crect.hxx:181
void drawBevelledRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, nxgl_mxpixel_t shineColor, nxgl_mxpixel_t shadowColor)
bool startApplication(IApplication *app, bool minimized)
Definition: ctaskbar.cxx:450
bool stopApplication(IApplication *app)
Definition: ctaskbar.cxx:667
bool redrawApplicationWindow(IApplication *app)
Definition: ctaskbar.cxx:1375
virtual IApplicationWindow * getWindow(void) const =0
virtual bool raise(void)=0
bool isTopApplication(void) const
CApplicationWindow * openApplicationWindow(uint8_t flags=0)
Definition: ctaskbar.cxx:365
bool isMinimized(void) const
virtual const nxgl_coord_t getHeight(void) const =0
NXWidgets::CImage * m_backImage
Definition: ctaskbar.hxx:105
const nxgl_coord_t getWidth(void) const
IApplication * m_topApp
Definition: ctaskbar.hxx:106
bool setPosition(FAR const struct nxgl_point_s *pPos)
Definition: cnxwindow.cxx:171
void hideApplicationWindow(IApplication *app)
Definition: ctaskbar.cxx:1415
void highlight(bool highlightOn)
Definition: cimage.cxx:418
void getPreferredDimensions(CRect &rect) const
Definition: cimage.cxx:139
void disconnect(void)
Definition: ctaskbar.cxx:118
virtual bool createBackgroundWindow(void)
Definition: ctaskbar.cxx:1014
bool setBackgroundColor(nxgl_mxpixel_t color)
Definition: cnxserver.hxx:153
virtual void stop(void)=0
NXWidgets::CNxWindow * m_background
Definition: ctaskbar.hxx:104
virtual void hide(void)=0
virtual bool click(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:630
virtual bool redrawTopApplication(void)
Definition: ctaskbar.cxx:1255
virtual NXWidgets::IBitmap * getIcon(void)=0
bool minimizeApplication(IApplication *app)
Definition: ctaskbar.cxx:639
void getDisplaySize(FAR struct nxgl_size_s &size)
Definition: ctaskbar.cxx:733
virtual bool redrawTaskbarWindow(void)
Definition: ctaskbar.cxx:1113
void getPos(struct nxgl_point_s &pos) const
Definition: cnxwidget.hxx:616
NXWidgets::CNxWindow * openRawWindow(void)
Definition: ctaskbar.cxx:808
void setTopApplication(bool topapp)
void addWidgetEventHandler(CWidgetEventHandler *eventHandler)
Definition: cnxwidget.hxx:854
bool setSize(FAR const struct nxgl_size_s *pSize)
Definition: cnxwindow.cxx:185
void clickIcon(int index, bool click)
Definition: ctaskbar.cxx:758
CFullScreenWindow * openFullScreenWindow(void)
Definition: ctaskbar.cxx:406
virtual bool createTaskbarWindow(void)
Definition: ctaskbar.cxx:950
void getSize(struct nxgl_size_s &size) const
Definition: crect.hxx:192
virtual NXWidgets::INxWindow * getWindow(void) const =0
virtual bool createBackgroundImage(void)
Definition: ctaskbar.cxx:1036
CNxTkWindow * createFramedWindow(CWidgetControl *widgetControl)
Definition: cnxserver.hxx:171
void drawFilledRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, nxgl_mxpixel_t color)
NXWidgets::CNxWindow * m_taskbar
Definition: ctaskbar.hxx:103
~CTaskbar(void)
Definition: ctaskbar.cxx:83
CNxWindow * createRawWindow(CWidgetControl *widgetControl)
Definition: cnxserver.hxx:162
virtual bool run(void)=0
void setApplicationGeometry(NXWidgets::INxWindow *window, bool fullscreen)
Definition: ctaskbar.cxx:882
void enableDrawing(void)
Definition: cnxwidget.hxx:917
void getSize(struct nxgl_size_s &size) const
Definition: cnxwidget.hxx:604
virtual bool setPosition(FAR const struct nxgl_point_s *pPos)=0
virtual bool setSize(FAR const struct nxgl_size_s *pSize)=0
bool initWindowManager(void)
Definition: ctaskbar.cxx:206
virtual const nxgl_coord_t getWidth(void) const =0
TNxArray< struct STaskbarSlot > m_slots
Definition: ctaskbar.hxx:107
CTaskbar(void)
Definition: ctaskbar.cxx:70
virtual void redraw(void)=0
virtual bool isFullScreen(void) const =0
const nxgl_coord_t getWidth(void) const
CWidgetControl * getWidgetControl(void) const
Definition: cnxwindow.cxx:120
static const NXWidgets::SRlePaletteBitmapEntry bitmap[]
virtual void destroy(void)=0
bool release(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:771
bool connect(void)
Definition: ctaskbar.cxx:95
NXWidgets::CNxTkWindow * openFramedWindow(void)
Definition: ctaskbar.cxx:845
void setMinimized(bool minimized)
const nxgl_coord_t getHeight(void) const
bool maximizeApplication(IApplication *app)
Definition: ctaskbar.cxx:620
void setBorderless(bool isBorderless)
Definition: cnxwidget.cxx:461
virtual void redraw(void)=0