NXWidgets  1.19
cnxwidget.cxx
Go to the documentation of this file.
1 /****************************************************************************
2  * NxWidgets/libnxwidgets/src/cnxwidget.cxx
3  *
4  * Copyright (C) 2012 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  * Portions of this package derive from Woopsi (http://woopsi.org/) and
37  * portions are original efforts. It is difficult to determine at this
38  * point what parts are original efforts and which parts derive from Woopsi.
39  * However, in any event, the work of Antony Dzeryn will be acknowledged
40  * in most NxWidget files. Thanks Antony!
41  *
42  * Copyright (c) 2007-2011, Antony Dzeryn
43  * All rights reserved.
44  *
45  * Redistribution and use in source and binary forms, with or without
46  * modification, are permitted provided that the following conditions are met:
47  *
48  * * Redistributions of source code must retain the above copyright
49  * notice, this list of conditions and the following disclaimer.
50  * * Redistributions in binary form must reproduce the above copyright
51  * notice, this list of conditions and the following disclaimer in the
52  * documentation and/or other materials provided with the distribution.
53  * * Neither the names "Woopsi", "Simian Zombie" nor the
54  * names of its contributors may be used to endorse or promote products
55  * derived from this software without specific prior written permission.
56  *
57  * THIS SOFTWARE IS PROVIDED BY Antony Dzeryn ``AS IS'' AND ANY
58  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60  * DISCLAIMED. IN NO EVENT SHALL Antony Dzeryn BE LIABLE FOR ANY
61  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
66  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67  *
68  ****************************************************************************/
69 
70 /****************************************************************************
71  * Included Files
72  ****************************************************************************/
73 
74 #include <nuttx/config.h>
75 
76 #include <cstdint>
77 #include <cstdbool>
78 
79 #include "cnxwidget.hxx"
80 #include "cgraphicsport.hxx"
81 #include "cwidgeteventhandler.hxx"
82 #include "cnxfont.hxx"
83 #include "cwidgetstyle.hxx"
84 #include "cwidgeteventargs.hxx"
85 #include "cwidgetcontrol.hxx"
86 #include "singletons.hxx"
87 
88 /****************************************************************************
89  * Pre-Processor Definitions
90  ****************************************************************************/
91 
92 #define DOUBLE_CLICK_BOUNDS 10
93 
94 /****************************************************************************
95  * Method Implementations
96  ****************************************************************************/
97 
98 using namespace NXWidgets;
99 
100 /**
101  * Constructor.
102  *
103  * @param pWidgetControl The controlling widget for the display
104  * @param x The x coordinate of the widget.
105  * @param y The y coordinate of the widget.
106  * @param width The width of the widget.
107  * @param height The height of the widget.
108  * @param flags Bitmask specifying some set-up values for the widget.
109  * @param style The style that the button should use. If this is not
110  * specified, the button will use the global default widget
111  * style.
112  * @see WidgetFlagType.
113  */
114 
115 CNxWidget::CNxWidget(CWidgetControl *pWidgetControl,
116  nxgl_coord_t x, nxgl_coord_t y,
117  nxgl_coord_t width, nxgl_coord_t height,
118  uint32_t flags, const CWidgetStyle *style)
119 {
120  // Save the controlling widget
121 
122  m_widgetControl = pWidgetControl;
123 
124  // Set properties from parameters. If this is a child widget, then
125  // this coordinates are relative to the parent widget.
126 
127  m_rect.setX(x);
128  m_rect.setY(y);
129  m_rect.setWidth(width);
130  m_rect.setHeight(height);
131 
132  // Do we need to fetch the default style?
133 
134  if (style == (CWidgetStyle *)NULL)
135  {
136  // Get the style from the controlling widget. This allows different
137  // widgets within a window to have the same style, unique to the window.
138 
139  pWidgetControl->getWidgetStyle(&m_style);
140  }
141  else
142  {
143  // Use specified style
144 
145  useWidgetStyle(style);
146  }
147 
148  // Add ourself to the list of controlled widgets
149 
150  pWidgetControl->addControlledWidget(this);
151 
152  // Mask flags against bitmasks and logical NOT twice to obtain boolean values
153 
154  m_flags.borderless = (!(!(flags & WIDGET_BORDERLESS)));
155  m_flags.draggable = (!(!(flags & WIDGET_DRAGGABLE)));
156  m_flags.permeable = (!(!(flags & WIDGET_PERMEABLE)));
158 
159  // Dragging values
160 
161  m_grabPointX = 0;
162  m_grabPointY = 0;
163  m_newX = 0;
164  m_newY = 0;
165 
166  // Set initial flag values
167 
168  m_flags.clicked = false;
169  m_flags.dragging = false;
170  m_flags.hasFocus = false;
171  m_flags.deleted = false;
172  m_flags.drawingEnabled = false;
173  m_flags.enabled = true;
174  m_flags.erased = true;
175  m_flags.hidden = false;
176 
177  // Set hierarchy pointers
178 
179  m_parent = (CNxWidget *)NULL;
180  m_focusedChild = (CNxWidget *)NULL;
181 
182  // Double-click
183 
184  clock_gettime(CLOCK_REALTIME, &m_lastClickTime);
185  m_lastClickX = 0;
186  m_lastClickY = 0;
187  m_doubleClickBounds = DOUBLE_CLICK_BOUNDS;
188 
189  // Set border size to 1 line
190 
191  m_borderSize.top = 1;
192  m_borderSize.right = 1;
193  m_borderSize.bottom = 1;
194  m_borderSize.left = 1;
195 
197 }
198 
199 /**
200  * Destructor.
201  */
202 
204 {
205  if (!m_flags.deleted)
206  {
207  m_flags.deleted = true;
208 
209  // Unset the clicked pointer if necessary
210 
211  if (m_widgetControl->getClickedWidget() == this)
212  {
214  }
215  }
216 
217  if (m_parent != (CNxWidget *)NULL)
218  {
219  m_parent->removeChild(this);
220  }
221 
222  // Delete children
223 
224  while (m_children.size() > 0)
225  {
226  m_children[0]->destroy();
227  }
228 
229  // Remove ourselve from the controlled widget list
230 
232 
233  // Delete instances. NOTE that we do not delete the controlling
234  // widget. It persists until the window is closed.
235 
236  delete m_widgetEventHandlers;
237 }
238 
239 /**
240  * Get the x coordinate of the widget in "Widget space".
241  *
242  * @return Widget space x coordinate.
243  */
244 
245 nxgl_coord_t CNxWidget::getX(void) const
246 {
247  if (m_parent != (CNxWidget *)NULL)
248  {
249  return m_parent->getX() + m_rect.getX();
250  }
251 
252  return m_rect.getX();
253 }
254 
255 /**
256  * Get the y coordinate of the widget in "Widget space".
257  *
258  * @return Widget space y coordinate.
259  */
260 
261 nxgl_coord_t CNxWidget::getY(void) const
262 {
263  if (m_parent != (CNxWidget *)NULL)
264  {
265  return m_parent->getY() + m_rect.getY();
266  }
267 
268  return m_rect.getY();
269 }
270 
271 /**
272  * Get the x coordinate of the widget relative to its parent.
273  *
274  * @return Parent-space x coordinate.
275  */
276 
277 nxgl_coord_t CNxWidget::getRelativeX(void) const
278 {
279  return m_rect.getX();
280 }
281 
282 /**
283  * Get the y coordinate of the widget relative to its parent.
284  *
285  * @return Parent-space y coordinate.
286  */
287 
288 nxgl_coord_t CNxWidget::getRelativeY(void) const
289 {
290  return m_rect.getY();
291 }
292 
293 /**
294  * Has the widget been marked for deletion? This function recurses up the widget
295  * hierarchy and only returns true if all of the widgets in the ancestor
296  * chain are not deleted.
297  *
298  * Widgets marked for deletion are automatically deleted and should not be
299  * interacted with.
300  *
301  * @return True if marked for deletion.
302  */
303 
304 bool CNxWidget::isDeleted(void) const
305 {
306  if (m_parent != (CNxWidget *)NULL)
307  {
308  if (m_parent->isDeleted())
309  {
310  return true;
311  }
312  }
313 
314  return m_flags.deleted;
315 }
316 
317 /**
318  * Is the widget allowed to draw? This function recurses up the widget
319  * hierarchy and only returns true if all of the widgets in the ancestor
320  * chain are visible.
321  *
322  * @return True if drawing is enabled.
323  */
324 
326 {
327  if (m_parent != (CNxWidget *)NULL)
328  {
329  if (m_parent->isDrawingEnabled())
330  {
331  // Drawing is enabled if the widget is drawable, not deleted, and not hidden
332 
334  }
335  }
336  else
337  {
338  // Drawing is enabled if the widget is drawable, not deleted, and not hidden
339 
341  }
342 
343  return false;
344 }
345 
346 /**
347  * Is the widget hidden? This function recurses up the widget
348  * hierarchy and returns true if any of the widgets in the ancestor
349  * chain are hidden.
350  *
351  * @return True if hidden.
352  */
353 
354 bool CNxWidget::isHidden(void) const
355 {
356  if (m_parent != (CNxWidget *)NULL)
357  {
358  if (!m_parent->isHidden())
359  {
360  // Hidden if the widget is deleted or hidden
361 
362  return (m_flags.deleted || m_flags.hidden);
363  }
364  }
365  else
366  {
367  return (m_flags.deleted || m_flags.hidden);
368  }
369 
370  return true;
371 }
372 
373 /**
374  * Is the widget enabled? This function recurses up the widget
375  * hierarchy and only returns true if all of the widgets in the ancestor
376  * chain are enabled.
377  *
378  * @return True if enabled.
379  */
380 
382 {
383  if (m_parent != (CNxWidget *)NULL)
384  {
385  if (m_parent->isEnabled())
386  {
387  // Enabled if the widget is enabled, not deleted and not hidden
388 
389  return (m_flags.enabled && (!m_flags.deleted) && (!m_flags.hidden));
390  }
391  }
392  else
393  {
394  return (m_flags.enabled && (!m_flags.deleted) && (!m_flags.hidden));
395  }
396 
397  return false;
398 }
399 
400 /**
401  * Insert the dimensions that this widget wants to have into the rect
402  * passed in as a parameter. All coordinates are relative to the widget's
403  * parent.
404  *
405  * @param rect Reference to a rect to populate with data.
406  */
407 
409 {
410  rect = m_rect;
411 }
412 
413 /**
414  * Insert the properties of the space within this widget that is available
415  * for children into the rect passed in as a parameter.
416  * All coordinates are relative to this widget.
417  *
418  * @param rect Reference to a rect to populate with data.
419  */
420 
422 {
423  if (m_flags.borderless)
424  {
425  rect.setX(0);
426  rect.setY(0);
427  rect.setWidth(getWidth());
428  rect.setHeight(getHeight());
429  }
430  else
431  {
432  rect.setX(m_borderSize.left);
433  rect.setY(m_borderSize.top);
436  }
437 }
438 
439 /**
440  * Insert the properties of the space within this widget that is
441  * available for children into the rect passed in as a parameter.
442  * Identical to getClientRect() except that all coordinates are
443  * absolute positions within the window.
444  *
445  * @param rect Reference to a rect to populate with data.
446  */
447 
448 void CNxWidget::getRect(CRect &rect) const
449 {
450  getClientRect(rect);
451  rect.setX(rect.getX() + getX());
452  rect.setY(rect.getY() + getY());
453 }
454 
455 /**
456  * Sets this widget's border state.
457  *
458  * @param isBorderless The border state.
459  */
460 
461 void CNxWidget::setBorderless(bool borderless)
462 {
463  m_flags.borderless = borderless;
464 }
465 
466 /**
467  * Sets the font.
468  *
469  * @param font A pointer to the font to use.
470  *
471  * NOTE: This font is not deleted when the widget is destroyed!
472  */
473 
475 {
476  m_style.font = font;
477 }
478 
479 /**
480  * Draws the visible regions of the widget and the widget's child widgets.
481  */
482 
484 {
485  if (isDrawingEnabled())
486  {
487  // Get the graphics port needed to draw on this window
488 
490 
491  // Draw the Widget
492 
493  drawBorder(port);
494  drawContents(port);
495 
496  // Remember that the widget is no longer erased
497 
498  m_flags.erased = false;
499 
500  // Draw the children of the widget
501 
502  drawChildren();
503  }
504 }
505 
506 /**
507  * Enables the widget.
508  *
509  * @return True if the widget was enabled.
510  */
511 
513 {
514  if (!m_flags.enabled)
515  {
516  m_flags.enabled = true;
517  onEnable();
518  redraw();
520  return true;
521  }
522 
523  return false;
524 }
525 
526 /**
527  * Disabled the widget.
528  *
529  * @return True if the widget was disabled.
530  */
531 
533 {
534  if (m_flags.enabled)
535  {
536  m_flags.enabled = false;
537  onDisable();
538  redraw();
540  return true;
541  }
542 
543  return false;
544 }
545 
546 /**
547  * Erases the widget, marks it as deleted, and moves it to the CNxWidget
548  * deletion queue. Widgets are automatically deleted by the framework and
549  * should not be deleted externally.
550  */
551 
553 {
554  if (!m_flags.deleted)
555  {
558 
559  m_flags.deleted = true;
560  m_flags.drawingEnabled = false;
561 
562  // Unset clicked widget if necessary
563 
564  CNxWidget *clickedWidget = m_widgetControl->getClickedWidget();
565  if (clickedWidget == this)
566  {
567  release(clickedWidget->getX(), clickedWidget->getY());
568  }
569 
570  if (m_parent != (CNxWidget *)NULL)
571  {
572  m_parent->closeChild(this);
573  }
574  }
575 }
576 
577 /**
578  * Draws the widget and makes it visible.
579  * Does not steal focus from other widgets.
580  *
581  * @return True if the widget was shown.
582  * @see hide()
583  */
584 
585 bool CNxWidget::show(void)
586 {
587  if (m_flags.hidden)
588  {
589  m_flags.hidden = false;
590 
592  redraw();
593  return true;
594  }
595 
596  return false;
597 }
598 
599 /**
600  * Erases the widget and makes it invisible.
601  * Does not re-assign focus to another widget.
602  *
603  * @return True if the widget was hidden.
604  * @see show()
605  */
606 
607 bool CNxWidget::hide(void)
608 {
609  if (!m_flags.hidden)
610  {
611  m_flags.hidden = true;
613  return true;
614  }
615 
616  return false;
617 }
618 
619 /**
620  * Click this widget at the supplied coordinates. This should only be
621  * overridden in subclasses if the default click behaviour needs to be changed.
622  * If the subclassed widget should just respond to a standard click,
623  * the onClick() method should be overridden instead.
624  *
625  * @param x X coordinate of the click.
626  * @param y Y coordinate of the click.
627  * @return True if the click was successful.
628  */
629 
630 bool CNxWidget::click(nxgl_coord_t x, nxgl_coord_t y)
631 {
632  if (!isEnabled() || !checkCollision(x, y))
633  {
634  return false;
635  }
636 
637  // Check for a double-click
638 
639  if (isDoubleClick(x, y))
640  {
641  return doubleClick(x, y);
642  }
643 
644  // Work out which child was clicked
645 
646  for (int i = m_children.size() - 1; i > -1; i--)
647  {
648  if (m_children[i]->click(x, y))
649  {
650  return true;
651  }
652  }
653 
654  // Handle clicks on this
655 
656  m_flags.clicked = true;
657 
658  // Record data for double-click
659 
660  clock_gettime(CLOCK_REALTIME, &m_lastClickTime);
661  m_lastClickX = x;
662  m_lastClickY = y;
663 
664  // Take focus away from child widgets
665 
666  setFocusedWidget((CNxWidget *)NULL);
667 
668  // Tell controlling widget that the clicked widget has changed
669 
671 
672  // Run any code in the inherited class
673 
674  onClick(x, y);
676  return true;
677 }
678 
679 /**
680  * Check if the click is a double-click.
681  *
682  * @param x X coordinate of the click.
683  * @param y Y coordinate of the click.
684  * @return True if the click is a double-click.
685  */
686 
687 bool CNxWidget::isDoubleClick(nxgl_coord_t x, nxgl_coord_t y)
688 {
689  // Check for a double-click
690 
692  {
693  // Within the allowed region?
694 
696  {
698  {
699  return true;
700  }
701  }
702  }
703 
704  return false;
705 }
706 
707 /**
708  * Double-click this widget at the supplied coordinates. This
709  * should only be overridden in subclasses if the default
710  * double-click behaviour needs to be changed. If the subclassed
711  * widget should just respond to a standard double-click, the
712  * onDoubleClick() method should be overridden instead.
713  *
714  * @param x X coordinate of the click.
715  * @param y Y coordinate of the click.
716  * @return True if the click was successful.
717  */
718 
719 bool CNxWidget::doubleClick(nxgl_coord_t x, nxgl_coord_t y)
720 {
721  if (!isEnabled() || !checkCollision(x, y))
722  {
723  return false;
724  }
725 
726  // Work out which child was clicked. Allow the
727  // child to determine if it has been double-clicked or not
728  // in case the second click has fallen on a different
729  // child to the first.
730 
731  for (int i = m_children.size() - 1; i > -1; i--)
732  {
733  if (m_children[i]->click(x, y))
734  {
735  return true;
736  }
737  }
738 
739  m_flags.clicked = true;
740 
741  // Record data for double-click
742 
743  clock_gettime(CLOCK_REALTIME, &m_lastClickTime);
744  m_lastClickX = x;
745  m_lastClickY = y;
746 
747  // Take focus away from child widgets
748 
749  setFocusedWidget((CNxWidget *)NULL);
750 
751  // Tell controlling widget that the clicked widget has changed
752 
754 
755  onDoubleClick(x, y);
757  return true;
758 }
759 
760 /**
761  * Release this widget at the supplied coordinates. This should only be
762  * overridden in subclasses if the default release behaviour needs to be
763  * changed. If the subclassed widget should just respond to a standard
764  * release, the onRelease() method should be overridden instead.
765  *
766  * @param x X coordinate of the release.
767  * @param y Y coordinate of the release.
768  * @return True if the release was successful.
769  */
770 
771 bool CNxWidget::release(nxgl_coord_t x, nxgl_coord_t y)
772 {
773  if (!m_flags.clicked)
774  {
775  return false;
776  }
777 
778  // Notify of the pre-release event. In this event, the widget is still in the
779  // clicked state. This event is used, for example, by button handlers so
780  // that the click event is really processed when the button is released
781  // instead of pressed. The former behavior is needed because the result
782  // of processing the press may obscure the button and make it impossible
783  // to receive the release event.
784 
785  onPreRelease(x, y);
786 
787  // Now mark the widget as NOT clicked and stop dragging actions.
788 
789  m_flags.clicked = false;
790  stopDragging(x, y);
791 
792  if (m_widgetControl->getClickedWidget() == this)
793  {
795  }
796 
797  // Determine which release event to fire
798 
799  if (checkCollision(x, y))
800  {
801  // Notify of the release event... the widget was NOT dragged outside of
802  // its original bounding box
803 
804  onRelease(x, y);
805 
806  // Release occurred within widget; raise release
807 
809  }
810  else
811  {
812  // Notify of the release event... the widget WAS dragged outside of
813  // its original bounding box
814 
815  onReleaseOutside(x, y);
816 
817  // Release occurred outside widget; raise release outside event
818 
820  }
821 
822  return true;
823 }
824 
825 /**
826  * Drag the widget to the supplied coordinates.
827  *
828  * @param x The x coordinate of the mouse.
829  * @param y The y coordinate of the mouse.
830  * @param vX The horizontal distance that the mouse was dragged.
831  * @param vY The vertical distance that the mouse was dragged.
832  * @return True if the drag was successful.
833  */
834 
835 bool CNxWidget::drag(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t vX, nxgl_coord_t vY)
836 {
837  if (isEnabled() && m_flags.dragging)
838  {
839  if (vX != 0 || vY != 0)
840  {
841  onDrag(x, y, vX, vY);
842  m_widgetEventHandlers->raiseDragEvent(x, y, vX, vY);
843  }
844 
845  return true;
846  }
847 
848  return false;
849 }
850 
851 /**
852  * Send a keypress to the widget.
853  *
854  * @param key The keycode to send to the widget.
855  * @return True if the keypress was processed.
856  */
857 
859 {
860  if (!isEnabled())
861  {
862  return false;
863  }
864 
865  // Raise keypress for this widget
866 
868 
869  // Handle active child
870 
871  if (m_focusedChild != NULL)
872  {
873  m_focusedChild->keyPress(key);
874  }
875 
876  return true;
877 }
878 
879 /**
880  * Send a cursor control event to the widget.
881  *
882  * @param cursorControl The cursor control code o send to the widget.
883  * @return True if the cursor control was processed.
884  */
885 
887 {
888  if (!isEnabled())
889  {
890  return false;
891  }
892 
893  // Raise cursor control for this widget
894 
896 
897  // Handle active child
898 
899  if (m_focusedChild != NULL)
900  {
901  m_focusedChild->cursorControl(control);
902  }
903 
904  return true;
905 }
906 
907 /**
908  * Give the widget focus.
909  *
910  * @return True if the widget received focus correctly.
911  */
912 
914 {
915  if (!isEnabled())
916  {
917  return false;
918  }
919 
920  // Remember if the widget has focus
921 
922  bool hadFocus = m_flags.hasFocus;
923  m_flags.hasFocus = true;
924 
925  // Notify parent that this widget has focus
926 
927  if (m_parent != (CNxWidget *)NULL)
928  {
929  m_parent->setFocusedWidget(this);
930  }
931 
932  // Raise an event only if the widget did not have focus
933 
934  if (!hadFocus)
935  {
936  onFocus();
937 
939  return true;
940  }
941 
942  return false;
943 }
944 
945 /**
946  * Remove focus from the widget.
947  *
948  * @return True if the widget lost focus correctly.
949  */
950 
951 bool CNxWidget::blur(void)
952 {
953  // Remember if the widget had focus
954 
955  bool hadFocus = m_flags.hasFocus;
956 
957  m_flags.hasFocus = false;
958 
959  // Take focus away from child widgets
960 
961  if (m_focusedChild != (CNxWidget *)NULL)
962  {
963  m_focusedChild->blur();
964  m_focusedChild = (CNxWidget *)NULL;
966  }
967 
968  // Raise an event only if the widget had focus
969 
970  if (hadFocus)
971  {
972  onBlur();
973 
975  return true;
976  }
977 
978  return false;
979 }
980 
981 /**
982  * Move the widget to the new coordinates.
983  * Co-ordinates are relative to the parent widget.
984  *
985  * @param x The new x coordinate.
986  * @param y The new y coordinate.
987  * @return True if the move was successful.
988  */
989 
990 bool CNxWidget::moveTo(nxgl_coord_t x, nxgl_coord_t y)
991 {
992  // Enforce widget to stay within parent confines if necessary
993 
994  if (m_parent != (CNxWidget *)NULL)
995  {
996  if (!m_parent->isPermeable())
997  {
998  CRect parentRect;
999  m_parent->getClientRect(parentRect);
1000 
1001  // Check x coordinate
1002 
1003  if (x < parentRect.getX())
1004  {
1005  x = parentRect.getX();
1006 
1007  // Check width against new value
1008 
1009  if (x + getWidth() > parentRect.getX2() + 1)
1010  {
1011  return false;
1012  }
1013  }
1014  else if (x + getWidth() > parentRect.getX2() + 1)
1015  {
1016  x = (parentRect.getX() + parentRect.getX()) - getWidth();
1017 
1018  // Check new x value
1019 
1020  if (x < parentRect.getX())
1021  {
1022  return false;
1023  }
1024  }
1025 
1026  // Check y coordinate
1027 
1028  if (y < parentRect.getY())
1029  {
1030  y = parentRect.getY();
1031 
1032  // Check height against new value
1033 
1034  if (y + getHeight() > parentRect.getY2() + 1)
1035  {
1036  return false;
1037  }
1038  }
1039  else if (y + getHeight() > parentRect.getY2() + 1)
1040  {
1041  y = (parentRect.getY() + parentRect.getY()) - getHeight();
1042 
1043  // Check new y value
1044 
1045  if (y < parentRect.getY())
1046  {
1047  return false;
1048  }
1049  }
1050  }
1051  }
1052 
1053  // Perform move if necessary
1054 
1055  if ((m_rect.getX() != x) || (m_rect.getY() != y))
1056  {
1057  nxgl_coord_t oldX = m_rect.getX();
1058  nxgl_coord_t oldY = m_rect.getY();
1059 
1060  m_rect.setX(x);
1061  m_rect.setY(y);
1062 
1063  redraw();
1064  m_widgetEventHandlers->raiseMoveEvent(x, y, x - oldX, y - oldY);
1065  return true;
1066  }
1067 
1068  return false;
1069 }
1070 
1071 /**
1072  * Resize the widget to the new dimensions.
1073  *
1074  * @param width The new width.
1075  * @param height The new height.
1076  * @return True if the resize was successful.
1077  */
1078 
1079 bool CNxWidget::resize(nxgl_coord_t width, nxgl_coord_t height)
1080 {
1081  // Enforce widget to stay within parent confines if necessary
1082 
1083  if (m_parent != (CNxWidget *)NULL)
1084  {
1085  if (!m_parent->isPermeable())
1086  {
1087  CRect parentRect;
1088  m_parent->getClientRect(parentRect);
1089 
1090  // Check width
1091 
1092  if (m_rect.getX() + width > parentRect.getX2() + 1)
1093  {
1094  width = parentRect.getX2() + 1 - m_rect.getX();
1095  }
1096 
1097  // Check height
1098 
1099  if (m_rect.getY() + height > parentRect.getY2() + 1)
1100  {
1101  height = parentRect.getY2() + 1 - m_rect.getY();
1102  }
1103  }
1104  }
1105 
1106  if (getWidth() != width || getHeight() != height)
1107  {
1108  // Remember if the widget is permeable
1109 
1110  bool wasPermeable = m_flags.permeable;
1111 
1112  // Remember if widget was drawing
1113 
1114  bool wasDrawEnabled = m_flags.drawingEnabled;
1115 
1116  m_flags.permeable = true;
1117  disableDrawing();
1118 
1119  m_rect.setWidth(width);
1120  m_rect.setHeight(height);
1121 
1122  onResize(width, height);
1123 
1124  // Reset the permeable value
1125 
1126  m_flags.permeable = wasPermeable;
1127 
1128  // Reset drawing value
1129 
1130  m_flags.drawingEnabled = wasDrawEnabled;
1131  redraw();
1132  m_widgetEventHandlers->raiseResizeEvent(width, height);
1133  return true;
1134  }
1135 
1136  return false;
1137 }
1138 
1139 /**
1140  * Resize and move the widget in one operation.
1141  * Only performs one redraw so it is faster than calling the
1142  * two separate functions.
1143  *
1144  * @param x The new x coordinate.
1145  * @param y The new y coordinate.
1146  * @param width The new width.
1147  * @param height The new height.
1148  * @return True if the widget was adjusted successfully.
1149  */
1150 
1151 bool CNxWidget::changeDimensions(nxgl_coord_t x, nxgl_coord_t y,
1152  nxgl_coord_t width, nxgl_coord_t height)
1153 {
1154  bool wasDrawing = m_flags.drawingEnabled;
1155  m_flags.drawingEnabled = false;
1156  bool moved = moveTo(x, y);
1157  m_flags.drawingEnabled = wasDrawing;
1158  return (resize(width, height) | moved);
1159 }
1160 
1161 /**
1162  * Moves the supplied child widget to the deletion queue.
1163  * For framework use only.
1164  *
1165  * @param widget A pointer to the child widget.
1166  */
1167 
1169 {
1170  // Locate widget in main vector
1171 
1172  for (int i = 0; i < m_children.size(); i++)
1173  {
1174  if (m_children[i] == widget)
1175  {
1176  // Add widget to controlling widget's delete vector
1177 
1179 
1180  // Remove widget from main vector
1181 
1182  m_children.erase(i);
1183  break;
1184  }
1185  }
1186 }
1187 
1188 /**
1189  * Sets the supplied widget as the focused child. The widget must
1190  * be a child of this widget.
1191  *
1192  * @param widget A pointer to the child widget.
1193  * @see getFocusedWidget()
1194  */
1195 
1197 {
1198  if (m_focusedChild != widget)
1199  {
1200  if (m_focusedChild != NULL)
1201  {
1202  // Blur the current active widget
1203 
1204  m_focusedChild->blur();
1205  }
1206  }
1207 
1208  // Remember the new active widget
1209 
1210  m_focusedChild = widget;
1211 
1212  // Make this widget active too
1213 
1214  focus();
1215 
1216  // Route keyboard input to the focused widget
1217 
1219 }
1220 
1221 /**
1222  * Checks if the supplied coordinates collide with this widget.
1223  *
1224  * @param x The x coordinate to check.
1225  * @param y The y coordinate to check.
1226  * @return True if a collision occurred.
1227  */
1228 
1229 bool CNxWidget::checkCollision(nxgl_coord_t x, nxgl_coord_t y) const
1230 {
1231  if (isHidden())
1232  {
1233  return false;
1234  }
1235 
1236  // Get the clipped rect
1237 
1238  CRect rect;
1239  getRect(rect);
1240  return rect.contains(x, y);
1241 }
1242 
1243 /**
1244  * Checks if the supplied rectangle definition collides with this widget.
1245  *
1246  * @param x The x coordinate of the rectangle to check.
1247  * @param y The y coordinate of the rectangle to check.
1248  * @param width The width of the rectangle to check.
1249  * @param height The height of the rectangle to check.
1250  * @return True if a collision occurred.
1251  */
1252 
1253 bool CNxWidget::checkCollision(nxgl_coord_t x, nxgl_coord_t y,
1254  nxgl_coord_t width, nxgl_coord_t height) const
1255 {
1256  if (isHidden())
1257  {
1258  return false;
1259  }
1260 
1261  // Get the clipped rect
1262 
1263  CRect rect;
1264  getRect(rect);
1265  return rect.intersects(CRect(x, y, width, height));
1266 }
1267 
1268 /**
1269  * Checks if the supplied widget collides with this widget.
1270  *
1271  * @param widget A pointer to another widget to check for collisions with.
1272  * @return True if a collision occurred.
1273  */
1274 
1276 {
1277  // Get the clipped rect
1278 
1279  CRect rect;
1280  widget->getRect(rect);
1281  return rect.intersects(m_rect);
1282 }
1283 
1284 /**
1285  * Adds a widget to this widget's child stack. The widget is added to the
1286  * top of the stack. Note that the widget can only be added if it is not
1287  * already a child of another widget.
1288  *
1289  * @param widget A pointer to the widget to add to the child list.
1290  * @see insertWidget()
1291  */
1292 
1294 {
1295  if (widget->getParent() == NULL)
1296  {
1297  widget->setParent(this);
1298  m_children.push_back(widget);
1299 
1300  // Should the widget steal the focus?
1301 
1302  if (widget->hasFocus())
1303  {
1304  setFocusedWidget(widget);
1305  }
1306 
1307  widget->enableDrawing();
1308  widget->redraw();
1309  }
1310 }
1311 
1312 /**
1313  * Inserts a widget into this widget's child stack at the bottom of the
1314  * stack. Note that the widget can only be added if it is not already
1315  * a child of another widget.
1316  *
1317  * @param widget A pointer to the widget to add to the child list.
1318  * @see addWidget()
1319  */
1320 
1322 {
1323  if (widget->getParent() == NULL)
1324  {
1325  widget->setParent(this);
1326  m_children.insert(0, widget);
1327 
1328  widget->enableDrawing();
1329  widget->redraw();
1330  }
1331 }
1332 
1333 /**
1334  * Remove this widget from the widget hierarchy. Returns
1335  * responsibility for deleting the widget back to the developer.
1336  * Does not unregister the widget from the VBL system.
1337  * Does not erase the widget from the display.
1338  *
1339  * @return True if the widget was successfully removed.
1340  */
1341 
1343 {
1344  if (m_parent != (CNxWidget *)NULL)
1345  {
1346  return m_parent->removeChild(this);
1347  }
1348 
1349  return false;
1350 }
1351 
1352 /**
1353  * Remove a child widget from the widget hierarchy. Returns
1354  * responsibility for deleting the widget back to the developer.
1355  * Does not unregister the widget from the VBL system.
1356  * Does not erase the widget from the display.
1357  *
1358  * @param widget Pointer to the widget to remove from the hierarchy.
1359  * @return True if the widget was succesfully removed.
1360  */
1361 
1363 {
1364  // Do we need to make another widget active?
1365 
1366  if (m_focusedChild == widget)
1367  {
1368  m_focusedChild = (CNxWidget *)NULL;
1370  }
1371 
1372  // Unset clicked widget if necessary
1373 
1374  CNxWidget *clickedWidget = m_widgetControl->getClickedWidget();
1375  if (clickedWidget == widget)
1376  {
1377  clickedWidget->release(clickedWidget->getX(), clickedWidget->getY());
1378  }
1379 
1380  // Divorce child from parent
1381 
1382  widget->setParent((CNxWidget *)NULL);
1383  widget->disableDrawing();
1384 
1385  // Locate widget in main vector
1386 
1387  for (int i = 0; i < m_children.size(); i++)
1388  {
1389  if (m_children[i] == widget)
1390  {
1391  // Remove widget from main vector
1392 
1393  m_children.erase(i);
1394  return true;
1395  }
1396  }
1397 
1398  return false;
1399 }
1400 
1401 /**
1402  * Get the child widget at the specified index.
1403  *
1404  * @param index Index of the child to retrieve.
1405  * @return Pointer to the child at the specified index.
1406  */
1407 
1408 const CNxWidget *CNxWidget::getChild(int index) const
1409 {
1410  if (index < (int)m_children.size())
1411  {
1412  return m_children[index];
1413  }
1414 
1415  return (CNxWidget *)NULL;
1416 }
1417 
1418 /**
1419  * Sets the border size. The border cannot be drawn over in the
1420  * drawContents() method.
1421  *
1422  * @param borderSize The new border size.
1423  */
1424 
1426 {
1427  m_borderSize.top = borderSize.top;
1428  m_borderSize.right = borderSize.right;
1429  m_borderSize.bottom = borderSize.bottom;
1430  m_borderSize.left = borderSize.left;
1431 }
1432 
1433 /**
1434  * Use the provided widget style
1435  */
1436 
1438 {
1447  m_style.font = style->font;
1448 }
1449 
1450 /**
1451  * Draw the area of this widget that falls within the clipping region.
1452  * Called by the redraw() function to draw all visible regions.
1453  *
1454  * @param port The CGraphicsPort to draw to.
1455  * @see redraw().
1456  */
1457 
1459 {
1460  port->drawFilledRect(getX(), getY(), getWidth(), getHeight(),
1461  getBackgroundColor());
1462 }
1463 
1464 /**
1465  * Draw all visible regions of this widget's children.
1466  */
1467 
1469 {
1470  for (int i = 0; i < m_children.size(); i++)
1471  {
1472  m_children[i]->redraw();
1473  }
1474 }
1475 
1476 /**
1477  * Remove the supplied child widget from this widget and send it to
1478  * the deletion queue.
1479  *
1480  * @param widget The widget to close.
1481  * @see close().
1482  */
1483 
1485 {
1486  if (widget == NULL)
1487  {
1488  return;
1489  }
1490 
1491  // Ensure widget knows it is being closed
1492 
1493  widget->close();
1494 
1495  // Do we need to make another widget active?
1496 
1497  if (m_focusedChild == widget)
1498  {
1499  m_focusedChild = (CNxWidget *)NULL;
1501 
1502  // Try to choose highest widget
1503 
1504  for (int i = m_children.size() - 1; i > -1; i--)
1505  {
1506  if ((m_children[i] != widget) && (!m_children[i]->isHidden()))
1507  {
1509  }
1510  }
1511 
1512  // Where should the focus go?
1513 
1514  if (m_focusedChild != NULL)
1515  {
1516  // Send focus to the new active widget
1517 
1518  m_focusedChild->focus();
1519 
1520  // Route keyboard input to the focused widget
1521 
1523  }
1524  else
1525  {
1526  // Give focus to this
1527 
1528  setFocusedWidget((CNxWidget *)NULL);
1529  }
1530  }
1531 
1532  moveChildToDeleteQueue(widget);
1533 }
1534 
1535 /**
1536  * Notify this widget that it is being dragged, and set its drag point.
1537  *
1538  * @param x The x coordinate of the drag position relative to this widget.
1539  * @param y The y coordinate of the drag position relative to this widget.
1540  */
1541 
1542 void CNxWidget::startDragging(nxgl_coord_t x, nxgl_coord_t y)
1543 {
1544  if (m_flags.draggable)
1545  {
1546  m_flags.dragging = true;
1547  m_flags.clicked = true;
1548  m_grabPointX = x - getX();
1549  m_grabPointY = y - getY();
1550  m_newX = m_rect.getX();
1551  m_newY = m_rect.getY();
1552 
1553  onDragStart();
1554  }
1555 }
1556 
1557 /**
1558  * Notify this widget that it is no longer being dragged.
1559  */
1560 
1561 void CNxWidget::stopDragging(nxgl_coord_t x, nxgl_coord_t y)
1562 {
1563  if (m_flags.dragging)
1564  {
1565  onDragStop();
1566  m_flags.dragging = false;
1568  }
1569 }
virtual void onClick(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.hxx:282
nxgl_mxpixel_t selectedBackground
WidgetBorderSize m_borderSize
Definition: cnxwidget.hxx:208
nxgl_coord_t getRelativeY(void) const
Definition: cnxwidget.cxx:288
nxgl_coord_t m_newY
Definition: cnxwidget.hxx:179
nxgl_mxpixel_t enabledText
nxgl_coord_t getY2(void) const
Definition: crect.hxx:319
CGraphicsPort * getGraphicsPort(void)
nxgl_coord_t m_newX
Definition: cnxwidget.hxx:178
void raiseDragEvent(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t vX, nxgl_coord_t vY)
virtual bool isDoubleClick(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:687
virtual void onReleaseOutside(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.hxx:328
void addControlledWidget(CNxWidget *widget)
bool moveTo(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:990
nxgl_coord_t m_grabPointY
Definition: cnxwidget.hxx:177
nxgl_mxpixel_t disabledText
void raiseResizeEvent(nxgl_coord_t width, nxgl_coord_t height)
void addToDeleteQueue(CNxWidget *widget)
void raiseCursorControlEvent(ECursorControl cursorControl)
virtual void getPreferredDimensions(CRect &rect) const
Definition: cnxwidget.cxx:408
bool isPermeable(void) const
Definition: cnxwidget.hxx:528
void disableDrawing(void)
Definition: cnxwidget.hxx:908
void getRect(CRect &rect) const
Definition: cnxwidget.cxx:448
bool cursorControl(ECursorControl control)
Definition: cnxwidget.cxx:886
virtual void drawBorder(CGraphicsPort *port)
Definition: cnxwidget.hxx:234
virtual void drawContents(CGraphicsPort *port)
Definition: cnxwidget.cxx:1458
nxgl_coord_t getX(void) const
Definition: crect.hxx:160
bool intersects(const CRect &rect) const
Definition: crect.cxx:318
nxgl_mxpixel_t getBackgroundColor(void) const
Definition: cnxwidget.hxx:716
nxgl_coord_t getX2(void) const
Definition: crect.hxx:308
void setFocusedWidget(CNxWidget *widget)
nxgl_coord_t m_grabPointX
Definition: cnxwidget.hxx:176
CNxWidget(const CNxWidget &widget)
Definition: cnxwidget.hxx:271
virtual ~CNxWidget(void)
Definition: cnxwidget.cxx:203
const CNxWidget * getChild(int index) const
Definition: cnxwidget.cxx:1408
void raiseDoubleClickEvent(nxgl_coord_t x, nxgl_coord_t y)
bool drag(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t vX, nxgl_coord_t vY)
Definition: cnxwidget.cxx:835
bool isEnabled(void) const
Definition: cnxwidget.cxx:381
bool resize(nxgl_coord_t width, nxgl_coord_t height)
Definition: cnxwidget.cxx:1079
virtual void onDisable(void)
Definition: cnxwidget.hxx:390
void stopDragging(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:1561
CWidgetControl * m_widgetControl
Definition: cnxwidget.hxx:171
void raiseMoveEvent(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t vX, nxgl_coord_t vY)
nxgl_coord_t getHeight(void) const
Definition: cnxwidget.hxx:593
void useWidgetStyle(const CWidgetStyle *style)
Definition: cnxwidget.cxx:1437
void setHeight(nxgl_coord_t height)
Definition: crect.hxx:261
bool isDeleted(void) const
Definition: cnxwidget.cxx:304
virtual bool click(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:630
void getClientRect(CRect &rect) const
Definition: cnxwidget.cxx:421
bool changeDimensions(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height)
Definition: cnxwidget.cxx:1151
virtual void onFocus(void)
Definition: cnxwidget.hxx:366
virtual void onDrag(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t vX, nxgl_coord_t vY)
Definition: cnxwidget.hxx:341
uint16_t nxwidget_char_t
Definition: nxconfig.hxx:454
void setX(nxgl_coord_t x)
Definition: crect.hxx:229
bool contains(nxgl_coord_t x, nxgl_coord_t y) const
Definition: crect.cxx:334
bool doubleClick(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:719
CNxWidget * getParent(void) const
Definition: cnxwidget.hxx:652
virtual void onRelease(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.hxx:317
nxgl_coord_t m_lastClickY
Definition: cnxwidget.hxx:197
virtual void onDragStart(void)
Definition: cnxwidget.hxx:350
void drawChildren(void)
Definition: cnxwidget.cxx:1468
virtual void setFont(CNxFont *font)
Definition: cnxwidget.cxx:474
void drawFilledRect(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t width, nxgl_coord_t height, nxgl_mxpixel_t color)
void setParent(CNxWidget *parent)
Definition: cnxwidget.hxx:1284
virtual bool checkCollision(nxgl_coord_t x, nxgl_coord_t y) const
Definition: cnxwidget.cxx:1229
void raiseReleaseOutsideEvent(nxgl_coord_t x, nxgl_coord_t y)
void closeChild(CNxWidget *widget)
Definition: cnxwidget.cxx:1484
virtual void onEnable(void)
Definition: cnxwidget.hxx:382
CNxWidget * getClickedWidget(void)
void enableDrawing(void)
Definition: cnxwidget.hxx:917
nxgl_coord_t m_lastClickX
Definition: cnxwidget.hxx:196
void raiseClickEvent(nxgl_coord_t x, nxgl_coord_t y)
bool removeChild(CNxWidget *widget)
Definition: cnxwidget.cxx:1362
virtual void onPreRelease(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.hxx:306
CWidgetEventHandlerList * m_widgetEventHandlers
Definition: cnxwidget.hxx:191
CNxWidget * m_focusedChild
Definition: cnxwidget.hxx:203
void insertWidget(CNxWidget *widget)
Definition: cnxwidget.cxx:1321
virtual void onResize(nxgl_coord_t width, nxgl_coord_t height)
Definition: cnxwidget.hxx:401
void addWidget(CNxWidget *widget)
Definition: cnxwidget.cxx:1293
bool keyPress(nxwidget_char_t key)
Definition: cnxwidget.cxx:858
nxgl_coord_t getRelativeX(void) const
Definition: cnxwidget.cxx:277
void getWidgetStyle(CWidgetStyle *style)
void setClickedWidget(CNxWidget *widget)
nxgl_coord_t getY(void) const
Definition: cnxwidget.cxx:261
void setWidth(nxgl_coord_t width)
Definition: crect.hxx:250
nxgl_coord_t getWidth(void) const
Definition: cnxwidget.hxx:582
nxgl_coord_t getX(void) const
Definition: cnxwidget.cxx:245
nxgl_coord_t getY(void) const
Definition: crect.hxx:170
CWidgetStyle m_style
Definition: cnxwidget.hxx:183
virtual void onBlur(void)
Definition: cnxwidget.hxx:374
bool release(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:771
nxgl_mxpixel_t selectedText
void setFocusedWidget(CNxWidget *widget)
Definition: cnxwidget.cxx:1196
virtual void onDragStop(void)
Definition: cnxwidget.hxx:358
void setY(nxgl_coord_t y)
Definition: crect.hxx:240
TNxArray< CNxWidget * > m_children
Definition: cnxwidget.hxx:204
void moveChildToDeleteQueue(CNxWidget *widget)
Definition: cnxwidget.cxx:1168
bool isDrawingEnabled(void) const
Definition: cnxwidget.cxx:325
void startDragging(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:1542
void setBorderSize(const WidgetBorderSize &borderSize)
Definition: cnxwidget.cxx:1425
struct timespec m_lastClickTime
Definition: cnxwidget.hxx:195
void setBorderless(bool isBorderless)
Definition: cnxwidget.cxx:461
void clearFocusedWidget(CNxWidget *widget)
bool isHidden(void) const
Definition: cnxwidget.cxx:354
CNxWidget * m_parent
Definition: cnxwidget.hxx:202
virtual void onDoubleClick(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.hxx:295
void raiseReleaseEvent(nxgl_coord_t x, nxgl_coord_t y)
void raiseDropEvent(nxgl_coord_t x, nxgl_coord_t y)
void removeControlledWidget(CNxWidget *widget)
bool hasFocus(void) const
Definition: cnxwidget.hxx:472