NXWidgets  1.19
cstartwindow.cxx
Go to the documentation of this file.
1 /********************************************************************************************
2  * NxWidgets/nxwm/src/cstartwindow.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 <cstdlib>
43 #include <cfcntl>
44 #include <csched>
45 #include <cerrno>
46 
47 #include "cwidgetcontrol.hxx"
48 
49 #include "nxwmconfig.hxx"
50 #include "nxwmglyphs.hxx"
51 #include "ctaskbar.hxx"
52 #include "cstartwindow.hxx"
53 
54 /********************************************************************************************
55  * Pre-Processor Definitions
56  ********************************************************************************************/
57 
58 /********************************************************************************************
59  * Global Data
60  ********************************************************************************************/
61 
62 /**
63  * The well-known name for the Start Window's message queue.
64  */
65 
66 FAR const char *NxWM::g_startWindowMqName = CONFIG_NXWM_STARTWINDOW_MQNAME;
67 
68 /********************************************************************************************
69  * CStartWindow Method Implementations
70  ********************************************************************************************/
71 
73 
74 using namespace NxWM;
75 
76 /**
77  * CStartWindow Constructor
78  *
79  * @param taskbar. A pointer to the parent task bar instance
80  * @param window. The window to be used by this application.
81  */
82 
84 {
85  // Save the constructor data
86 
87  m_taskbar = taskbar;
88  m_window = window;
89 
90  // Add our personalized window label
91 
92  NXWidgets::CNxString myName = getName();
93  window->setWindowLabel(myName);
94 
95  // Add our callbacks to the application window
96 
97  window->registerCallbacks(static_cast<IApplicationCallback *>(this));
98 }
99 
100 /**
101  * CStartWindow Constructor
102  */
103 
105 {
106  // There would be a problem if we were stopped with the start window task
107  // running... that should never happen but we'll check anyway:
108 
109  stop();
110 
111  // Although we didn't create it, we are responsible for deleting the
112  // application window
113 
114  delete m_window;
115 
116  // Then stop and delete all applications
117 
119 }
120 
121 /**
122  * Each implementation of IApplication must provide a method to recover
123  * the contained IApplicationWindow instance.
124  */
125 
127 {
128  return static_cast<IApplicationWindow*>(m_window);
129 }
130 
131 /**
132  * Get the icon associated with the application
133  *
134  * @return An instance if IBitmap that may be used to rend the
135  * application's icon. This is an new IBitmap instance that must
136  * be deleted by the caller when it is no long needed.
137  */
138 
140 {
142  new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_STARTWINDOW_ICON);
143 
144  return bitmap;
145 }
146 
147 /**
148  * Get the name string associated with the application
149  *
150  * @return A copy if CNxString that contains the name of the application.
151  */
152 
154 {
155  return NXWidgets::CNxString("Start Window");
156 }
157 
158 /**
159  * Start the application.
160  *
161  * @return True if the application was successfully started.
162  */
163 
165 {
166  return true;
167 }
168 
169 /**
170  * Stop the application.
171  */
172 
174 {
175 }
176 
177 /**
178  * Destroy the application and free all of its resources. This method
179  * will initiate blocking of messages from the NX server. The server
180  * will flush the window message queue and reply with the blocked
181  * message. When the block message is received by CWindowMessenger,
182  * it will send the destroy message to the start window task which
183  * will, finally, safely delete the application.
184  */
185 
187 {
188  // What are we doing? This should never happen because the start
189  // window task is persistent!
190 
191  // Block any further window messages
192 
193  m_window->block(this);
194 
195  // Make sure that the application is stopped
196 
197  stop();
198 }
199 
200 /**
201  * The application window is hidden (either it is minimized or it is
202  * maximized, but not at the top of the hierarchy
203  */
204 
206 {
207  // Disable drawing and events on all icons
208 
209  for (int i = 0; i < m_slots.size(); i++)
210  {
211  NXWidgets::CImage *image = m_slots.at(i).image;
212  image->disableDrawing();
213  image->setRaisesEvents(false);
214  }
215 }
216 
217 /**
218  * Redraw the entire window. The application has been maximized or
219  * otherwise moved to the top of the hiearchy
220  */
221 
223 {
224  // Recover the NXTK window instance contained in the application window
225 
227 
228  // Get the widget control associated with the NXTK window
229 
230  NXWidgets::CWidgetControl *control = window->getWidgetControl();
231 
232  // Get the graphics port for drawing on the widget control
233 
234  NXWidgets::CGraphicsPort *port = control->getGraphicsPort();
235 
236  // Get the size of the application window
237 
238  struct nxgl_size_s windowSize;
239  if (!window->getSize(&windowSize))
240  {
241  return;
242  }
243 
244  // Fill the entire window with the background color
245 
246  port->drawFilledRect(0, 0, windowSize.w, windowSize.h,
247  CONFIG_NXWM_DEFAULT_BACKGROUNDCOLOR);
248 
249  // Begin adding icons in the upper left corner
250 
251  struct nxgl_point_s iconPos;
252  iconPos.x = CONFIG_NXWM_STARTWINDOW_HSPACING;
253  iconPos.y = CONFIG_NXWM_STARTWINDOW_VSPACING;
254 
255  // Add each icon in the list of applications
256 
257  for (int i = 0; i < m_slots.size(); i++)
258  {
259  // Get the icon associated with this application
260 
261  NXWidgets::CImage *image = m_slots.at(i).image;
262 
263  // Disable drawing of the icon image; disable events from the icon
264 
265  image->disableDrawing();
266  image->setRaisesEvents(false);
267 
268  // Get the size of the icon image
269 
270  NXWidgets::CRect rect;
271  image->getPreferredDimensions(rect);
272 
273  // Center the image in the region defined by the maximum icon size
274 
275  struct nxgl_point_s imagePos;
276  imagePos.x = iconPos.x;
277  imagePos.y = iconPos.y;
278 
279  if (rect.getWidth() < m_iconSize.w)
280  {
281  imagePos.x += ((m_iconSize.w - rect.getWidth()) >> 1);
282  }
283 
284  if (rect.getHeight() < m_iconSize.h)
285  {
286  imagePos.y += ((m_iconSize.h - rect.getHeight()) >> 1);
287  }
288 
289  // Set the position of the icon bitmap
290 
291  image->moveTo(imagePos.x, imagePos.y);
292 
293  // Then re-draw the icon at the new position
294 
295  image->enableDrawing();
296  image->redraw();
297  image->setRaisesEvents(true);
298 
299  // Advance the next icon position to the left
300 
301  iconPos.x += m_iconSize.w + CONFIG_NXWM_TASKBAR_HSPACING;
302 
303  // If there is insufficient space on on this row for the next
304  // max-sized icon, then advance to the next row
305 
306  if (iconPos.x + m_iconSize.w >= windowSize.w)
307  {
308  iconPos.x = CONFIG_NXWM_STARTWINDOW_HSPACING;
309  iconPos.y += m_iconSize.h + CONFIG_NXWM_TASKBAR_VSPACING;
310 
311  // Don't try drawing past the bottom of the window
312 
313  if (iconPos.y >= windowSize.w)
314  {
315  break;
316  }
317  }
318  }
319 }
320 
321 /**
322  * Report of this is a "normal" window or a full screen window. The
323  * primary purpose of this method is so that window manager will know
324  * whether or not it show draw the task bar.
325  *
326  * @return True if this is a full screen window.
327  */
328 
330 {
331  return m_window->isFullScreen();
332 }
333 
334 /**
335  * Add the application to the start window. The general sequence is:
336  *
337  * 1. Call IAppicationFactory::create to a new instance of the application
338  * 2. Call CStartWindow::addApplication to add the application to the
339  * start window.
340  *
341  * @param app. The new application to add to the start window
342  * @return true on success
343  */
344 
346 {
347  // Recover the NXTK window instance contained in the application window
348 
350 
351  // Get the widget control associated with the NXTK window
352 
353  NXWidgets::CWidgetControl *control = window->getWidgetControl();
354 
355  // Get the bitmap icon that goes with this application
356 
358 
359  // Create a CImage instance to manage the application icon
360 
361  NXWidgets::CImage *image =
362  new NXWidgets::CImage(control, 0, 0, bitmap->getWidth(),
363  bitmap->getHeight(), bitmap, 0);
364  if (!image)
365  {
366  return false;
367  }
368 
369  // Configure the image, disabling drawing for now
370 
371  image->setBorderless(true);
372  image->disableDrawing();
373 
374  // Register to get events from the mouse clicks on the image
375 
376  image->addWidgetEventHandler(this);
377 
378  // Add the application to end of the list of applications managed by
379  // the start window
380 
381  struct SStartWindowSlot slot;
382  slot.app = app;
383  slot.image = image;
384  m_slots.push_back(slot);
385 
386  // Re-calculate the icon bounding box
387 
388  getIconBounds();
389  return true;
390 }
391 
392 /**
393  * Simulate a mouse click or release on the icon at index. This method
394  * is only available during automated testing of NxWM.
395  *
396  * @param index. Selects the icon in the start window
397  * @param click. True to click and false to release
398  */
399 
400 #if defined(CONFIG_NXWM_UNITTEST) && !defined(CONFIG_NXWM_TOUCHSCREEN)
401 void CStartWindow::clickIcon(int index, bool click)
402 {
403  if (index < m_slots.size())
404  {
405  // Get the image widget at this index
406 
407  NXWidgets::CImage *image = m_slots.at(index).image;
408 
409  // Get the size and position of the widget
410 
411  struct nxgl_size_s imageSize;
412  image->getSize(imageSize);
413 
414  struct nxgl_point_s imagePos;
415  image->getPos(imagePos);
416 
417  // And click or release the image at its center
418 
419  if (click)
420  {
421  image->click(imagePos.x + (imageSize.w >> 1),
422  imagePos.y + (imageSize.h >> 1));
423  }
424  else
425  {
426  image->release(imagePos.x + (imageSize.w >> 1),
427  imagePos.y + (imageSize.h >> 1));
428  }
429  }
430 }
431 #endif
432 
433 /**
434  * Called when the window minimize button is pressed.
435  */
436 
438 {
439  m_taskbar->minimizeApplication(static_cast<IApplication*>(this));
440 }
441 
442 /**
443  * Called when the window minimize close is pressed.
444  */
445 
447 {
448  // Do nothing... you can't close the start window!!!
449 }
450 
451 /**
452  * Calculate the icon bounding box
453  */
454 
456 {
457  // Visit each icon
458 
459  struct nxgl_size_s maxSize;
460  maxSize.w = 0;
461  maxSize.h = 0;
462 
463  for (int i = 0; i < m_slots.size(); i++)
464  {
465  // Get the icon associated with this application
466 
467  NXWidgets::CImage *image = m_slots.at(i).image;
468 
469  // Get the size of the icon image
470 
471  NXWidgets::CRect rect;
472  image->getPreferredDimensions(rect);
473 
474  // Keep the maximum height and width
475 
476  if (rect.getWidth() > maxSize.h)
477  {
478  maxSize.w = rect.getWidth() ;
479  }
480 
481  if (rect.getHeight() > maxSize.h)
482  {
483  maxSize.h = rect.getHeight();
484  }
485  }
486 
487  // And save the new maximum size
488 
489  m_iconSize.w = maxSize.w;
490  m_iconSize.h = maxSize.h;
491 }
492 
493 /**
494  * Stop all applications
495  */
496 
498 {
499  // Stop all applications and remove them from the start window. Clearly, there
500  // are some ordering issues here... On an orderly system shutdown, disconnection
501  // should really occur priority to deleting instances
502 
503  while (!m_slots.empty())
504  {
505  // Remove the application factory from the start menu
506 
507  IApplicationFactory *app = m_slots.at(0).app;
508 
509  // Now, delete the image and the application
510 
511  delete app;
512  delete m_slots.at(0).image;
513 
514  // And discard the data in this slot
515 
516  m_slots.erase(0);
517  }
518 }
519 
520 /**
521  * Handle a widget action event. For CImage, this is a mouse button pre-release event.
522  *
523  * @param e The event data.
524  */
525 
527 {
528  // Was an ICON clicked?
529 
530  for (int i = 0; i < m_slots.size(); i++)
531  {
532  // Is this the clicked icon?
533 
534  NXWidgets::CImage *image = m_slots.at(i).image;
535  if (image->isClicked())
536  {
537  // Create a new copy of the application
538 
539  IApplication *app = m_slots.at(i).app->create();
540  if (app)
541  {
542  // Start the new copy of the application
543 
544  if (m_taskbar->startApplication(app, false))
545  {
546  // Then break out of the loop
547 
548  break;
549  }
550  else
551  {
552  // If we cannot start the app. Destroy the instance we
553  // created and see what happens next. Could be interesting.
554 
555  app->stop();
556  app->destroy();
557  }
558  }
559  }
560  }
561 }
562 
void handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
CApplicationWindow * m_window
bool isClicked(void) const
Definition: cnxwidget.hxx:560
nxgl_coord_t getHeight(void) const
Definition: crect.hxx:204
CGraphicsPort * getGraphicsPort(void)
bool moveTo(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:990
bool isFullScreen(void) const
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
virtual NXWidgets::IBitmap * getIcon(void)=0
bool startApplication(IApplication *app, bool minimized)
Definition: ctaskbar.cxx:450
NXWidgets::IBitmap * getIcon(void)
NXWidgets::CNxString getName(void)
const struct NXWidgets::SRlePaletteBitmap CONFIG_NXWM_STARTWINDOW_ICON
virtual const nxgl_coord_t getHeight(void) const =0
IApplicationWindow * getWindow(void) const
void setWindowLabel(NXWidgets::CNxString &appname)
bool addApplication(IApplicationFactory *app)
void getPreferredDimensions(CRect &rect) const
Definition: cimage.cxx:139
void getIconBounds(void)
virtual void stop(void)=0
virtual bool getSize(FAR struct nxgl_size_s *pSize)=0
virtual bool click(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:630
bool minimizeApplication(IApplication *app)
Definition: ctaskbar.cxx:639
void getPos(struct nxgl_point_s &pos) const
Definition: cnxwidget.hxx:616
struct nxgl_size_s m_iconSize
void addWidgetEventHandler(CWidgetEventHandler *eventHandler)
Definition: cnxwidget.hxx:854
CStartWindow(CTaskbar *taskbar, CApplicationWindow *window)
void block(IApplication *app)
void drawFilledRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, nxgl_mxpixel_t color)
TNxArray< struct SStartWindowSlot > m_slots
void registerCallbacks(IApplicationCallback *callback)
void enableDrawing(void)
Definition: cnxwidget.hxx:917
void getSize(struct nxgl_size_s &size) const
Definition: cnxwidget.hxx:604
NXWidgets::INxWindow * getWindow(void) const
FAR const char * g_startWindowMqName
virtual const nxgl_coord_t getWidth(void) const =0
virtual CWidgetControl * getWidgetControl(void) const =0
static const NXWidgets::SRlePaletteBitmapEntry bitmap[]
virtual void destroy(void)=0
bool release(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:771
void clickIcon(int index, bool click)
void setBorderless(bool isBorderless)
Definition: cnxwidget.cxx:461
void removeAllApplications(void)