From 944fd507fe9bac69a3d1a7cebf817899cece3ebc Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 8 May 2019 15:28:06 -0600 Subject: [PATCH] With these changes, the main menu appears when any location on the background no occupied by an icon is clicked. apps/graphics/nxwidgets: CWidgetControl::handleLeftClick now returns a value to indicate if the click was actually processed or not. CWidgetControl::pollMouseEvents: Correct return value. apps/graphics/twm4nx: CBackground::event(): Implement logic to handle a left click on the background and to bring up the main Menu. CWindowEvent: Extend message to distinguish between keyboard and mouse input. Mouse position and buttons now accompany the mouse input data. CMenus: Add methods to query and control the visibility of the menu. --- graphics/nxwidgets/src/cwidgetcontrol.cxx | 39 +++-- graphics/twm4nx/README.txt | 4 +- graphics/twm4nx/src/cbackground.cxx | 136 ++++++++++++++---- graphics/twm4nx/src/cmainmenu.cxx | 21 ++- graphics/twm4nx/src/cmenus.cxx | 4 +- graphics/twm4nx/src/cwindowevent.cxx | 119 +++++++-------- graphics/twm4nx/src/cwindowfactory.cxx | 13 +- include/graphics/nxwidgets/cwidgetcontrol.hxx | 3 +- include/graphics/twm4nx/cbackground.hxx | 9 ++ include/graphics/twm4nx/cmainmenu.hxx | 14 +- include/graphics/twm4nx/cmenus.hxx | 46 +++++- include/graphics/twm4nx/cwindowevent.hxx | 6 - .../graphics/twm4nx/twm4nx_widgetevents.hxx | 48 ++++--- 13 files changed, 331 insertions(+), 131 deletions(-) diff --git a/graphics/nxwidgets/src/cwidgetcontrol.cxx b/graphics/nxwidgets/src/cwidgetcontrol.cxx index cdace6b62..b7d0251e6 100644 --- a/graphics/nxwidgets/src/cwidgetcontrol.cxx +++ b/graphics/nxwidgets/src/cwidgetcontrol.cxx @@ -737,9 +737,11 @@ uint32_t CWidgetControl::elapsedTime(FAR const struct timespec *startTime) * @param x Click xcoordinate. * @param y Click ycoordinate. * @param widget Pointer to a specific widget or NULL. + * @return True if is a widget responds to the left click */ -void CWidgetControl::handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, CNxWidget *widget) +bool CWidgetControl::handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, + CNxWidget *widget) { // Working with a specific widget or the whole structure? @@ -751,7 +753,7 @@ void CWidgetControl::handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, CNxWidget * { if (m_widgets[i]->click(x, y)) { - return; + return true; } } } @@ -759,8 +761,10 @@ void CWidgetControl::handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, CNxWidget * { // One widget - (void)widget->click(x, y); + return widget->click(x, y); } + + return false; } /** @@ -784,23 +788,29 @@ void CWidgetControl::processDeleteQueue(void) * * @param widget. Specific widget to poll. Use NULL to run the * all widgets in the window. - * @return True means a mouse event occurred + * @return True means an interesting mouse event occurred */ bool CWidgetControl::pollMouseEvents(CNxWidget *widget) { #ifdef CONFIG_NX_XYINPUT - bool mouseEvent = true; // Assume that an interesting mouse event occurred + bool mouseEvent = false; // Assume that no interesting mouse event occurred - // All widgets + // Left click event for all widgets if (m_xyinput.leftPressed) { // Handle a new left button press event - handleLeftClick(m_xyinput.x, m_xyinput.y, widget); + if (handleLeftClick(m_xyinput.x, m_xyinput.y, widget)) + { + mouseEvent = true; + } } - else if (m_xyinput.leftDrag) + + // Drag event for the clicked widget + + if (!mouseEvent && m_xyinput.leftDrag) { // The left button is still being held down @@ -811,19 +821,18 @@ bool CWidgetControl::pollMouseEvents(CNxWidget *widget) m_clickedWidget->drag(m_xyinput.x, m_xyinput.y, m_xyinput.x - m_xyinput.lastX, m_xyinput.y - m_xyinput.lastY); + mouseEvent = true; } } - else if (m_clickedWidget != (CNxWidget *)NULL) + + // Check for release event on the clicked widget + + if (!mouseEvent && m_clickedWidget != (CNxWidget *)NULL) { // Mouse left button release event m_clickedWidget->release(m_xyinput.x, m_xyinput.y); - } - else - { - // No interesting mouse events - - mouseEvent = false; + mouseEvent = true; } // Clear all press and release events once they have been processed diff --git a/graphics/twm4nx/README.txt b/graphics/twm4nx/README.txt index 6ae329c11..ed2bf7f83 100644 --- a/graphics/twm4nx/README.txt +++ b/graphics/twm4nx/README.txt @@ -54,5 +54,7 @@ STATUS The Icon Manager window can be grabbed by the toolbar title and moved about on the window (the icon grab'n'move does not work however). Further progress depends upon getting a main menu in place. The main - menu should come up on any click on a visible region of the background. + menu does now come up on any click on a visible region of the + background, but the menu is not complete enough to be usable; it needs + some applications to start and a CTextBox widget. diff --git a/graphics/twm4nx/src/cbackground.cxx b/graphics/twm4nx/src/cbackground.cxx index 3953db16d..689be6d11 100644 --- a/graphics/twm4nx/src/cbackground.cxx +++ b/graphics/twm4nx/src/cbackground.cxx @@ -40,6 +40,9 @@ #include +#include +#include + #include #include "graphics/nxwidgets/cscaledbitmap.hxx" @@ -52,6 +55,7 @@ #include "graphics/twm4nx/twm4nx_config.hxx" #include "graphics/twm4nx/cwindowevent.hxx" #include "graphics/twm4nx/cicon.hxx" +#include "graphics/twm4nx/cmainmenu.hxx" #include "graphics/twm4nx/cbackground.hxx" ///////////////////////////////////////////////////////////////////////////// @@ -69,6 +73,7 @@ using namespace Twm4Nx; CBackground::CBackground(FAR CTwm4Nx *twm4nx) { m_twm4nx = twm4nx; // Save the session instance + m_eventq = (mqd_t)-1; // No NxWidget event message queue yet m_backWindow = (NXWidgets::CBgWindow *)0; // No background window yet m_backImage = (NXWidgets::CImage *)0; // No background image yet } @@ -79,30 +84,9 @@ CBackground::CBackground(FAR CTwm4Nx *twm4nx) CBackground::~CBackground(void) { - // Delete the background + // Free resources helf by the background - if (m_backWindow != (NXWidgets::CBgWindow *)0) - { - // Delete the contained widget control. We are responsible for it - // because we created it - - NXWidgets::CWidgetControl *control = m_backWindow->getWidgetControl(); - if (control != (NXWidgets::CWidgetControl *)0) - { - delete control; - } - - // Then delete the background - - delete m_backWindow; - } - - // Delete the background image - - if (m_backImage != (NXWidgets::CImage *)0) - { - delete m_backImage; - } + cleanup(); } /** @@ -119,12 +103,25 @@ bool CBackground:: { twminfo("Create the background window\n"); + // Open a message queue to send fully digested NxWidget events. + + FAR const char *mqname = m_twm4nx->getEventQueueName(); + + m_eventq = mq_open(mqname, O_WRONLY | O_NONBLOCK); + if (m_eventq == (mqd_t)-1) + { + twmerr("ERROR: Failed open message queue '%s': %d\n", + mqname, errno); + return false; + } + // Create the background window (if we have not already done so) if (m_backWindow == (NXWidgets::CBgWindow *)0 && !createBackgroundWindow()) { twmerr("ERROR: Failed to create the background window\n"); + cleanup(); return false; } @@ -135,8 +132,7 @@ bool CBackground:: if (!createBackgroundImage(sbitmap)) { twmerr("ERROR: Failed to create the background image\n"); - delete m_backWindow; - m_backWindow = (NXWidgets::CBgWindow *)0; + cleanup(); return false; } @@ -246,18 +242,60 @@ bool CBackground::event(FAR struct SEventMsg *eventmsg) bool success = true; switch (eventmsg->eventID) { - case EVENT_BACKGROUND_POLL: // Poll for icon events + case EVENT_BACKGROUND_XYINPUT: // Poll for icon mouse/touch events { + // This event message is sent from CWindowEvent whenever mouse, + // touchscreen, or keyboard entry events are received in the + // background window. + NXWidgets::CWidgetControl *control = m_backWindow->getWidgetControl(); - // pollEvents() returns true if any interesting event occurred. + // pollEvents() returns true if any interesting event occurred + // within a widget that is associated with the background window. // false is not a failure. - (void)control->pollEvents(); + if (!control->pollEvents()) + { + // If there is no interesting widget event, then this might be + // a background click. In that case, we should bring up the + // main menu (if it is not already up). + + // Is the main menu already up? Was the mouse left button + // pressed? + + FAR struct SXyInputEventMsg *xymsg = + (FAR struct SXyInputEventMsg *)eventmsg; + + FAR CMainMenu *cmain = m_twm4nx->getMainMenu(); + if (!cmain->isVisible() && + (xymsg->buttons & MOUSE_BUTTON_1) != 0) + { + // Bring up the main menu + + struct SEventMsg outmsg; + outmsg.eventID = EVENT_MAINMENU_SELECT; + outmsg.pos.x = eventmsg->pos.x; + outmsg.pos.y = eventmsg->pos.y; + outmsg.context = EVENT_CONTEXT_BACKGROUND; + outmsg.handler = (FAR CTwm4NxEvent *)0; + outmsg.obj = (FAR void *)this; + + int ret = mq_send(m_eventq, (FAR const char *)&outmsg, + sizeof(struct SEventMsg), 100); + if (ret < 0) + { + twmerr("ERROR: mq_send failed: %d\n", ret); + } + } + + } } break; + case EVENT_WINDOW_KBDINPUT: // Poll for icon keyboard events + break; // There aren't any + case EVENT_BACKGROUND_REDRAW: // Redraw the background { FAR struct SRedrawEventMsg *redrawmsg = @@ -417,3 +455,45 @@ bool CBackground:: m_backImage->redraw(); return true; } + +/** + * Release resources held by the background. + */ + +void CBackground::cleanup(void) +{ + // Close the NxWidget event message queue + + if (m_eventq != (mqd_t)-1) + { + (void)mq_close(m_eventq); + m_eventq = (mqd_t)-1; + } + + // Delete the background + + if (m_backWindow != (NXWidgets::CBgWindow *)0) + { + // Delete the contained widget control. We are responsible for it + // because we created it + + NXWidgets::CWidgetControl *control = m_backWindow->getWidgetControl(); + if (control != (NXWidgets::CWidgetControl *)0) + { + delete control; + } + + // Then delete the background + + delete m_backWindow; + m_backWindow = (NXWidgets::CBgWindow *)0; + } + + // Delete the background image + + if (m_backImage != (NXWidgets::CImage *)0) + { + delete m_backImage; + m_backImage = (NXWidgets::CImage *)0; + } +} diff --git a/graphics/twm4nx/src/cmainmenu.cxx b/graphics/twm4nx/src/cmainmenu.cxx index bc4311b8e..43cb5328a 100644 --- a/graphics/twm4nx/src/cmainmenu.cxx +++ b/graphics/twm4nx/src/cmainmenu.cxx @@ -75,7 +75,7 @@ CMainMenu::CMainMenu(FAR CTwm4Nx *twm4nx) * CMainMenu Destructor */ -CMainMenu:: ~CMainMenu(void) +CMainMenu::~CMainMenu(void) { if (m_mainMenu != (FAR CMenus *)0) { @@ -172,9 +172,24 @@ bool CMainMenu::event(FAR struct SEventMsg *eventmsg) switch (eventmsg->eventID) { + // This event is sent from CBackground when a left mouse click + // is received in the background window (and not on an icon) + case EVENT_MAINMENU_SELECT: // Main menu selection -#warning Missing logic - success = false; + // Check if the main menu is already visible + + if (!m_mainMenu->isVisible()) + { + // No.. then make it visible now + + // REVISIT: Need to reset the menu to its initial state + // REVISIT: Need to position the main menu as close as + // possible to the click position in eventmsg. + + m_mainMenu->show(); // Make the main menu visible + } + + break; default: success = false; diff --git a/graphics/twm4nx/src/cmenus.cxx b/graphics/twm4nx/src/cmenus.cxx index 76da383ef..ea8d77cf8 100644 --- a/graphics/twm4nx/src/cmenus.cxx +++ b/graphics/twm4nx/src/cmenus.cxx @@ -101,6 +101,7 @@ CMenus::CMenus(CTwm4Nx *twm4nx) m_nMenuItems = 0; // No menu items yet m_menuDepth = 0; // No menus up m_entryHeight = 0; // Menu entry height + m_visible = false; // Menu not visible m_menuPull = false; // No pull right entry // Windows @@ -123,7 +124,8 @@ CMenus::~CMenus(void) /** * CMenus Initializer. Performs the parts of the CMenus construction - * that may fail. + * that may fail. The menu window is created but is not initially + * visible. Use the show() method to make the menu visible. * * @param name The name of the menu * @result True is returned on success diff --git a/graphics/twm4nx/src/cwindowevent.cxx b/graphics/twm4nx/src/cwindowevent.cxx index 19cc4a941..092ec5390 100644 --- a/graphics/twm4nx/src/cwindowevent.cxx +++ b/graphics/twm4nx/src/cwindowevent.cxx @@ -33,6 +33,38 @@ // ///////////////////////////////////////////////////////////////////////////// +// The logic path for mouse/touchscreen input is tortuous but flexible: +// +// 1. A listener thread receives mouse or touchscreen input and injects +// that into NX via nx_mousein +// 2. In the multi-user mode, this will send a message to the NX server +// 3. The NX server will determine which window gets the mouse input +// and send a window event message to the NX listener thread. +// 4. The NX listener thread receives a windows event. The NX listener thread +// is part of CTwm4Nx and was created when NX server connection was +// established. This event may be a positional change notification, a +// redraw request, or mouse or keyboard input. In this case, mouse input. +// 5. The NX listener thread handles the message by calling nx_eventhandler(). +// nx_eventhandler() dispatches the message by calling a method in the +// NXWidgets::CCallback instance associated with the window. +// NXWidgets::CCallback is a part of the CWidgetControl. +// 6. NXWidgets::CCallback calls into NXWidgets::CWidgetControl to process +// the event. +// 7. NXWidgets::CWidgetControl records the new state data and raises a +// window event. +// 8. NXWidgets::CWindowEventHandlerList will give the event to this method +// NxWM::CWindowEvent. +// 9. This NxWM::CWindowEvent method will send a message to the Event +// loop running in the Twm4Nx main thread. +// 10. The Twm4Nx main thread will call the CWindowEvent::event() method +// which +// 11. Finally call pollEvents() to execute whatever actions the input event +// should trigger. +// 12. This might call an event handler in and overrident method of +// CWidgetEventHandler which will again notify the Event loop running +// in the Twm4Nx main thread. The event will, finally be delivered +// to the recipient in its fully digested and decorated form. + ///////////////////////////////////////////////////////////////////////////// // Included Files ///////////////////////////////////////////////////////////////////////////// @@ -118,59 +150,6 @@ CWindowEvent::~CWindowEvent(void) removeWindowEventHandler(this); } -/** - * Send the EVENT_MSG_POLL input event message to the Twm4Nx event loop. - */ - -void CWindowEvent::sendInputEvent(void) -{ - twminfo("Input...\n"); - - // The logic path here is tortuous but flexible: - // - // 1. A listener thread receives mouse or touchscreen input and injects - // that into NX via nx_mousein - // 2. In the multi-user mode, this will send a message to the NX server - // 3. The NX server will determine which window gets the mouse input - // and send a window event message to the NX listener thread. - // 4. The NX listener thread receives a windows event. The NX listener thread - // is part of CTwm4Nx and was created when NX server connection was - // established. This event may be a positional change notification, a - // redraw request, or mouse or keyboard input. In this case, mouse input. - // 5. The NX listener thread handles the message by calling nx_eventhandler(). - // nx_eventhandler() dispatches the message by calling a method in the - // NXWidgets::CCallback instance associated with the window. - // NXWidgets::CCallback is a part of the CWidgetControl. - // 6. NXWidgets::CCallback calls into NXWidgets::CWidgetControl to process - // the event. - // 7. NXWidgets::CWidgetControl records the new state data and raises a - // window event. - // 8. NXWidgets::CWindowEventHandlerList will give the event to this method - // NxWM::CWindowEvent. - // 9. This NxWM::CWindowEvent method will send a message to the Event - // loop running in the Twm4Nx main thread. - // 10. The Twm4Nx main thread will call the CWindowEvent::event() method - // which - // 11. Finally call pollEvents() to execute whatever actions the input event - // should trigger. - // 12. This might call an event handler in and overrident method of - // CWidgetEventHandler which will again notify the Event loop running - // in the Twm4Nx main thread. The event will, finally be delivered - // to the recipient in its fully digested and decorated form. - - struct SNxEventMsg msg; - msg.eventID = m_isBackground ? EVENT_BACKGROUND_POLL : EVENT_WINDOW_POLL; - msg.instance = this; - msg.obj = m_object; - - int ret = mq_send(m_eventq, (FAR const char *)&msg, - sizeof(struct SNxEventMsg), 100); - if (ret < 0) - { - twmerr("ERROR: mq_send failed: %d\n", ret); - } -} - /** * Handle a NX window redraw request event * @@ -305,9 +284,23 @@ void CWindowEvent::handleMouseEvent(FAR const struct nxgl_point_s *pos, } } - // Stimulate an input poll + // Stimulate an XY input poll - sendInputEvent(); + twminfo("Mouse Input...\n"); + + struct SXyInputEventMsg msg; + msg.eventID = m_isBackground ? EVENT_BACKGROUND_XYINPUT : EVENT_WINDOW_XYINPUT; + msg.pos.x = pos->x; + msg.pos.y = pos->y; + msg.buttons = buttons; + msg.obj = m_object; + + int ret = mq_send(m_eventq, (FAR const char *)&msg, + sizeof(struct SXyInputEventMsg), 100); + if (ret < 0) + { + twmerr("ERROR: mq_send failed: %d\n", ret); + } } #endif @@ -320,9 +313,21 @@ void CWindowEvent::handleKeyboardEvent(void) { twminfo("Keyboard input...\n"); - // Stimulate an input poll + // Stimulate an keyboard event widget poll - sendInputEvent(); + twminfo("Keyboard Input...\n"); + + struct SNxEventMsg msg; + msg.eventID = m_isBackground ? EVENT_BACKGROUND_KBDINPUT : EVENT_WINDOW_KBDINPUT; + msg.instance = this; + msg.obj = m_object; + + int ret = mq_send(m_eventq, (FAR const char *)&msg, + sizeof(struct SNxEventMsg), 100); + if (ret < 0) + { + twmerr("ERROR: mq_send failed: %d\n", ret); + } } #endif diff --git a/graphics/twm4nx/src/cwindowfactory.cxx b/graphics/twm4nx/src/cwindowfactory.cxx index 09692e3d2..0c8659c68 100644 --- a/graphics/twm4nx/src/cwindowfactory.cxx +++ b/graphics/twm4nx/src/cwindowfactory.cxx @@ -254,7 +254,18 @@ bool CWindowFactory::event(FAR struct SEventMsg *eventmsg) switch (eventmsg->eventID) { - case EVENT_WINDOW_POLL: // Poll for icon events + case EVENT_WINDOW_XYINPUT: // Poll for toolbar mouse/touch events + { + FAR struct SXyInputEventMsg *nxmsg = + (FAR struct SXyInputEventMsg *)eventmsg; + FAR CWindow *cwin = (FAR CWindow *)nxmsg->obj; + DEBUGASSERT(cwin != (FAR CWindow *)0); + + success = cwin->pollToolbarEvents(); + } + break; + + case EVENT_WINDOW_KBDINPUT: // Poll for toolbar keyboard events { FAR struct SNxEventMsg *nxmsg = (FAR struct SNxEventMsg *)eventmsg; diff --git a/include/graphics/nxwidgets/cwidgetcontrol.hxx b/include/graphics/nxwidgets/cwidgetcontrol.hxx index 8753a4782..e0068d991 100644 --- a/include/graphics/nxwidgets/cwidgetcontrol.hxx +++ b/include/graphics/nxwidgets/cwidgetcontrol.hxx @@ -253,9 +253,10 @@ namespace NXWidgets * @param y Click ycoordinate. * @param widget. Specific widget to poll. Use NULL to run the * all widgets in the window. + * @return True means an interesting mouse event occurred */ - void handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, CNxWidget *widget); + bool handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, CNxWidget *widget); /** * Get the index of the specified controlled widget. diff --git a/include/graphics/twm4nx/cbackground.hxx b/include/graphics/twm4nx/cbackground.hxx index 76321f4b0..f3ca40db5 100644 --- a/include/graphics/twm4nx/cbackground.hxx +++ b/include/graphics/twm4nx/cbackground.hxx @@ -43,6 +43,8 @@ #include +#include + #include "graphics/nxwidgets/nxconfig.hxx" #include "graphics/nxwidgets/cnxwindow.hxx" #include "graphics/nxwidgets/cnxserver.hxx" @@ -75,6 +77,7 @@ namespace Twm4Nx { protected: FAR CTwm4Nx *m_twm4nx; /**< Cached CTwm4Nx instance */ + mqd_t m_eventq; /**< NxWidget event message queue */ FAR NXWidgets::CBgWindow *m_backWindow; /**< The background window */ FAR NXWidgets::CImage *m_backImage; /**< The background image */ @@ -102,6 +105,12 @@ namespace Twm4Nx bool createBackgroundImage(FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap); + /** + * Release resources held by the background. + */ + + void cleanup(void); + public: /** * CBackground Constructor diff --git a/include/graphics/twm4nx/cmainmenu.hxx b/include/graphics/twm4nx/cmainmenu.hxx index 1d153e6b9..190d97aff 100644 --- a/include/graphics/twm4nx/cmainmenu.hxx +++ b/include/graphics/twm4nx/cmainmenu.hxx @@ -42,6 +42,10 @@ ///////////////////////////////////////////////////////////////////////////// #include +#include + +#include "graphics/twm4nx/ctwm4nxevent.hxx" +#include "graphics/twm4nx/cmenus.hxx" ///////////////////////////////////////////////////////////////////////////// // Implementation Class Definition @@ -50,7 +54,6 @@ namespace Twm4Nx { class CTwm4Nx; // Forward Reference - class CMenus; // Forward Reference class IApplication; // Forward Reference struct SEventMsg; // Forward Reference @@ -134,6 +137,15 @@ namespace Twm4Nx bool addApplication(FAR IApplication *app); + /** + * Return true if the main menu is currently being displayed + */ + + inline bool isVisible(void) + { + return m_mainMenu->isVisible(); + } + /** * Handle MAIN MENU events. * diff --git a/include/graphics/twm4nx/cmenus.hxx b/include/graphics/twm4nx/cmenus.hxx index e378917aa..3ae7bb0db 100644 --- a/include/graphics/twm4nx/cmenus.hxx +++ b/include/graphics/twm4nx/cmenus.hxx @@ -123,6 +123,7 @@ namespace Twm4Nx uint16_t m_nMenuItems; /**< Number of items in the menu */ uint8_t m_menuDepth; /**< Number of menus up */ bool m_menuPull; /**< Is there a pull right entry? */ + bool m_visible; /**< True: The menu is visible */ char m_info[INFO_LINES][INFO_SIZE]; void identify(FAR CWindow *cwin); @@ -266,7 +267,8 @@ namespace Twm4Nx /** * CMenus Initializer. Performs the parts of the CMenus construction - * that may fail. + * that may fail. The menu window is created but is not initially + * visible. Use the show() method to make the menu visible. * * @param name The menu name * @result True is returned on success @@ -287,6 +289,48 @@ namespace Twm4Nx bool addMenuItem(FAR NXWidgets::CNxString &text, FAR CMenus *subMenu, FAR CTwm4NxEvent *handler, uint16_t event); + /** + * Return true if the main menu is currently being displayed + */ + + + inline bool isVisible(void) + { + return m_visible; + } + + /** + * Make the menu visible. + * + * @return True if the main menu is shown. + */ + + inline bool show(void) + { + if (!m_visible) + { + m_visible = m_menuWindow->show(); + } + + return m_visible; + } + + /** + * Hide the menu + * + * @return True if the menu was hidden. + */ + + inline bool hide(void) + { + if (m_visible) + { + m_visible = !m_menuWindow->hide(); + } + + return !m_visible; + } + /** * Handle MENU events. * diff --git a/include/graphics/twm4nx/cwindowevent.hxx b/include/graphics/twm4nx/cwindowevent.hxx index d3a673eef..516fd5196 100644 --- a/include/graphics/twm4nx/cwindowevent.hxx +++ b/include/graphics/twm4nx/cwindowevent.hxx @@ -149,12 +149,6 @@ namespace Twm4Nx FAR IDragEvent *m_dragHandler; /**< Drag event handlers (may be NULL) */ uintptr_t m_dragArg; /**< User argument associated with callback */ - /** - * Send the EVENT_MSG_POLL input event message to the Twm4Nx event loop. - */ - - void sendInputEvent(void); - // Override CWidgetEventHandler virtual methods /////////////////////// /** diff --git a/include/graphics/twm4nx/twm4nx_widgetevents.hxx b/include/graphics/twm4nx/twm4nx_widgetevents.hxx index f5cba5aed..1b67d7c78 100644 --- a/include/graphics/twm4nx/twm4nx_widgetevents.hxx +++ b/include/graphics/twm4nx/twm4nx_widgetevents.hxx @@ -110,8 +110,9 @@ namespace Twm4Nx // Recipient == BACKGOUND - EVENT_BACKGROUND_POLL = 0x1000, /**< Poll background icons for events */ - EVENT_BACKGROUND_REDRAW = 0x1001, /**< Redraw the background */ + EVENT_BACKGROUND_XYINPUT = 0x1000, /**< Poll window for widget mouse/touch events */ + EVENT_BACKGROUND_KBDINPUT = 0x1001, /**< Poll window for widget keyboard events */ + EVENT_BACKGROUND_REDRAW = 0x1002, /**< Redraw the background */ // Recipient == ICONWIDGET @@ -137,14 +138,15 @@ namespace Twm4Nx // Recipient == WINDOW - EVENT_WINDOW_POLL = 0x6000, /**< Poll window for widget events */ - EVENT_WINDOW_FOCUS = 0x6001, /**< Enter modal state */ - EVENT_WINDOW_UNFOCUS = 0x6002, /**< Exit modal state */ - EVENT_WINDOW_RAISE = 0x6003, /**< Raise window to the top of the heirarchy */ - EVENT_WINDOW_LOWER = 0x6004, /**< Lower window to the bottom of the heirarchy */ - EVENT_WINDOW_DEICONIFY = 0x6005, /**< De-iconify and raise window */ - EVENT_WINDOW_DRAG = 0x6006, /**< Drag window */ - EVENT_WINDOW_DELETE = 0x6007, /**< Delete window */ + EVENT_WINDOW_XYINPUT = 0x6000, /**< Poll window for widget mouse/touch events */ + EVENT_WINDOW_KBDINPUT = 0x6001, /**< Poll window for widget keyboard events */ + EVENT_WINDOW_FOCUS = 0x6002, /**< Enter modal state */ + EVENT_WINDOW_UNFOCUS = 0x6003, /**< Exit modal state */ + EVENT_WINDOW_RAISE = 0x6004, /**< Raise window to the top of the heirarchy */ + EVENT_WINDOW_LOWER = 0x6005, /**< Lower window to the bottom of the heirarchy */ + EVENT_WINDOW_DEICONIFY = 0x6006, /**< De-iconify and raise window */ + EVENT_WINDOW_DRAG = 0x6007, /**< Drag window */ + EVENT_WINDOW_DELETE = 0x6008, /**< Delete window */ // Recipient == TOOLBAR @@ -174,12 +176,14 @@ namespace Twm4Nx }; - // Contexts for button press events + // Contexts for button press events. These basically identify the sender + // of the event message. enum EButtonContext { EVENT_CONTEXT_WINDOW = 0, EVENT_CONTEXT_TOOLBAR, + EVENT_CONTEXT_BACKGROUND, EVENT_CONTEXT_ICON, EVENT_CONTEXT_FRAME, EVENT_CONTEXT_ICONMGR, @@ -189,8 +193,8 @@ namespace Twm4Nx }; /** - * This type represents a generic message containing all possible, - * message-specific options (wasteful, but a lot easier). + * This type represents a generic messages, particularly button press + * or released events. */ struct SEventMsg @@ -203,7 +207,7 @@ namespace Twm4Nx }; /** - * This is the alternative form of the message used with redraw commands + * This message form is used with CWindowEvent redraw commands */ struct SRedrawEventMsg @@ -214,8 +218,20 @@ namespace Twm4Nx }; /** - * This is the alternative form of the message used on in - * CWindowEvent::event() + * This message for is used with CWindowEVent mouse/keyboard input events + */ + + struct SXyInputEventMsg + { + uint16_t eventID; /**< Encoded event ID */ + struct nxgl_point_s pos; /**< X/Y position */ + uint8_t buttons; /**< Bit set of button presses */ + FAR void *obj; /**< Context specific reference */ + }; + + /** + * This is the alternative form of the message used by + * CWindowEvent for blocked and keyboard input messages */ struct SNxEventMsg