Squashed commit of the following:

graphics/twm4nx/src/ciconmgr.cxx:  Integrate use of CButtonArray; implement first cut at event handling.

    graphics/nxwidgets/src/cbuttonarray.cxx:  Add a method to CButtonArray that will allow us to dynamically resize the array (at the cost of losing all button labels).

    graphics/twm4nx/src/ciconmgr.cxx:  Add some fragments of CButtonArray logic.

    graphics/twm4nx/src/cwindow.cxx:  Finishes first cut at window event management.
This commit is contained in:
Gregory Nutt 2019-04-26 12:50:35 -06:00
parent 27194275a5
commit 601659ff59
12 changed files with 592 additions and 328 deletions

View File

@ -125,11 +125,62 @@ CButtonArray::~CButtonArray(void)
delete [] m_buttonText;
}
/**
* Resize the array of buttons. Button labels will be removed and will
* have to be reapplied in the new geometry.
*
* @param buttonColumns The number of buttons in one row of the button array
* @param buttonRows The number of buttons in one column of the button array
* @param buttonWidth The width of one button
* @param buttonHeight The height of one button
*/
bool CButtonArray::resizeArray(uint8_t buttonColumns, uint8_t buttonRows,
nxgl_coord_t buttonWidth, nxgl_coord_t buttonHeight)
{
setRaisesEvents(false);
disableDrawing();
// Delete the current array of CNxString instances
delete [] m_buttonText;
// Update configuration
m_buttonRows = buttonRows;
m_buttonColumns = buttonColumns;
m_buttonWidth = buttonWidth;
m_buttonHeight = buttonHeight;
// Reset the cursor position if necessary
if (m_cursorColumn >= m_buttonColumns)
{
m_cursorColumn = m_buttonColumns - 1;
}
if (m_cursorRow >= m_buttonRows)
{
m_cursorRow = m_buttonRows - 1;
}
// Allocate the new text array
m_buttonText = new CNxString[m_buttonRows * m_buttonColumns];
// And go active again with a resized button array (with no labels)
enableDrawing();
redraw();
setRaisesEvents(true);
return true;
}
/**
* Returns the string shown in the label.
*
* @param column The column index of the button of interest
* @param row The row index of the button of interest
* @param row The row index of the button of interest
* @return The label's text.
*/

View File

@ -731,6 +731,13 @@ int CNxString::compareTo(const CNxString &string) const
getLength());
}
int CNxString::compareTo(FAR const char *string) const
{
return memcmp((FAR const char*)m_text,
(FAR const char*)string,
getLength());
}
/**
* Allocate memory for the string.
*

View File

@ -45,4 +45,6 @@ STATUS
4. Widget events are only partially integrated. A lot more needs to be
done. A partial change to the event system that hints at the redesign
is in place but it is far from complete.
2019-04-26: Added button arrays for implementation of Icon Manager.
Integrated event handling into CWindows and CIconMgr.

View File

@ -52,6 +52,8 @@
#include "graphics/nxwidgets/cnxwindow.hxx"
#include "graphics/nxwidgets/cnxfont.hxx"
#include "graphics/nxwidgets/cnxstring.hxx"
#include "graphics/nxwidgets/cbuttonarray.hxx"
#include <nuttx/nx/nx.h>
#include <nuttx/nx/nxglib.h>
@ -81,17 +83,17 @@ using namespace Twm4Nx;
* @param ncolumns The number of columns this icon manager has
*/
CIconMgr::CIconMgr(CTwm4Nx *twm4nx, int ncolumns)
CIconMgr::CIconMgr(CTwm4Nx *twm4nx, uint8_t ncolumns)
{
m_twm4nx = twm4nx; // Cached the Twm4Nx session
m_head = (FAR struct SWindowEntry *)0; // Head of the winow list
m_tail = (FAR struct SWindowEntry *)0; // Tail of the winow list
m_active = (FAR struct SWindowEntry *)0; // No active window
m_window = (FAR CWindow *)0; // No icon manager Window
m_columns = ncolumns;
m_currows = 0;
m_curcolumns = 0;
m_count = 0;
m_maxColumns = ncolumns; // Max columns per row
m_nrows = 0; // No rows yet
m_ncolumns = 0; // No columns yet
m_nWindows = 0; // No windows yet
}
/**
@ -100,14 +102,19 @@ CIconMgr::CIconMgr(CTwm4Nx *twm4nx, int ncolumns)
CIconMgr::~CIconMgr(void)
{
// Free memory allocations
// Free the icon manager window
if (m_window != (FAR CWindow *)0)
{
delete m_window;
}
// Free the button array
if (m_buttons != (FAR NXWidgets::CButtonArray *)0)
{
delete m_buttons;
}
}
/**
@ -171,25 +178,16 @@ bool CIconMgr::add(FAR CWindow *cwin)
wentry->active = false;
wentry->down = false;
wentry->cwin = cwin;
FAR CFonts *fonts = m_twm4nx->getFonts();
FAR NXWidgets::CNxFont *iconManagerFont = fonts->getIconManagerFont();
wentry->me = m_count;
wentry->pos.x = -1;
wentry->pos.y = -1;
wentry->pos.x = -1;
wentry->pos.y = -1;
// Insert the new entry into the list
insertEntry(wentry, cwin);
// The height of one row is determined (mostly) by the fond height
// The height of one row is determined (mostly) by the font height
int rowHeight = iconManagerFont->getHeight() + 10;
if (rowHeight < (CONFIG_TWM4NX_ICONMGR_IMAGE.width + 4))
{
rowHeight = CONFIG_TWM4NX_ICONMGR_IMAGE.width + 4;
}
nxgl_coord_t rowHeight = getRowHeight();
// Increase the icon window size
@ -200,13 +198,13 @@ bool CIconMgr::add(FAR CWindow *cwin)
}
else
{
windowSize.h = rowHeight * m_count;
windowSize.h = rowHeight * m_nWindows;
m_window->setWindowSize(&windowSize);
}
// Increment the window count
m_count++;
m_nWindows++;
// Pack the windows
@ -238,155 +236,25 @@ void CIconMgr::remove(FAR struct SWindow *win)
removeEntry(wentry);
// Destroy the button array widget
#warning Missing logic
// Destroy the window
CWindowFactory *factory = m_twm4nx->getWindowFactory();
factory->destroyWindow(wentry->cwin);
m_count -= 1;
m_nWindows--;
std::free(wentry);
pack();
}
}
/**
* Move the pointer around in an icon manager
*
* @param dir one of the following:
* - EVENT_ICONMGR_FORWARD: Forward in the window list
* - EVENT_ICONMGR_BACK: Backward in the window list
* - EVENT_ICONMGR_UP: Up one row
* - EVENT_ICONMGR_DOWN: Down one row
* - EVENT_ICONMGR_LEFT: Left one column
* - EVENT_ICONMGR_RIGHT: Right one column
*/
void CIconMgr::move(int dir)
{
if (!m_active)
{
return;
}
int curRow = m_active->row;
int curCol = m_active->col;
int rowIncr = 0;
int colIncr = 0;
bool gotIt = false;
FAR struct SWindowEntry *wentry = (FAR struct SWindowEntry *)0;
switch (dir)
{
case EVENT_ICONMGR_FORWARD:
if ((wentry = m_active->flink) == (FAR struct SWindowEntry *)0)
{
wentry = m_head;
}
gotIt = true;
break;
case EVENT_ICONMGR_BACK:
if ((wentry = m_active->blink) == (FAR struct SWindowEntry *)0)
{
wentry = m_tail;
}
gotIt = true;
break;
case EVENT_ICONMGR_UP:
rowIncr = -1;
break;
case EVENT_ICONMGR_DOWN:
rowIncr = 1;
break;
case EVENT_ICONMGR_LEFT:
colIncr = -1;
break;
case EVENT_ICONMGR_RIGHT:
colIncr = 1;
break;
}
// If gotIt is false ast this point then we got a left, right, up, or down,
// command.
int newRow = curRow;
int newCol = curCol;
while (!gotIt)
{
newRow += rowIncr;
newCol += colIncr;
if (newRow < 0)
{
newRow = m_currows - 1;
}
if (newCol < 0)
{
newCol = m_curcolumns - 1;
}
if (newRow >= (int)m_currows)
{
newRow = 0;
}
if (newCol >= (int)m_curcolumns)
{
newCol = 0;
}
// Now let's go through the list to see if there is an entry with this
// new position.
for (wentry = m_head; wentry != NULL; wentry = wentry->flink)
{
if (wentry->row == newRow && wentry->col == newCol)
{
gotIt = true;
break;
}
}
}
if (!gotIt)
{
gwarn("WARNING: unable to find window (%d, %d) in icon manager\n",
newRow, newCol);
return;
}
// raise the frame so the icon manager is visible
}
/**
* Pack the icon manager windows following an addition or deletion
*/
void CIconMgr::pack(void)
{
FAR CFonts *fonts = m_twm4nx->getFonts();
FAR NXWidgets::CNxFont *iconManagerFont = fonts->getIconManagerFont();
struct nxgl_size_s colsize;
colsize.h = iconManagerFont->getHeight() + 10;
if (colsize.h < (CONFIG_TWM4NX_ICONMGR_IMAGE.height + 4))
{
colsize.h = CONFIG_TWM4NX_ICONMGR_IMAGE.height + 4;
}
colsize.h = getRowHeight();
struct nxgl_size_s windowSize;
if (!m_window->getWindowSize(&windowSize))
@ -395,13 +263,13 @@ void CIconMgr::pack(void)
return;
}
colsize.w = windowSize.w / m_columns;
colsize.w = windowSize.w / m_maxColumns;
int rowIncr = colsize.h;
int colIncr = colsize.w;
int row = 0;
int col = m_columns;
int col = m_maxColumns;
int maxcol = 0;
FAR struct SWindowEntry *wentry;
@ -411,10 +279,9 @@ void CIconMgr::pack(void)
wentry != (FAR struct SWindowEntry *)0;
i++, wentry = wentry->flink)
{
wentry->me = i;
if (++col >= (int)m_columns)
if (++col >= (int)m_maxColumns)
{
col = 0;
col = 0;
row += 1;
}
@ -424,11 +291,11 @@ void CIconMgr::pack(void)
}
struct nxgl_point_s newpos;
newpos.x = col * colIncr;
newpos.y = (row - 1) * rowIncr;
newpos.x = col * colIncr;
newpos.y = (row - 1) * rowIncr;
wentry->row = row - 1;
wentry->col = col;
wentry->row = row - 1;
wentry->col = col;
// If the position or size has not changed, don't touch it
@ -446,53 +313,85 @@ void CIconMgr::pack(void)
}
}
maxcol += 1;
m_currows = row;
m_curcolumns = maxcol;
maxcol++;
// The height of one row is determined (mostly) by the fond height
// Check if there is a change in the dimension of the button array
int rowHeight = iconManagerFont->getHeight() + 10;
if (rowHeight < (CONFIG_TWM4NX_ICONMGR_IMAGE.width + 4))
if (m_nrows != row && m_ncolumns != maxcol)
{
rowHeight = CONFIG_TWM4NX_ICONMGR_IMAGE.width + 4;
// Yes.. remember the new size
m_nrows = row;
m_ncolumns = maxcol;
// The height of one row is determined (mostly) by the font height
windowSize.h = getRowHeight() * m_nWindows;
if (!m_window->getWindowSize(&windowSize))
{
gerr("ERROR: getWindowSize() failed\n");
return;
}
if (windowSize.h == 0)
{
windowSize.h = rowIncr;
}
struct nxgl_size_s newsize;
newsize.w = maxcol * colIncr;
if (newsize.w == 0)
{
newsize.w = colIncr;
}
newsize.h = windowSize.h;
if (!m_window->setWindowSize(&newsize))
{
gerr("ERROR: setWindowSize() failed\n");
return;
}
// Resize the button array
nxgl_coord_t buttonWidth = newsize.w / m_maxColumns;
nxgl_coord_t buttonHeight = newsize.w / m_nrows;
if (!m_buttons->resizeArray(m_maxColumns, m_nrows,
buttonWidth, buttonHeight))
{
gerr("ERROR: CButtonArray::resizeArray failed\n");
return;
}
// Re-apply all of the button labels
int rowndx = 0;
int colndx = 0;
for (FAR struct SWindowEntry *swin = m_head;
swin != (FAR struct SWindowEntry *)0;
swin = swin->flink)
{
// Get the window name as an NWidgets::CNxString
NXWidgets::CNxString string = swin->cwin->getWindowName();
// Apply the window name to the button
m_buttons->setText(colndx, rowndx, string);
// Increment the column, rolling over to the next row if necessary
if (++colndx >= m_maxColumns)
{
colndx = 0;
rowndx++;
}
}
}
windowSize.h = rowHeight * m_count;
m_window->setWindowSize(&windowSize);
if (windowSize.h == 0)
{
windowSize.h = rowIncr;
}
struct nxgl_size_s newsize;
newsize.w = maxcol * colIncr;
if (newsize.w == 0)
{
newsize.w = colIncr;
}
newsize.h = windowSize.h;
if (!m_window->setWindowSize(&newsize))
{
return;
}
// Get the net size of the containing frame
struct nxgl_size_s frameSize;
m_window->windowToFrameSize(&windowSize, &frameSize);
struct nxgl_point_s framePos;
m_window->getFramePosition(&framePos);
// Resize the frame
FAR CResize *resize = m_twm4nx->getResize();
resize->setupWindow(m_window, &framePos, &frameSize);
}
/**
@ -546,35 +445,6 @@ bool CIconMgr::event(FAR struct SEventMsg *msg)
switch (msg->eventID)
{
case EVENT_ICONMGR_UP:
case EVENT_ICONMGR_DOWN:
case EVENT_ICONMGR_LEFT:
case EVENT_ICONMGR_RIGHT:
case EVENT_ICONMGR_FORWARD:
case EVENT_ICONMGR_BACK:
{
move(msg->eventID);
}
break;
case EVENT_ICONMGR_SHOWPARENT: // Raise Icon manager parent window
{
m_window->deIconify();
}
break;
case EVENT_ICONMGR_HIDE: // Hide the Icon Manager
{
hide();
}
break;
case EVENT_ICONMGR_SORT: // Sort the Icon Manager
{
sort();
}
break;
default:
ret = false;
break;
@ -583,6 +453,26 @@ bool CIconMgr::event(FAR struct SEventMsg *msg)
return ret;
}
/**
* Return the height of one row
*
* @return The height of one row
*/
nxgl_coord_t CIconMgr::getRowHeight(void)
{
FAR CFonts *fonts = m_twm4nx->getFonts();
FAR NXWidgets::CNxFont *iconManagerFont = fonts->getIconManagerFont();
nxgl_coord_t rowHeight = iconManagerFont->getHeight() + 10;
if (rowHeight < (CONFIG_TWM4NX_ICONMGR_IMAGE.width + 4))
{
rowHeight = CONFIG_TWM4NX_ICONMGR_IMAGE.width + 4;
}
return rowHeight;
}
/**
* Create and initialize the icon manager window
*
@ -634,8 +524,66 @@ bool CIconMgr::createWindow(FAR const char *prefix)
bool CIconMgr::createButtonArray(void)
{
#warning Missing logic
return false;
// Create a Widget control instance for the window using the default style
// for now. CWindowEvent derives from CWidgetControl.
// REVISIT: Create the style, using the selected colors.
FAR CWindowEvent *control = new CWindowEvent(m_twm4nx);
if (control == (FAR CWindowEvent *)0)
{
return false;
}
// Get the width of the window
struct nxgl_size_s windowSize;
if (!m_window->getWindowSize(&windowSize))
{
gerr("ERROR: Failed to get window size\n");
delete control;
return false;
}
// The button must be positioned at the upper left of the window
struct nxgl_point_s arrayPos;
m_window->getWindowPosition(&arrayPos);
// Create the button array
// REVISIT: Hmm.. Button array cannot be dynamically resized!
uint8_t nrows = m_nrows > 0 ? m_nrows : 1;
nxgl_coord_t buttonWidth = windowSize.w / m_maxColumns;
nxgl_coord_t buttonHeight = windowSize.w / nrows;
// Now we have enough information to create the button array
m_buttons = new NXWidgets::CButtonArray(control,
arrayPos.x, arrayPos.y,
m_maxColumns, nrows,
buttonWidth, buttonHeight);
if (m_buttons == (FAR NXWidgets::CButtonArray *)0)
{
gerr("ERROR: Failed to get window size\n");
delete control;
return false;
}
// Configure the button array widget
FAR CFonts *fonts = m_twm4nx->getFonts();
FAR NXWidgets::CNxFont *iconManagerFont = fonts->getIconManagerFont();
m_buttons->setFont(iconManagerFont);
m_buttons->setBorderless(true);
m_buttons->disableDrawing();
m_buttons->setRaisesEvents(false);
// Register to get events from the mouse clicks on the image
m_buttons->addWidgetEventHandler(this);
return true;
}
/**
@ -755,3 +703,54 @@ void CIconMgr::freeWEntry(FAR struct SWindowEntry *wentry)
free(wentry);
}
/**
* Handle a widget action event. This will be a button pre-release event.
*
* @param e The event data.
*/
void CIconMgr::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
{
// A button should now be clicked
int column;
int row;
if (m_buttons->isButtonClicked(column, row))
{
// Get the text associated with this button
const NXWidgets::CNxString string = m_buttons->getText(column, row);
// Now find the window with this name
for (FAR struct SWindowEntry *swin = m_head;
swin != (FAR struct SWindowEntry *)0;
swin = swin->flink)
{
// Check if the button string is the same as the window name
if (string.compareTo(swin->cwin->getWindowName()) == 0)
{
// Got it. Is the window Iconified?
if (swin->cwin->isIconified())
{
// Yes, de-Iconify it
swin->cwin->deIconify();
}
else
{
// Otherwise, raise the window to the top of the heirarchy
swin->cwin->raiseWindow();
}
break;
}
}
}
}

View File

@ -323,10 +323,9 @@ bool CMenus::event(FAR struct SEventMsg *eventmsg)
newmsg.eventID = item->func;
newmsg.pos.x = eventmsg->pos.x;
newmsg.pos.y = eventmsg->pos.y;
newmsg.delta.x = 0;
newmsg.delta.y = 0;
newmsg.context = eventmsg->context;
newmsg.pulldown = eventmsg->pulldown;
newmsg.action = item->action;
newmsg.nxwin = eventmsg->nxwin;
newmsg.obj = eventmsg->obj;
// NOTE that we cannot block because we are on the same thread

View File

@ -661,7 +661,7 @@ void CResize::endResize(FAR CWindow *cwin)
CIconMgr *iconMgr = cwin->getIconMgr();
DEBUGASSERT(iconMgr != (CIconMgr *)0);
unsigned int currcol = iconMgr->getCurrColumn();
unsigned int currcol = iconMgr->getNumberOfColumns();
if (currcol == 0)
{
currcol = 1;
@ -671,7 +671,7 @@ void CResize::endResize(FAR CWindow *cwin)
iconMgr->getSize(&iconMgrSize);
iconMgrSize.w = (unsigned int)
((m_dragsize.w * (unsigned long)iconMgr->getColumns()) / currcol);
((m_dragsize.w * (unsigned long)iconMgr->getDisplayColumns()) / currcol);
cwin->resizeFrame(&iconMgrSize, &pos);
iconMgr->pack();
@ -950,7 +950,7 @@ bool CResize::event(FAR struct SEventMsg *eventmsg)
if (eventmsg->context == EVENT_CONTEXT_FRAME ||
eventmsg->context == EVENT_CONTEXT_WINDOW ||
eventmsg->context == EVENT_CONTEXT_TITLE)
eventmsg->context == EVENT_CONTEXT_TOOLBAR)
{
resizeFromCenter(cwin);
}

View File

@ -80,24 +80,42 @@
#include "graphics/twm4nx/twm4nx_cursor.hxx"
/////////////////////////////////////////////////////////////////////////////
// Private Data
// Private Types
/////////////////////////////////////////////////////////////////////////////
using namespace Twm4Nx;
// Association of configured bitmaps with buttons
static FAR const NXWidgets::SRlePaletteBitmap *GTbBitmaps[NTOOLBAR_BUTTONS] =
struct SToolbarInfo
{
&CONFIG_TWM4NX_MENU_IMAGE, // MENU_BUTTON (first on left)
&CONFIG_TWM4NX_TERMINATE_IMAGE, // DELETE_BUTTON (first on right)
&CONFIG_TWM4NX_RESIZE_IMAGE, // RESIZE_BUTTON
&CONFIG_TWM4NX_MINIMIZE_IMAGE // MINIMIZE_BUTTON
FAR const NXWidgets::SRlePaletteBitmap *bitmap; /**< Bitmap configured for button */
bool rightSide; /**< True: Button packed on the right */
uint16_t event; /**< Event when button released */
};
static bool GButtonRightSide[NTOOLBAR_BUTTONS] =
/////////////////////////////////////////////////////////////////////////////
// Private Data
/////////////////////////////////////////////////////////////////////////////
// This array provides a static description of the toolbar buttons
struct SToolbarInfo GToolBarInfo[NTOOLBAR_BUTTONS] =
{
false, true, true, true,
[MENU_BUTTON] =
{
&CONFIG_TWM4NX_MENU_IMAGE, false, EVENT_TOOLBAR_MENU
},
[DELETE_BUTTON] =
{
&CONFIG_TWM4NX_TERMINATE_IMAGE, true, EVENT_TOOLBAR_TERMINATE
},
[RESIZE_BUTTON] =
{
&CONFIG_TWM4NX_RESIZE_IMAGE, true, EVENT_TOOLBAR_RESIZE
},
[MINIMIZE_BUTTON] =
{
&CONFIG_TWM4NX_MINIMIZE_IMAGE, true, EVENT_TOOLBAR_MINIMIZE
}
};
/////////////////////////////////////////////////////////////////////////////
@ -184,7 +202,7 @@ bool CWindow::initialize(FAR const char *name,
FAR const char *mqname = m_twm4nx->getEventQueueName();
m_eventq = mq_open(mqname, O_WRONLY);
m_eventq = mq_open(mqname, O_WRONLY | O_NONBLOCK);
if (m_eventq == (mqd_t)-1)
{
gerr("ERROR: Failed open message queue '%s': %d\n",
@ -474,17 +492,16 @@ void CWindow::deIconify(void)
bool CWindow::event(FAR struct SEventMsg *eventmsg)
{
FAR NXWidgets::CNxTkWindow *nxwin = eventmsg->nxwin;
bool success = true;
switch (eventmsg->eventID)
{
case EVENT_WINDOW_RAISE: // Raise window to the top of the heirarchy
nxwin->raise(); // Could be the main or the icon window
m_nxWin->raise(); // Could be the main or the icon window
break;
case EVENT_WINDOW_LOWER: // Lower window to the bottom of the heirarchy
nxwin->lower(); // Could be the main or the icon window
m_nxWin->lower(); // Could be the main or the icon window
break;
case EVENT_WINDOW_POPUP: // De-iconify and raise the main window
@ -519,7 +536,7 @@ bool CWindow::event(FAR struct SEventMsg *eventmsg)
// drains all of the message events. We will get the
// EVENT_WINDOW_DELETE event at that point
NXWidgets::CWidgetControl *control = nxwin->getWidgetControl();
NXWidgets::CWidgetControl *control = m_nxWin->getWidgetControl();
nxtk_block(control->getWindowHandle(), (FAR void *)m_nxWin);
}
@ -640,7 +657,7 @@ bool CWindow::getToolbarHeight(FAR const char *name)
for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++)
{
nxgl_coord_t btnHeight = GTbBitmaps[btindex]->height;
nxgl_coord_t btnHeight = GToolBarInfo[btindex].bitmap->height;
if (btnHeight > m_tbHeight)
{
m_tbHeight = btnHeight;
@ -698,7 +715,7 @@ bool CWindow::updateToolbarLayout(void)
m_tbRightX = 0;
for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++)
{
if (GButtonRightSide[btindex])
if (GToolBarInfo[btindex].rightSide)
{
FAR NXWidgets::CImage *cimage = m_tbButtons[btindex];
@ -799,7 +816,8 @@ bool CWindow::createToolbarButtons(void)
for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++)
{
FAR const NXWidgets::SRlePaletteBitmap *sbitmap = GTbBitmaps[btindex];
FAR const NXWidgets::SRlePaletteBitmap *sbitmap =
GToolBarInfo[btindex].bitmap;
#ifdef CONFIG_TWM4NX_TOOLBAR_ICONSCALE
// Create a CScaledBitmap to scale the bitmap icon
@ -817,6 +835,7 @@ bool CWindow::createToolbarButtons(void)
return false;
}
#endif
// Create the image. The image will serve as button since it
// can detect clicks and release just like a button.
@ -885,7 +904,7 @@ bool CWindow::createToolbarButtons(void)
// Pack on the left or right horizontally
if (GButtonRightSide[btindex])
if (GToolBarInfo[btindex].rightSide)
{
m_tbRightX -= (cimage->getWidth() + CONFIG_TWM4NX_TOOLBAR_HSPACING);
pos.x = m_tbRightX;
@ -943,12 +962,9 @@ bool CWindow::createToolbarTitle(FAR const char *name)
titlePos.x = m_tbLeftX + CONFIG_TWM4NX_FRAME_VSPACING;
titlePos.y = 0;
// Create the widget control (with the window messenger) using the default style
// REVISIT: Create the style, using the selected colors.
// Create a Widget control instance for the window using the default style
// for now. CWindowEvent derives from CWidgetControl.
// REVISIT: Create the style, using the selected colors.
FAR CWindowEvent *control = new CWindowEvent(m_twm4nx);
if (control == (FAR CWindowEvent *)0)
@ -984,6 +1000,49 @@ bool CWindow::createToolbarTitle(FAR const char *name)
return true;
}
/**
* After the toolbar was grabbed, it may be dragged then dropped, or it
* may be simply "un-grabbed". Both cases are handled here.
*
* NOTE: Unlike the other event handlers, this does NOT override any
* virtual event handling methods. It just combines some common event-
* handling logic.
*
* @param e The event data.
*/
void CWindow::handleUngrabEvent(const NXWidgets::CWidgetEventArgs &e)
{
// Exit the dragging state
m_drag = false;
// Generate the un-grab event
struct SEventMsg msg;
msg.eventID = EVENT_TOOLBAR_UNGRAB;
msg.pos.x = e.getX();
msg.pos.y = e.getY();
msg.delta.x = 0;
msg.delta.y = 0;
msg.context = EVENT_CONTEXT_TOOLBAR;
msg.obj = (FAR void *)this;
// NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then
// we have no other option but to lose events.
//
// I suppose we could recurse and call Twm4Nx::dispatchEvent at
// the risk of runawy stack usage.
int ret = mq_send(m_eventq, (FAR const char *)&msg,
sizeof(struct SEventMsg), 100);
if (ret < 0)
{
gerr("ERROR: mq_send failed: %d\n", ret);
}
}
/**
* Override the mouse button drag event.
*
@ -995,9 +1054,32 @@ void CWindow::handleDragEvent(const NXWidgets::CWidgetEventArgs &e)
// We are interested only the the drag event on the title box while we are
// in the dragging state.
if (m_drag)
if (m_drag && m_tbTitle->isBeingDragged())
{
#warning Missing logic
// Generate the event
struct SEventMsg msg;
msg.eventID = EVENT_WINDOW_DRAG;
msg.pos.x = e.getX();
msg.pos.y = e.getY();
msg.delta.x = e.getVX();
msg.delta.y = e.getVY();
msg.context = EVENT_CONTEXT_TOOLBAR;
msg.obj = (FAR void *)this;
// NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then
// we have no other option but to lose events.
//
// I suppose we could recurse and call Twm4Nx::dispatchEvent at
// the risk of runawy stack usage.
int ret = mq_send(m_eventq, (FAR const char *)&msg,
sizeof(struct SEventMsg), 100);
if (ret < 0)
{
gerr("ERROR: mq_send failed: %d\n", ret);
}
}
}
@ -1011,10 +1093,16 @@ void CWindow::handleDropEvent(const NXWidgets::CWidgetEventArgs &e)
{
// We are interested only the the drag drop event on the title box while we
// are in the dragging state.
//
// When the Drop Event is received, both isClicked and isBeingDragged()
// will return false. It is sufficient to verify that the isClicked() is
// not true to exit the drag.
if (m_drag)
if (m_drag && !m_tbTitle->isClicked())
{
#warning Missing logic
// Yes.. handle the drop event
handleUngrabEvent(e);
}
}
@ -1026,11 +1114,56 @@ void CWindow::handleDropEvent(const NXWidgets::CWidgetEventArgs &e)
void CWindow::handleKeyPressEvent(const NXWidgets::CWidgetEventArgs &e)
{
// We are interested only the the press event on the title box
// We are interested only the the press event on the title box and
// only if we are not already dragging the window
if (!m_drag)
if (!m_drag && m_tbTitle->isClicked())
{
#warning Missing logic
// Generate the event
struct SEventMsg msg;
msg.eventID = EVENT_TOOLBAR_GRAB;
msg.pos.x = e.getX();
msg.pos.y = e.getY();
msg.delta.x = 0;
msg.delta.y = 0;
msg.context = EVENT_CONTEXT_TOOLBAR;
msg.obj = (FAR void *)this;
// NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then
// we have no other option but to lose events.
//
// I suppose we could recurse and call Twm4Nx::dispatchEvent at
// the risk of runawy stack usage.
int ret = mq_send(m_eventq, (FAR const char *)&msg,
sizeof(struct SEventMsg), 100);
if (ret < 0)
{
gerr("ERROR: mq_send failed: %d\n", ret);
}
}
}
/**
* Override the virtual CWidgetEventHandler::handleReleaseEvent. This
* event will fire when the title widget is released. isClicked()
* will return false for the title widget.
*
* @param e The event data.
*/
void CWindow::handleReleaseEvent(const NXWidgets::CWidgetEventArgs &e)
{
// Handle the case where a click event was received, but the
// window was not dragged.
if (m_drag && !m_tbTitle->isClicked())
{
// Handle the non-drag drop event
handleUngrabEvent(e);
}
}
@ -1039,13 +1172,47 @@ void CWindow::handleKeyPressEvent(const NXWidgets::CWidgetEventArgs &e)
* event will fire when the image is released but before it has been
* has been drawn. isClicked() will return true for the appropriate
* images.
*
* @param e The event data.
*/
void CWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
{
// We are are interested in the pre-release event for any of the
// toolbar buttons.
#warning Missing logic
for (int btindex = 0; btindex < NTOOLBAR_BUTTONS; btindex++)
{
// Check if the widget is clicked
if (m_tbButtons[btindex]->isClicked())
{
// Yes.. generate the event
struct SEventMsg msg;
msg.eventID = GToolBarInfo[btindex].event;
msg.pos.x = e.getX();
msg.pos.y = e.getY();
msg.delta.x = 0;
msg.delta.y = 0;
msg.context = EVENT_CONTEXT_TOOLBAR;
msg.obj = (FAR void *)this;
// NOTE that we cannot block because we are on the same thread
// as the message reader. If the event queue becomes full then
// we have no other option but to lose events.
//
// I suppose we could recurse and call Twm4Nx::dispatchEvent at
// the risk of runawy stack usage.
int ret = mq_send(m_eventq, (FAR const char *)&msg,
sizeof(struct SEventMsg), 100);
if (ret < 0)
{
gerr("ERROR: mq_send failed: %d\n", ret);
}
}
}
}
/**

View File

@ -214,6 +214,19 @@ namespace NXWidgets
~CButtonArray(void);
/**
* Resize the array of buttons. Button labels will be removed and will
* have to be reapplied in the new geometry.
*
* @param buttonColumns The number of buttons in one row of the button array
* @param buttonRows The number of buttons in one column of the button array
* @param buttonWidth The width of one button
* @param buttonHeight The height of one button
*/
bool resizeArray(uint8_t buttonColumns, uint8_t buttonRows,
nxgl_coord_t buttonWidth, nxgl_coord_t buttonHeight);
/**
* Returns the string shown in the label.
*

View File

@ -465,7 +465,7 @@ namespace NXWidgets
* @return This string.
*/
CNxString &operator=(const char *string);
CNxString &operator=(FAR const char *string);
/**
* Overloaded assignment operator. Copies the data from the argument
@ -509,6 +509,7 @@ namespace NXWidgets
*/
int compareTo(const CNxString &string) const;
int compareTo(FAR const char *string) const;
/**
* snprintf()-style string formatting. Automatically allocates correct

View File

@ -57,6 +57,8 @@
namespace NXWidgets
{
class CNxTkWindow; // Forward reference
class CButtonArray; // Forward reference
class CWidgetEventArgs; // Forward reference
struct SRlePaletteBitmap; // Forward reference
}
@ -72,12 +74,11 @@ namespace Twm4Nx
nxgl_size_s size;
int row;
int col;
int me;
bool active;
bool down;
};
class CIconMgr
class CIconMgr : protected NXWidgets::CWidgetEventHandler
{
private:
@ -86,10 +87,19 @@ namespace Twm4Nx
FAR struct SWindowEntry *m_tail; /**< Tail of the window list */
FAR struct SWindowEntry *m_active; /**< The active entry */
FAR struct CWindow *m_window; /**< Parent window */
unsigned int m_columns; /**< Number of columns icon manager */
unsigned int m_currows;
unsigned int m_curcolumns;
unsigned int m_count;
FAR NXWidgets::CButtonArray *m_buttons; /**< The cotained button array */
uint8_t m_maxColumns; /**< Max columns per row */
uint8_t m_nrows; /**< Number of rows in the button array */
uint8_t m_ncolumns; /**< Number of columns in the button array */
unsigned int m_nWindows; /**< The number of windows in the icon mgr. */
/**
* Return the height of one row
*
* @return The height of one row
*/
nxgl_coord_t getRowHeight(void);
/**
* Create and initialize the icon manager window
@ -144,6 +154,14 @@ namespace Twm4Nx
void freeWEntry(FAR struct SWindowEntry *wentry);
/**
* Handle a widget action event. This will be a button pre-release event.
*
* @param e The event data.
*/
void handleActionEvent(const NXWidgets::CWidgetEventArgs &e);
public:
/**
@ -153,7 +171,7 @@ namespace Twm4Nx
* @param ncolumns The number of columns this icon manager has
*/
CIconMgr(CTwm4Nx *twm4nx, int ncolumns);
CIconMgr(CTwm4Nx *twm4nx, uint8_t ncolumns);
/**
* CIconMgr Destructor
@ -177,6 +195,14 @@ namespace Twm4Nx
bool add(FAR CWindow *win);
/**
* Remove a window from the icon manager
*
* @param win the TWM window structure
*/
void remove(FAR struct SWindow *win);
/**
* Hide the icon manager
*/
@ -189,30 +215,22 @@ namespace Twm4Nx
}
}
/**
* Remove a window from the icon manager
*
* @param win the TWM window structure
*/
void remove(FAR struct SWindow *win);
/**
* Get the number of columns
*/
inline unsigned int getColumns(void)
inline unsigned int getDisplayColumns(void)
{
return m_columns;
return m_maxColumns;
}
/**
* Get the current column
*/
inline unsigned int getCurrColumn(void)
inline unsigned int getNumberOfColumns(void)
{
return m_curcolumns;
return m_ncolumns;
}
/**
@ -224,20 +242,6 @@ namespace Twm4Nx
return m_window->getFrameSize(size);
}
/**
* Move the pointer around in an icon manager
*
* @param dir one of the following:
* - EVENT_ICONMGR_FORWARD: Forward in the window list
* - EVENT_ICONMGR_BACK: Backward in the window list
* - EVENT_ICONMGR_UP: Up one row
* - EVENT_ICONMGR_DOWN: Down one row
* - EVENT_ICONMGR_LEFT: Left one column
* - EVENT_ICONMGR_RIGHT: Right one column
*/
void move(int dir);
/**
* Pack the icon manager windows following an addition or deletion
*/

View File

@ -98,7 +98,6 @@ namespace Twm4Nx
class CWindow; // Forward reference
struct SMenuRoot; // Forward reference
struct SMenuItem; // Forward reference
struct SToolbarButton; // Forward reference
// The CWindow class implements a standard, framed window with a toolbar
// containing the standard buttons and the window title.
@ -198,6 +197,19 @@ namespace Twm4Nx
bool enableWidgets(void);
/**
* After the toolbar was grabbed, it may be dragged then dropped, or it
* may be simply "un-grabbed". Both cases are handled here.
*
* NOTE: Unlike the other event handlers, this does NOT override any
* virtual event handling methods. It just combines some common event-
* handling logic.
*
* @param e The event data.
*/
void handleUngrabEvent(const NXWidgets::CWidgetEventArgs &e);
/**
* Override the mouse button drag event.
*
@ -222,6 +234,16 @@ namespace Twm4Nx
void handleKeyPressEvent(const NXWidgets::CWidgetEventArgs &e);
/**
* Override the virtual CWidgetEventHandler::handleReleaseEvent. This
* event will fire when the title widget is released. isClicked()
* will return false for the title widget.
*
* @param e The event data.
*/
void handleReleaseEvent(const NXWidgets::CWidgetEventArgs &e);
/**
* Override the virtual CWidgetEventHandler::handleActionEvent. This
* event will fire when the image is released but before it has been
@ -337,7 +359,7 @@ namespace Twm4Nx
/**
* Get the size of the primary window. This is useful only
* for applications that need to know the drawing area.
* for applications that need to know about the drawing area.
*
* @param size Location to return the primary window size
*/
@ -347,6 +369,18 @@ namespace Twm4Nx
return m_nxWin->getSize(size);
}
/**
* Get the position of the primary window. This is useful only
* for applications that need to know about the drawing area.
*
* @param pos Location to return the primary window position
*/
inline bool getWindowPosition(FAR struct nxgl_point_s *pos)
{
return m_nxWin->getPosition(pos);
}
/**
* Set the size of the primary window. This is useful only
* for oapplications that need to control the drawing area.

View File

@ -109,22 +109,12 @@ namespace Twm4Nx
// Recipient == ICONWIN
EVENT_ICONWIN_GRAB = 0x2000, /**< Click on toolbar (not toolbar buttons) */
EVENT_ICONWIN_GRAB = 0x2000, /**< Click on toolbar title */
EVENT_ICONWIN_DRAG = 0x2001, /**< Drag window */
EVENT_ICONWIN_UNGRAB = 0x2002, /**< Release click on toolbar */
// Recipient == ICONMGR
EVENT_ICONMGR_FORWARD = 0x3000, /**< Forward in the window list */
EVENT_ICONMGR_BACK = 0x3001, /**< Backward in the window list */
EVENT_ICONMGR_UP = 0x3002, /**< Up one row */
EVENT_ICONMGR_DOWN = 0x3003, /**< Down one row */
EVENT_ICONMGR_LEFT = 0x3004, /**< Left one column */
EVENT_ICONMGR_RIGHT = 0x3005, /**< Right one column */
EVENT_ICONMGR_SHOWPARENT = 0x3006, /**< Raise Icon Manager parent window */
EVENT_ICONMGR_HIDE = 0x3007, /**< Hide the Icon Manager */
EVENT_ICONMGR_SORT = 0x3008, /**< Sort the Icon Manager */
// Recipient == MENU
EVENT_MENU_IDENTIFY = 0x4001, /**< Describe the window */
@ -173,9 +163,8 @@ namespace Twm4Nx
enum EButtonContext
{
EVENT_CONTEXT_WINDOW = 0,
EVENT_CONTEXT_TITLE,
EVENT_CONTEXT_TOOLBAR,
EVENT_CONTEXT_ICON,
EVENT_CONTEXT_ROOT,
EVENT_CONTEXT_FRAME,
EVENT_CONTEXT_ICONMGR,
EVENT_CONTEXT_NAME,
@ -192,10 +181,8 @@ namespace Twm4Nx
{
uint16_t eventID; /**< Encoded event ID */
struct nxgl_point_s pos; /**< X/Y position */
struct nxgl_point_s delta; /**< X/Y change (for dragging only) */
uint8_t context; /**< Button press context */
bool pulldown; /**< Pull-down menu */
FAR const char *action; /**< Menu action */
FAR NXWidgets::CNxTkWindow *nxwin; /**< Raw NX window reference */
FAR void *obj; /**< Window object (CWindow or CIconWin) */
};
@ -208,7 +195,7 @@ namespace Twm4Nx
{
uint16_t eventID; /**< Encoded event ID */
FAR CWindowEvent *instance; /**< X/Y position */
FAR struct SWindow *win; /**< Twm4NX window reference */
FAR struct SWindow *win; /**< Twm4NX window reference */
};
}