Squashed commit of the following:

apps/graphics/twm4nx:  This resolves the problems noted in the previous commit comments.  Window events are now communicated properly to the appliation-specific event handler.  Menus now seem to be receiving events and working well.

    apps/graphics/twm4nx:  Revamp application event handler.  Better design but still crashes when a main menu entry is clicked.

    apps/graphics/twm4nx:  First cut at application window event distribution.  Has some issues.  Not ready for prime time.

    apps/graphics/twm4nx:  Add more controls for the events that will be generated on basic window redraw, mouse/keyboard input, and keyboard input.

    apps/graphpics/twm4nx:  Add a 'Desktop' item to the main menu that will iconify all windows and menus and just show the open desktop.
This commit is contained in:
Gregory Nutt 2019-05-10 15:22:27 -06:00
parent 28b4be1913
commit dbb5211060
15 changed files with 544 additions and 176 deletions

View File

@ -38,8 +38,7 @@ STATUS
1. Update some logic that is only fragmentary for things like resizing.
Resizing events should be be generated when user pulls to right,
left, top, bottom, etc. None of that is implemented.
2. Left click on background should bring up a user provided main menu.
Right click should bring up a window list (like the icon manager???)
2. Right click should bring up a window list (like the icon manager???)
3. For TWM-like behavior, a window frame and toolbar should be highlighted
when the window has focus.
4. A right click on the toolbar should bring up a window-specific menu.
@ -52,9 +51,22 @@ STATUS
properly and the Icon Manager appears properly in the upper rightthand
corner. The Icon Manager Window can be iconfified or de-inconified.
The Icon Manager window can be grabbed by the toolbar title and moved
about on the window (the icon grab'n'move does not work however).
Further progress depends upon getting a main menu in place. The main
menu 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.
about on the window (the movement is not very smooth on the particular
hardware that I am working with).
2019-05-10: A left click on the background brings up the main menu. At
present there are only two options: "Desktop" which will iconify all
windows and "Twm4Nx Icon Manager" which will de-configy and/or raise
the Icon Manager window to the top of the hierarchy. That latter option
is only meaningful when the desktop is very crowded.
Further progress depends upon getting a some additional applications
in place in the main menu in place. NxTerm is needed as is probably
a clock. These would provide good illustrations of how to hook in an
arbitrary application.
Some known bugs yet-to-fixed. Surely there are more as will be revealed
by additional testing:
1. The is a small artifact in the upper lefthand corner. I am not sure
exactly what that is.
2. The logic to move an icon on the desk top does not work.

View File

@ -293,9 +293,6 @@ bool CBackground::event(FAR struct SEventMsg *eventmsg)
}
break;
case EVENT_WINDOW_KBDINPUT: // Poll for icon keyboard events
break; // There aren't any
case EVENT_BACKGROUND_REDRAW: // Redraw the background
{
FAR struct SRedrawEventMsg *redrawmsg =
@ -331,7 +328,8 @@ bool CBackground::createBackgroundWindow(void)
// style for now. CWindowEvent derives from CWidgetControl.
FAR CWindowEvent *control =
new CWindowEvent(m_twm4nx, (FAR void *)this, true);
new CWindowEvent(m_twm4nx, (FAR void *)this, EVENT_BACKGROUND_REDRAW,
EVENT_BACKGROUND_XYINPUT, EVENT_SYSTEM_NOP);
// Create the background window (CTwm4Nx inherits from CNxServer)

View File

@ -503,6 +503,25 @@ bool CIconMgr::event(FAR struct SEventMsg *eventmsg)
switch (eventmsg->eventID)
{
case EVENT_ICONMGR_XYINPUT: // Poll for button array events
{
// This event message is sent from CWindowEvent whenever mouse,
// touchscreen, or keyboard entry events are received in the
// Icon Manager application window that contains the button
// array.
NXWidgets::CWidgetControl *control = m_window->getWidgetControl();
// Poll for button array events.
//
// pollEvents() returns true if any interesting event in the
// button array. handleActionEvent() will be called in that
// case. false is not a failure.
(void)control->pollEvents();
}
break;
case EVENT_ICONMGR_DEICONIFY: // De-iconify or raise the Icon Manager
{
// Is the Icon manager conified?
@ -603,6 +622,18 @@ bool CIconMgr::createIconManagerWindow(FAR const char *prefix)
return false;
}
// Configure mouse events needed by the button array.
bool success =
m_window->configureEvents((FAR void *)this, EVENT_SYSTEM_NOP,
EVENT_ICONMGR_XYINPUT, EVENT_SYSTEM_NOP);
if (!success)
{
delete m_window;
m_window = (FAR CWindow *)0;
return false;
}
// Adjust the height of the window (and probably the width too?)
// The height of one row is determined (mostly) by the font height

View File

@ -203,10 +203,10 @@ bool CMenus::addMenuItem(FAR NXWidgets::CNxString &text, FAR CMenus *subMenu,
FAR struct SMenuItem *item = new SMenuItem;
if (item == (FAR struct SMenuItem *)0)
{
{
twmerr("ERROR: Failed to allocate menu item\n");
return false;
}
}
// Clone the item name so that we have control over its lifespan
@ -221,7 +221,7 @@ bool CMenus::addMenuItem(FAR NXWidgets::CNxString &text, FAR CMenus *subMenu,
// Increment the total number of menu items
int index = m_nMenuItems++;
m_nMenuItems++;
// Add the menu item to the tail of the item list
@ -259,9 +259,16 @@ bool CMenus::addMenuItem(FAR NXWidgets::CNxString &text, FAR CMenus *subMenu,
return false;
}
// Add the new item text to the button array
// We have to update all button labels after resizing
int index;
for (index = 0, item = m_menuHead;
item != (FAR struct SMenuItem *)0;
index++, item = item->flink)
{
m_buttons->setText(0, index, item->text);
}
m_buttons->setText(0, index, item->text);
return true;
}
@ -279,6 +286,25 @@ bool CMenus::event(FAR struct SEventMsg *eventmsg)
switch (eventmsg->eventID)
{
case EVENT_MENU_XYINPUT: // Poll for button array events
{
// This event message is sent from CWindowEvent whenever mouse,
// touchscreen, or keyboard entry events are received in the
// menu application window that contains the button array.
NXWidgets::CWidgetControl *control =
m_menuWindow->getWidgetControl();
// Poll for button array events.
//
// pollEvents() returns true if any interesting event in the
// button array. handleActionEvent() will be called in that
// case. false is not a failure.
(void)control->pollEvents();
}
break;
case EVENT_MENU_IDENTIFY: // Describe the window
{
identify((FAR CWindow *)eventmsg->obj);
@ -485,7 +511,7 @@ void CMenus::menuToFramePos(FAR const struct nxgl_point_s *menupos,
*/
void CMenus::frameToMenuPos(FAR const struct nxgl_point_s *framepos,
FAR struct nxgl_point_s *menupos)
FAR struct nxgl_point_s *menupos)
{
nxgl_coord_t tbheight = m_menuWindow->getToolbarHeight();
menupos->x = framepos->x + CONFIG_NXTK_BORDERWIDTH;
@ -542,6 +568,18 @@ bool CMenus::createMenuWindow(void)
return false;
}
// Configure mouse events needed by the button array.
bool success =
m_menuWindow->configureEvents((FAR void *)this, EVENT_SYSTEM_NOP,
EVENT_MENU_XYINPUT, EVENT_SYSTEM_NOP);
if (!success)
{
delete m_menuWindow;
m_menuWindow = (FAR CWindow *)0;
return false;
}
// Adjust the size of the window
struct nxgl_size_s windowSize;
@ -719,8 +757,9 @@ bool CMenus::createMenuButtonArray(void)
m_buttons->setBorderless(true);
m_buttons->setRaisesEvents(true);
// Draw the button array
// Enable and draw the button array
m_buttons->enable();
m_buttons->enableDrawing();
m_buttons->redraw();

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
// apps/graphics/twm4nx/src/cwindow.cxx
// apps/graphics/twm4nx/src/cnxterm.cxx
// NxTerm window
//
// Copyright (C) 2019 Gregory Nutt. All rights reserved.

View File

@ -900,7 +900,13 @@ bool CResize::event(FAR struct SEventMsg *eventmsg)
switch (eventmsg->eventID)
{
case EVENT_RESIZE_START: // Start window resize
case EVENT_RESIZE_XYINPUT: // Poll for XY input
{
#warning Missing logic
}
break;
case EVENT_RESIZE_START: // Start window resize
{
// Can't resize icons
@ -957,7 +963,9 @@ bool CResize::createSizeWindow(void)
// 3. Create a Widget control instance for the window using the default
// style for now. CWindowEvent derives from CWidgetControl.
FAR CWindowEvent *control = new CWindowEvent(m_twm4nx, (FAR void *)this);
FAR CWindowEvent *control =
new CWindowEvent(m_twm4nx, (FAR void *)this, EVENT_SYSTEM_NOP,
EVENT_RESIZE_XYINPUT, EVENT_SYSTEM_NOP);
// 4. Create the main window

View File

@ -312,6 +312,12 @@ bool CTwm4Nx::run(void)
// Now, complete the initialization of some preceding instances that
// depend on the Main Menu being in place
if (!m_factory->addMenuItems())
{
cleanup();
return false;
}
if (!m_iconmgr->addMenuItems())
{
cleanup();

View File

@ -139,7 +139,12 @@ CWindow::CWindow(CTwm4Nx *twm4nx)
m_nxWin = (FAR NXWidgets::CNxTkWindow *)0;
m_toolbar = (FAR NXWidgets::CNxToolbar *)0;
m_windowEvent = (FAR CWindowEvent *)0;
m_eventObj = (FAR void *)0;
m_minWidth = 1;
m_redrawEvent = EVENT_SYSTEM_NOP; // Redraw event ID
m_mouseEvent = EVENT_SYSTEM_NOP; // Mouse/touchscreen event ID
m_kbdEvent = EVENT_SYSTEM_NOP; // Keyboard event ID
m_zoom = ZOOM_NONE;
m_modal = false;
@ -185,8 +190,12 @@ CWindow::~CWindow(void)
/**
* CWindow Initializer (unlike the constructor, this may fail)
*
* The window is initialized with all application events disabled.
* The CWindows::configureEvents() method may be called as a second
* initialization step in order to enable application events.
*
* @param name The the name of the window (and its icon)
* @param pos The initialize position of the window
* @param pos The initial position of the window
* @param size The initial size of the window
* @param sbitmap The Icon bitmap image. null if no icon.
* @param iconMgr Pointer to icon manager instance
@ -358,6 +367,33 @@ bool CWindow::initialize(FAR const NXWidgets::CNxString &name,
return true;
}
/**
* Configure application window events.
*
* @param obj An object reference that will be provided with the event
* to assist in handling the event. This may be NULL is not needed
* @param redrawEvent The event to send on window redraw events. This
* may be EVENT_SYSTEM_NOP to ignore all rdraw events.
* @param mouseEvent The event to send on mouse/touchscreen input
* events. This may be EVENT_SYSTEM_NOP to ignore all mouse/
* touchscreen input events.
* @param kbdEvent The event to send on keyboard input events. This
* may be EVENT_SYSTEM_NOP to ignore all keyboard input events.
* @return True is returned on success
*/
bool CWindow::configureEvents(FAR void *obj, uint16_t redrawEvent,
uint16_t mouseEvent, uint16_t kbdEvent)
{
m_eventObj = obj; // Event object
m_redrawEvent = redrawEvent; // Redraw event ID
m_mouseEvent = mouseEvent; // Mouse/touchscreen event ID
m_kbdEvent = kbdEvent; // Keyboard event ID
return m_windowEvent->configureEvents(m_eventObj, m_redrawEvent,
m_mouseEvent, m_kbdEvent);
}
/**
* Get the raw window size (including toolbar and frame)
*
@ -701,6 +737,11 @@ bool CWindow::event(FAR struct SEventMsg *eventmsg)
/**
* Create the main window
*
* Initially, the application window will generate no window-related events
* (redraw, mouse/touchscreen, keyboard input, etc.). After creating the
* window, the user may call the configureEvents() method to select the
* eventIDs of the events to be generated.
*
* @param winsize The initial window size
* @param winpos The initial window position
* @param flags Toolbar customizations see WFLAGS_NO_* definitions
@ -719,8 +760,9 @@ bool CWindow::createMainWindow(FAR const nxgl_size_s *winsize,
// Setup the the CWindowEvent instance to use our inherited drag event
// handler
FAR CWindowEvent *control = new CWindowEvent(m_twm4nx, (FAR void *)this);
control->registerDragEventHandler(this, (uintptr_t)1);
m_windowEvent = new CWindowEvent(m_twm4nx, m_eventObj, m_redrawEvent,
m_mouseEvent, m_kbdEvent);
m_windowEvent->registerDragEventHandler(this, (uintptr_t)1);
// 4. Create the window. Handling provided flags. NOTE: that menu windows
// are always created hidden and in the iconified state (although they
@ -732,10 +774,11 @@ bool CWindow::createMainWindow(FAR const nxgl_size_s *winsize,
cflags |= NXBE_WINDOW_HIDDEN;
}
m_nxWin = m_twm4nx->createFramedWindow(control, cflags);
m_nxWin = m_twm4nx->createFramedWindow(m_windowEvent, cflags);
if (m_nxWin == (FAR NXWidgets::CNxTkWindow *)0)
{
delete control;
delete m_windowEvent;
m_windowEvent = (FAR CWindowEvent *)0;
return false;
}
@ -816,7 +859,9 @@ bool CWindow::createToolbar(void)
// 2. Create a Widget control instance for the window using the default
// style for now. CWindowEvent derives from CWidgetControl.
FAR CWindowEvent *control = new CWindowEvent(m_twm4nx, (FAR void *)this);
FAR CWindowEvent *control =
new CWindowEvent(m_twm4nx, (FAR void *)this, EVENT_SYSTEM_NOP,
EVENT_TOOLBAR_XYINPUT, EVENT_SYSTEM_NOP);
control->registerDragEventHandler(this, (uintptr_t)0);
// 3. Get the toolbar sub-window from the framed window
@ -1488,6 +1533,18 @@ bool CWindow::toolbarGrab(FAR struct SEventMsg *eventmsg)
{
twminfo("GRAB (%d,%d)\n", eventmsg->pos.x, eventmsg->pos.y);
// Override application mouse events while dragging. This is necessary to
// to handle cases where the drag that starts in the toolbar is moved
// into the application window area.
bool success =
m_windowEvent->configureEvents((FAR void *)this, EVENT_SYSTEM_NOP,
EVENT_TOOLBAR_XYINPUT, EVENT_SYSTEM_NOP);
if (!success)
{
return false;
}
// Promote the window to a modal window
m_modal = true;
@ -1645,7 +1702,11 @@ bool CWindow::toolbarUngrab(FAR struct SEventMsg *eventmsg)
m_twm4nx->setCursorImage(&CONFIG_TWM4NX_CURSOR_IMAGE);
#endif
return true;
// Restore normal application event handling.
return m_windowEvent->configureEvents(m_eventObj, m_redrawEvent,
m_mouseEvent, m_kbdEvent);
}
/**

View File

@ -96,20 +96,29 @@ using namespace Twm4Nx;
*
* @param twm4nx The Twm4Nx session instance.
* @param obj Contextual object (Usually 'this' of instantiator)
* @param isBackground True is this for the background window.
* @param redrawEvent The event to send on window redraw events. This may
* be EVENT_SYSTEM_NOP to ignore all rdraw events.
* @param mouseEvent The event to send on mouse/touchscreen input events.
* This may be EVENT_SYSTEM_NOP to ignore all mouse/touchscreen input
* events.
* @param kbdEvent The event to send on keyboard input events. This may be
* EVENT_SYSTEM_NOP to ignore all keyboard input events.
* @param style The default style that all widgets on this display
* should use. If this is not specified, the widget will use the
* values stored in the defaultCWidgetStyle object.
*/
CWindowEvent::CWindowEvent(FAR CTwm4Nx *twm4nx, FAR void *obj,
bool isBackground,
uint16_t redrawEvent, uint16_t mouseEvent,
uint16_t kbdEvent,
FAR const NXWidgets::CWidgetStyle *style)
: NXWidgets::CWidgetControl(style)
{
m_twm4nx = twm4nx; // Cache the Twm4Nx session
m_object = obj; // Used for event message construction
m_isBackground = isBackground; // Background window?
m_redrawEvent = redrawEvent; // Redraw event ID
m_mouseEvent = mouseEvent; // Mouse/touchscreen event ID
m_kbdEvent = kbdEvent; // Keyboard event ID
// Dragging
@ -162,12 +171,12 @@ void CWindowEvent::handleRedrawEvent(FAR const nxgl_rect_s *nxRect,
{
twminfo("background=%s\n", m_isBackground ? "YES" : "NO");
// At present, only the background window will get redraw events
// Does the user need redraw events?
if (m_isBackground)
if (m_redrawEvent != EVENT_SYSTEM_NOP)
{
struct SRedrawEventMsg msg;
msg.eventID = EVENT_BACKGROUND_REDRAW;
msg.eventID = m_redrawEvent;
msg.rect.pt1.x = nxRect->pt1.x;
msg.rect.pt1.y = nxRect->pt1.y;
msg.rect.pt2.x = nxRect->pt2.x;
@ -284,22 +293,27 @@ void CWindowEvent::handleMouseEvent(FAR const struct nxgl_point_s *pos,
}
}
// Stimulate an XY input poll
// Does the user want to know about mouse input?
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)
if (m_mouseEvent != EVENT_SYSTEM_NOP)
{
twmerr("ERROR: mq_send failed: %d\n", ret);
// Stimulate an XY input poll
twminfo("Mouse Input...\n");
struct SXyInputEventMsg msg;
msg.eventID = m_mouseEvent;
msg.obj = m_object;
msg.pos.x = pos->x;
msg.pos.y = pos->y;
msg.buttons = buttons;
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
@ -311,22 +325,25 @@ void CWindowEvent::handleMouseEvent(FAR const struct nxgl_point_s *pos,
void CWindowEvent::handleKeyboardEvent(void)
{
twminfo("Keyboard input...\n");
// Does the user want to know about keyboard input?
// Stimulate an keyboard event widget poll
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)
if (m_kbdEvent != EVENT_SYSTEM_NOP)
{
twmerr("ERROR: mq_send failed: %d\n", ret);
twminfo("Keyboard input...\n");
// Stimulate an keyboard event widget poll
struct SNxEventMsg msg;
msg.eventID = m_kbdEvent;
msg.obj = m_object;
msg.instance = this;
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
@ -349,12 +366,10 @@ void CWindowEvent::handleBlockedEvent(FAR void *arg)
{
twminfo("Blocked...\n");
struct SNxEventMsg msg =
{
.eventID = EVENT_WINDOW_DELETE,
.instance = this,
.obj = arg
};
struct SNxEventMsg msg;
msg.eventID = EVENT_WINDOW_DELETE;
msg.obj = arg;
msg.instance = this;
int ret = mq_send(m_eventq, (FAR const char *)&msg,
sizeof(struct SNxEventMsg), 100);

View File

@ -62,6 +62,7 @@
#include "graphics/twm4nx/cwindow.hxx"
#include "graphics/twm4nx/cwindowfactory.hxx"
#include "graphics/twm4nx/ciconmgr.hxx"
#include "graphics/twm4nx/cmainmenu.hxx"
#include "graphics/twm4nx/twm4nx_widgetevents.hxx"
/////////////////////////////////////////////////////////////////////////////
@ -95,9 +96,36 @@ CWindowFactory::~CWindowFactory(void)
{
}
/**
* Add Icon Manager menu items to the Main menu. This is really part
* of the instance initialization, but cannot be executed until the
* Main Menu logic is ready.
*
* @return True on success
*/
bool CWindowFactory::addMenuItems(void)
{
// Add the Icon Manager entry to the Main Menu. This provides a quick
// way to de-iconfigy all windows and show a clean desktop.
FAR CMainMenu *cmain = m_twm4nx->getMainMenu();
if (!cmain->addApplication(&m_desktopItem))
{
twmerr("ERROR: Failed to add to the Main Menu\n");
return false;
}
return true;
}
/**
* Create a new window and add it to the window list.
*
* The window is initialized with all application events disabled.
* The CWindows::configureEvents() method may be called as a second
* initialization step in order to enable application events.
*
* @param name The window name
* @param sbitmap The Icon bitmap
* @param iconMgr Pointer to icon manager instance
@ -266,7 +294,7 @@ bool CWindowFactory::event(FAR struct SEventMsg *eventmsg)
switch (eventmsg->eventID)
{
case EVENT_WINDOW_XYINPUT: // Poll for toolbar mouse/touch events
case EVENT_TOOLBAR_XYINPUT: // Poll for toolbar mouse/touch events
{
FAR struct SXyInputEventMsg *nxmsg =
(FAR struct SXyInputEventMsg *)eventmsg;
@ -277,20 +305,13 @@ bool CWindowFactory::event(FAR struct SEventMsg *eventmsg)
}
break;
case EVENT_WINDOW_KBDINPUT: // Poll for toolbar keyboard events
{
FAR struct SNxEventMsg *nxmsg =
(FAR struct SNxEventMsg *)eventmsg;
FAR CWindow *cwin = (FAR CWindow *)nxmsg->obj;
DEBUGASSERT(cwin != (FAR CWindow *)0);
success = cwin->pollToolbarEvents();
}
case EVENT_WINDOW_DESKTOP: // Show the desktop
success = showDesktop();
break;
// Forward the event to the appropriate window
default: // All other window messsages
default: // All other window messsages
{
FAR CWindow *cwin = (FAR CWindow *)eventmsg->obj;
DEBUGASSERT(cwin != (FAR CWindow *)0);
@ -373,3 +394,26 @@ FAR struct SWindow *CWindowFactory::findWindow(FAR CWindow *cwin)
return (FAR struct SWindow *)0;
}
/**
* This is the function that responds to the EVENT_WINDOW_DESKTOP. It
* iconifies all windows so that the desktop is visible.
*/
bool CWindowFactory::showDesktop(void)
{
// Add the Icon Manager entry to the Main Menu. This provides a quick
// way to de-iconfigy all windows and show a clean desktop.
for (FAR struct SWindow *win = m_windowHead;
win != (FAR struct SWindow *)0;
win = win->flink)
{
// Iconify everything: Application windows, the Icon Manage, all
// Menus, etc.
win->cwin->iconify();
}
return true;
}

View File

@ -184,8 +184,7 @@ namespace Twm4Nx
void handleActionEvent(const NXWidgets::CWidgetEventArgs &e);
/**
* Return the name of the application. This is the string that will
* appear in the Main Menu item. This overrides the method from
* Return the Main Menu item string. This overrides the method from
* IApplication
*
* @param name The name of the application.
@ -197,10 +196,7 @@ namespace Twm4Nx
}
/**
* Return any submenu item associated with the menu entry. If a non-
* null value is returned, then this sub-menu will be brought up when
* the menu entry is selected. Otherwise, the start() method will be
* called. These two behaviors are mutually exlusive. This overrides
* 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.
@ -212,13 +208,8 @@ namespace Twm4Nx
}
/**
* This is the application start up function. This function will be
* called when its menu entry has been selected in order to start the
* application. This function will not be called in this implementation
*
* @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.
* There is no application start-up function. This function will not
* be called in this implementation
*/
inline void start(FAR CTwm4Nx *twm4nx)
@ -226,10 +217,7 @@ namespace Twm4Nx
}
/**
* External applications may provide their own event handler that runs
* when the the menu item is selection. If so, then this method will
* return the instance of CTwm4NxEvent that will handle the event. This
* method always returns NULL in this case.
* There is no custom event handler. We use the common event handler.
*
* @return. null is always returned in this impementation.
*/
@ -240,10 +228,10 @@ namespace Twm4Nx
}
/**
* Get the Twm4Nx event that will be generated when the menu item is
* selected.
* Return the Twm4Nx event that will be generated when the Main Menu
* item is selected.
*
* @return. This function returns .
* @return. This function always returns EVENT_ICONMGR_DEICONIFY.
*/
inline uint16_t getEvent(void)

View File

@ -115,19 +115,19 @@
namespace NXWidgets
{
class CNxString; // Forward reference
class CImage; // Forward reference
class CLabel; // Forward reference
struct SRlePaletteBitmap; // Forward reference
class CNxString; // Forward reference
class CImage; // Forward reference
class CLabel; // Forward reference
struct SRlePaletteBitmap; // Forward reference
}
namespace Twm4Nx
{
class CIconWidget; // Forward reference
class CIconMgr; // Forward reference
class CWindow; // Forward reference
struct SMenuRoot; // Forward reference
struct SMenuItem; // Forward reference
class CIconWidget; // Forward reference
class CIconMgr; // Forward reference
class CWindow; // Forward reference
struct SMenuRoot; // Forward reference
struct SMenuItem; // Forward reference
// The CWindow class implements a standard, framed window with a toolbar
// containing the standard buttons and the window title.
@ -137,35 +137,40 @@ namespace Twm4Nx
public CTwm4NxEvent
{
private:
CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */
mqd_t m_eventq; /**< NxWidget event message queue */
CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */
mqd_t m_eventq; /**< NxWidget event message queue */
// Primary Window
NXWidgets::CNxString m_name; /**< Name of the window */
FAR NXWidgets::CNxTkWindow *m_nxWin; /**< The contained NX primary window */
nxgl_coord_t m_minWidth; /**< The minimum width of the window */
uint16_t m_zoom; /**< Window zoom: ZOOM_NONE or EVENT_RESIZE_* */
bool m_modal; /**< Window zoom: ZOOM_NONE or EVENT_RESIZE_* */
NXWidgets::CNxString m_name; /**< Name of the window */
FAR NXWidgets::CNxTkWindow *m_nxWin; /**< The contained NX primary window */
FAR CWindowEvent *m_windowEvent; /**< Cached window event reference */
FAR void *m_eventObj; /**< Object reference that accompanies events */
nxgl_coord_t m_minWidth; /**< The minimum width of the window */
uint16_t m_redrawEvent; /**< Redraw event ID */
uint16_t m_mouseEvent; /**< Mouse/touchscreen event ID */
uint16_t m_kbdEvent; /**< Keyboard event ID */
uint16_t m_zoom; /**< Window zoom: ZOOM_NONE or EVENT_RESIZE_* */
bool m_modal; /**< Window zoom: ZOOM_NONE or EVENT_RESIZE_* */
// Icon
FAR NXWidgets::CRlePaletteBitmap *m_iconBitMap; /**< The icon image */
FAR CIconWidget *m_iconWidget; /**< The icon widget */
FAR CIconMgr *m_iconMgr; /**< Pointer to it if this is an icon manager */
bool m_iconMoved; /**< User explicitly moved the icon. */
bool m_iconOn; /**< Icon is visible. */
bool m_iconified; /**< Is the window an icon now ? */
FAR CIconWidget *m_iconWidget; /**< The icon widget */
FAR CIconMgr *m_iconMgr; /**< Pointer to it if this is an icon manager */
bool m_iconMoved; /**< User explicitly moved the icon. */
bool m_iconOn; /**< Icon is visible. */
bool m_iconified; /**< Is the window an icon now ? */
// Toolbar
FAR NXWidgets::CNxToolbar *m_toolbar; /**< The tool bar sub-window */
FAR NXWidgets::CLabel *m_tbTitle; /**< Toolbar title widget */
nxgl_coord_t m_tbHeight; /**< Height of the toolbar */
nxgl_coord_t m_tbLeftX; /**< Rightmost position of left buttons */
nxgl_coord_t m_tbRightX; /**< Leftmost position of right buttons */
uint8_t m_tbFlags; /**< Toolbar button customizations */
FAR NXWidgets::CNxToolbar *m_toolbar; /**< The tool bar sub-window */
FAR NXWidgets::CLabel *m_tbTitle; /**< Toolbar title widget */
nxgl_coord_t m_tbHeight; /**< Height of the toolbar */
nxgl_coord_t m_tbLeftX; /**< Rightmost position of left buttons */
nxgl_coord_t m_tbRightX; /**< Leftmost position of right buttons */
uint8_t m_tbFlags; /**< Toolbar button customizations */
// List of all toolbar button images
@ -173,14 +178,19 @@ namespace Twm4Nx
// Dragging
struct nxgl_point_s m_dragPos; /**< Last reported mouse position */
struct nxgl_size_s m_dragCSize; /**< The grab cursor size */
bool m_dragging; /**< True: Drag in-progress */
volatile bool m_clicked; /**< True: Mouse left button is clicked */
struct nxgl_point_s m_dragPos; /**< Last reported mouse position */
struct nxgl_size_s m_dragCSize; /**< The grab cursor size */
bool m_dragging; /**< True: Drag in-progress */
volatile bool m_clicked; /**< True: Mouse left button is clicked */
/**
* Create the main window
*
* Initially, the application window will generate no window-related events
* (redraw, mouse/touchscreen, keyboard input, etc.). After creating the
* window, the user may call the configureEvents() method to select the
* eventIDs of the events to be generated.
*
* @param winsize The initial window size
* @param winpos The initial window position
* @param flags Toolbar customizations see WFLAGS_NO_* definitions
@ -391,6 +401,10 @@ namespace Twm4Nx
/**
* CWindow Initializer (unlike the constructor, this may fail)
*
* The window is initialized with all application events disabled.
* The CWindows::configureEvents() method may be called as a second
* initialization step in order to enable application events.
*
* @param name The the name of the window (and its icon)
* @param pos The initial position of the window
* @param size The initial size of the window
@ -407,6 +421,24 @@ namespace Twm4Nx
FAR const struct NXWidgets::SRlePaletteBitmap *sbitmap,
FAR CIconMgr *iconMgr, uint8_t flags);
/**
* Configure application window events.
*
* @param obj An object reference that will be provided with the event
* to assist in handling the event. This may be NULL is not needed
* @param redrawEvent The event to send on window redraw events. This
* may be EVENT_SYSTEM_NOP to ignore all rdraw events.
* @param mouseEvent The event to send on mouse/touchscreen input
* events. This may be EVENT_SYSTEM_NOP to ignore all mouse/
* touchscreen input events.
* @param kbdEvent The event to send on keyboard input events. This
* may be EVENT_SYSTEM_NOP to ignore all keyboard input events.
* @return True is returned on success
*/
bool configureEvents(FAR void *obj, uint16_t redrawEvent,
uint16_t mouseEvent, uint16_t kbdEvent);
/**
* Synchronize the window with the NX server. This function will delay
* until the the NX server has caught up with all of the queued requests.

View File

@ -142,7 +142,9 @@ namespace Twm4Nx
FAR CTwm4Nx *m_twm4nx; /**< Cached instance of CTwm4Nx */
mqd_t m_eventq; /**< NxWidget event message queue */
FAR void *m_object; /**< Window object (context specific) */
bool m_isBackground; /**< True if this serves the background window */
uint16_t m_redrawEvent; /**< Redraw event ID */
uint16_t m_mouseEvent; /**< Mouse/touchscreen event ID */
uint16_t m_kbdEvent; /**< Keyboard event ID */
// Dragging
@ -192,14 +194,21 @@ namespace Twm4Nx
*
* @param twm4nx The Twm4Nx session instance.
* @param obj Contextual object (Usually 'this' of instantiator)
* @param isBackground True is this for the background window.
* @param redrawEvent The event to send on window redraw events. This
* may be EVENT_SYSTEM_NOP to ignore all rdraw events.
* @param mouseEvent The event to send on mouse/touchscreen input
* events. This may be EVENT_SYSTEM_NOP to ignore all mouse/
* touchscreen input events.
* @param kbdEvent The event to send on keyboard input events. This
* may be EVENT_SYSTEM_NOP to ignore all keyboard input events.
* @param style The default style that all widgets on this display
* should use. If this is not specified, the widget will use the
* values stored in the defaultCWidgetStyle object.
*/
CWindowEvent(FAR CTwm4Nx *twm4nx, FAR void *obj,
bool isBackground = false,
uint16_t redrawEvent, uint16_t mouseEvent,
uint16_t kbdEvent,
FAR const NXWidgets::CWidgetStyle *style =
(const NXWidgets::CWidgetStyle *)NULL);
@ -225,6 +234,32 @@ namespace Twm4Nx
m_dragHandler = dragHandler;
m_dragArg = arg;
}
/**
* Modify event handlers.
*
* One use for this is by the window drag logic to temporarily capture
* application mouse/touchscreen inputs to handle cases where the drag
* position enters the application window area.
*
* @param redrawEvent The event to send on window redraw events. This
* may be EVENT_SYSTEM_NOP to ignore all rdraw events.
* @param mouseEvent The event to send on mouse/touchscreen input
* events. This may be EVENT_SYSTEM_NOP to ignore all mouse/
* touchscreen input events.
* @param kbdEvent The event to send on keyboard input events. This
* may be EVENT_SYSTEM_NOP to ignore all keyboard input events.
*/
inline bool configureEvents(FAR void *obj, uint16_t redrawEvent,
uint16_t mouseEvent, uint16_t kbdEvent)
{
m_object = obj; // Event object reference
m_redrawEvent = redrawEvent; // Redraw event ID
m_mouseEvent = mouseEvent; // Mouse/touchscreen event ID
m_kbdEvent = kbdEvent; // Keyboard event ID
return true;
}
};
}

View File

@ -53,6 +53,7 @@
#include "graphics/twm4nx/cwindow.hxx"
#include "graphics/twm4nx/ctwm4nxevent.hxx"
#include "graphics/twm4nx/iapplication.hxx"
/////////////////////////////////////////////////////////////////////////////
// Implementation Classes
@ -81,6 +82,72 @@ namespace Twm4Nx
FAR CWindow *cwin; /**< Window object payload */
};
/**
* This class is a simple implement of the interface to the Main Menu that
* provides the Desktop Main Menu entry.
*/
class CDesktopItem : public IApplication
{
public:
/**
* Return the Main Menu item string. This overrides the method from
* IApplication
*
* @param name The name of the application.
*/
inline const NXWidgets::CNxString getName(void)
{
return NXWidgets::CNxString("Desktop");
}
/**
* 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 FAR CMenus *getSubMenu(void)
{
return (FAR CMenus *)0;
}
/**
* There is no application start-up function. This function will not
* be called in this implementation
*/
inline void start(FAR CTwm4Nx *twm4nx)
{
}
/**
* There is no custom event handler. We use the common event handler.
*
* @return. null is always returned in this impementation.
*/
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_WINDOW_DESKTOP.
*/
inline uint16_t getEvent(void)
{
return EVENT_WINDOW_DESKTOP;
}
};
/**
* The CWindowFactory class creates new window instances and manages some
* things that are common to all windows.
@ -90,9 +157,10 @@ namespace Twm4Nx
{
private:
CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */
struct nxgl_point_s m_winpos; /**< Position of next window created */
FAR struct SWindow *m_windowHead; /**< List of all windows on the display */
CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */
struct nxgl_point_s m_winpos; /**< Position of next window created */
FAR struct SWindow *m_windowHead; /**< List of windows on the display */
CDesktopItem m_desktopItem; /**< For the "Desktop" Main Menu item */
/**
* Add a window container to the window list.
@ -120,6 +188,15 @@ namespace Twm4Nx
FAR struct SWindow *findWindow(FAR CWindow *cwin);
/**
* This is the function that responds to the EVENT_WINDOW_DESKTOP. It
* iconifies all windows so that the desktop is visible.
*
* @return True is returned if the operation was successful.
*/
bool showDesktop(void);
public:
/**
@ -136,9 +213,23 @@ namespace Twm4Nx
~CWindowFactory(void);
/**
* Add Icon Manager menu items to the Main menu. This is really part
* of the instance initialization, but cannot be executed until the
* Main Menu logic is ready.
*
* @return True on success
*/
bool addMenuItems(void);
/**
* Create a new window and add it to the window list.
*
* The window is initialized with all application events disabled.
* The CWindows::configureEvents() method may be called as a second
* initialization step in order to enable application events.
*
* @param name The window name
* @param sbitmap The Icon bitmap
* @param iconMgr Pointer to icon manager instance

View File

@ -110,9 +110,8 @@ namespace Twm4Nx
// Recipient == BACKGOUND
EVENT_BACKGROUND_XYINPUT = 0x1000, /**< Poll window for widget mouse/touch events */
EVENT_BACKGROUND_KBDINPUT = 0x1001, /**< Poll window for widget keyboard events */
EVENT_BACKGROUND_REDRAW = 0x1002, /**< Redraw the background */
EVENT_BACKGROUND_XYINPUT = 0x1000, /**< Poll for widget mouse/touch events */
EVENT_BACKGROUND_REDRAW = 0x1001, /**< Redraw the background */
// Recipient == ICONWIDGET
@ -122,16 +121,18 @@ namespace Twm4Nx
// Recipient == ICONMGR
EVENT_ICONMGR_DEICONIFY = 0x3000, /**< De-iconify or raise the Icon Manager */
EVENT_ICONMGR_XYINPUT = 0x3000, /**< Poll for widget mouse/touch events */
EVENT_ICONMGR_DEICONIFY = 0x3001, /**< De-iconify or raise the Icon Manager */
// Recipient == MENU
EVENT_MENU_IDENTIFY = 0x4000, /**< Describe the window */
EVENT_MENU_VERSION = 0x4001, /**< Show the Twm4Nx version */
EVENT_MENU_ICONIFY = 0x4002, /**< Tool bar minimize button pressed */
EVENT_MENU_DEICONIFY = 0x4003, /**< Window icon pressed */
EVENT_MENU_SUBMENU = 0x4004, /**< Sub-menu selected */
EVENT_MENU_FUNCTION = 0x4005, /**< Perform function on unknown menu */
EVENT_MENU_XYINPUT = 0x4000, /**< Poll for widget mouse/touch events */
EVENT_MENU_IDENTIFY = 0x4001, /**< Describe the window */
EVENT_MENU_VERSION = 0x4002, /**< Show the Twm4Nx version */
EVENT_MENU_ICONIFY = 0x4003, /**< Tool bar minimize button pressed */
EVENT_MENU_DEICONIFY = 0x4004, /**< Window icon pressed */
EVENT_MENU_SUBMENU = 0x4005, /**< Sub-menu selected */
EVENT_MENU_FUNCTION = 0x4006, /**< Perform function on unknown menu */
// Recipient == MAINMENU
@ -139,37 +140,38 @@ namespace Twm4Nx
// Recipient == WINDOW
EVENT_WINDOW_XYINPUT = 0x6000, /**< Poll window for widget mouse/touch events */
EVENT_WINDOW_KBDINPUT = 0x6001, /**< Poll window for widget keyboard events */
EVENT_WINDOW_FOCUS = 0x6002, /**< Enter modal state */
EVENT_WINDOW_UNFOCUS = 0x6003, /**< Exit modal state */
EVENT_WINDOW_RAISE = 0x6004, /**< Raise window to the top of the heirarchy */
EVENT_WINDOW_LOWER = 0x6005, /**< Lower window to the bottom of the heirarchy */
EVENT_WINDOW_DEICONIFY = 0x6006, /**< De-iconify and raise window */
EVENT_WINDOW_DRAG = 0x6007, /**< Drag window */
EVENT_WINDOW_DELETE = 0x6008, /**< Delete window */
EVENT_WINDOW_FOCUS = 0x6000, /**< Enter modal state */
EVENT_WINDOW_UNFOCUS = 0x6001, /**< Exit modal state */
EVENT_WINDOW_RAISE = 0x6002, /**< Raise window to the top of the heirarchy */
EVENT_WINDOW_LOWER = 0x6003, /**< Lower window to the bottom of the heirarchy */
EVENT_WINDOW_DEICONIFY = 0x6004, /**< De-iconify and raise window */
EVENT_WINDOW_DRAG = 0x6005, /**< Drag window */
EVENT_WINDOW_DELETE = 0x6006, /**< Delete window */
EVENT_WINDOW_DESKTOP = 0x6007, /**< Show the desktop */
// Recipient == TOOLBAR
EVENT_TOOLBAR_GRAB = 0x7000, /**< Click on title widget */
EVENT_TOOLBAR_UNGRAB = 0x7001, /**< Release click on title widget */
EVENT_TOOLBAR_MENU = 0x7002, /**< Toolbar menu button released */
EVENT_TOOLBAR_MINIMIZE = 0x7003, /**< Toolbar minimize button released */
EVENT_TOOLBAR_RESIZE = 0x7004, /**< Toolbar resize button released */
EVENT_TOOLBAR_TERMINATE = 0x7005, /**< Toolbar delete button released */
EVENT_TOOLBAR_XYINPUT = 0x7000, /**< Poll for widget mouse/touch events */
EVENT_TOOLBAR_GRAB = 0x7001, /**< Click on title widget */
EVENT_TOOLBAR_UNGRAB = 0x7002, /**< Release click on title widget */
EVENT_TOOLBAR_MENU = 0x7003, /**< Toolbar menu button released */
EVENT_TOOLBAR_MINIMIZE = 0x7004, /**< Toolbar minimize button released */
EVENT_TOOLBAR_RESIZE = 0x7005, /**< Toolbar resize button released */
EVENT_TOOLBAR_TERMINATE = 0x7006, /**< Toolbar delete button released */
// Recipient == BORDER
// Recipient == RESIZE
EVENT_RESIZE_START = 0x9000, /**< Start window resize */
EVENT_RESIZE_VERTZOOM = 0x9001, /**< Zoom vertically only */
EVENT_RESIZE_HORIZOOM = 0x9002, /**< Zoom horizontally only */
EVENT_RESIZE_FULLZOOM = 0x9003, /**< Zoom both vertically and horizontally */
EVENT_RESIZE_LEFTZOOM = 0x9004, /**< Zoom left only */
EVENT_RESIZE_RIGHTZOOM = 0x9005, /**< Zoom right only */
EVENT_RESIZE_TOPZOOM = 0x9006, /**< Zoom top only */
EVENT_RESIZE_BOTTOMZOOM = 0x9007, /**< Zoom bottom only */
EVENT_RESIZE_XYINPUT = 0x9000, /**< Poll for widget mouse/touch events */
EVENT_RESIZE_START = 0x9001, /**< Start window resize */
EVENT_RESIZE_VERTZOOM = 0x9002, /**< Zoom vertically only */
EVENT_RESIZE_HORIZOOM = 0x9003, /**< Zoom horizontally only */
EVENT_RESIZE_FULLZOOM = 0x9004, /**< Zoom both vertically and horizontally */
EVENT_RESIZE_LEFTZOOM = 0x9005, /**< Zoom left only */
EVENT_RESIZE_RIGHTZOOM = 0x9006, /**< Zoom right only */
EVENT_RESIZE_TOPZOOM = 0x9007, /**< Zoom top only */
EVENT_RESIZE_BOTTOMZOOM = 0x9008, /**< Zoom bottom only */
// Recipient == APP
// All application defined events must (1) use recepient == EVENT_RECIPIENT_APP,
@ -194,16 +196,17 @@ namespace Twm4Nx
/**
* This type represents a generic messages, particularly button press
* or released events.
* or release events.
*/
struct SEventMsg
{
uint16_t eventID; /**< Encoded event ID */
FAR void *obj; /**< Context specific reference */
struct nxgl_point_s pos; /**< X/Y position */
uint8_t context; /**< Button press context */
FAR CTwm4NxEvent *handler; /**< App event handler (APP recipient only) */
FAR void *obj; /**< Window object (CWindow or CIconWidget) */
};
/**
@ -213,32 +216,37 @@ namespace Twm4Nx
struct SRedrawEventMsg
{
uint16_t eventID; /**< Encoded event ID */
FAR void *obj; /**< Context specific reference */
struct nxgl_rect_s rect; /**< Region to be redrawn */
bool more; /**< True: More redraw requests will follow */
};
/**
* This message for is used with CWindowEVent mouse/keyboard input events
* This message form is used with CWindowEVent mouse/touchscreen
* input events
*/
struct SXyInputEventMsg
{
uint16_t eventID; /**< Encoded event ID */
FAR void *obj; /**< Context specific reference */
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
* This message form of the message used by CWindowEvent for blocked and
* keyboard input messages
*/
struct SNxEventMsg
{
uint16_t eventID; /**< Encoded event ID */
FAR CWindowEvent *instance; /**< X/Y position */
FAR void *obj; /**< Context specific reference */
FAR CWindowEvent *instance; /**< X/Y position */
};
}