NXWidgets: cwidgetcontrol.cxx Source File

NXWidgets 1.19

cwidgetcontrol.cxx
Go to the documentation of this file.
1 /****************************************************************************
2 * NxWidgets/libnxwidgets/src/cwidgetcontrol.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 <cstdint>
43 #include <cstdbool>
44 #include <cstring>
45 #include <csched>
46 #include <cerrno>
47
48 #include "nxconfig.hxx"
49 #include "cnxserver.hxx"
50 #include "cnxwidget.hxx"
51 #include "cnxfont.hxx"
52 #include "cwidgetstyle.hxx"
53 #include "cnxtimer.hxx"
54 #include "cgraphicsport.hxx"
55 #include "cwidgetcontrol.hxx"
56 #include "singletons.hxx"
57
58 /****************************************************************************
59 * Pre-Processor Definitions
60 ****************************************************************************/
61
62 /****************************************************************************
63 * Global Static Data
64 ****************************************************************************/
65
66 using namespace NXWidgets;
67
68 /****************************************************************************
69 * Method Implementations
70 ****************************************************************************/
71
72 /**
73 * CWidgetControl constructor (for the case where the display size is known)
74 *
75 * @param style The style that the widget should use. If this is not
76 * specified, the widget will use the values stored in the global
77 * defaultCWidgetStyle object. The widget will copy the properties of
78 * the style into its own internal style object.
79 */
80
81 CWidgetControl::CWidgetControl(FAR const CWidgetStyle *style)
82 {
83 // Initialize state
84
85 m_port = (CGraphicsPort *)NULL;
86 m_haveGeometry = false;
87 m_clickedWidget = (CNxWidget *)NULL;
88 m_focusedWidget = (CNxWidget *)NULL;
89
90 // Initialize data that we will get from the position callback
91
92 m_hWindow = NULL;
93 m_size.h = 0;
94 m_size.w = 0;
95 m_pos.x = 0;
96 m_pos.y = 0;
97 m_bounds.pt1.x = 0;
98 m_bounds.pt1.y = 0;
99 m_bounds.pt2.y = 0;
100 m_bounds.pt2.y = 0;
101
102 // Initialize the mouse/touchscreen event and keyboard data structures
103
104 #ifdef CONFIG_NX_XYINPUT
105 memset(&m_xyinput, 0, sizeof(struct SXYInput));
106 #endif
107 m_nCh = 0;
108 m_nCc = 0;
109
110 // Intialize semaphores:
111 //
112 // m_waitSem. The semaphore that will wake up the external logic on mouse events,
113 // keypress events, or widget deletion events.
114 // m_geoSem. The semaphore that will synchronize window size and position
115 // information.
116
117 #ifdef CONFIG_NXWIDGET_EVENTWAIT
118 m_waiting = false;
119 sem_init(&m_waitSem, 0, 0);
120 #endif
121 sem_init(&m_boundsSem, 0, 0);
122 sem_init(&m_geoSem, 0, 0);
123
124 // Do we need to fetch the default style?
125
126 if (style == (CWidgetStyle *)NULL)
127 {
128 // Get the style from the controlling widget
129
130 copyWidgetStyle(&m_style, g_defaultWidgetStyle);
131 }
132 else
133 {
134 // Use specified style
135
136 copyWidgetStyle(&m_style, style);
137 }
138 }
139
140 /**
141 * Destructor.
142 */
143
144 CWidgetControl::~CWidgetControl(void)
145 {
146 // Notify any external waiters... this should not happen because it
147 // it is probably already too late
148
149 #ifdef CONFIG_NXWIDGET_EVENTWAIT
150 postWindowEvent();
151 #endif
152
153 // Delete any contained instances
154
155 if (m_port)
156 {
157 delete m_port;
158 }
159
160 // Flush the delete queue
161
162 processDeleteQueue();
163
164 // Delete controlled widget list
165
166 while (m_widgets.size() > 0)
167 {
168 m_widgets[0]->destroy();
169 }
170 }
171
172 /**
173 * Wait for an interesting window event to occur (like a mouse or keyboard event).
174 * Caller's should exercise care to assure that the test for waiting and this
175 * call are "atomic" .. perhaps by locking the scheduler like:
176 *
177 * sched_lock();
178 * ...
179 * if (no interesting events)
180 * {
181 * window->waitForWindowEvent();
182 * }
183 * sched_unlock();
184 */
185
186 #ifdef CONFIG_NXWIDGET_EVENTWAIT
187 void CWidgetControl::waitForWindowEvent(void)
188 {
189 m_waiting = true;
190 (void)sem_wait(&m_waitSem);
191 m_waiting = false;
192 }
193 #endif
194
195 /**
196 * Wake up external logic waiting for a window event
197 */
198
199 #ifdef CONFIG_NXWIDGET_EVENTWAIT
200 void CWidgetControl::postWindowEvent(void)
201 {
202 if (m_waiting)
203 {
204 (void)sem_post(&m_waitSem);
205 }
206 }
207 #endif
208
209 /**
210 * Run all code that needs to take place on a periodic basis.
211 * This method normally called externally... either periodically
212 * or when a window event is detected. If CONFIG_NXWIDGET_EVENTWAIT
213 * is defined, then external logic want call waitWindow event and
214 * when awakened, they chould call this function. As an example:
215 *
216 * for (;;)
217 * {
218 * sched_lock(); // Make the sequence atomic
219 * if (!window->pollEvents(0))
220 * {
221 * window->waitWindowEvent();
222 * }
223 * sched_unlock();
224 * }
225 *
226 * This method is just a wrapper simply calls the following methods.
227 * It can easily be replace with custom, external logic.
228 *
229 * processDeleteQueue()
230 * pollMouseEvents(widget)
231 * pollKeyboardEvents()
232 * pollCursorControlEvents()
233 *
234 * @param widget. Specific widget to poll. Use NULL to run the
235 * all widgets in the window.
236 * @return True means some interesting event occurred
237 */
238
239 bool CWidgetControl::pollEvents(CNxWidget *widget)
240 {
241 // Delete any queued widgets
242
243 processDeleteQueue();
244
245 // Handle mouse input
246
247 bool mouseEvent = pollMouseEvents(widget);
248
249 // Handle keyboard input
250
251 bool keyboardEvent = pollKeyboardEvents();
252
253 // Handle cursor control input
254
255 bool cursorControlEvent = pollCursorControlEvents();
256 return mouseEvent || keyboardEvent || cursorControlEvent;
257 }
258
259 /**
260 * Get the index of the specified controlled widget.
261 *
262 * @param widget The widget to get the index of.
263 * @return The index of the widget. -1 if the widget is not found.
264 */
265
266 const int CWidgetControl::getWidgetIndex(const CNxWidget *widget) const
267 {
268 for (int i = 0; i < m_widgets.size(); i++)
269 {
270 if (m_widgets[i] == widget)
271 {
272 return i;
273 }
274 }
275
276 return -1;
277 }
278
279 /**
280 * Remove a controlled widget
281 *
282 * @param widget The widget to be removed
283 */
284
285 void CWidgetControl::removeControlledWidget(CNxWidget *widget)
286 {
287 // Locate the widget
288
289 int index = getWidgetIndex(widget);
290 if (index >= 0)
291 {
292 m_widgets.erase(index);
293 }
294 }
295
296 /**
297 * Add a widget to the list of widgets to be deleted.
298 * Must never be called by anything other than the framework itself.
299 *
300 * @param widget The widget to add to the delete queue.
301 */
302
303 void CWidgetControl::addToDeleteQueue(CNxWidget *widget)
304 {
305 // Add the widget to the delete queue
306
307 m_deleteQueue.push_back(widget);
308
309 // Then wake up logic that may be waiting for a window event
310
311 #ifdef CONFIG_NXWIDGET_EVENTWAIT
312 postWindowEvent();
313 #endif
314 }
315
316 /**
317 * Set the clicked widget pointer. Note that this should not be
318 * called by code other than within the CWidgetControl library itself.
319 *
320 * @param widget The new clicked widget.
321 */
322
323 void CWidgetControl::setClickedWidget(CNxWidget *widget)
324 {
325 // Do we have a clicked widget already?
326
327 if (m_clickedWidget != (CNxWidget *)NULL)
328 {
329 // Ensure that the existing clicked widget is released *outside* its bounds
330
331 m_clickedWidget->release(m_clickedWidget->getX() - 10, 0);
332 }
333
334 // Update the pointer
335
336 m_clickedWidget = widget;
337 }
338
339 /**
340 * Set the focused widget that will receive keyboard input.
341 *
342 * @param widget The new focused widget.
343 */
344
345 void CWidgetControl::setFocusedWidget(CNxWidget *widget)
346 {
347 if (m_focusedWidget != widget)
348 {
349 // This widget will now receive focus
350
351 m_focusedWidget = widget;
352
353 // Make sure that the widget knows that is has focus
354
355 widget->focus();
356 }
357 }
358
359 /**
360 * This event is called from CCallback instance to provide
361 * notifications of certain NX-server related events. This event,
362 * in particular, will occur when the position or size of the underlying
363 * window occurs.
364 *
365 * @param hWindow The window handle that should be used to communicate
366 * with the window
367 * @param pos The position of the window in the physical device space.
368 * @param size The size of the window.
369 * @param bounds The size of the underlying display (pixels x rows)
370 */
371
372 void CWidgetControl::geometryEvent(NXHANDLE hWindow,
373 FAR const struct nxgl_size_s *size,
374 FAR const struct nxgl_point_s *pos,
375 FAR const struct nxgl_rect_s *bounds)
376 {
377 // Disable pre-emption so that we can be assured that the following
378 // operations are atomic
379
380 sched_lock();
381
382 // Save positional data that may change dynamically
383
384 m_pos.x = pos->x;
385 m_pos.y = pos->y;
386 m_size.h = size->h;
387 m_size.w = size->w;
388
389 // The first callback is important. This is the handshake that proves
390 // that we are truly communicating with the servier. This is also
391 // a critical point because this is when we know the physical
392 // dimensions of the underlying window.
393
394 if (!m_hWindow)
395 {
396 // Save one-time server specific information
397
398 m_hWindow = hWindow;
399 nxgl_rectcopy(&m_bounds, bounds);
400 giveBoundsSem();
401 }
402
403 // In the normal start up sequence, the window is created with zero size
404 // at position 0,0. The safe thing to do is to set the position (still
405 // with size 0, then then set the size. Assuming that is what is being
406 // done, we will not report that we have valid geometry until the size
407 // becomes nonzero (or actually over 1).
408
409 if (!m_haveGeometry && size->h > 1 && size->w > 1)
410 {
411 // Wake up any threads waiting for initial position information.
412 // REVISIT: If the window is moved or repositioned, then the
413 // position and size data will be incorrect for a period of time.
414 // That case should be handled here as well.
415
416 m_haveGeometry = true;
417 giveGeoSem();
418 }
419
420 m_eventHandlers.raiseGeometryEvent();
421 sched_unlock();
422 }
423
424 /**
425 * This event is called from CCallback instance to provide
426 * notifications of certain NX-server related events. This event,
427 * in particular, will occur when the a portion of the window that was
428 * previously obscured is now exposed.
429 *
430 * @param rect The region in the window that must be redrawn.
431 * @param more True means that more re-draw requests will follow
432 */
433
434 void CWidgetControl::redrawEvent(FAR const struct nxgl_rect_s *nxRect, bool more)
435 {
436 // REVISIT. This is not not yet used and not fully implemented.
437 CRect rect;
438 rect.setNxRect(nxRect);
439 m_eventHandlers.raiseRedrawEvent();
440 }
441
442 /**
443 * This event is called from CCallback instance to provide notifications of
444 * certain NX-server related events. This event, in particular, means that
445 * new mouse data is available for the window.
446 *
447 * @param pos The (x,y) position of the mouse.
448 * @param buttons See NX_MOUSE_* definitions.
449 */
450
451 #ifdef CONFIG_NX_XYINPUT
452 void CWidgetControl::newMouseEvent(FAR const struct nxgl_point_s *pos, uint8_t buttons)
453 {
454 // Save the mouse X/Y position
455
456 m_xyinput.x = pos->x;
457 m_xyinput.y = pos->y;
458
459 // Update button press states
460
461 clearMouseEvents();
462
463 if ((buttons & NX_MOUSE_LEFTBUTTON) != 0)
464 {
465 // Handle left button press events. leftHeld means that the left mouse
466 // button was pressed on the previous sample as well.
467
468 if (m_xyinput.leftHeld)
469 {
470 m_xyinput.leftDrag = 1;
471 }
472 else
473 {
474 // New left button press
475
476 m_xyinput.leftPressed = 1;
477
478 (void)clock_gettime(CLOCK_REALTIME, &m_xyinput.leftPressTime);
479
480 // Check for double click event
481
482 if (elapsedTime(&m_xyinput.leftReleaseTime) <= CONFIG_NXWIDGETS_DOUBLECLICK_TIME)
483 {
484 m_xyinput.doubleClick = 1;
485 }
486 }
487
488 m_xyinput.leftHeld = 1;
489 }
490 else
491 {
492 // Handle left button release events
493
494 if (m_xyinput.leftHeld)
495 {
496 // New left button release
497
498 m_xyinput.leftReleased = 1;
499 (void)clock_gettime(CLOCK_REALTIME, &m_xyinput.leftReleaseTime);
500 }
501
502 m_xyinput.leftHeld = 0;
503 }
504
505 #if 0 // Center and right buttons not used
506 if ((buttons & NX_MOUSE_CENTERBUTTON) != 0)
507 {
508 // Handle center button press events. centerHeld means that the center mouse
509 // button was pressed on the previous sample as well.
510
511 if (m_xyinput.centerHeld)
512 {
513 m_xyinput.centerDrag = 1;
514 }
515 else
516 {
517 // New center button press
518
519 m_xyinput.centerPressed = 1;
520 }
521
522 m_xyinput.centerHeld = 1;
523 }
524 else
525 {
526 // Handle center button release events
527
528 if (m_xyinput.centerHeld)
529 {
530 // New center button release
531
532 m_xyinput.centerReleased = 1;
533 }
534
535 m_xyinput.centerHeld = 0;
536 }
537
538 if ((buttons & NX_MOUSE_RIGHTBUTTON) != 0)
539 {
540 // Handle right button press events. rightHeld means that the right mouse
541 // button was pressed on the previous sample as well.
542
543 if (m_xyinput.rightHeld)
544 {
545 m_xyinput.rightDrag = 1;
546 }
547 else
548 {
549 // New right button press
550
551 m_xyinput.rightPressed = 1;
552 }
553
554 m_xyinput.rightHeld = 1;
555 }
556 else
557 {
558 // Handle right button release events
559
560 if (m_xyinput.rightHeld)
561 {
562 // New right button release
563
564 m_xyinput.rightReleased = 1;
565 }
566
567 m_xyinput.rightHeld = 0;
568 }
569 #endif
570
571 // Notify any external logic that a keyboard event has occurred
572
573 m_eventHandlers.raiseMouseEvent();
574
575 // Then wake up logic that may be waiting for a window event
576
577 #ifdef CONFIG_NXWIDGET_EVENTWAIT
578 postWindowEvent();
579 #endif
580 }
581 #endif
582
583 /**
584 * This event is called from CCallback instance to provide notifications of
585 * certain NX-server related events. This event, in particular, means that
586 * keyboard/keypad data is available for the window.
587 *
588 * @param nCh The number of characters that are available in pStr[].
589 * @param pStr The array of characters.
590 */
591
592 #ifdef CONFIG_NX_KBD
593 void CWidgetControl::newKeyboardEvent(uint8_t nCh, FAR const uint8_t *pStr)
594 {
595 FAR uint8_t *pBuffer = &m_kbdbuf[m_nCh];
596
597 // Append each new character to keyboard character buffer
598
599 for (uint8_t i = 0;
600 i < nCh && m_nCh < CONFIG_NXWIDGETS_KBDBUFFER_SIZE;
601 i++, m_nCh++)
602 {
603 *pBuffer++ = *pStr++;
604 }
605
606 // Notify any external logic that a keyboard event has occurred
607
608 m_eventHandlers.raiseKeyboardEvent();
609
610 // Then wake up logic that may be waiting for a window event
611
612 #ifdef CONFIG_NXWIDGET_EVENTWAIT
613 postWindowEvent();
614 #endif
615 }
616 #endif
617
618 /**
619 * This event means that cursor control data is available for the window.
620 *
621 * @param cursorControl The cursor control code received.
622 */
623
624 void CWidgetControl::newCursorControlEvent(ECursorControl cursorControl)
625 {
626 // Append the new cursor control
627
628 if (m_nCc < CONFIG_NXWIDGETS_CURSORCONTROL_SIZE)
629 {
630 m_controls[m_nCc] = (uint8_t)cursorControl;
631 m_nCc++;
632 }
633
634 // Then wake up logic that may be waiting for a window event
635
636 #ifdef CONFIG_NXWIDGET_EVENTWAIT
637 postWindowEvent();
638 #endif
639 }
640
641 /**
642 * The creation sequence is:
643 *
644 * 1) Create a dumb CWigetControl instance
645 * 2) Pass the dumb CWidgetControl instance to the window constructor
646 * that inherits from INxWindow.
647 * 3) The call this method with the static_cast to INxWindow to,
648 * finally, create the CGraphicsPort for this window.
649 * 4) After that, the fully smartened CWidgetControl instance can
650 * be used to generate additional widgets.
651 *
652 * @param window The instance of INxWindow needed to construct the
653 * CGraphicsPort instance
654 */
655
656 bool CWidgetControl::createGraphicsPort(INxWindow *window)
657 {
658 #ifdef CONFIG_NX_WRITEONLY
659 m_port = new CGraphicsPort(window, m_style.colors.background);
660 #else
661 m_port = new CGraphicsPort(window);
662 #endif
663 return m_port != (CGraphicsPort *)NULL;
664 }
665
666 /**
667 * Copy a widget style
668 *
669 * @param dest The destination style
670 * @param src The source to use
671 */
672
673 void CWidgetControl::copyWidgetStyle(CWidgetStyle *dest, const CWidgetStyle *src)
674 {
675 dest->colors.background = src->colors.background;
676 dest->colors.selectedBackground = src->colors.selectedBackground;
677 dest->colors.shineEdge = src->colors.shineEdge;
678 dest->colors.shadowEdge = src->colors.shadowEdge;
679 dest->colors.highlight = src->colors.highlight;
680 dest->colors.disabledText = src->colors.disabledText;
681 dest->colors.enabledText = src->colors.enabledText;
682 dest->colors.selectedText = src->colors.selectedText;
683 dest->font = src->font;
684 }
685
686 /**
687 * Return the elapsed time in milliseconds
688 *
689 * @param tp A time in the past from which to compute the elapsed time.
690 * @return The elapsed time since tp
691 */
692
693 uint32_t CWidgetControl::elapsedTime(FAR const struct timespec *startTime)
694 {
695 struct timespec endTime;
696
697 (void)clock_gettime(CLOCK_REALTIME, &endTime);
698 if (startTime->tv_sec <= endTime.tv_sec)
699 {
700 // Get the elapsed seconds
701
702 uint32_t seconds = endTime.tv_sec - startTime->tv_sec;
703
704 // Get the elapsed nanoseconds, borrowing from the seconds if necessary
705
706 int32_t endNanoSeconds = endTime.tv_nsec;
707 if (startTime->tv_nsec > endNanoSeconds)
708 {
709 // Are there any seconds to borrow from?
710
711 if (seconds < 1)
712 {
713 // startTime is in the future???
714
715 return 0;
716 }
717
718 // Borrow from the seconds
719
720 seconds--;
721 endNanoSeconds += 1000000000;
722 }
723 uint32_t nanoseconds = endNanoSeconds - startTime->tv_nsec;
724
725 // Then return the elapsed time in milliseconds
726
727 return seconds * 1000000 + nanoseconds / 1000;
728 }
729
730 // startTime is in the future???
731
732 return 0;
733 }
734
735 /**
736 * Pass clicks to the widget hierarchy. If a single widget
737 * is supplied, only that widget is sent the click.
738 *
739 * @param x Click xcoordinate.
740 * @param y Click ycoordinate.
741 * @param widget Pointer to a specific widget or NULL.
742 */
743
744 void CWidgetControl::handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, CNxWidget *widget)
745 {
746 // Working with a specific widget or the whole structure?
747
748 if (widget == (CNxWidget *)NULL)
749 {
750 // All widgets
751
752 for (int i = m_widgets.size() - 1; i > -1; i--)
753 {
754 if (m_widgets[i]->click(x, y))
755 {
756 return;
757 }
758 }
759 }
760 else
761 {
762 // One widget
763
764 (void)widget->click(x, y);
765 }
766 }
767
768 /**
769 * Delete any widgets in the deletion queue.
770 */
771
772 void CWidgetControl::processDeleteQueue(void)
773 {
774 int i = 0;
775 while (i < m_deleteQueue.size())
776 {
777 m_deleteQueue[i]->destroy();
778 i++;
779 }
780
781 m_deleteQueue.clear();
782 }
783
784 /**
785 * Process mouse/touchscreen events and send throughout the hierarchy.
786 *
787 * @param widget. Specific widget to poll. Use NULL to run the
788 * all widgets in the window.
789 * @return True means a mouse event occurred
790 */
791
792 bool CWidgetControl::pollMouseEvents(CNxWidget *widget)
793 {
794 #ifdef CONFIG_NX_XYINPUT
795 bool mouseEvent = true; // Assume that an interesting mouse event occurred
796
797 // All widgets
798
799 if (m_xyinput.leftPressed)
800 {
801 // Handle a new left button press event
802
803 handleLeftClick(m_xyinput.x, m_xyinput.y, widget);
804 }
805 else if (m_xyinput.leftDrag)
806 {
807 // The left button is still being held down
808
809 if (m_clickedWidget != (CNxWidget *)NULL)
810 {
811 // Handle a mouse drag event
812
813 m_clickedWidget->drag(m_xyinput.x, m_xyinput.y,
814 m_xyinput.x - m_xyinput.lastX,
815 m_xyinput.y - m_xyinput.lastY);
816 }
817 }
818 else if (m_clickedWidget != (CNxWidget *)NULL)
819 {
820 // Mouse left button release event
821
822 m_clickedWidget->release(m_xyinput.x, m_xyinput.y);
823 }
824 else
825 {
826 // No interesting mouse events
827
828 mouseEvent = false;
829 }
830
831 // Clear all press and release events once they have been processed
832
833 clearMouseEvents();
834
835 // Save the mouse position for the next poll
836
837 m_xyinput.lastX = m_xyinput.x;
838 m_xyinput.lastY = m_xyinput.y;
839 return mouseEvent;
840 #else
841 return false;
842 #endif
843 }
844
845 /**
846 * Process keypad events and send throughout the hierarchy.
847 *
848 * @return True means a keyboard event occurred
849 */
850
851 bool CWidgetControl::pollKeyboardEvents(void)
852 {
853 bool keyboardEvent = false; // Assume no interesting keyboard events
854
855 // Keyboard presses with no focused widget is not an interesting
856 // event
857
858 if (m_focusedWidget != (CNxWidget *)NULL)
859 {
860 // Forward each character to the widget with the focus
861
862 for (uint8_t i = 0; i < m_nCh; i++)
863 {
864 m_focusedWidget->keyPress((nxwidget_char_t)m_kbdbuf[i]);
865 keyboardEvent = true;
866 }
867 }
868
869 // All of the buffered characters have been consumed
870
871 m_nCh = 0;
872 return keyboardEvent;
873 }
874
875 /**
876 * Process cursor control events and send throughout the hierarchy.
877 *
878 * @return True means a cursor control event was processes
879 */
880
881 bool CWidgetControl::pollCursorControlEvents(void)
882 {
883 bool cursorControlEvent = false; // Assume no interesting cursor events
884
885 // Cursor controls with no focused widget is not an interesting
886 // event
887
888 if (m_focusedWidget != (CNxWidget *)NULL)
889 {
890 // Forward each cursor control to the widget with the focus
891
892 for (uint8_t i = 0; i < m_nCc; i++)
893 {
894 m_focusedWidget->cursorControl((ECursorControl)m_controls[i]);
895 cursorControlEvent = true;
896 }
897 }
898
899 // All of the buffered events have been consumed
900
901 m_nCc = 0;
902 return cursorControlEvent;
903 }
904
905 /**
906 * Take the geometry semaphore (handling signal interruptions)
907 */
908
909 void CWidgetControl::takeGeoSem(void)
910 {
911 // Take the geometry semaphore. Retry is an error occurs (only if
912 // the error is due to a signal interruption).
913
914 int ret;
915 do
916 {
917 ret = sem_wait(&m_geoSem);
918 }
919 while (ret < 0 && errno == EINTR);
920 }
921
922 /**
923 * Take the bounds semaphore (handling signal interruptions)
924 */
925
926 void CWidgetControl::takeBoundsSem(void)
927 {
928 // Take the bounds semaphore. Retry is an error occurs (only if
929 // the error is due to a signal interruption).
930
931 int ret;
932 do
933 {
934 ret = sem_wait(&m_boundsSem);
935 }
936 while (ret < 0 && errno == EINTR);
937 }
938
939 /**
940 * Clear all mouse events
941 */
942
943 #ifdef CONFIG_NX_XYINPUT
944 void CWidgetControl::clearMouseEvents(void)
945 {
946 // Clear all press and release events once they have been processed
947
948 m_xyinput.leftPressed = 0;
949 m_xyinput.leftReleased = 0;
950 m_xyinput.leftDrag = 0;
951
952 #if 0 // Center and right buttons are not used
953 m_xyinput.centerPressed = 0;
954 m_xyinput.centerReleased = 0;
955 m_xyinput.centerDrag = 0;
956
957 m_xyinput.rightPressed = 0;
958 m_xyinput.rightReleased = 0;
959 m_xyinput.rightDrag = 0;
960 #endif
961
962 m_xyinput.doubleClick = 0;
963 }
964 #endif
NXWidgets::CWindowEventHandlerList::raiseGeometryEvent
void raiseGeometryEvent(void)
Definition: cwindoweventhandlerlist.cxx:127
NXWidgets::CWidgetColors::selectedBackground
nxgl_mxpixel_t selectedBackground
Definition: cwidgetstyle.hxx:106
NXWidgets::CNxWidget
Definition: cnxwidget.hxx:121
NXWidgets::CWidgetControl::createGraphicsPort
bool createGraphicsPort(INxWindow *window)
Definition: cwidgetcontrol.cxx:656
NXWidgets::CWidgetColors::enabledText
nxgl_mxpixel_t enabledText
Definition: cwidgetstyle.hxx:111
NXWidgets::CWidgetControl::CWidgetControl
CWidgetControl(FAR const CWidgetStyle *style=(const CWidgetStyle *) NULL)
Definition: cwidgetcontrol.cxx:81
NXWidgets::CWidgetStyle
Definition: cwidgetstyle.hxx:125
NXWidgets::CWindowEventHandlerList::raiseRedrawEvent
void raiseRedrawEvent(void)
Definition: cwindoweventhandlerlist.cxx:115
NXWidgets::CWidgetControl::SXYInput::lastX
nxgl_coord_t lastX
Definition: cwidgetcontrol.hxx:160
NXWidgets::CWidgetControl::m_waitSem
sem_t m_waitSem
Definition: cwidgetcontrol.hxx:187
NXWidgets::CWidgetControl::m_hWindow
NXHANDLE m_hWindow
Definition: cwidgetcontrol.hxx:214
NXWidgets::CWidgetControl::pollKeyboardEvents
bool pollKeyboardEvents(void)
Definition: cwidgetcontrol.cxx:851
NXWidgets::CWidgetControl::SXYInput::rightPressed
uint16_t rightPressed
Definition: cwidgetcontrol.hxx:119
NXWidgets::CWidgetControl::SXYInput::leftDrag
uint16_t leftDrag
Definition: cwidgetcontrol.hxx:127
NXWidgets::CWidgetControl::m_deleteQueue
TNxArray< CNxWidget * > m_deleteQueue
Definition: cwidgetcontrol.hxx:178
singletons.hxx
NXWidgets::CWidgetColors::disabledText
nxgl_mxpixel_t disabledText
Definition: cwidgetstyle.hxx:110
NXWidgets::CWidgetControl::m_clickedWidget
CNxWidget * m_clickedWidget
Definition: cwidgetcontrol.hxx:199
NXWidgets::CWidgetControl::addToDeleteQueue
void addToDeleteQueue(CNxWidget *widget)
Definition: cwidgetcontrol.cxx:303
NXWidgets::CWidgetControl::m_waiting
bool m_waiting
Definition: cwidgetcontrol.hxx:185
NXWidgets::CNxWidget::cursorControl
bool cursorControl(ECursorControl control)
Definition: cnxwidget.cxx:886
NXWidgets::CWidgetControl::SXYInput::centerDrag
uint16_t centerDrag
Definition: cwidgetcontrol.hxx:129
NXWidgets::CWidgetControl::SXYInput::leftReleaseTime
struct timespec leftReleaseTime
Definition: cwidgetcontrol.hxx:166
NXWidgets::CWidgetControl::SXYInput::x
nxgl_coord_t x
Definition: cwidgetcontrol.hxx:156
NXWidgets::CWidgetControl::copyWidgetStyle
void copyWidgetStyle(CWidgetStyle *dest, const CWidgetStyle *src)
Definition: cwidgetcontrol.cxx:673
cgraphicsport.hxx
NXWidgets::CWidgetControl::waitForWindowEvent
void waitForWindowEvent(void)
Definition: cwidgetcontrol.cxx:187
NXWidgets::CWidgetControl::setFocusedWidget
void setFocusedWidget(CNxWidget *widget)
Definition: cwidgetcontrol.cxx:345
NXWidgets::CWidgetColors::shadowEdge
nxgl_mxpixel_t shadowEdge
Definition: cwidgetstyle.hxx:108
NXWidgets::CWidgetControl::getWidgetIndex
const int getWidgetIndex(const CNxWidget *widget) const
Definition: cwidgetcontrol.cxx:266
NXWidgets::CWidgetControl::m_geoSem
sem_t m_geoSem
Definition: cwidgetcontrol.hxx:218
NXWidgets::CWidgetControl::elapsedTime
uint32_t elapsedTime(FAR const struct timespec *startTime)
Definition: cwidgetcontrol.cxx:693
cwidgetstyle.hxx
NXWidgets::CWidgetControl::takeBoundsSem
void takeBoundsSem(void)
Definition: cwidgetcontrol.cxx:926
cwidgetcontrol.hxx
NXWidgets::CNxWidget::drag
bool drag(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t vX, nxgl_coord_t vY)
Definition: cnxwidget.cxx:835
NXWidgets::CWidgetControl::redrawEvent
void redrawEvent(FAR const struct nxgl_rect_s *nxRect, bool more)
Definition: cwidgetcontrol.cxx:434
NXWidgets::CWidgetControl::m_bounds
struct nxgl_rect_s m_bounds
Definition: cwidgetcontrol.hxx:217
NXWidgets::CWidgetControl::SXYInput::rightDrag
uint16_t rightDrag
Definition: cwidgetcontrol.hxx:131
NXWidgets::CWindowEventHandlerList::raiseMouseEvent
void raiseMouseEvent(void)
Definition: cwindoweventhandlerlist.cxx:140
NXWidgets::CRect::setNxRect
void setNxRect(FAR const struct nxgl_rect_s *rect)
Definition: crect.hxx:272
NXWidgets
Definition: cbgwindow.hxx:65
NXWidgets::CNxWidget::click
virtual bool click(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:630
NXWidgets::CWidgetControl::m_port
CGraphicsPort * m_port
Definition: cwidgetcontrol.hxx:175
NXWidgets::CWidgetControl::m_kbdbuf
uint8_t m_kbdbuf[CONFIG_NXWIDGETS_KBDBUFFER_SIZE]
Definition: cwidgetcontrol.hxx:204
NXWidgets::CWidgetControl::m_pos
struct nxgl_point_s m_pos
Definition: cwidgetcontrol.hxx:216
NXWidgets::CWidgetControl::SXYInput::centerPressed
uint16_t centerPressed
Definition: cwidgetcontrol.hxx:117
NXWidgets::CNxWidget::focus
bool focus(void)
Definition: cnxwidget.cxx:913
NXWidgets::CWidgetControl::pollEvents
bool pollEvents(CNxWidget *widget=(CNxWidget *) NULL)
Definition: cwidgetcontrol.cxx:239
NXWidgets::CWidgetControl::pollCursorControlEvents
bool pollCursorControlEvents(void)
Definition: cwidgetcontrol.cxx:881
NXWidgets::CWidgetControl::processDeleteQueue
void processDeleteQueue(void)
Definition: cwidgetcontrol.cxx:772
NXWidgets::CWidgetControl::m_style
CWidgetStyle m_style
Definition: cwidgetcontrol.hxx:226
NXWidgets::CWidgetControl::handleLeftClick
void handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, CNxWidget *widget)
Definition: cwidgetcontrol.cxx:744
NXWidgets::CWidgetControl::newCursorControlEvent
void newCursorControlEvent(ECursorControl cursorControl)
Definition: cwidgetcontrol.cxx:624
NXWidgets::nxwidget_char_t
uint16_t nxwidget_char_t
Definition: nxconfig.hxx:454
NXWidgets::CWidgetControl::giveBoundsSem
void giveBoundsSem(void)
Definition: cwidgetcontrol.hxx:344
nxconfig.hxx
NXWidgets::CWidgetControl::~CWidgetControl
virtual ~CWidgetControl(void)
Definition: cwidgetcontrol.cxx:144
cnxtimer.hxx
NXWidgets::CWidgetControl::SXYInput::centerHeld
uint16_t centerHeld
Definition: cwidgetcontrol.hxx:123
NXWidgets::CWindowEventHandlerList::raiseKeyboardEvent
void raiseKeyboardEvent(void)
Definition: cwindoweventhandlerlist.cxx:154
NXWidgets::CWidgetControl::postWindowEvent
void postWindowEvent(void)
Definition: cwidgetcontrol.cxx:200
NXWidgets::CWidgetColors::shineEdge
nxgl_mxpixel_t shineEdge
Definition: cwidgetstyle.hxx:107
NXWidgets::CWidgetControl::SXYInput::centerReleased
uint16_t centerReleased
Definition: cwidgetcontrol.hxx:135
NXWidgets::CWidgetControl::m_nCc
uint8_t m_nCc
Definition: cwidgetcontrol.hxx:208
NXWidgets::CWidgetControl::SXYInput::leftPressTime
struct timespec leftPressTime
Definition: cwidgetcontrol.hxx:164
NXWidgets::CWidgetColors::background
nxgl_mxpixel_t background
Definition: cwidgetstyle.hxx:105
NXWidgets::CRect
Definition: crect.hxx:101
NXWidgets::CWidgetControl::SXYInput::rightHeld
uint16_t rightHeld
Definition: cwidgetcontrol.hxx:125
NXWidgets::CWidgetControl::geometryEvent
void geometryEvent(NXHANDLE hWindow, const struct nxgl_size_s *size, const struct nxgl_point_s *pos, const struct nxgl_rect_s *bounds)
Definition: cwidgetcontrol.cxx:372
NXWidgets::CWidgetControl::SXYInput::leftHeld
uint16_t leftHeld
Definition: cwidgetcontrol.hxx:121
NXWidgets::ECursorControl
ECursorControl
Definition: cwidgeteventargs.hxx:111
NXWidgets::CWidgetControl::m_eventHandlers
CWindowEventHandlerList m_eventHandlers
Definition: cwidgetcontrol.hxx:220
NXWidgets::CWidgetStyle::font
CNxFont * font
Definition: cwidgetstyle.hxx:129
NXWidgets::CNxWidget::keyPress
bool keyPress(nxwidget_char_t key)
Definition: cnxwidget.cxx:858
NXWidgets::CWidgetControl::SXYInput::rightReleased
uint16_t rightReleased
Definition: cwidgetcontrol.hxx:137
NXWidgets::CWidgetControl::m_xyinput
struct SXYInput m_xyinput
Definition: cwidgetcontrol.hxx:196
cnxfont.hxx
NXWidgets::g_defaultWidgetStyle
CWidgetStyle * g_defaultWidgetStyle
Definition: singletons.hxx:101
NXWidgets::CWidgetControl::m_nCh
uint8_t m_nCh
Definition: cwidgetcontrol.hxx:205
NXWidgets::CWidgetControl::m_widgets
TNxArray< CNxWidget * > m_widgets
Definition: cwidgetcontrol.hxx:180
NXWidgets::CWidgetControl::newKeyboardEvent
void newKeyboardEvent(uint8_t nCh, FAR const uint8_t *pStr)
Definition: cwidgetcontrol.cxx:593
NXWidgets::CWidgetControl::setClickedWidget
void setClickedWidget(CNxWidget *widget)
Definition: cwidgetcontrol.cxx:323
NXWidgets::CWidgetControl::m_focusedWidget
CNxWidget * m_focusedWidget
Definition: cwidgetcontrol.hxx:201
NXWidgets::CWidgetControl::m_boundsSem
sem_t m_boundsSem
Definition: cwidgetcontrol.hxx:219
NXWidgets::CWidgetControl::m_controls
uint8_t m_controls[CONFIG_NXWIDGETS_CURSORCONTROL_SIZE]
Definition: cwidgetcontrol.hxx:207
NXWidgets::CNxWidget::getX
nxgl_coord_t getX(void) const
Definition: cnxwidget.cxx:245
NXWidgets::CWidgetControl::SXYInput::leftReleased
uint16_t leftReleased
Definition: cwidgetcontrol.hxx:133
NXWidgets::CWidgetControl::m_haveGeometry
bool m_haveGeometry
Definition: cwidgetcontrol.hxx:182
NXWidgets::CWidgetControl::SXYInput::y
nxgl_coord_t y
Definition: cwidgetcontrol.hxx:158
NXWidgets::CWidgetControl::m_size
struct nxgl_size_s m_size
Definition: cwidgetcontrol.hxx:215
cnxserver.hxx
NXWidgets::CWidgetColors::highlight
nxgl_mxpixel_t highlight
Definition: cwidgetstyle.hxx:109
NXWidgets::CWidgetStyle::colors
CWidgetColors colors
Definition: cwidgetstyle.hxx:128
NXWidgets::CNxWidget::release
bool release(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:771
cnxwidget.hxx
NXWidgets::CWidgetControl::SXYInput::leftPressed
uint16_t leftPressed
Definition: cwidgetcontrol.hxx:115
NXWidgets::CWidgetControl::takeGeoSem
void takeGeoSem(void)
Definition: cwidgetcontrol.cxx:909
NXWidgets::CWidgetColors::selectedText
nxgl_mxpixel_t selectedText
Definition: cwidgetstyle.hxx:112
NXWidgets::INxWindow
Definition: inxwindow.hxx:83
NXWidgets::CWidgetControl::giveGeoSem
void giveGeoSem(void)
Definition: cwidgetcontrol.hxx:319
NXWidgets::CWidgetControl::clearMouseEvents
void clearMouseEvents(void)
Definition: cwidgetcontrol.cxx:944
NXWidgets::CWidgetControl::pollMouseEvents
bool pollMouseEvents(CNxWidget *widget)
Definition: cwidgetcontrol.cxx:792
NXWidgets::CWidgetControl::newMouseEvent
void newMouseEvent(FAR const struct nxgl_point_s *pos, uint8_t buttons)
Definition: cwidgetcontrol.cxx:452
NXWidgets::CWidgetControl::SXYInput::lastY
nxgl_coord_t lastY
Definition: cwidgetcontrol.hxx:162
NXWidgets::CWidgetControl::SXYInput
Definition: cwidgetcontrol.hxx:106
NXWidgets::CGraphicsPort
Definition: cgraphicsport.hxx:106
NXWidgets::CWidgetControl::SXYInput::doubleClick
uint16_t doubleClick
Definition: cwidgetcontrol.hxx:139
NXWidgets::CWidgetControl::removeControlledWidget
void removeControlledWidget(CNxWidget *widget)
Definition: cwidgetcontrol.cxx:285