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.
This commit is contained in:
Gregory Nutt 2019-05-08 15:28:06 -06:00
parent 9e1257deed
commit 944fd507fe
13 changed files with 331 additions and 131 deletions

View File

@ -737,9 +737,11 @@ uint32_t CWidgetControl::elapsedTime(FAR const struct timespec *startTime)
* @param x Click xcoordinate. * @param x Click xcoordinate.
* @param y Click ycoordinate. * @param y Click ycoordinate.
* @param widget Pointer to a specific widget or NULL. * @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? // 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)) 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 // 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 * @param widget. Specific widget to poll. Use NULL to run the
* all widgets in the window. * 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) bool CWidgetControl::pollMouseEvents(CNxWidget *widget)
{ {
#ifdef CONFIG_NX_XYINPUT #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) if (m_xyinput.leftPressed)
{ {
// Handle a new left button press event // 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 // 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_clickedWidget->drag(m_xyinput.x, m_xyinput.y,
m_xyinput.x - m_xyinput.lastX, m_xyinput.x - m_xyinput.lastX,
m_xyinput.y - m_xyinput.lastY); 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 // Mouse left button release event
m_clickedWidget->release(m_xyinput.x, m_xyinput.y); m_clickedWidget->release(m_xyinput.x, m_xyinput.y);
} mouseEvent = true;
else
{
// No interesting mouse events
mouseEvent = false;
} }
// Clear all press and release events once they have been processed // Clear all press and release events once they have been processed

View File

@ -54,5 +54,7 @@ STATUS
The Icon Manager window can be grabbed by the toolbar title and moved 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). 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 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.

View File

@ -40,6 +40,9 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <cfcntl>
#include <cerrno>
#include <nuttx/nx/nxglib.h> #include <nuttx/nx/nxglib.h>
#include "graphics/nxwidgets/cscaledbitmap.hxx" #include "graphics/nxwidgets/cscaledbitmap.hxx"
@ -52,6 +55,7 @@
#include "graphics/twm4nx/twm4nx_config.hxx" #include "graphics/twm4nx/twm4nx_config.hxx"
#include "graphics/twm4nx/cwindowevent.hxx" #include "graphics/twm4nx/cwindowevent.hxx"
#include "graphics/twm4nx/cicon.hxx" #include "graphics/twm4nx/cicon.hxx"
#include "graphics/twm4nx/cmainmenu.hxx"
#include "graphics/twm4nx/cbackground.hxx" #include "graphics/twm4nx/cbackground.hxx"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -69,6 +73,7 @@ using namespace Twm4Nx;
CBackground::CBackground(FAR CTwm4Nx *twm4nx) CBackground::CBackground(FAR CTwm4Nx *twm4nx)
{ {
m_twm4nx = twm4nx; // Save the session instance 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_backWindow = (NXWidgets::CBgWindow *)0; // No background window yet
m_backImage = (NXWidgets::CImage *)0; // No background image yet m_backImage = (NXWidgets::CImage *)0; // No background image yet
} }
@ -79,30 +84,9 @@ CBackground::CBackground(FAR CTwm4Nx *twm4nx)
CBackground::~CBackground(void) CBackground::~CBackground(void)
{ {
// Delete the background // Free resources helf by the background
if (m_backWindow != (NXWidgets::CBgWindow *)0) cleanup();
{
// 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;
}
} }
/** /**
@ -119,12 +103,25 @@ bool CBackground::
{ {
twminfo("Create the background window\n"); 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) // Create the background window (if we have not already done so)
if (m_backWindow == (NXWidgets::CBgWindow *)0 && if (m_backWindow == (NXWidgets::CBgWindow *)0 &&
!createBackgroundWindow()) !createBackgroundWindow())
{ {
twmerr("ERROR: Failed to create the background window\n"); twmerr("ERROR: Failed to create the background window\n");
cleanup();
return false; return false;
} }
@ -135,8 +132,7 @@ bool CBackground::
if (!createBackgroundImage(sbitmap)) if (!createBackgroundImage(sbitmap))
{ {
twmerr("ERROR: Failed to create the background image\n"); twmerr("ERROR: Failed to create the background image\n");
delete m_backWindow; cleanup();
m_backWindow = (NXWidgets::CBgWindow *)0;
return false; return false;
} }
@ -246,18 +242,60 @@ bool CBackground::event(FAR struct SEventMsg *eventmsg)
bool success = true; bool success = true;
switch (eventmsg->eventID) 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 = NXWidgets::CWidgetControl *control =
m_backWindow->getWidgetControl(); 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. // 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; break;
case EVENT_WINDOW_KBDINPUT: // Poll for icon keyboard events
break; // There aren't any
case EVENT_BACKGROUND_REDRAW: // Redraw the background case EVENT_BACKGROUND_REDRAW: // Redraw the background
{ {
FAR struct SRedrawEventMsg *redrawmsg = FAR struct SRedrawEventMsg *redrawmsg =
@ -417,3 +455,45 @@ bool CBackground::
m_backImage->redraw(); m_backImage->redraw();
return true; 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;
}
}

View File

@ -75,7 +75,7 @@ CMainMenu::CMainMenu(FAR CTwm4Nx *twm4nx)
* CMainMenu Destructor * CMainMenu Destructor
*/ */
CMainMenu:: ~CMainMenu(void) CMainMenu::~CMainMenu(void)
{ {
if (m_mainMenu != (FAR CMenus *)0) if (m_mainMenu != (FAR CMenus *)0)
{ {
@ -172,9 +172,24 @@ bool CMainMenu::event(FAR struct SEventMsg *eventmsg)
switch (eventmsg->eventID) 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 case EVENT_MAINMENU_SELECT: // Main menu selection
#warning Missing logic // Check if the main menu is already visible
success = false;
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: default:
success = false; success = false;

View File

@ -101,6 +101,7 @@ CMenus::CMenus(CTwm4Nx *twm4nx)
m_nMenuItems = 0; // No menu items yet m_nMenuItems = 0; // No menu items yet
m_menuDepth = 0; // No menus up m_menuDepth = 0; // No menus up
m_entryHeight = 0; // Menu entry height m_entryHeight = 0; // Menu entry height
m_visible = false; // Menu not visible
m_menuPull = false; // No pull right entry m_menuPull = false; // No pull right entry
// Windows // Windows
@ -123,7 +124,8 @@ CMenus::~CMenus(void)
/** /**
* CMenus Initializer. Performs the parts of the CMenus construction * 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 * @param name The name of the menu
* @result True is returned on success * @result True is returned on success

View File

@ -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 // Included Files
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -118,59 +150,6 @@ CWindowEvent::~CWindowEvent(void)
removeWindowEventHandler(this); 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 * 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 #endif
@ -320,9 +313,21 @@ void CWindowEvent::handleKeyboardEvent(void)
{ {
twminfo("Keyboard input...\n"); 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 #endif

View File

@ -254,7 +254,18 @@ bool CWindowFactory::event(FAR struct SEventMsg *eventmsg)
switch (eventmsg->eventID) 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 *nxmsg =
(FAR struct SNxEventMsg *)eventmsg; (FAR struct SNxEventMsg *)eventmsg;

View File

@ -253,9 +253,10 @@ namespace NXWidgets
* @param y Click ycoordinate. * @param y Click ycoordinate.
* @param widget. Specific widget to poll. Use NULL to run the * @param widget. Specific widget to poll. Use NULL to run the
* all widgets in the window. * 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. * Get the index of the specified controlled widget.

View File

@ -43,6 +43,8 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <mqueue.h>
#include "graphics/nxwidgets/nxconfig.hxx" #include "graphics/nxwidgets/nxconfig.hxx"
#include "graphics/nxwidgets/cnxwindow.hxx" #include "graphics/nxwidgets/cnxwindow.hxx"
#include "graphics/nxwidgets/cnxserver.hxx" #include "graphics/nxwidgets/cnxserver.hxx"
@ -75,6 +77,7 @@ namespace Twm4Nx
{ {
protected: protected:
FAR CTwm4Nx *m_twm4nx; /**< Cached CTwm4Nx instance */ 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::CBgWindow *m_backWindow; /**< The background window */
FAR NXWidgets::CImage *m_backImage; /**< The background image */ FAR NXWidgets::CImage *m_backImage; /**< The background image */
@ -102,6 +105,12 @@ namespace Twm4Nx
bool createBackgroundImage(FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap); bool createBackgroundImage(FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap);
/**
* Release resources held by the background.
*/
void cleanup(void);
public: public:
/** /**
* CBackground Constructor * CBackground Constructor

View File

@ -42,6 +42,10 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/input/mouse.h>
#include "graphics/twm4nx/ctwm4nxevent.hxx"
#include "graphics/twm4nx/cmenus.hxx"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Implementation Class Definition // Implementation Class Definition
@ -50,7 +54,6 @@
namespace Twm4Nx namespace Twm4Nx
{ {
class CTwm4Nx; // Forward Reference class CTwm4Nx; // Forward Reference
class CMenus; // Forward Reference
class IApplication; // Forward Reference class IApplication; // Forward Reference
struct SEventMsg; // Forward Reference struct SEventMsg; // Forward Reference
@ -134,6 +137,15 @@ namespace Twm4Nx
bool addApplication(FAR IApplication *app); 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. * Handle MAIN MENU events.
* *

View File

@ -123,6 +123,7 @@ namespace Twm4Nx
uint16_t m_nMenuItems; /**< Number of items in the menu */ uint16_t m_nMenuItems; /**< Number of items in the menu */
uint8_t m_menuDepth; /**< Number of menus up */ uint8_t m_menuDepth; /**< Number of menus up */
bool m_menuPull; /**< Is there a pull right entry? */ bool m_menuPull; /**< Is there a pull right entry? */
bool m_visible; /**< True: The menu is visible */
char m_info[INFO_LINES][INFO_SIZE]; char m_info[INFO_LINES][INFO_SIZE];
void identify(FAR CWindow *cwin); void identify(FAR CWindow *cwin);
@ -266,7 +267,8 @@ namespace Twm4Nx
/** /**
* CMenus Initializer. Performs the parts of the CMenus construction * 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 * @param name The menu name
* @result True is returned on success * @result True is returned on success
@ -287,6 +289,48 @@ namespace Twm4Nx
bool addMenuItem(FAR NXWidgets::CNxString &text, FAR CMenus *subMenu, bool addMenuItem(FAR NXWidgets::CNxString &text, FAR CMenus *subMenu,
FAR CTwm4NxEvent *handler, uint16_t event); 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. * Handle MENU events.
* *

View File

@ -149,12 +149,6 @@ namespace Twm4Nx
FAR IDragEvent *m_dragHandler; /**< Drag event handlers (may be NULL) */ FAR IDragEvent *m_dragHandler; /**< Drag event handlers (may be NULL) */
uintptr_t m_dragArg; /**< User argument associated with callback */ 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 /////////////////////// // Override CWidgetEventHandler virtual methods ///////////////////////
/** /**

View File

@ -110,8 +110,9 @@ namespace Twm4Nx
// Recipient == BACKGOUND // Recipient == BACKGOUND
EVENT_BACKGROUND_POLL = 0x1000, /**< Poll background icons for events */ EVENT_BACKGROUND_XYINPUT = 0x1000, /**< Poll window for widget mouse/touch events */
EVENT_BACKGROUND_REDRAW = 0x1001, /**< Redraw the background */ EVENT_BACKGROUND_KBDINPUT = 0x1001, /**< Poll window for widget keyboard events */
EVENT_BACKGROUND_REDRAW = 0x1002, /**< Redraw the background */
// Recipient == ICONWIDGET // Recipient == ICONWIDGET
@ -137,14 +138,15 @@ namespace Twm4Nx
// Recipient == WINDOW // Recipient == WINDOW
EVENT_WINDOW_POLL = 0x6000, /**< Poll window for widget events */ EVENT_WINDOW_XYINPUT = 0x6000, /**< Poll window for widget mouse/touch events */
EVENT_WINDOW_FOCUS = 0x6001, /**< Enter modal state */ EVENT_WINDOW_KBDINPUT = 0x6001, /**< Poll window for widget keyboard events */
EVENT_WINDOW_UNFOCUS = 0x6002, /**< Exit modal state */ EVENT_WINDOW_FOCUS = 0x6002, /**< Enter modal state */
EVENT_WINDOW_RAISE = 0x6003, /**< Raise window to the top of the heirarchy */ EVENT_WINDOW_UNFOCUS = 0x6003, /**< Exit modal state */
EVENT_WINDOW_LOWER = 0x6004, /**< Lower window to the bottom of the heirarchy */ EVENT_WINDOW_RAISE = 0x6004, /**< Raise window to the top of the heirarchy */
EVENT_WINDOW_DEICONIFY = 0x6005, /**< De-iconify and raise window */ EVENT_WINDOW_LOWER = 0x6005, /**< Lower window to the bottom of the heirarchy */
EVENT_WINDOW_DRAG = 0x6006, /**< Drag window */ EVENT_WINDOW_DEICONIFY = 0x6006, /**< De-iconify and raise window */
EVENT_WINDOW_DELETE = 0x6007, /**< Delete window */ EVENT_WINDOW_DRAG = 0x6007, /**< Drag window */
EVENT_WINDOW_DELETE = 0x6008, /**< Delete window */
// Recipient == TOOLBAR // 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 enum EButtonContext
{ {
EVENT_CONTEXT_WINDOW = 0, EVENT_CONTEXT_WINDOW = 0,
EVENT_CONTEXT_TOOLBAR, EVENT_CONTEXT_TOOLBAR,
EVENT_CONTEXT_BACKGROUND,
EVENT_CONTEXT_ICON, EVENT_CONTEXT_ICON,
EVENT_CONTEXT_FRAME, EVENT_CONTEXT_FRAME,
EVENT_CONTEXT_ICONMGR, EVENT_CONTEXT_ICONMGR,
@ -189,8 +193,8 @@ namespace Twm4Nx
}; };
/** /**
* This type represents a generic message containing all possible, * This type represents a generic messages, particularly button press
* message-specific options (wasteful, but a lot easier). * or released events.
*/ */
struct SEventMsg 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 struct SRedrawEventMsg
@ -214,8 +218,20 @@ namespace Twm4Nx
}; };
/** /**
* This is the alternative form of the message used on in * This message for is used with CWindowEVent mouse/keyboard input events
* CWindowEvent::event() */
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 struct SNxEventMsg