From c144919a4e760f299acc98e2a8883044ec0bcdd7 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 27 Apr 2019 09:35:05 -0600 Subject: [PATCH] apps/graphics/twm4nx: Finsh menu-related event handling. Extended menu handling. Allow external application event handling using a new base class (CTwm4NxEvent). --- graphics/twm4nx/src/ciconmgr.cxx | 55 +++++++- graphics/twm4nx/src/ciconwin.cxx | 1 + graphics/twm4nx/src/cmenus.cxx | 126 ++++++++++++++---- graphics/twm4nx/src/cresize.cxx | 4 +- graphics/twm4nx/src/ctwm4nx.cxx | 32 +++-- graphics/twm4nx/src/cwindow.cxx | 23 ++-- include/graphics/twm4nx/cbackground.hxx | 1 + include/graphics/twm4nx/ciconmgr.hxx | 10 +- include/graphics/twm4nx/ciconwin.hxx | 4 +- include/graphics/twm4nx/cmenus.hxx | 34 +++-- include/graphics/twm4nx/cresize.hxx | 8 +- include/graphics/twm4nx/ctwm4nxevent.hxx | 91 +++++++++++++ include/graphics/twm4nx/cwindow.hxx | 15 ++- include/graphics/twm4nx/cwindowfactory.hxx | 3 +- .../graphics/twm4nx/twm4nx_widgetevents.hxx | 17 ++- 15 files changed, 353 insertions(+), 71 deletions(-) create mode 100644 include/graphics/twm4nx/ctwm4nxevent.hxx diff --git a/graphics/twm4nx/src/ciconmgr.cxx b/graphics/twm4nx/src/ciconmgr.cxx index 661fa9cf3..da8a7845f 100644 --- a/graphics/twm4nx/src/ciconmgr.cxx +++ b/graphics/twm4nx/src/ciconmgr.cxx @@ -68,6 +68,8 @@ #include "graphics/twm4nx/cwindow.hxx" #include "graphics/twm4nx/cwindowevent.hxx" #include "graphics/twm4nx/cwindowfactory.hxx" +#include "graphics/twm4nx/ctwm4nxevent.hxx" +#include "graphics/twm4nx/twm4nx_widgetevents.hxx" #include "graphics/twm4nx/ciconmgr.hxx" ///////////////////////////////////////////////////////////////////////////// @@ -86,6 +88,7 @@ using namespace Twm4Nx; CIconMgr::CIconMgr(CTwm4Nx *twm4nx, uint8_t ncolumns) { m_twm4nx = twm4nx; // Cached the Twm4Nx session + m_eventq = (mqd_t)-1; // No widget message queue yet m_head = (FAR struct SWindowEntry *)0; // Head of the winow list m_tail = (FAR struct SWindowEntry *)0; // Tail of the winow list m_active = (FAR struct SWindowEntry *)0; // No active window @@ -102,6 +105,14 @@ CIconMgr::CIconMgr(CTwm4Nx *twm4nx, uint8_t ncolumns) CIconMgr::~CIconMgr(void) { + // Close the NxWidget event message queue + + if (m_eventq != (mqd_t)-1) + { + (void)mq_close(m_eventq); + m_eventq = (mqd_t)-1; + } + // Free the icon manager window if (m_window != (FAR CWindow *)0) @@ -125,6 +136,17 @@ CIconMgr::~CIconMgr(void) bool CIconMgr::initialize(FAR const char *prefix) { + // Open a message queue to NX events. + + FAR const char *mqname = m_twm4nx->getEventQueueName(); + m_eventq = mq_open(mqname, O_WRONLY | O_NONBLOCK); + if (m_eventq == (mqd_t)-1) + { + gerr("ERROR: Failed open message queue '%s': %d\n", + mqname, errno); + return false; + } + // Create the icon manager window if (!createWindow(prefix)) @@ -530,7 +552,6 @@ bool CIconMgr::createButtonArray(void) if (!m_window->getWindowSize(&windowSize)) { gerr("ERROR: Failed to get window size\n"); - delete control; return false; } @@ -733,24 +754,52 @@ void CIconMgr::handleActionEvent(const NXWidgets::CWidgetEventArgs &e) if (string.compareTo(swin->cwin->getWindowName()) == 0) { + // Got it... send an event message + + struct SEventMsg msg; + msg.pos.x = e.getX(); + msg.pos.y = e.getY(); + msg.delta.x = 0; + msg.delta.y = 0; + msg.context = EVENT_CONTEXT_ICONMGR; + msg.handler = (FAR CTwm4NxEvent *)0; + msg.obj = (FAR void *)swin->cwin; + // Got it. Is the window Iconified? if (swin->cwin->isIconified()) { // Yes, de-Iconify it - swin->cwin->deIconify(); + msg.eventID = EVENT_WINDOW_DEICONIFY; } else { // Otherwise, raise the window to the top of the heirarchy - swin->cwin->raiseWindow(); + msg.eventID = EVENT_WINDOW_RAISE; + } + + // NOTE that we cannot block because we are on the same thread + // as the message reader. If the event queue becomes full + // then we have no other option but to lose events. + // + // I suppose we could recurse raise() or de-Iconifiy directly + // here at the risk of runaway stack usage (we are already deep + // in the stack here). + + int ret = mq_send(m_eventq, (FAR const char *)&msg, + sizeof(struct SEventMsg), 100); + if (ret < 0) + { + gerr("ERROR: mq_send failed: %d\n", ret); } break; } } + + gwarn("WARNING: No matching window name\n"); } } diff --git a/graphics/twm4nx/src/ciconwin.cxx b/graphics/twm4nx/src/ciconwin.cxx index 4bdaef963..4b0fc2633 100644 --- a/graphics/twm4nx/src/ciconwin.cxx +++ b/graphics/twm4nx/src/ciconwin.cxx @@ -57,6 +57,7 @@ #include "graphics/twm4nx/cwindowevent.hxx" #include "graphics/twm4nx/cicon.hxx" #include "graphics/twm4nx/ciconwin.hxx" +#include "graphics/twm4nx/ctwm4nxevent.hxx" #include "graphics/twm4nx/twm4nx_widgetevents.hxx" #include "graphics/twm4nx/twm4nx_cursor.hxx" diff --git a/graphics/twm4nx/src/cmenus.cxx b/graphics/twm4nx/src/cmenus.cxx index 495c94ec7..f0209dad6 100644 --- a/graphics/twm4nx/src/cmenus.cxx +++ b/graphics/twm4nx/src/cmenus.cxx @@ -58,6 +58,7 @@ #include "graphics/nxwidgets/cnxfont.hxx" #include "graphics/nxwidgets/clistbox.hxx" +#include "graphics/nxwidgets/cwidgeteventargs.hxx" #include "graphics/twm4nx/ctwm4nx.hxx" #include "graphics/twm4nx/cmenus.hxx" @@ -68,6 +69,7 @@ #include "graphics/twm4nx/cwindow.hxx" #include "graphics/twm4nx/cwindowfactory.hxx" #include "graphics/twm4nx/cwindowevent.hxx" +#include "graphics/twm4nx/ctwm4nxevent.hxx" #include "graphics/twm4nx/twm4nx_widgetevents.hxx" #include "graphics/twm4nx/cmenus.hxx" @@ -86,6 +88,7 @@ CMenus::CMenus(CTwm4Nx *twm4nx) // Save the Twm4Nx session m_twm4nx = twm4nx; // Save the Twm4Nx session + m_eventq = (mqd_t)-1; // No widget message queue yet // Menus @@ -103,10 +106,6 @@ CMenus::CMenus(CTwm4Nx *twm4nx) // Widgets m_menuListBox = (FAR NXWidgets::CListBox *)0; //The menu list box - - // Functions - - m_funcKeyHead = (FAR struct SFuncKey *)0; } /** @@ -135,6 +134,7 @@ bool CMenus::initialize(FAR const char *name) { gerr("ERROR: Failed open message queue '%s': %d\n", mqname, errno); + return false; } // Save the menu name @@ -169,20 +169,18 @@ bool CMenus::initialize(FAR const char *name) /** * Add an item to a menu * - * \param text The text to appear in the menu - * \param action The string to possibly execute - * \param subMenu The menu if it is a pull-right entry - * \param func The numeric function + * \param text The text to appear in the menu + * \param subMenu The menu if it is a pull-right entry + * \param handler The application event handler. Should be null unless + * the event recipient is EVENT_RECIPIENT_APP + * \param event The event to generate on menu item selection */ -// REVISIT: Only used internally. Was used in .twmrc parsing. - -bool CMenus::addMenuItem(FAR const char *text, - FAR const char *action, FAR CMenus *subMenu, - int func) +bool CMenus::addMenuItem(FAR const char *text, FAR CMenus *subMenu, + FAR CTwm4NxEvent *handler, uint16_t event) { - ginfo("Adding menu text=\"%s\", action=%s, subMenu=%d, f=%d\n", - text, action, subMenu, func); + ginfo("Adding menu text=\"%s\", subMenu=%p, event=%04x\n", + text, subMenu, event); // Allocate a new menu item entry @@ -206,10 +204,10 @@ bool CMenus::addMenuItem(FAR const char *text, // Save information about the menu item - item->action = action; item->flink = NULL; item->subMenu = NULL; - item->func = func; + item->handler = handler; + item->event = event; CFonts *fonts = m_twm4nx->getFonts(); FAR NXWidgets::CNxFont *menuFont = fonts->getMenuFont(); @@ -266,6 +264,7 @@ bool CMenus::addMenuItem(FAR const char *text, // Redraw the list box + m_menuListBox->enable(); m_menuListBox->enableDrawing(); m_menuListBox->setRaisesEvents(true); m_menuListBox->redraw(); @@ -320,12 +319,13 @@ bool CMenus::event(FAR struct SEventMsg *eventmsg) // Send another event message to the session manager struct SEventMsg newmsg; - newmsg.eventID = item->func; + newmsg.eventID = item->event; newmsg.pos.x = eventmsg->pos.x; newmsg.pos.y = eventmsg->pos.y; newmsg.delta.x = 0; newmsg.delta.y = 0; newmsg.context = eventmsg->context; + newmsg.handler = item->handler; newmsg.obj = eventmsg->obj; // NOTE that we cannot block because we are on the same thread @@ -333,7 +333,7 @@ bool CMenus::event(FAR struct SEventMsg *eventmsg) // we have no other option but to lose events. // // I suppose we could recurse and call Twm4Nx::dispatchEvent at - // the risk of runawy stack usage. + // the risk of runaway stack usage. int ret = mq_send(m_eventq, (FAR const char *)&newmsg, sizeof(struct SEventMsg), 100); @@ -629,7 +629,7 @@ bool CMenus::setMenuWindowPosition(FAR struct nxgl_point_s *framePos) bool CMenus::createMenuListBox(void) { // Get the Widget control instance from the menu window. This - // will force all widget drawing to go to the Icon Manager window. + // will force all widget drawing to go to the Menu window. FAR NXWidgets:: CWidgetControl *control = m_menuWindow->getWidgetControl(); if (control == (FAR NXWidgets:: CWidgetControl *)0) @@ -657,11 +657,19 @@ bool CMenus::createMenuListBox(void) return false; } + // Get the menu font + + FAR CFonts *cfont = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *menuFont = cfont->getMenuFont(); + // Configure the list box m_menuListBox->disable(); m_menuListBox->disableDrawing(); - m_menuListBox->disableDrawing(); + m_menuListBox->setRaisesEvents(false); + m_menuListBox->setAllowMultipleSelections(false); + m_menuListBox->setFont(menuFont); + m_menuListBox->setBorderless(false); // Register to get events from the mouse clicks on the image @@ -702,8 +710,8 @@ bool CMenus::popUpMenu(FAR struct nxgl_point_s *pos) return false; } - m_popUpMenu->addMenuItem("TWM Windows", (FAR const char *)0, - (FAR CMenus *)0, 0); + m_popUpMenu->addMenuItem("TWM Windows", (FAR CMenus *)0, + (FAR CTwm4NxEvent *)0, EVENT_SYSTEM_NOP); FAR CWindowFactory *factory = m_twm4nx->getWindowFactory(); int nWindowNames; @@ -754,8 +762,8 @@ bool CMenus::popUpMenu(FAR struct nxgl_point_s *pos) for (int i = 0; i < nWindowNames; i++) { m_popUpMenu->addMenuItem(windowNames[i]->getWindowName(), - (FAR const char *)0, (FAR CMenus *)0, - EVENT_WINDOW_POPUP); + (FAR CMenus *)0, (FAR CTwm4NxEvent *)0, + EVENT_WINDOW_DEICONIFY); } std::free(windowNames); @@ -814,6 +822,74 @@ bool CMenus::popUpMenu(FAR struct nxgl_point_s *pos) return m_popUpMenu; } +/** + * Override the virtual value change event. This will get events + * when there is a change in the list box selection. + * + * @param e The event data. + */ + +void CMenus::handleValueChangeEvent(const NXWidgets::CWidgetEventArgs &e) +{ + // Check if anything is selected + + int menuSelection = m_menuListBox->getSelectedIndex(); + if (menuSelection >= 0) + { + // Yes.. Get the selection menu item list box entry + + FAR const NXWidgets::CListBoxDataItem *option = + m_menuListBox->getSelectedOption(); + + // Get the menu item string + + FAR const NXWidgets::CNxString itemText = option->getText(); + + // Now find the window with this name + + for (FAR struct SMenuItem *item = m_menuHead; + item != (FAR struct SMenuItem *)0; + item = item->flink) + { + // Check if the menu item string matches the listbox selection + // string + + if (itemText.compareTo(item->text) == 0) + { + // Generate the menu event + + struct SEventMsg msg; + msg.eventID = item->event; + msg.pos.x = e.getX(); + msg.pos.y = e.getY(); + msg.delta.x = 0; + msg.delta.y = 0; + msg.context = EVENT_CONTEXT_TOOLBAR; + msg.handler = item->handler; + msg.obj = (FAR void *)this; + + // NOTE that we cannot block because we are on the same thread + // as the message reader. If the event queue becomes full then + // we have no other option but to lose events. + // + // I suppose we could recurse and call Twm4Nx::dispatchEvent at + // the risk of runaway stack usage. + + int ret = mq_send(m_eventq, (FAR const char *)&msg, + sizeof(struct SEventMsg), 100); + if (ret < 0) + { + gerr("ERROR: mq_send failed: %d\n", ret); + } + + break; + } + } + + gwarn("WARNING: No matching menu item\n"); + } +} + /** * Cleanup or initialization error or on deconstruction. */ diff --git a/graphics/twm4nx/src/cresize.cxx b/graphics/twm4nx/src/cresize.cxx index 6745bfbf7..9d1824391 100644 --- a/graphics/twm4nx/src/cresize.cxx +++ b/graphics/twm4nx/src/cresize.cxx @@ -51,11 +51,13 @@ #include "graphics/twm4nx/twm4nx_config.hxx" #include "graphics/twm4nx/ctwm4nx.hxx" #include "graphics/twm4nx/cmenus.hxx" -#include "graphics/twm4nx/cresize.hxx" #include "graphics/twm4nx/ciconmgr.hxx" #include "graphics/twm4nx/cwindowevent.hxx" #include "graphics/twm4nx/cfonts.hxx" #include "graphics/twm4nx/cwindow.hxx" +#include "graphics/twm4nx/ctwm4nxevent.hxx" +#include "graphics/twm4nx/twm4nx_widgetevents.hxx" +#include "graphics/twm4nx/cresize.hxx" ///////////////////////////////////////////////////////////////////////////// // Pre-processor Definitions diff --git a/graphics/twm4nx/src/ctwm4nx.cxx b/graphics/twm4nx/src/ctwm4nx.cxx index 18e008254..7f330ff0b 100644 --- a/graphics/twm4nx/src/ctwm4nx.cxx +++ b/graphics/twm4nx/src/ctwm4nx.cxx @@ -383,16 +383,19 @@ bool CTwm4Nx::systemEvent(FAR struct SEventMsg *eventmsg) { switch (eventmsg->eventID) { - case EVENT_SYSTEM_ERROR: // Report system error - // REVISIT: An audible tone should be generated - break; + case EVENT_SYSTEM_NOP: // Null event + break; - case EVENT_SYSTEM_EXIT: // Terminate the Twm4Nx session - abort(); - break; // Does not return + case EVENT_SYSTEM_ERROR: // Report system error + // REVISIT: An audible tone should be generated + break; - default: - return false; + case EVENT_SYSTEM_EXIT: // Terminate the Twm4Nx session + abort(); + break; // Does not return + + default: + return false; } return true; @@ -448,10 +451,21 @@ bool CTwm4Nx::dispatchEvent(FAR struct SEventMsg *eventmsg) ret = m_factory->event(eventmsg); break; - case EVENT_RECIPIENT_RESIZE: // Windw resize event + case EVENT_RECIPIENT_RESIZE: // Wind0w resize event ret = m_resize->event(eventmsg); break; + case EVENT_RECIPIENT_APP: // Application menu event + { + // Application events are unique in that they do not have any + // fixed, a priori endpoint. Rather, the endpoint must be + // provided in the 'handler' field of the message + + DEBUGASSERT(eventmsg->handler != (FAR CTwm4NxEvent *)0); + ret = eventmsg->handler->event(eventmsg); + } + break; + case EVENT_RECIPIENT_MASK: // Used to isolate recipient default: break; diff --git a/graphics/twm4nx/src/cwindow.cxx b/graphics/twm4nx/src/cwindow.cxx index 74bc6d2a3..fc60700ec 100644 --- a/graphics/twm4nx/src/cwindow.cxx +++ b/graphics/twm4nx/src/cwindow.cxx @@ -76,6 +76,7 @@ #include "graphics/twm4nx/cwindowevent.hxx" #include "graphics/twm4nx/cwindow.hxx" #include "graphics/twm4nx/cwindowfactory.hxx" +#include "graphics/twm4nx/ctwm4nxevent.hxx" #include "graphics/twm4nx/twm4nx_widgetevents.hxx" #include "graphics/twm4nx/twm4nx_cursor.hxx" @@ -496,15 +497,15 @@ bool CWindow::event(FAR struct SEventMsg *eventmsg) switch (eventmsg->eventID) { - case EVENT_WINDOW_RAISE: // Raise window to the top of the heirarchy - m_nxWin->raise(); // Could be the main or the icon window + case EVENT_WINDOW_RAISE: // Raise window to the top of the heirarchy + m_nxWin->raise(); // Could be the main or the icon window break; - case EVENT_WINDOW_LOWER: // Lower window to the bottom of the heirarchy - m_nxWin->lower(); // Could be the main or the icon window + case EVENT_WINDOW_LOWER: // Lower window to the bottom of the heirarchy + m_nxWin->lower(); // Could be the main or the icon window break; - case EVENT_WINDOW_POPUP: // De-iconify and raise the main window + case EVENT_WINDOW_DEICONIFY: // De-iconify and raise the main window { deIconify(); } @@ -1028,6 +1029,7 @@ void CWindow::handleUngrabEvent(const NXWidgets::CWidgetEventArgs &e) msg.delta.x = 0; msg.delta.y = 0; msg.context = EVENT_CONTEXT_TOOLBAR; + msg.handler = (FAR CTwm4NxEvent *)0; msg.obj = (FAR void *)this; // NOTE that we cannot block because we are on the same thread @@ -1035,7 +1037,7 @@ void CWindow::handleUngrabEvent(const NXWidgets::CWidgetEventArgs &e) // we have no other option but to lose events. // // I suppose we could recurse and call Twm4Nx::dispatchEvent at - // the risk of runawy stack usage. + // the risk of runaway stack usage. int ret = mq_send(m_eventq, (FAR const char *)&msg, sizeof(struct SEventMsg), 100); @@ -1067,6 +1069,7 @@ void CWindow::handleDragEvent(const NXWidgets::CWidgetEventArgs &e) msg.delta.x = e.getVX(); msg.delta.y = e.getVY(); msg.context = EVENT_CONTEXT_TOOLBAR; + msg.handler = (FAR CTwm4NxEvent *)0; msg.obj = (FAR void *)this; // NOTE that we cannot block because we are on the same thread @@ -1074,7 +1077,7 @@ void CWindow::handleDragEvent(const NXWidgets::CWidgetEventArgs &e) // we have no other option but to lose events. // // I suppose we could recurse and call Twm4Nx::dispatchEvent at - // the risk of runawy stack usage. + // the risk of runaway stack usage. int ret = mq_send(m_eventq, (FAR const char *)&msg, sizeof(struct SEventMsg), 100); @@ -1130,6 +1133,7 @@ void CWindow::handleKeyPressEvent(const NXWidgets::CWidgetEventArgs &e) msg.delta.x = 0; msg.delta.y = 0; msg.context = EVENT_CONTEXT_TOOLBAR; + msg.handler = (FAR CTwm4NxEvent *)0; msg.obj = (FAR void *)this; // NOTE that we cannot block because we are on the same thread @@ -1137,7 +1141,7 @@ void CWindow::handleKeyPressEvent(const NXWidgets::CWidgetEventArgs &e) // we have no other option but to lose events. // // I suppose we could recurse and call Twm4Nx::dispatchEvent at - // the risk of runawy stack usage. + // the risk of runaway stack usage. int ret = mq_send(m_eventq, (FAR const char *)&msg, sizeof(struct SEventMsg), 100); @@ -1198,6 +1202,7 @@ void CWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e) msg.delta.x = 0; msg.delta.y = 0; msg.context = EVENT_CONTEXT_TOOLBAR; + msg.handler = (FAR CTwm4NxEvent *)0; msg.obj = (FAR void *)this; // NOTE that we cannot block because we are on the same thread @@ -1205,7 +1210,7 @@ void CWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e) // we have no other option but to lose events. // // I suppose we could recurse and call Twm4Nx::dispatchEvent at - // the risk of runawy stack usage. + // the risk of runaway stack usage. int ret = mq_send(m_eventq, (FAR const char *)&msg, sizeof(struct SEventMsg), 100); diff --git a/include/graphics/twm4nx/cbackground.hxx b/include/graphics/twm4nx/cbackground.hxx index 5f60090b7..b2f69acba 100644 --- a/include/graphics/twm4nx/cbackground.hxx +++ b/include/graphics/twm4nx/cbackground.hxx @@ -67,6 +67,7 @@ namespace NXWidgets namespace Twm4Nx { class CTwm4Nx; // Forward reference + /** * Background management */ diff --git a/include/graphics/twm4nx/ciconmgr.hxx b/include/graphics/twm4nx/ciconmgr.hxx index 56f6f88af..1385b364b 100644 --- a/include/graphics/twm4nx/ciconmgr.hxx +++ b/include/graphics/twm4nx/ciconmgr.hxx @@ -47,8 +47,12 @@ // Included Files ///////////////////////////////////////////////////////////////////////////// +#include +#include + #include #include "graphics/twm4nx/cwindow.hxx" +#include "graphics/twm4nx/ctwm4nxevent.hxx" ///////////////////////////////////////////////////////////////////////////// // Implementation Classes @@ -58,6 +62,7 @@ namespace NXWidgets { class CNxTkWindow; // Forward reference class CButtonArray; // Forward reference + class CWidgetEventHandler; // Forward reference class CWidgetEventArgs; // Forward reference struct SRlePaletteBitmap; // Forward reference } @@ -68,7 +73,7 @@ namespace Twm4Nx { FAR struct SWindowEntry *flink; FAR struct SWindowEntry *blink; - FAR CWindow *cwin; // Used only for the window name + FAR CWindow *cwin; FAR CIconMgr *iconmgr; nxgl_point_s pos; nxgl_size_s size; @@ -78,11 +83,12 @@ namespace Twm4Nx bool down; }; - class CIconMgr : protected NXWidgets::CWidgetEventHandler + class CIconMgr : protected NXWidgets::CWidgetEventHandler, public CTwm4NxEvent { private: FAR CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */ + mqd_t m_eventq; /**< NxWidget event message queue */ FAR struct SWindowEntry *m_head; /**< Head of the window list */ FAR struct SWindowEntry *m_tail; /**< Tail of the window list */ FAR struct SWindowEntry *m_active; /**< The active entry */ diff --git a/include/graphics/twm4nx/ciconwin.hxx b/include/graphics/twm4nx/ciconwin.hxx index 4b949909e..5d3afa73c 100644 --- a/include/graphics/twm4nx/ciconwin.hxx +++ b/include/graphics/twm4nx/ciconwin.hxx @@ -51,6 +51,8 @@ #include "graphics/nxwidgets/cnxwindow.hxx" +#include "graphics/twm4nx/ctwm4nxevent.hxx" + ///////////////////////////////////////////////////////////////////////////// // Implementation Classes ///////////////////////////////////////////////////////////////////////////// @@ -69,7 +71,7 @@ namespace Twm4Nx * The CIconWin represents on icon window */ - class CIconWin + class CIconWin : public CTwm4NxEvent { private: diff --git a/include/graphics/twm4nx/cmenus.hxx b/include/graphics/twm4nx/cmenus.hxx index f790b8590..ba3952038 100644 --- a/include/graphics/twm4nx/cmenus.hxx +++ b/include/graphics/twm4nx/cmenus.hxx @@ -48,11 +48,13 @@ // Included Files ///////////////////////////////////////////////////////////////////////////// -#include "mqueue.h" +#include #include "graphics/nxwidgets/cwidgeteventhandler.hxx" #include "graphics/nxwidgets/cwidgeteventargs.hxx" +#include "graphics/twm4nx/ctwm4nxevent.hxx" + ///////////////////////////////////////////////////////////////////////////// // Pre-processor Definitions ///////////////////////////////////////////////////////////////////////////// @@ -83,6 +85,8 @@ namespace NXWidgets { class CNxTkWindow; // Forward reference class CListBox; // Forward reference + class CWidgetEventArgs; // Forward reference + class CWidgetEventArgs; // Forward reference } namespace Twm4Nx @@ -97,18 +101,17 @@ namespace Twm4Nx FAR struct SMenuItem *blink; /**< Backward link previous menu item */ FAR CMenus *subMenu; /**< Menu root of a pull right menu */ FAR char *text; /**< The text string for the menu item */ - FAR const char *action; /**< Action to be performed */ - short index; /**< Index of this menu item */ - short func; /**< Built-in function */ + FAR CTwm4NxEvent *handler; /**< Application event handler */ + uint16_t index; /**< Index of this menu item */ + uint16_t event; /**< Menu selection event */ }; - class CMenus: protected NXWidgets::CWidgetEventHandler + class CMenus : protected NXWidgets::CWidgetEventHandler, public CTwm4NxEvent { private: CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */ mqd_t m_eventq; /**< NxWidget event message queue */ - FAR struct SFuncKey *m_funcKeyHead; /**< Head of function key list */ FAR NXWidgets::CNxTkWindow *m_menuWindow; /**< The menu window */ FAR CMenus *m_popUpMenu; /**< Pop-up menu */ FAR NXWidgets::CListBox *m_menuListBox; /**< The menu list box */ @@ -230,6 +233,15 @@ namespace Twm4Nx bool popUpMenu(FAR struct nxgl_point_s *pos); + /** + * Override the virtual value change event. This will get events + * when there is a change in the list box selection. + * + * @param e The event data. + */ + + void handleValueChangeEvent(const NXWidgets::CWidgetEventArgs &e); + /** * Cleanup or initialization error or on deconstruction. */ @@ -265,14 +277,14 @@ namespace Twm4Nx * Add an item to a root menu * * \param text The text to appear in the menu - * \param action The string to possibly execute * \param subMenu The menu root if it is a pull-right entry - * \param func The numeric function + * \param handler The application event handler. Should be NULL unless + * the event recipient is EVENT_RECIPIENT_APP + * \param event The event to generate on menu item selection */ - bool addMenuItem(FAR const char *text, - FAR const char *action, - FAR CMenus *subMenu, int func); + bool addMenuItem(FAR const char *text, FAR CMenus *subMenu, + FAR CTwm4NxEvent *handler, uint16_t event); /** * Handle MENU events. diff --git a/include/graphics/twm4nx/cresize.hxx b/include/graphics/twm4nx/cresize.hxx index 139a60a9d..1ad9b8886 100644 --- a/include/graphics/twm4nx/cresize.hxx +++ b/include/graphics/twm4nx/cresize.hxx @@ -52,6 +52,8 @@ #include +#include "graphics/twm4nx/ctwm4nxevent.hxx" + ///////////////////////////////////////////////////////////////////////////// // Implementation Classes ///////////////////////////////////////////////////////////////////////////// @@ -63,10 +65,10 @@ namespace NXWidgets namespace Twm4Nx { - class CWindow; // Forward referernce - struct SEventMsg; // Forward referernce + class CWindow; // Forward reference + struct SEventMsg; // Forward reference - class CResize + class CResize : protected NXWidgets::CWidgetEventHandler, public CTwm4NxEvent { private: diff --git a/include/graphics/twm4nx/ctwm4nxevent.hxx b/include/graphics/twm4nx/ctwm4nxevent.hxx new file mode 100644 index 000000000..e172db822 --- /dev/null +++ b/include/graphics/twm4nx/ctwm4nxevent.hxx @@ -0,0 +1,91 @@ +///////////////////////////////////////////////////////////////////////////// +// apps/graphics/twm4nx/include/ctwmnxevent.hxx +// Twm4Nx Event handler base class +// +// Copyright (C) 2019 Gregory Nutt. All rights reserved. +// Author: Gregory Nutt +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// 3. Neither the name NuttX nor the names of its contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef __APPS_INCLUDE_GRAPHICS_TWM4NX_CTWM4NXEVNT_HXX +#define __APPS_INCLUDE_GRAPHICS_TWM4NX_CTWM4NXEVNT_HXX + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Implementation Class Definition + ****************************************************************************/ + +namespace Twm4Nx +{ + /** + * Twm4Nx Event Handler base class + */ + + class CTwm4NxEvent + { + public: + + /** + * A virtual destructor is required in order to override the INxWindow + * destructor. We do this because if we delete INxWindow, we want the + * destructor of the class that inherits from INxWindow to run, not this + * one. + */ + + virtual ~CTwm4NxEvent(void) + { + } + + /** + * Handle Twm4Nx events. + * + * @param eventmsg. The received NxWidget WINDOW event message. + * @return True if the message was properly handled. false is + * return on any failure. + */ + + virtual bool event(FAR struct SEventMsg *eventmsg) + { + return false; + } + }; +} + +#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CTWM4NXEVNT_HXX diff --git a/include/graphics/twm4nx/cwindow.hxx b/include/graphics/twm4nx/cwindow.hxx index e009ce4ad..f3eb1e095 100644 --- a/include/graphics/twm4nx/cwindow.hxx +++ b/include/graphics/twm4nx/cwindow.hxx @@ -57,6 +57,7 @@ #include "graphics/nxwidgets/cwidgeteventargs.hxx" #include "graphics/twm4nx/ciconwin.hxx" +#include "graphics/twm4nx/ctwm4nxevent.hxx" ///////////////////////////////////////////////////////////////////////////// // Pre-processor Definitions @@ -102,7 +103,7 @@ namespace Twm4Nx // The CWindow class implements a standard, framed window with a toolbar // containing the standard buttons and the window title. - class CWindow : protected NXWidgets::CWidgetEventHandler + class CWindow : protected NXWidgets::CWidgetEventHandler, public CTwm4NxEvent { private: CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */ @@ -330,6 +331,16 @@ namespace Twm4Nx FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap, bool isIconMgr, FAR CIconMgr *iconMgr, bool noToolbar); + /** + * Get the widget control instance needed to support application drawing + * into the window. + */ + + inline FAR NXWidgets::CWidgetControl *getWidgetControl() + { + return m_nxWin->getWidgetControl(); + } + /** * Get the name of the window */ @@ -612,7 +623,7 @@ namespace Twm4Nx } /** - * Handle WINDOW events. + * Handle Twm4Nx events. * * @param eventmsg. The received NxWidget WINDOW event message. * @return True if the message was properly handled. false is diff --git a/include/graphics/twm4nx/cwindowfactory.hxx b/include/graphics/twm4nx/cwindowfactory.hxx index 6c18ef232..28bd773fc 100644 --- a/include/graphics/twm4nx/cwindowfactory.hxx +++ b/include/graphics/twm4nx/cwindowfactory.hxx @@ -52,6 +52,7 @@ #include #include "graphics/twm4nx/cwindow.hxx" +#include "graphics/twm4nx/ctwm4nxevent.hxx" ///////////////////////////////////////////////////////////////////////////// // Implementation Classes @@ -85,7 +86,7 @@ namespace Twm4Nx * things that are common to all windows. */ - class CWindowFactory + class CWindowFactory: public CTwm4NxEvent { private: diff --git a/include/graphics/twm4nx/twm4nx_widgetevents.hxx b/include/graphics/twm4nx/twm4nx_widgetevents.hxx index c21e4002d..a42da8310 100644 --- a/include/graphics/twm4nx/twm4nx_widgetevents.hxx +++ b/include/graphics/twm4nx/twm4nx_widgetevents.hxx @@ -68,6 +68,7 @@ namespace Twm4Nx { class CWindow; // Forward reference class CWindowEvent; // Forward reference + class CTwm4NxEvent; // Forward reference class CTwm4Nx; // Forward reference /////////////////////////////////////////////////////////////////////////// @@ -89,6 +90,7 @@ namespace Twm4Nx EVENT_RECIPIENT_TOOLBAR = 0x6000, /**< Toolbar related event */ EVENT_RECIPIENT_BORDER = 0x7000, /**< Window border related event */ EVENT_RECIPIENT_RESIZE = 0x8000, /**< Window resize event */ + EVENT_RECIPIENT_APP = 0x9000, /**< App received event via CTwn4NxEvent */ EVENT_RECIPIENT_MASK = 0xf000, /**< Used to isolate recipient */ }; @@ -104,8 +106,9 @@ namespace Twm4Nx // Recipient == SYSTEM - EVENT_SYSTEM_ERROR = 0x1000, /**< Report system error */ - EVENT_SYSTEM_EXIT = 0x1001, /**< Terminate the Twm4Nx session */ + EVENT_SYSTEM_NOP = 0x1000, /**< Null event */ + EVENT_SYSTEM_ERROR = 0x1001, /**< Report system error */ + EVENT_SYSTEM_EXIT = 0x1002, /**< Terminate the Twm4Nx session */ // Recipient == ICONWIN @@ -131,8 +134,8 @@ namespace Twm4Nx EVENT_WINDOW_UNFOCUS = 0x5001, /**< Exit modal state */ EVENT_WINDOW_RAISE = 0x5002, /**< Raise window to the top of the heirarchy */ EVENT_WINDOW_LOWER = 0x5003, /**< Lower window to the bottom of the heirarchy */ - EVENT_WINDOW_DRAG = 0x5004, /**< Drag window */ - EVENT_WINDOW_POPUP = 0x5005, /**< De-iconify and raise window */ + EVENT_WINDOW_DEICONIFY = 0x5004, /**< De-iconify and raise window */ + EVENT_WINDOW_DRAG = 0x5005, /**< Drag window */ EVENT_WINDOW_DELETE = 0x5006, /**< Delete window */ // Recipient == TOOLBAR @@ -156,6 +159,11 @@ namespace Twm4Nx EVENT_RESIZE_RIGHTZOOM = 0x8005, /**< Zoom right only */ EVENT_RESIZE_TOPZOOM = 0x8006, /**< Zoom top only */ EVENT_RESIZE_BOTTOMZOOM = 0x8007, /**< Zoom bottom only */ + + // Recipient == ICONWIN + // All application defined events must (1) use recepient == EVENT_RECIPIENT_APP, + // and (2) provide an instance of CTwm4NxEvent in the SEventMsg structure. + }; // Contexts for button press events @@ -183,6 +191,7 @@ namespace Twm4Nx struct nxgl_point_s pos; /**< X/Y position */ struct nxgl_point_s delta; /**< X/Y change (for dragging only) */ uint8_t context; /**< Button press context */ + FAR CTwm4NxEvent *handler; /**< App event handler (APP recipient only) */ FAR void *obj; /**< Window object (CWindow or CIconWin) */ };