apps/graphics/twm4nx: Modify how applications register with the main menu. Add logic to support all possible menu selection notification methods: But putting up a subment, by starting an application, or be sending an event.

This commit is contained in:
Gregory Nutt 2019-05-11 13:17:19 -06:00
parent 2b2e17d126
commit c6802efc38
14 changed files with 399 additions and 252 deletions

View File

@ -314,7 +314,7 @@ bool CBackground::event(FAR struct SEventMsg *eventmsg)
outmsg.pos.x = eventmsg->pos.x; outmsg.pos.x = eventmsg->pos.x;
outmsg.pos.y = eventmsg->pos.y; outmsg.pos.y = eventmsg->pos.y;
outmsg.context = EVENT_CONTEXT_BACKGROUND; outmsg.context = EVENT_CONTEXT_BACKGROUND;
outmsg.handler = (FAR CTwm4NxEvent *)0; outmsg.handler = (FAR void *)0;
outmsg.obj = (FAR void *)this; outmsg.obj = (FAR void *)this;
int ret = mq_send(m_eventq, (FAR const char *)&outmsg, int ret = mq_send(m_eventq, (FAR const char *)&outmsg,

View File

@ -936,11 +936,11 @@ void CIconMgr::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
// Got it... send an event message // Got it... send an event message
struct SEventMsg msg; struct SEventMsg msg;
msg.obj = (FAR void *)this;
msg.pos.x = e.getX(); msg.pos.x = e.getX();
msg.pos.y = e.getY(); msg.pos.y = e.getY();
msg.context = EVENT_CONTEXT_ICONMGR; msg.context = EVENT_CONTEXT_ICONMGR;
msg.handler = (FAR CTwm4NxEvent *)0; msg.handler = (FAR void *)0;
msg.obj = (FAR void *)swin->cwin;
// Got it. Is the window Iconified? // Got it. Is the window Iconified?

View File

@ -460,11 +460,11 @@ void CIconWidget::handleUngrabEvent(const NXWidgets::CWidgetEventArgs &e)
struct SEventMsg msg; struct SEventMsg msg;
msg.eventID = EVENT_ICONWIDGET_UNGRAB; msg.eventID = EVENT_ICONWIDGET_UNGRAB;
msg.obj = (FAR void *)this;
msg.pos.x = e.getX(); msg.pos.x = e.getX();
msg.pos.y = e.getY(); msg.pos.y = e.getY();
msg.context = EVENT_CONTEXT_ICON; msg.context = EVENT_CONTEXT_ICON;
msg.handler = (FAR CTwm4NxEvent *)0; msg.handler = (FAR void *)0;
msg.obj = (FAR void *)this;
// NOTE that we cannot block because we are on the same thread // NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then // as the message reader. If the event queue becomes full then
@ -498,11 +498,11 @@ void CIconWidget::handleDragEvent(const NXWidgets::CWidgetEventArgs &e)
struct SEventMsg msg; struct SEventMsg msg;
msg.eventID = EVENT_ICONWIDGET_DRAG; msg.eventID = EVENT_ICONWIDGET_DRAG;
msg.obj = (FAR void *)this;
msg.pos.x = e.getX(); msg.pos.x = e.getX();
msg.pos.y = e.getY(); msg.pos.y = e.getY();
msg.context = EVENT_CONTEXT_ICON; msg.context = EVENT_CONTEXT_ICON;
msg.handler = (FAR CTwm4NxEvent *)0; msg.handler = (FAR void *)0;
msg.obj = (FAR void *)this;
// NOTE that we cannot block because we are on the same thread // NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then // as the message reader. If the event queue becomes full then
@ -557,11 +557,11 @@ void CIconWidget::handleClickEvent(const NXWidgets::CWidgetEventArgs &e)
struct SEventMsg msg; struct SEventMsg msg;
msg.eventID = EVENT_ICONWIDGET_GRAB; msg.eventID = EVENT_ICONWIDGET_GRAB;
msg.obj = (FAR void *)this;
msg.pos.x = e.getX(); msg.pos.x = e.getX();
msg.pos.y = e.getY(); msg.pos.y = e.getY();
msg.context = EVENT_CONTEXT_ICON; msg.context = EVENT_CONTEXT_ICON;
msg.handler = (FAR CTwm4NxEvent *)0; msg.handler = (FAR void *)0;
msg.obj = (FAR void *)this;
// NOTE that we cannot block because we are on the same thread // NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then // as the message reader. If the event queue becomes full then

View File

@ -142,10 +142,7 @@ bool CMainMenu::addApplication(FAR IApplication *app)
// Add the new menu item to the main menu // Add the new menu item to the main menu
FAR NXWidgets::CNxString appName = app->getName(); if (!m_mainMenu->addMenuItem(app))
if (!m_mainMenu->addMenuItem(appName, app->getSubMenu(),
app->getEventHandler(), app->getEvent()))
{ {
twmerr("ERROR: addMenuItem failed\n"); twmerr("ERROR: addMenuItem failed\n");
std::free(mmitem); std::free(mmitem);

View File

@ -185,38 +185,31 @@ bool CMenus::initialize(FAR NXWidgets::CNxString &name)
/** /**
* Add an item to a menu * Add an item to a menu
* *
* \param text The text to appear in the menu * @param item Describes the menu item entry
* \param subMenu The menu if it is a pull-right entry * @return True if the menu item was added successfully
* \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 CMenus::addMenuItem(FAR NXWidgets::CNxString &text, FAR CMenus *subMenu, bool CMenus::addMenuItem(FAR IApplication *item)
FAR CTwm4NxEvent *handler, uint16_t event)
{ {
twminfo("Adding: subMenu=%p, event=%04x\n", subMenu, event); twminfo("Adding: subMenu=%p, event=%04x\n", subMenu, event);
// Allocate a new menu item entry // Allocate a new menu item entry
FAR struct SMenuItem *item = new SMenuItem; FAR struct SMenuItem *newitem = new SMenuItem;
if (newitem == (FAR struct SMenuItem *)0)
if (item == (FAR struct SMenuItem *)0)
{ {
twmerr("ERROR: Failed to allocate menu item\n"); twmerr("ERROR: Failed to allocate menu item\n");
return false; return false;
} }
// Clone the item name so that we have control over its lifespan
item->text = text;
// Save information about the menu item // Save information about the menu item
item->flink = NULL; newitem->flink = NULL;
item->subMenu = subMenu; newitem->text = item->getName();
item->handler = handler; newitem->subMenu = item->getSubMenu();
item->event = event; newitem->start = item->getStartFunction();
newitem->handler = item->getEventHandler();
newitem->event = item->getEvent();
// Increment the total number of menu items // Increment the total number of menu items
@ -226,17 +219,17 @@ bool CMenus::addMenuItem(FAR NXWidgets::CNxString &text, FAR CMenus *subMenu,
if (m_menuHead == NULL) if (m_menuHead == NULL)
{ {
m_menuHead = item; m_menuHead = newitem;
item->blink = (FAR struct SMenuItem *)0; newitem->blink = (FAR struct SMenuItem *)0;
} }
else else
{ {
m_menuTail->flink = item; m_menuTail->flink = newitem;
item->blink = m_menuTail; newitem->blink = m_menuTail;
} }
m_menuTail = item; m_menuTail = newitem;
item->flink = (FAR struct SMenuItem *)0; newitem->flink = (FAR struct SMenuItem *)0;
// Update the menu window size // Update the menu window size
@ -260,12 +253,14 @@ bool CMenus::addMenuItem(FAR NXWidgets::CNxString &text, FAR CMenus *subMenu,
// We have to update all button labels after resizing // We have to update all button labels after resizing
FAR struct SMenuItem *tmpitem;
int index; int index;
for (index = 0, item = m_menuHead;
item != (FAR struct SMenuItem *)0; for (index = 0, tmpitem = m_menuHead;
index++, item = item->flink) tmpitem != (FAR struct SMenuItem *)0;
index++, tmpitem = tmpitem->flink)
{ {
m_buttons->setText(0, index, item->text); m_buttons->setText(0, index, tmpitem->text);
} }
return true; return true;
@ -339,11 +334,11 @@ bool CMenus::event(FAR struct SEventMsg *eventmsg)
struct SEventMsg newmsg; struct SEventMsg newmsg;
newmsg.eventID = item->event; newmsg.eventID = item->event;
newmsg.obj = eventmsg->obj;
newmsg.pos.x = eventmsg->pos.x; newmsg.pos.x = eventmsg->pos.x;
newmsg.pos.y = eventmsg->pos.y; newmsg.pos.y = eventmsg->pos.y;
newmsg.context = eventmsg->context; newmsg.context = eventmsg->context;
newmsg.handler = item->handler; newmsg.handler = (FAR void *)item->handler;
newmsg.obj = eventmsg->obj;
// NOTE that we cannot block because we are on the same thread // NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then // as the message reader. If the event queue becomes full then
@ -807,14 +802,44 @@ void CMenus::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
struct SEventMsg msg; struct SEventMsg msg;
// If there is a subMenu, then bring the sub-menu up // Precedence:
// now. // 1. Event with recipient == EVENT_RECIPIENT_APP.
// getEventHandler() must return a non-NULL instance in this
// case.
// 2. Sub-menu
// 3. Task start-up
// 4. Event with other recipients
if (item->subMenu != (FAR CMenus *)0) if ((item->event & EVENT_RECIPIENT_MASK) != EVENT_RECIPIENT_APP)
{ {
msg.eventID = EVENT_MENU_SUBMENU; // If there is a subMenu, then bring the sub-menu up
msg.handler = (FAR CTwm4NxEvent *)0; // now.
msg.obj = (FAR void *)item->subMenu;
if (item->subMenu != (FAR CMenus *)0)
{
msg.eventID = EVENT_MENU_SUBMENU;
msg.obj = (FAR void *)item->subMenu;
msg.handler = (FAR void *)0;
}
// If there is a start-up function, then execute the
// start-up function
else if (item->start != (TStartFunction)0)
{
msg.eventID = EVENT_MENU_SUBMENU;
msg.obj = (FAR void *)this;
msg.handler = (FAR void *)item->start;
}
// Otherwise, this is an internal message with no handler
else
{
msg.eventID = item->event;
msg.obj = (FAR void *)this;
msg.handler = (FAR void *)0;
}
} }
// Otherwise, send the event specified for the menu item. The // Otherwise, send the event specified for the menu item. The
@ -824,8 +849,8 @@ void CMenus::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
else else
{ {
msg.eventID = item->event; msg.eventID = item->event;
msg.handler = item->handler;
msg.obj = (FAR void *)this; msg.obj = (FAR void *)this;
msg.handler = (FAR void *)item->handler;
} }
// Fill in the remaining, common stuff // Fill in the remaining, common stuff

View File

@ -58,6 +58,7 @@
#include "graphics/nxglyphs.hxx" #include "graphics/nxglyphs.hxx"
#include "graphics/twm4nx/twm4nx_config.hxx" #include "graphics/twm4nx/twm4nx_config.hxx"
#include "graphics/twm4nx/twm4nx.hxx"
#include "graphics/twm4nx/cnxterm.hxx" #include "graphics/twm4nx/cnxterm.hxx"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -67,7 +68,7 @@
// Configuration //////////////////////////////////////////////////////////// // Configuration ////////////////////////////////////////////////////////////
#ifdef CONFIG_NSH_USBKBD #ifdef CONFIG_NSH_USBKBD
# warning You probably do not really want CONFIG_NSH_USBKBD, try CONFIG_NXWM_KEYBOARD_USBHOST # warning You probably do not really want CONFIG_NSH_USBKBD, try CONFIG_TWM4NX_KEYBOARD_USBHOST
#endif #endif
/* If Telnet is used and both IPv6 and IPv4 are enabled, then we need to /* If Telnet is used and both IPv6 and IPv4 are enabled, then we need to
@ -127,7 +128,7 @@ using namespace Twm4Nx;
* @param window. The application window * @param window. The application window
*/ */
CNxTerm::CNxTerm(CTaskbar *twm4nx, CApplicationWindow *window) CNxTerm::CNxTerm(CTwm4Nx *twm4nx, CApplicationWindow *window)
{ {
// Save the constructor data // Save the constructor data
@ -189,22 +190,11 @@ IApplicationWindow *CNxTerm::getWindow(void) const
NXWidgets::IBitmap *CNxTerm::getIcon(void) NXWidgets::IBitmap *CNxTerm::getIcon(void)
{ {
NXWidgets::CRlePaletteBitmap *bitmap = NXWidgets::CRlePaletteBitmap *bitmap =
new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_NXTERM_ICON); new NXWidgets::CRlePaletteBitmap(&CONFIG_TWM4NX_NXTERM_ICON);
return bitmap; return bitmap;
} }
/**
* Get the name string associated with the application
*
* @return A copy if CNxString that contains the name of the application.
*/
NXWidgets::CNxString CNxTerm::getName(void)
{
return NXWidgets::CNxString("NuttShell");
}
/** /**
* Start the application (perhaps in the minimized state). * Start the application (perhaps in the minimized state).
* *
@ -245,9 +235,9 @@ bool CNxTerm::run(void)
// Describe the NxTerm // Describe the NxTerm
g_nxtermvars.wndo.wcolor[0] = CONFIG_NXWM_NXTERM_WCOLOR; g_nxtermvars.wndo.wcolor[0] = CONFIG_TWM4NX_NXTERM_WCOLOR;
g_nxtermvars.wndo.fcolor[0] = CONFIG_NXWM_NXTERM_FONTCOLOR; g_nxtermvars.wndo.fcolor[0] = CONFIG_TWM4NX_NXTERM_FONTCOLOR;
g_nxtermvars.wndo.fontid = CONFIG_NXWM_NXTERM_FONTID; g_nxtermvars.wndo.fontid = CONFIG_TWM4NX_NXTERM_FONTID;
// Remember the device minor number (before it is incremented) // Remember the device minor number (before it is incremented)
@ -264,8 +254,8 @@ bool CNxTerm::run(void)
g_nxtermvars.nxterm = 0; g_nxtermvars.nxterm = 0;
sched_lock(); sched_lock();
m_pid = task_create("NxTerm", CONFIG_NXWM_NXTERM_PRIO, m_pid = task_create("NxTerm", CONFIG_TWM4NX_NXTERM_PRIO,
CONFIG_NXWM_NXTERM_STACKSIZE, nxterm, CONFIG_TWM4NX_NXTERM_STACKSIZE, nxterm,
(FAR char * const *)0); (FAR char * const *)0);
// Did we successfully start the NxTerm task? // Did we successfully start the NxTerm task?
@ -321,7 +311,7 @@ bool CNxTerm::run(void)
void CNxTerm::stop(void) void CNxTerm::stop(void)
{ {
// Delete the NxTerm task if it is still running (this could strand // Delete the NxTerm task if it is still running (this could strand
// resources). If we get here due to CTaskbar::stopApplication() processing // resources). If we get here due to CTwm4Nx::stopApplication() processing
// initialed by CNxTerm::exitHandler, then do *not* delete the task (it // initialed by CNxTerm::exitHandler, then do *not* delete the task (it
// is already being deleted). // is already being deleted).
@ -394,7 +384,7 @@ void CNxTerm::hide(void)
/** /**
* Redraw the entire window. The application has been maximized or * Redraw the entire window. The application has been maximized or
* otherwise moved to the top of the hierarchy. This method is call from * otherwise moved to the top of the hierarchy. This method is call from
* CTaskbar when the application window must be displayed * CTwm4Nx when the application window must be displayed
*/ */
void CNxTerm::redraw(void) void CNxTerm::redraw(void)
@ -573,7 +563,7 @@ void CNxTerm::exitHandler(int code, FAR void *arg)
{ {
// Set m_pid to -1 to prevent calling detlete_task() in CNxTerm::stop(). // Set m_pid to -1 to prevent calling detlete_task() in CNxTerm::stop().
// CNxTerm::stop() is called by the processing initiated by the following // CNxTerm::stop() is called by the processing initiated by the following
// call to CTaskbar::stopApplication() // call to CTwm4Nx::stopApplication()
This->m_pid = -1; This->m_pid = -1;
@ -606,16 +596,31 @@ void CNxTerm::close(void)
* @param twm4nx. The twm4nx instance used to terminate the console * @param twm4nx. The twm4nx instance used to terminate the console
*/ */
CNxTermFactory::CNxTermFactory(CTaskbar *twm4nx) CNxTermFactory::CNxTermFactory(CTwm4Nx *twm4nx)
{ {
m_twm4nx = twm4nx; m_twm4nx = twm4nx;
} }
/** /**
* Create a new instance of an CNxTerm (as IApplication). * CNxTermFactory Initializer. Performs parts of the instance construction
* that may fail
*
* @param twm4nx. The twm4nx instance used to terminate the console
*/ */
IApplication *CNxTermFactory::create(void) bool CNxTermFactory::initialize(void)
{
// Register an entry with the Main menu. When selected, this will
FAR CMainMenu *cmain = m_twm4nx->getMainMenu();
return cmain->addApplication(this);
}
/**
* Create and start a new instance of an CNxTerm.
*/
bool *CNxTermFactory::startFunction(CTwm4Nx *twm4n)
{ {
// Call CTaskBar::openFullScreenWindow to create a full screen window for // Call CTaskBar::openFullScreenWindow to create a full screen window for
// the NxTerm application // the NxTerm application
@ -647,7 +652,7 @@ IApplication *CNxTermFactory::create(void)
return (IApplication *)0; return (IApplication *)0;
} }
return static_cast<IApplication*>(nxterm); return true;
} }
/** /**
@ -661,7 +666,7 @@ IApplication *CNxTermFactory::create(void)
NXWidgets::IBitmap *CNxTermFactory::getIcon(void) NXWidgets::IBitmap *CNxTermFactory::getIcon(void)
{ {
NXWidgets::CRlePaletteBitmap *bitmap = NXWidgets::CRlePaletteBitmap *bitmap =
new NXWidgets::CRlePaletteBitmap(&CONFIG_NXWM_NXTERM_ICON); new NXWidgets::CRlePaletteBitmap(&CONFIG_TWM4NX_NXTERM_ICON);
return bitmap; return bitmap;
} }

View File

@ -501,8 +501,9 @@ bool CTwm4Nx::dispatchEvent(FAR struct SEventMsg *eventmsg)
// fixed, a priori endpoint. Rather, the endpoint must be // fixed, a priori endpoint. Rather, the endpoint must be
// provided in the 'handler' field of the message // provided in the 'handler' field of the message
DEBUGASSERT(eventmsg->handler != (FAR CTwm4NxEvent *)0); DEBUGASSERT(eventmsg->handler != (FAR void *)0);
ret = eventmsg->handler->event(eventmsg); FAR CTwm4NxEvent *handler = (FAR CTwm4NxEvent *)eventmsg->handler;
ret = handler->event(eventmsg);
} }
break; break;

View File

@ -1270,11 +1270,11 @@ void CWindow::handleUngrabEvent(nxgl_coord_t x, nxgl_coord_t y)
struct SEventMsg msg; struct SEventMsg msg;
msg.eventID = EVENT_TOOLBAR_UNGRAB; msg.eventID = EVENT_TOOLBAR_UNGRAB;
msg.obj = (FAR void *)this;
msg.pos.x = x; msg.pos.x = x;
msg.pos.y = y; msg.pos.y = y;
msg.context = EVENT_CONTEXT_TOOLBAR; msg.context = EVENT_CONTEXT_TOOLBAR;
msg.handler = (FAR CTwm4NxEvent *)0; msg.handler = (FAR void *)0;
msg.obj = (FAR void *)this;
// NOTE that we cannot block because we are on the same thread // NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then // as the message reader. If the event queue becomes full then
@ -1308,11 +1308,11 @@ void CWindow::handleClickEvent(const NXWidgets::CWidgetEventArgs &e)
struct SEventMsg msg; struct SEventMsg msg;
msg.eventID = EVENT_TOOLBAR_GRAB; msg.eventID = EVENT_TOOLBAR_GRAB;
msg.obj = (FAR void *)this;
msg.pos.x = e.getX(); msg.pos.x = e.getX();
msg.pos.y = e.getY(); msg.pos.y = e.getY();
msg.context = EVENT_CONTEXT_TOOLBAR; msg.context = EVENT_CONTEXT_TOOLBAR;
msg.handler = (FAR CTwm4NxEvent *)0; msg.handler = (FAR void *)0;
msg.obj = (FAR void *)this;
// NOTE that we cannot block because we are on the same thread // NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then // as the message reader. If the event queue becomes full then
@ -1380,11 +1380,11 @@ void CWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
struct SEventMsg msg; struct SEventMsg msg;
msg.eventID = GToolBarInfo[btindex].event; msg.eventID = GToolBarInfo[btindex].event;
msg.obj = (FAR void *)this;
msg.pos.x = e.getX(); msg.pos.x = e.getX();
msg.pos.y = e.getY(); msg.pos.y = e.getY();
msg.context = EVENT_CONTEXT_TOOLBAR; msg.context = EVENT_CONTEXT_TOOLBAR;
msg.handler = (FAR CTwm4NxEvent *)0; msg.handler = (FAR void *)0;
msg.obj = (FAR void *)this;
// NOTE that we cannot block because we are on the same thread // NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then // as the message reader. If the event queue becomes full then
@ -1436,11 +1436,11 @@ bool CWindow::dragEvent(FAR const struct nxgl_point_s &pos,
struct SEventMsg msg; struct SEventMsg msg;
msg.eventID = EVENT_WINDOW_DRAG; msg.eventID = EVENT_WINDOW_DRAG;
msg.obj = (FAR void *)this;
msg.pos.x = pos.x; msg.pos.x = pos.x;
msg.pos.y = pos.y + yIncr; msg.pos.y = pos.y + yIncr;
msg.context = EVENT_CONTEXT_TOOLBAR; msg.context = EVENT_CONTEXT_TOOLBAR;
msg.handler = (FAR CTwm4NxEvent *)0; msg.handler = (FAR void *)0;
msg.obj = (FAR void *)this;
// NOTE that we cannot block because we are on the same thread // NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then // as the message reader. If the event queue becomes full then

View File

@ -190,7 +190,7 @@ namespace Twm4Nx
* @param name The name of the application. * @param name The name of the application.
*/ */
inline const NXWidgets::CNxString getName(void) inline NXWidgets::CNxString getName(void)
{ {
return m_name; return m_name;
} }
@ -212,8 +212,9 @@ namespace Twm4Nx
* be called in this implementation * be called in this implementation
*/ */
inline void start(FAR CTwm4Nx *twm4nx) inline TStartFunction getStartFunction(void)
{ {
return (TStartFunction)0;
} }
/** /**

View File

@ -56,6 +56,7 @@
#include "graphics/twm4nx/cwindow.hxx" #include "graphics/twm4nx/cwindow.hxx"
#include "graphics/twm4nx/ctwm4nxevent.hxx" #include "graphics/twm4nx/ctwm4nxevent.hxx"
#include "graphics/twm4nx/iapplication.hxx"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Pre-processor Definitions // Pre-processor Definitions
@ -99,8 +100,9 @@ namespace Twm4Nx
{ {
FAR struct SMenuItem *flink; /**< Forward link to next menu item */ FAR struct SMenuItem *flink; /**< Forward link to next menu item */
FAR struct SMenuItem *blink; /**< Backward link previous menu item */ FAR struct SMenuItem *blink; /**< Backward link previous menu item */
FAR CMenus *subMenu; /**< Menu root of a pull right menu */
FAR NXWidgets::CNxString text; /**< The text string for the menu item */ FAR NXWidgets::CNxString text; /**< The text string for the menu item */
FAR CMenus *subMenu; /**< Menu root of a pull right menu */
TStartFunction start; /**< Application start-up function */
FAR CTwm4NxEvent *handler; /**< Application event handler */ FAR CTwm4NxEvent *handler; /**< Application event handler */
uint16_t event; /**< Menu selection event */ uint16_t event; /**< Menu selection event */
}; };
@ -266,15 +268,11 @@ namespace Twm4Nx
/** /**
* Add an item to a menu * Add an item to a menu
* *
* \param text The text to appear in the menu * @param item Describes the menu item entry
* \param subMenu The menu root if it is a pull-right entry * @return True if the menu item was added successfully
* \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 NXWidgets::CNxString &text, FAR CMenus *subMenu, bool addMenuItem(FAR IApplication *item);
FAR CTwm4NxEvent *handler, uint16_t event);
/** /**
* Return the size of the menu window frame * Return the size of the menu window frame

View File

@ -48,6 +48,7 @@
#include <nuttx/nx/nxterm.h> #include <nuttx/nx/nxterm.h>
#include "graphics/twm4nx/ctwm4nx.hxx" #include "graphics/twm4nx/ctwm4nx.hxx"
#include "graphics/twm4nx/iapplication.hxx"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Implementation Classes // Implementation Classes
@ -68,170 +69,236 @@ namespace Twm4Nx
* This class implements the NxTerm application. * This class implements the NxTerm application.
*/ */
class CNxTerm : public IApplication, private IApplicationCallback class CNxTerm
{ {
private: private:
CTaskbar *m_twm4nx; /**< Reference to the "parent" twm4nx */ CTaskbar *m_twm4nx; /**< Reference to the "parent" twm4nx */
CApplicationWindow *m_window; /**< Reference to the application window */ CApplicationWindow *m_window; /**< Reference to the application window */
NXTERM m_nxterm; /**< NxTerm handle */ NXTERM m_nxterm; /**< NxTerm handle */
pid_t m_pid; /**< Task ID of the NxTerm thread */ pid_t m_pid; /**< Task ID of the NxTerm thread */
int m_minor; /**< Terminal device minor number */ int m_minor; /**< Terminal device minor number */
/** /**
* This is the NxTerm task. This function first redirects output to the * This is the NxTerm task. This function first redirects output to the
* console window then calls to start the NSH logic. * console window then calls to start the NSH logic.
*/ */
static int nxterm(int argc, char *argv[]); static int nxterm(int argc, char *argv[]);
/** /**
* This is the NxTerm task exit handler. It is registered with on_exit() * This is the NxTerm task exit handler. It is registered with on_exit()
* and called automatically when the nxterm task exits. * and called automatically when the nxterm task exits.
*/ */
static void exitHandler(int code, FAR void *arg); static void exitHandler(int code, FAR void *arg);
/** /**
* Called when the window minimize button is pressed. * Called when the window minimize button is pressed.
*/ */
void minimize(void); void minimize(void);
/** /**
* Called when the window close button is pressed. * Called when the window close button is pressed.
*/ */
void close(void); void close(void);
public: /**
/** * Start the application (perhaps in the minimized state).
* CNxTerm constructor *
* * @return True if the application was successfully started.
* @param window. The application window */
*
* @param twm4nx. A pointer to the parent task bar instance
* @param window. The window to be used by this application.
*/
CNxTerm(CTaskbar *twm4nx, CApplicationWindow *window); bool run(void);
/** /**
* CNxTerm destructor * Stop the application.
*/ */
~CNxTerm(void); void stop(void);
/** /**
* Each implementation of IApplication must provide a method to recover * Destroy the application and free all of its resources. This method
* the contained CApplicationWindow instance. * will initiate blocking of messages from the NX server. The server
*/ * will flush the window message queue and reply with the blocked
* message. When the block message is received by CWindowMessenger,
* it will send the destroy message to the start window task which
* will, finally, safely delete the application.
*/
IApplicationWindow *getWindow(void) const; void destroy(void);
/** /**
* Get the icon associated with the application * The application window is hidden (either it is minimized or it is
* * maximized, but not at the top of the hierarchy
* @return An instance if IBitmap that may be used to rend the */
* application's icon. This is an new IBitmap instance that must
* be deleted by the caller when it is no long needed.
*/
NXWidgets::IBitmap *getIcon(void); void hide(void);
/** /**
* Get the name string associated with the application * Redraw the entire window. The application has been maximized or
* * otherwise moved to the top of the hierarchy. This method is call from
* @return A copy if CNxString that contains the name of the application. * CTaskbar when the application window must be displayed
*/ */
NXWidgets::CNxString getName(void); void redraw(void);
/** /**
* Start the application (perhaps in the minimized state). * Report of this is a "normal" window or a full screen window. The
* * primary purpose of this method is so that window manager will know
* @return True if the application was successfully started. * whether or not it show draw the task bar.
*/ *
* @return True if this is a full screen window.
*/
bool run(void); bool isFullScreen(void) const;
/**
* Stop the application.
*/
void stop(void);
/**
* Destroy the application and free all of its resources. This method
* will initiate blocking of messages from the NX server. The server
* will flush the window message queue and reply with the blocked
* message. When the block message is received by CWindowMessenger,
* it will send the destroy message to the start window task which
* will, finally, safely delete the application.
*/
void destroy(void);
/**
* The application window is hidden (either it is minimized or it is
* maximized, but not at the top of the hierarchy
*/
void hide(void);
/**
* Redraw the entire window. The application has been maximized or
* otherwise moved to the top of the hierarchy. This method is call from
* CTaskbar when the application window must be displayed
*/
void redraw(void);
/**
* Report of this is a "normal" window or a full screen window. The
* primary purpose of this method is so that window manager will know
* whether or not it show draw the task bar.
*
* @return True if this is a full screen window.
*/
bool isFullScreen(void) const;
}; };
class CNxTermFactory : public IApplicationFactory class CNxTermFactory : public IApplication, public IApplicationFactory
{ {
private: private:
CTaskbar *m_twm4nx; /**< The twm4nx */ CTaskbar *m_twm4nx; /**< The twm4nx */
public: /**
/** * Return the Main Menu item string. This overrides the method from
* CNxTermFactory Constructor * IApplication
* *
* @param twm4nx. The twm4nx instance used to terminate calibration * @param name The name of the application.
*/ */
CNxTermFactory(CTaskbar *twm4nx); inline NXWidgets::CNxString getName(void)
{
return NXWidgets::CNxString("NxTerm");
}
/** /**
* CNxTermFactory Destructor * There is no sub-menu for this Main Menu item. This overrides
*/ * the method from IApplication.
*
* @return This implementation will always return a null value.
*/
inline ~CNxTermFactory(void) { } inline FAR CMenus *getSubMenu(void)
{
return (FAR CMenus *)0;
}
/** /**
* Create a new instance of an CNxTerm (as IApplication). * There is no application start-up function. This function will not
*/ * be called in this implementation
*/
IApplication *create(void); inline TStartFunction getStartFunction(void)
{
return (TStartFunction)startFunction;
}
/** /**
* Get the icon associated with the application * There is no custom event handler. We use the common event handler.
* *
* @return An instance if IBitmap that may be used to rend the * @return. null is always returned in this impementation.
* application's icon. This is an new IBitmap instance that must */
* be deleted by the caller when it is no long needed.
*/
NXWidgets::IBitmap *getIcon(void); inline FAR CTwm4NxEvent *getEventHandler(void)
{
return (FAR CTwm4NxEvent *)0;
}
/**
* Return the Twm4Nx event that will be generated when the Main Menu
* item is selected.
*
* @return. This function always returns EVENT_SYSTEM_NOP.
*/
inline uint16_t getEvent(void)
{
return EVENT_SYSTEM_NOP;
}
public:
/**
* CNxTerm constructor
*
* @param window. The application window
*
* @param twm4nx. A pointer to the parent task bar instance
* @param window. The window to be used by this application.
*/
CNxTerm(CTaskbar *twm4nx, CApplicationWindow *window);
/**
* CNxTerm destructor
*/
~CNxTerm(void);
/**
* Each implementation of IApplication must provide a method to recover
* the contained CApplicationWindow instance.
*/
IApplicationWindow *getWindow(void) const;
/**
* Get the icon associated with the application
*
* @return An instance if IBitmap that may be used to rend the
* application's icon. This is an new IBitmap instance that must
* be deleted by the caller when it is no long needed.
*/
NXWidgets::IBitmap *getIcon(void);
/**
* Get the name string associated with the application
*
* @return A copy if CNxString that contains the name of the application.
*/
NXWidgets::CNxString getName(void);
public:
/**
* CNxTermFactory Constructor
*
* @param twm4nx. The twm4nx instance used to terminate calibration
*/
CNxTermFactory(CTaskbar *twm4nx);
/**
* CNxTermFactory Destructor
*/
inline ~CNxTermFactory(void) { }
/**
* CNxTermFactory Initializer. Performs parts of the instance
* construction that may fail
*
* @param twm4nx. The twm4nx instance used to terminate the console
*/
bool CNxTermFactory::initialize(void);
/**
* Create a new instance of an CNxTerm (as IApplication).
*/
IApplication *create(void);
/**
* Get the icon associated with the application
*
* @return An instance if IBitmap that may be used to rend the
* application's icon. This is an new IBitmap instance that must
* be deleted by the caller when it is no long needed.
*/
NXWidgets::IBitmap *getIcon(void);
}; };
} }

View File

@ -98,7 +98,7 @@ namespace Twm4Nx
* @param name The name of the application. * @param name The name of the application.
*/ */
inline const NXWidgets::CNxString getName(void) inline NXWidgets::CNxString getName(void)
{ {
return NXWidgets::CNxString("Desktop"); return NXWidgets::CNxString("Desktop");
} }
@ -120,8 +120,9 @@ namespace Twm4Nx
* be called in this implementation * be called in this implementation
*/ */
inline void start(FAR CTwm4Nx *twm4nx) inline TStartFunction getStartFunction(void)
{ {
return (TStartFunction)0;
} }
/** /**

View File

@ -59,6 +59,17 @@ namespace Twm4Nx
class CMenus; // Forward reference class CMenus; // Forward reference
class CTwm4NxEvent; // Forward reference class CTwm4NxEvent; // Forward reference
/**
* Get the start function entry point.
*
* @param twm4nx The Twm4Nx session object. Use with care! The CTwm4Nx
* logic runs on a different thread and some of the methods of the
* class may not be thread safe.
* @return True if the application was started successfully
*/
typedef CODE bool (*TStartFunction)(FAR CTwm4Nx *twm4nx);
/** /**
* Defines the interface of an application to the Main Menu. "Built-In" * Defines the interface of an application to the Main Menu. "Built-In"
* applications are started via CMainMenu. This interface class defines * applications are started via CMainMenu. This interface class defines
@ -86,7 +97,7 @@ namespace Twm4Nx
* @return The name of the application. * @return The name of the application.
*/ */
virtual const NXWidgets::CNxString getName(void) = 0; virtual NXWidgets::CNxString getName(void) = 0;
/** /**
* Return any submenu item associated with the menu entry. If a non- * Return any submenu item associated with the menu entry. If a non-
@ -94,10 +105,22 @@ namespace Twm4Nx
* the menu entry is selected. Otherwise, the start() method will be * the menu entry is selected. Otherwise, the start() method will be
* called. These two behaviors are mutually exlusive. * called. These two behaviors are mutually exlusive.
* *
* NOTE: Both the start() and getSubMenu() return values are ignored * NOTEs:
* if the event() method returns an event with recipient = * * Both the start() and getSubMenu() methods are ignoredif the event()
* EVENT_RECIPIENT_APP. In that case, the application will be fully * method returns an event with recipient = EVENT_RECIPIENT_APP. In
* responsible for handling the menu selection event. * that case, the application will be fully responsible for handling
* the menu selection event.
* * Otherwise, the sub-menu or start-up take precedence over
* the event.
* * If getSubMenu() returns a non-NULL CMenu instance, then the
* subMenu is used and the start() is not called.
*
* Precedence:
* 1. Event with recipient == EVENT_RECIPIENT_APP. getEventHandler()
* must return a non-NULL instance in this case.
* 2. Sub-menu
* 3. Task start-up
* 4. Event with other recipients
* *
* @return. A reference to any sub-menu that should be brought up if * @return. A reference to any sub-menu that should be brought up if
* the menu item is selected. This must be null if the menu item * the menu item is selected. This must be null if the menu item
@ -115,17 +138,28 @@ namespace Twm4Nx
* The Main Menu runs on the main Twm4Nx thread so this function will, * The Main Menu runs on the main Twm4Nx thread so this function will,
* typically, create a new thread to host the application. * typically, create a new thread to host the application.
* *
* NOTE: Both the start() and getSubMenu() return values are ignored * NOTEs:
* if the event() method returns an event with recipient = * * Both the start() and getSubMenu() methods are ignoredif the event()
* EVENT_RECIPIENT_APP. In that case, the application will be fully * method returns an event with recipient = EVENT_RECIPIENT_APP. In
* responsible for handling the menu selection event. * that case, the application will be fully responsible for handling
* the menu selection event.
* * Otherwise, the sub-menu or start-up take precedence over
* the event.
* * If getSubMenu() returns a non-NULL CMenu instance, then the
* subMenu is used and the start() is not called.
* *
* @param twm4nx The Twm4Nx session object. Use with care! The CTwm4Nx * Precedence:
* logic runs on a different thread and some of the methods of the * 1. Event with recipient == EVENT_RECIPIENT_APP. getEventHandler()
* class may not be thread safe. * must return a non-NULL instance in this case.
* 2. Sub-menu
* 3. Task start-up
* 4. Event with other recipients
*
* @return The start-up function entry point. A null value is returned
* if there is no startup function.
*/ */
virtual void start(FAR CTwm4Nx *twm4nx) = 0; virtual TStartFunction getStartFunction(void) = 0;
/** /**
* External applications may provide their own event handler that runs * External applications may provide their own event handler that runs
@ -150,15 +184,33 @@ namespace Twm4Nx
/** /**
* Get the Twm4Nx event that will be generated when the menu item is * Get the Twm4Nx event that will be generated when the menu item is
* selected. All returned values are ignored unless the event recipient * selected. If the returned value has the event recipient of
* is EVENT_RECIPIENT_APP. Otherwise, the event EVENT_MAINMENU_SELECT * EVENT_RECIPIENT_APP, then getEventHandler() must return the event
* is used and any subsequent menu item action, either bringing up * handling instance. Otherwise, the event will be handled by internal
* a sub-menu or starting an application, will be performed by CMainMenu. * Twm4Nx logic based on the internal recipient.
* *
* This method may return zero in that case. It would be an error if * This method may return EVENT_SYSTEM_NOP if a subMenu or task start-up
* this method returned an event with EVENT_RECIPIENT_APP but the * function should be executed. It would be an error if this method
* returned an event with EVENT_RECIPIENT_APP but the
* getEventHandler() method returned null. * getEventHandler() method returned null.
* *
* NOTEs:
* * Both the start() and getSubMenu() methods are ignoredif the event()
* method returns an event with recipient = EVENT_RECIPIENT_APP. In
* that case, the application will be fully responsible for handling
* the menu selection event.
* * Otherwise, the sub-menu or start-up take precedence over
* the event.
* * If getSubMenu() returns a non-NULL CMenu instance, then the
* subMenu is used and the start() is not called.
*
* Precedence:
* 1. Event with recipient == EVENT_RECIPIENT_APP. getEventHandler()
* must return a non-NULL instance in this case.
* 2. Sub-menu
* 3. Task start-up
* 4. Event with other recipients
*
* @return. Either, (1) an event with recipient = EVENT_RECIPIENT_APP * @return. Either, (1) an event with recipient = EVENT_RECIPIENT_APP
* that will be generated when menu item is selected, or (2) any other * that will be generated when menu item is selected, or (2) any other
* value (preferabley zero) that indicates that standard, built-in * value (preferabley zero) that indicates that standard, built-in

View File

@ -47,7 +47,6 @@
#include <cstdbool> #include <cstdbool>
#include <nuttx/nx/nxglib.h> #include <nuttx/nx/nxglib.h>
#include "graphics/nxwidgets/cwindoweventhandler.hxx"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Preprocessor Definitions // Preprocessor Definitions
@ -107,6 +106,7 @@ namespace Twm4Nx
EVENT_SYSTEM_NOP = 0x0000, /**< Null event */ EVENT_SYSTEM_NOP = 0x0000, /**< Null event */
EVENT_SYSTEM_ERROR = 0x0001, /**< Report system error */ EVENT_SYSTEM_ERROR = 0x0001, /**< Report system error */
EVENT_SYSTEM_EXIT = 0x0002, /**< Terminate the Twm4Nx session */ EVENT_SYSTEM_EXIT = 0x0002, /**< Terminate the Twm4Nx session */
EVENT_SYSTEM_STARTUP = 0x0003, /**< Start an application */
// Recipient == BACKGOUND // Recipient == BACKGOUND
@ -206,7 +206,7 @@ namespace Twm4Nx
struct nxgl_point_s pos; /**< X/Y position */ struct nxgl_point_s pos; /**< X/Y position */
uint8_t context; /**< Button press context */ uint8_t context; /**< Button press context */
FAR CTwm4NxEvent *handler; /**< App event handler (APP recipient only) */ FAR void *handler; /**< Context specific handler */
}; };
/** /**