From 9030bf631d44f48569774ce0873a38888edf3af5 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 27 Apr 2019 12:05:18 -0600 Subject: [PATCH] apps/graphics/twm4nx: Flesh out some of the Resize logic. Still missing the pull events needed to do the resize. --- graphics/twm4nx/README.txt | 24 +- graphics/twm4nx/src/ciconmgr.cxx | 3 +- graphics/twm4nx/src/cresize.cxx | 365 ++++++++++++++---------- graphics/twm4nx/src/cwindow.cxx | 8 +- include/graphics/twm4nx/cbackground.hxx | 15 +- include/graphics/twm4nx/cresize.hxx | 42 +-- 6 files changed, 269 insertions(+), 188 deletions(-) diff --git a/graphics/twm4nx/README.txt b/graphics/twm4nx/README.txt index fa79de369..8e6cf98e6 100644 --- a/graphics/twm4nx/README.txt +++ b/graphics/twm4nx/README.txt @@ -29,22 +29,20 @@ within this directory. STATUS ====== - 2019-04-25: This port was brutal. Much TWM logic was removed because it + 2019-04-27: This port was brutal. Much TWM logic was removed because it depended on X11 features (or just because I could not understand how to - use it). The replacement logic is only partially in place. A lot more + use it). The replacement logic is only mostly in place but more needs to be done to have a complete system (hence, it is marked EXPERIMENTAL). The kinds of things that need to done are: - 1. Update some logic that is only fragmentary for how like resizing, and - menus. - 2. Integrate NxWidgets into the windows: The resize menu needs a CLabel, - the menus are CListBox'es, but not completely integrated, the Icon - Manager needs to be a button array. - 3. Revisit Icons. They are windows now, but need to be compound widgets + 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. Revisit Icons. They are windows now, but need to be compound widgets lying on the background (compound: CImage + CLabel) - 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. + 3. Left click on background should bring up a user provided main main menu. + Right click should bring up a window list (like the icon manager???) + 4. For TWM-like behavior, a window frame and toolbar should be highlighted + when the window has focus. + 5. A right click on the toolbar should bring up a window-specific menu. diff --git a/graphics/twm4nx/src/ciconmgr.cxx b/graphics/twm4nx/src/ciconmgr.cxx index da8a7845f..1bfa66937 100644 --- a/graphics/twm4nx/src/ciconmgr.cxx +++ b/graphics/twm4nx/src/ciconmgr.cxx @@ -105,12 +105,11 @@ CIconMgr::CIconMgr(CTwm4Nx *twm4nx, uint8_t ncolumns) CIconMgr::~CIconMgr(void) { - // Close the NxWidget event message queue + // Close the NxWidget event message queue if (m_eventq != (mqd_t)-1) { (void)mq_close(m_eventq); - m_eventq = (mqd_t)-1; } // Free the icon manager window diff --git a/graphics/twm4nx/src/cresize.cxx b/graphics/twm4nx/src/cresize.cxx index 9d1824391..fa8eca193 100644 --- a/graphics/twm4nx/src/cresize.cxx +++ b/graphics/twm4nx/src/cresize.cxx @@ -47,6 +47,7 @@ #include #include "graphics/nxwidgets/cnxfont.hxx" +#include "graphics/nxwidgets/clabel.hxx" #include "graphics/twm4nx/twm4nx_config.hxx" #include "graphics/twm4nx/ctwm4nx.hxx" @@ -84,17 +85,11 @@ using namespace Twm4Nx; CResize::CResize(CTwm4Nx *twm4nx) { - // Save the Twm4Nx session - - m_twm4nx = twm4nx; - - // Windows - - m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; - - // Strings - - m_stringWidth = 0; + m_twm4nx = twm4nx; // Save the Twm4Nx session + m_eventq = (mqd_t)-1; // No widget message queue yet + m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; // No resize dimension windows yet + m_sizeLabel = (FAR NXWidgets::CLabel *)0; // No resize dismsion label + m_stringWidth = 0; // String width } /** @@ -103,7 +98,23 @@ CResize::CResize(CTwm4Nx *twm4nx) CResize::~CResize(void) { - // Free the resize dimensions window + // Close the NxWidget event message queue + + if (m_eventq != (mqd_t)-1) + { + (void)mq_close(m_eventq); + m_eventq = (mqd_t)-1; + } + + // Delete the resize dimension label + + if (m_sizeLabel != (FAR NXWidgets::CLabel *)0) + { + delete m_sizeLabel; + m_sizeLabel = (FAR NXWidgets::CLabel *)0; + } + + // Delete the resize dimensions window if (m_sizeWindow != (FAR NXWidgets::CNxTkWindow *)0) { @@ -121,65 +132,31 @@ CResize::~CResize(void) bool CResize::initialize(void) { - // Create the main window - // 1. Get the server instance. m_twm4nx inherits from NXWidgets::CNXServer - // so we all ready have the server instance. - // 2. Create the style, using the selected colors (REVISIT) + // Open a message queue to NX events. - // 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); - - // 4. Create the main window - - m_sizeWindow = m_twm4nx->createFramedWindow(control); - if (m_sizeWindow == (FAR NXWidgets::CNxTkWindow *)0) + FAR const char *mqname = m_twm4nx->getEventQueueName(); + m_eventq = mq_open(mqname, O_WRONLY | O_NONBLOCK); + if (m_eventq == (mqd_t)-1) { - delete control; + gerr("ERROR: Failed open message queue '%s': %d\n", + mqname, errno); return false; } - // 5. Open and initialize the main window + // Create the size window - bool success = m_sizeWindow->open(); - if (!success) + if (!createSizeWindow()) { - delete m_sizeWindow; - m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; + gerr("ERROR: Failed to create menu window\n"); return false; } - // 6. Set the initial window size + // Create the size label widget - // Create the resize dimension window - - FAR CFonts *fonts = m_twm4nx->getFonts(); - FAR NXWidgets::CNxFont *sizeFont = fonts->getSizeFont(); - - m_stringWidth = sizeFont->getStringWidth(" 8888 x 8888 "); - - struct nxgl_size_s size; - size.w = m_stringWidth, - size.h = (sizeFont->getHeight() + CONFIG_TWM4NX_ICONMGR_VSPACING * 2); - - if (!m_sizeWindow->setSize(&size)) + if (!createSizeLabel()) { - delete m_sizeWindow; - m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; - return false; - } + gerr("ERROR: Failed to recreate size label\n"); - // 7. Set the initial window position - - struct nxgl_point_s pos = - { - .x = 0, - .y = 0 - }; - - if (!m_sizeWindow->setPosition(&pos)) - { delete m_sizeWindow; m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; return false; @@ -246,10 +223,6 @@ void CResize::startResize(FAR struct SEventMsg *eventmsg, FAR CWindow *cwin) m_delta.x = 0; m_delta.y = 0; -#ifdef CONFIG_TWM4NX_AUTO_RERESIZE // Resize relative to position in quad - autoClamp(cwin, eventmsg); -#endif - FAR CFonts *fonts = m_twm4nx->getFonts(); FAR NXWidgets::CNxFont *sizeFont = fonts->getSizeFont(); @@ -259,8 +232,9 @@ void CResize::startResize(FAR struct SEventMsg *eventmsg, FAR CWindow *cwin) // Set the window size - if (!m_sizeWindow->setSize(&size)) + if (!setWindowSize(&size)) { + gerr("ERROR: setWindowSize() failed\n"); return; } @@ -271,7 +245,7 @@ void CResize::startResize(FAR struct SEventMsg *eventmsg, FAR CWindow *cwin) m_last.w = 0; m_last.h = 0; - displaySize(cwin, &m_origsize); + updateSizeLabel(cwin, &m_origsize); // Set the new frame position and size @@ -311,15 +285,16 @@ void CResize::menuStartResize(FAR CWindow *cwin, winsize.w = m_stringWidth + CONFIG_TWM4NX_ICONMGR_HSPACING * 2; winsize.h = sizeFont->getHeight() + CONFIG_TWM4NX_ICONMGR_VSPACING * 2; - if (!m_sizeWindow->setSize(&winsize)) + if (!setWindowSize(&winsize)) { + gerr("ERROR: setWindowSize() failed\n"); return; } // Move the size window it to the top of the hieararchy m_sizeWindow->raise(); - displaySize(cwin, &m_origsize); + updateSizeLabel(cwin, &m_origsize); // Set the new frame position and size @@ -359,7 +334,7 @@ void CResize::addStartResize(FAR CWindow *cwin, m_last.w = 0; m_last.h = 0; - displaySize(cwin, &m_origsize); + updateSizeLabel(cwin, &m_origsize); } /** @@ -488,12 +463,12 @@ void CResize::menuDoResize(FAR CWindow *cwin, } } - displaySize(cwin, &m_dragsize); + updateSizeLabel(cwin, &m_dragsize); } /** - * Move the rubberband around. This is called for each motion event when - * we are resizing + * Resize the window. This is called for each motion event while we are + * resizing * * @param cwin The current Twm4Nx window * @param root The X position in the root window @@ -620,7 +595,7 @@ void CResize::doResize(FAR CWindow *cwin, } } - displaySize(cwin, &m_dragsize); + updateSizeLabel(cwin, &m_dragsize); } /** @@ -708,22 +683,6 @@ void CResize::menuEndResize(FAR CWindow *cwin) setupWindow(cwin, &m_dragpos, &m_dragsize); } -/** - * Finish the resize operation for AddWindotype) + // 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); + + // 4. Create the main window + + m_sizeWindow = m_twm4nx->createFramedWindow(control); + if (m_sizeWindow == (FAR NXWidgets::CNxTkWindow *)0) { - case ButtonPress: - pos.x = eventmsg->pos.x; - pos.y = eventmsg->pos.y; - break; - - case KeyPress: - pos.x = eventmsg->pos.x; - pos.y = eventmsg->pos.y; - break; - - default: - // Root window position - - root.x = 0; // REVISIT - root.y = 0; - - // Relative window position - - if (!xxx->getPosition(&pos)) - { - return; - } + delete control; + return false; } - h = ((pos.x - m_dragpos.x) / (m_dragsize.w < 3 ? 1 : (m_dragsize.w / 3))); - v = ((pos.y - m_dragpos.y) / (m_dragsize.h < 3 ? 1 : (m_dragsize.h / 3))); + // 5. Open and initialize the main window - if (h <= 0) + bool success = m_sizeWindow->open(); + if (!success) { - m_clamp.pt1.x = 1; - m_delta.x = (pos.x - m_dragpos.x); - } - else if (h >= 2) - { - m_clamp.pt2.x = 1; - m_delta.x = (pos.x - m_dragpos.x - m_dragsize.w); + delete m_sizeWindow; + m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; + return false; } - if (v <= 0) + // 6. Set the initial window size + + // Create the resize dimension window + + FAR CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *sizeFont = fonts->getSizeFont(); + + m_stringWidth = sizeFont->getStringWidth(" 8888 x 8888 "); + + struct nxgl_size_s size; + size.w = m_stringWidth, + size.h = (sizeFont->getHeight() + CONFIG_TWM4NX_ICONMGR_VSPACING * 2); + + if (!m_sizeWindow->setSize(&size)) { - m_clamp.pt1.y = 1; - m_delta.y = (pos.y - m_dragpos.y); + delete m_sizeWindow; + m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; + return false; } - else if (v >= 2) + + // 7. Set the initial window position + + struct nxgl_point_s pos = + { + .x = 0, + .y = 0 + }; + + if (!m_sizeWindow->setPosition(&pos)) { - m_clamp.pt2.y = 1; - m_delta.y = (pos.y - m_dragpos.y - m_dragsize.h); + delete m_sizeWindow; + m_sizeWindow = (FAR NXWidgets::CNxTkWindow *)0; + return false; } + + return true; } -#endif /** - * Display the size in the dimensions window. + * Create the size label widget + */ + +bool CResize::createSizeLabel(void) +{ + // The size of the selected is selected to fill the entire size window + + struct nxgl_size_s labelSize; + if (!m_sizeWindow->setSize(&labelSize)) + { + gerr("ERROR: Failed to get window size\n"); + return false; + } + + // Position the label at the origin of the window. + + struct nxgl_point_s labelPos; + labelPos.x = 0; + labelPos.y = 0; + + // Get the Widget control instance from the size window. This + // will force all widget drawing to go to the size window. + + FAR NXWidgets:: CWidgetControl *control = + m_sizeWindow->getWidgetControl(); + + if (control == (FAR NXWidgets:: CWidgetControl *)0) + { + // Should not fail + + return false; + } + + // Create the size label widget + + m_sizeLabel = new NXWidgets::CLabel(control, labelPos.x, labelPos.y, + labelSize.w, labelSize.h, + " 8888 x 8888 "); + if (m_sizeLabel == (FAR NXWidgets::CLabel *)0) + { + gerr("ERROR: Failed to construct size label widget\n"); + return false; + } + + // Configure the size label + + FAR CFonts *fonts = m_twm4nx->getFonts(); + FAR NXWidgets::CNxFont *sizeFont = fonts->getSizeFont(); + + m_sizeLabel->setFont(sizeFont); + m_sizeLabel->setBorderless(true); + m_sizeLabel->disableDrawing(); + m_sizeLabel->setTextAlignmentHoriz(NXWidgets::CLabel::TEXT_ALIGNMENT_HORIZ_CENTER); + m_sizeLabel->setTextAlignmentVert(NXWidgets::CLabel::TEXT_ALIGNMENT_VERT_CENTER); + m_sizeLabel->setRaisesEvents(false); + + // Register to get events from the mouse clicks on the image + + m_sizeLabel->addWidgetEventHandler(this); + return true; +} + +/** + * Set the Window Size + */ + +bool CResize::setWindowSize(FAR struct nxgl_size_s *size) +{ + // Set the window size + + if (!m_sizeWindow->setSize(size)) + { + return false; + } + + // Set the label size to match + + if (!m_sizeLabel->resize(size->w, size->h)) + { + return false; + } + + return true; +} + +/** + * Update the size show in the size dimension label. * - * @param cwin The current window being resize + * @param cwin The current window being resized * @param size She size of the rubber band */ -void CResize::displaySize(FAR CWindow *cwin, FAR struct nxgl_size_s *size) +void CResize::updateSizeLabel(FAR CWindow *cwin, FAR struct nxgl_size_s *size) { + // Do nothing if the size has not changed + if (m_last.w == size->w && m_last.h == size->h) { return; @@ -1062,21 +1119,29 @@ void CResize::displaySize(FAR CWindow *cwin, FAR struct nxgl_size_s *size) m_last.w = size->w; m_last.h = size->h; - char str[100]; - (void)snprintf(str, sizeof(str), " %4d x %-4d ", size->w, size->h); + FAR char *str; + (void)asprintf(&str, " %4d x %-4d ", size->w, size->h); + if (str == (FAR char *)0) + { + gerr("ERROR: Failed to get size string\n"); + return; + } + + // Bring the window to the top of the hierarchy m_sizeWindow->raise(); -#warning Missing logic -#if 0 - FAR CFonts *fonts = m_twm4nx->getFonts(); - FAR NXWidgets::CNxFont *sizeFont = fonts->getSizeFont(); + // Add the string to the label widget - // Show the string in the CLable in the size window + m_sizeLabel->disableDrawing(); + m_sizeLabel->setRaisesEvents(false); - // REVISIT: This no longer exists - fonts->renderString(m_twm4nx, m_sizeWindow, sizeFont, - CONFIG_TWM4NX_ICONMGR_HSPACING, - sizeFont->getHeight() + CONFIG_TWM4NX_ICONMGR_VSPACING, str); -#endif + m_sizeLabel->setText(str); + std::free(str); + + // Re-enable and redraw the label widget + + m_sizeLabel->enableDrawing(); + m_sizeLabel->setRaisesEvents(true); + m_sizeLabel->redraw(); } diff --git a/graphics/twm4nx/src/cwindow.cxx b/graphics/twm4nx/src/cwindow.cxx index fc60700ec..f59510942 100644 --- a/graphics/twm4nx/src/cwindow.cxx +++ b/graphics/twm4nx/src/cwindow.cxx @@ -957,7 +957,7 @@ bool CWindow::createToolbarTitle(FAR const char *name) titleSize.h = m_tbHeight; titleSize.w = m_tbRightX - m_tbLeftX - CONFIG_TWM4NX_FRAME_VSPACING + 1; - // Position the tile. Packed to the left horizontally, positioned at the + // Position the title. Packed to the left horizontally, positioned at the // top of the toolbar. struct nxgl_point_s titlePos; @@ -1167,6 +1167,10 @@ void CWindow::handleReleaseEvent(const NXWidgets::CWidgetEventArgs &e) if (m_drag && !m_tbTitle->isClicked()) { + // A click with no drag should raise the window. + + m_iconWin->raise(); + // Handle the non-drag drop event handleUngrabEvent(e); @@ -1224,7 +1228,7 @@ void CWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e) /** * Handle the TOOLBAR_GRAB event. That corresponds to a left - * mouse click on the tile widget in the toolbar + * mouse click on the title widget in the toolbar * * @param eventmsg. The received NxWidget event message. * @return True if the message was properly handled. false is diff --git a/include/graphics/twm4nx/cbackground.hxx b/include/graphics/twm4nx/cbackground.hxx index b2f69acba..8086b3175 100644 --- a/include/graphics/twm4nx/cbackground.hxx +++ b/include/graphics/twm4nx/cbackground.hxx @@ -49,10 +49,6 @@ #include "graphics/nxwidgets/cwidgeteventhandler.hxx" #include "graphics/nxwidgets/cwidgeteventargs.hxx" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - /**************************************************************************** * Implementation Class Definition ****************************************************************************/ @@ -61,6 +57,7 @@ namespace NXWidgets { class CBgWindow; // Forward reference class CImage; // Forward reference + class CWidgetControl; // Forward reference struct SRlePaletteBitmap; // Forward reference } @@ -119,6 +116,16 @@ namespace Twm4Nx ~CBackground(void); + /** + * Get the widget control instance needed to support application drawing + * into the background. + */ + + inline FAR NXWidgets::CWidgetControl *getWidgetControl() + { + return m_backWindow->getWidgetControl(); + } + /** * Set the background image * diff --git a/include/graphics/twm4nx/cresize.hxx b/include/graphics/twm4nx/cresize.hxx index 1ad9b8886..97d91c884 100644 --- a/include/graphics/twm4nx/cresize.hxx +++ b/include/graphics/twm4nx/cresize.hxx @@ -61,6 +61,7 @@ namespace NXWidgets { class CNxTkWindow; // Forward reference + class CLabel; // Forward reference } namespace Twm4Nx @@ -73,7 +74,9 @@ namespace Twm4Nx private: CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */ + mqd_t m_eventq; /**< NxWidget event message queue */ FAR NXWidgets::CNxTkWindow *m_sizeWindow; /**< The resize dimensions window */ + FAR NXWidgets::CLabel *m_sizeLabel; /**< Resize dimension label */ FAR CWindow *m_resizeWindow; /**< The window being resized */ struct nxgl_point_s m_origpos; /**< Original position */ struct nxgl_size_s m_origsize; /**< Original size */ @@ -86,9 +89,23 @@ namespace Twm4Nx struct nxgl_size_s m_addingSize; int m_stringWidth; /**< Size of current size string */ -#ifdef CONFIG_TWM4NX_AUTO_RERESIZE // Resize relative to position in quad - void autoClamp(CWindow *cwin, FAR struct SEventMsg *eventmsg); -#endif + /** + * Create the size window + */ + + bool createSizeWindow(void); + + /** + * Create the size label widget + */ + + bool createSizeLabel(void); + + /** + * Set the Window Size + */ + + bool setWindowSize(FAR struct nxgl_size_s *size); void resizeFromCenter(FAR CWindow *win); @@ -105,13 +122,13 @@ namespace Twm4Nx FAR struct nxgl_size_s *size); /** - * Display the size in the dimensions window. + * Update the size show in the size dimension label. * - * @param cwin The current window + * @param cwin The current window be resized * @param size The size of the rubber band */ - void displaySize(FAR CWindow *cwin, FAR struct nxgl_size_s *size); + void updateSizeLabel(FAR CWindow *cwin, FAR struct nxgl_size_s *size); public: @@ -167,8 +184,8 @@ namespace Twm4Nx FAR struct nxgl_point_s *root); /** - * Move the rubberband around. This is called for each motion event when - * we are resizing + * Resize the window. This is called for each motion event while we are + * resizing * * @param cwin The current Twm4Nx window * @param root The X position in the root window @@ -185,15 +202,6 @@ namespace Twm4Nx void menuEndResize(FAR CWindow *cwin); - /** - * Finish the resize operation for AddWindo