apps/graphics/twm4nx: Icons can now be moved, but there are artifacts: Need to erase the old icon region on the background before drawing the new icon image during the move.

This commit is contained in:
Gregory Nutt 2019-05-13 18:09:20 -06:00
parent c800b43950
commit 75fc1a2dd3
6 changed files with 173 additions and 53 deletions

View File

@ -178,7 +178,7 @@ bool CBackground::checkCollision(FAR const struct nxgl_rect_s &bounds,
{
// Is there a background image
if (m_backImage != (NXWidgets::CImage *)0)
if (m_backImage != (NXWidgets::CImage *)0)
{
// Create a bounding box for the background image
@ -510,6 +510,14 @@ void CBackground::cleanup(void)
m_eventq = (mqd_t)-1;
}
// Delete the background image
if (m_backImage != (NXWidgets::CImage *)0)
{
delete m_backImage;
m_backImage = (NXWidgets::CImage *)0;
}
// Delete the background
if (m_backWindow != (NXWidgets::CBgWindow *)0)
@ -528,12 +536,4 @@ void CBackground::cleanup(void)
delete m_backWindow;
m_backWindow = (NXWidgets::CBgWindow *)0;
}
// Delete the background image
if (m_backImage != (NXWidgets::CImage *)0)
{
delete m_backImage;
m_backImage = (NXWidgets::CImage *)0;
}
}

View File

@ -102,13 +102,16 @@ CIconWidget::CIconWidget(FAR CTwm4Nx *twm4nx,
// Dragging
m_drag = false; // No drag in-progress */
m_dragging = false; // No drag in-progress */
m_moved = false; // Icon has not been moved */
// Configure the widget
m_flags.borderless = true; // The widget is borderless (and transparent)
m_flags.draggable = true; // This widget may be dragged
setBorderless(true); // The widget is borderless (and transparent)
setDraggable(true); // This widget may be dragged
enable(); // Enable the widget
setRaisesEvents(true); // Enable event firing
disableDrawing(); // No drawing yet
}
/**
@ -268,13 +271,13 @@ bool CIconWidget::initialize(FAR CWindow *parent,
iconImagePos.x = (maxLabelWidth - iconImageSize.w) / 2;
}
// Create a new CImage to hold the bitmap image
// Create a new CIconLabel to hold the bitmap image
FAR NXWidgets::CImage *image =
new NXWidgets::CImage(m_widgetControl, iconImagePos.x,
iconImagePos.y, iconImageSize.w, iconImageSize.h,
ibitmap, &m_style);
if (image == (FAR NXWidgets::CImage *)0)
FAR CIconImage *image =
new CIconImage(m_widgetControl, iconImagePos.x,
iconImagePos.y, iconImageSize.w, iconImageSize.h,
ibitmap, &m_style);
if (image == (FAR CIconImage *)0)
{
twmerr("ERROR: Failed to create image\n");
return false;
@ -286,8 +289,9 @@ bool CIconWidget::initialize(FAR CWindow *parent,
image->enable();
image->disableDrawing();
image->setRaisesEvents(true);
image->setDraggable(true);
// Add the CImage to to the containing widget
// Add the CIconImage to to the containing widget
image->addWidgetEventHandler(this);
addWidget(image);
@ -304,13 +308,13 @@ bool CIconWidget::initialize(FAR CWindow *parent,
iconTopLabelPos.x = (iconWidgetSize.w - iconTopLabelSize.w) / 2;
}
// Create a new CLabel to hold the upper icon title
// Create a new CIconLabel to hold the upper icon title
FAR NXWidgets::CLabel *topLabel =
new NXWidgets::CLabel(m_widgetControl, iconTopLabelPos.x,
iconTopLabelPos.y, iconTopLabelSize.w,
iconTopLabelSize.h, topString, &m_style);
if (topLabel == (FAR NXWidgets::CLabel *)0)
FAR CIconLabel *topLabel =
new CIconLabel(m_widgetControl, iconTopLabelPos.x,
iconTopLabelPos.y, iconTopLabelSize.w,
iconTopLabelSize.h, topString, &m_style);
if (topLabel == (FAR CIconLabel *)0)
{
twmerr("ERROR: Failed to create icon topLabel\n");
delete image;
@ -324,6 +328,7 @@ bool CIconWidget::initialize(FAR CWindow *parent,
topLabel->enable();
topLabel->disableDrawing();
topLabel->setRaisesEvents(true);
topLabel->setDraggable(true);
// Add the top label to to the containing widget
@ -348,13 +353,13 @@ bool CIconWidget::initialize(FAR CWindow *parent,
iconBottomLabelPos.x = (iconWidgetSize.w - iconBottomLabelSize.w) / 2;
}
// Create a new CLabel to hold the lower icon title
// Create a new CIconLabel to hold the lower icon title
FAR NXWidgets::CLabel *bottomLabel =
new NXWidgets::CLabel(m_widgetControl, iconBottomLabelPos.x,
iconBottomLabelPos.y, iconBottomLabelSize.w,
iconBottomLabelSize.h, bottomString,&m_style);
if (bottomLabel == (FAR NXWidgets::CLabel *)0)
FAR CIconLabel *bottomLabel =
new CIconLabel(m_widgetControl, iconBottomLabelPos.x,
iconBottomLabelPos.y, iconBottomLabelSize.w,
iconBottomLabelSize.h, bottomString,&m_style);
if (bottomLabel == (FAR CIconLabel *)0)
{
twmerr("ERROR: Failed to create icon bottomLabel\n");
delete topLabel;
@ -369,6 +374,7 @@ bool CIconWidget::initialize(FAR CWindow *parent,
bottomLabel->enable();
bottomLabel->disableDrawing();
bottomLabel->setRaisesEvents(true);
bottomLabel->setDraggable(true);
// Add the top label to to the containing widget
@ -452,10 +458,6 @@ bool CIconWidget::event(FAR struct SEventMsg *eventmsg)
void CIconWidget::handleUngrabEvent(const NXWidgets::CWidgetEventArgs &e)
{
// Exit the dragging state
m_drag = false;
// Generate the un-grab event
struct SEventMsg msg;
@ -492,7 +494,7 @@ void CIconWidget::handleDragEvent(const NXWidgets::CWidgetEventArgs &e)
// We don't care which component of the icon widget was clicked only that
// we are not currently being dragged
if (m_drag)
if (m_dragging)
{
// Generate the event
@ -532,7 +534,7 @@ void CIconWidget::handleDropEvent(const NXWidgets::CWidgetEventArgs &e)
// When the Drop Event is received, both isClicked and isBeingDragged()
// will return false. No checks are performed.
if (m_drag)
if (m_dragging)
{
// Yes.. handle the drop event
@ -551,7 +553,7 @@ void CIconWidget::handleClickEvent(const NXWidgets::CWidgetEventArgs &e)
// We don't care which component of the icon widget was clicked only that
// we are not currently being dragged
if (!m_drag)
if (!m_dragging)
{
// Generate the event
@ -592,7 +594,7 @@ void CIconWidget::handleReleaseEvent(const NXWidgets::CWidgetEventArgs &e)
// Handle the case where a release event was received, but the
// window was not dragged.
if (m_drag)
if (m_dragging)
{
// Handle the non-drag drop event
@ -612,7 +614,7 @@ void CIconWidget::handleReleaseOutsideEvent(const NXWidgets::CWidgetEventArgs &e
// Handle the case where a release event was received, but the
// window was not dragged.
if (m_drag)
if (m_dragging)
{
// Handle the non-drag drop event
@ -634,8 +636,8 @@ bool CIconWidget::iconGrab(FAR struct SEventMsg *eventmsg)
// Indicate that dragging has started but the icon has not
// yet been moved.
m_drag = true;
m_moved = false;
m_dragging = true;
m_moved = false;
// Get the icon position.
@ -647,9 +649,11 @@ bool CIconWidget::iconGrab(FAR struct SEventMsg *eventmsg)
m_dragOffset.x = widgetPos.x - eventmsg->pos.x;
m_dragOffset.y = widgetPos.y - eventmsg->pos.y;
#ifdef CONFIG_TWM4NX_MOUSE
// Select the grab cursor image
m_twm4nx->setCursorImage(&CONFIG_TWM4NX_GBCURSOR_IMAGE);
#endif
// Remember the grab cursor size
@ -669,7 +673,7 @@ bool CIconWidget::iconGrab(FAR struct SEventMsg *eventmsg)
bool CIconWidget::iconDrag(FAR struct SEventMsg *eventmsg)
{
if (m_drag)
if (m_dragging)
{
// Calculate the new icon position
@ -745,23 +749,27 @@ bool CIconWidget::iconUngrab(FAR struct SEventMsg *eventmsg)
return false;
}
#ifdef CONFIG_TWM4NX_MOUSE
// Restore the normal cursor image
m_twm4nx->setCursorImage(&CONFIG_TWM4NX_CURSOR_IMAGE);
#endif
// There are two possibilities: (1) The icon was moved. In this case, we
// leave the icon up and in its new position. Or (2) the icon was simply
// clicked in which case we need to de-iconify the window.
// clicked in which case we need to de-iconify the window. We also check
// that we still have m_dragging == true to handle multiple UNGRAB events.
// That happens when we get both the DROP and RELEASE events.
if (!m_moved)
if (m_dragging && !m_moved)
{
m_parent->deIconify();
}
// Indicate no longer dragging
m_drag = false;
m_moved = false;
m_dragging = false;
m_moved = false;
return true;
}

View File

@ -367,7 +367,8 @@ bool CTwm4Nx::eventLoop(void)
if (!dispatchEvent(&u.eventmsg))
{
twmerr("ERROR: dispatchEvent failed\n");
twmerr("ERROR: dispatchEvent() failed, eventID=%u\n",
u.eventmsg.eventID);
cleanup();
return false;
}

View File

@ -80,6 +80,90 @@ namespace Twm4Nx
class CTwm4Nx; // Forward reference
class CWindow; // Forward reference
/**
* Self-dragging versions of CLabel and CImage
*/
class CIconLabel : public NXWidgets::CLabel
{
public:
/**
* Constructor for a label containing a string.
*
* @param pWidgetControl The controlling widget for the display
* @param x The x coordinate of the text box, relative to its parent.
* @param y The y coordinate of the text box, relative to its parent.
* @param width The width of the textbox.
* @param height The height of the textbox.
* @param text Pointer to a string to display in the textbox.
* @param style The style that the button should use. If this is not
* specified, the button will use the global default widget
* style.
*/
inline CIconLabel(NXWidgets::CWidgetControl *pWidgetControl,
nxgl_coord_t x, nxgl_coord_t y,
nxgl_coord_t width, nxgl_coord_t height,
const NXWidgets::CNxString &text,
NXWidgets::CWidgetStyle *style = (NXWidgets::CWidgetStyle *)0) :
NXWidgets::CLabel(pWidgetControl, x, y, width, height, text, style)
{
}
/**
* Called when the widget is clicked.
*
* @param x The x coordinate of the click.
* @param y The y coordinate of the click.
*/
inline void onClick(nxgl_coord_t x, nxgl_coord_t y)
{
startDragging(x, y);
}
};
class CIconImage : public NXWidgets::CImage
{
public:
/**
* Constructor for an image.
*
* @param pWidgetControl The controlling widget for the display
* @param x The x coordinate of the image box, relative to its parent.
* @param y The y coordinate of the image box, relative to its parent.
* @param width The width of the textbox.
* @param height The height of the textbox.
* @param bitmap The source bitmap image.
* @param style The style that the widget should use. If this is not
* specified, the button will use the global default widget
* style.
*/
inline CIconImage(NXWidgets::CWidgetControl *pWidgetControl,
nxgl_coord_t x, nxgl_coord_t y,
nxgl_coord_t width, nxgl_coord_t height,
FAR NXWidgets::IBitmap *bitmap,
NXWidgets::CWidgetStyle *style = (NXWidgets::CWidgetStyle *)0) :
NXWidgets::CImage(pWidgetControl, x, y, width, height, bitmap, style)
{
}
/**
* Called when the widget is clicked.
*
* @param x The x coordinate of the click.
* @param y The y coordinate of the click.
*/
inline void onClick(nxgl_coord_t x, nxgl_coord_t y)
{
startDragging(x, y);
}
};
/**
* Container class that holds the Icon image and table widgets
*/
@ -98,9 +182,21 @@ namespace Twm4Nx
struct nxgl_point_s m_dragPos; /**< Last mouse position */
struct nxgl_point_s m_dragOffset; /**< Offset from mouse to window origin */
struct nxgl_size_s m_dragCSize; /**< The grab cursor size */
bool m_drag; /**< Drag in-progress */
bool m_dragging; /**< Drag in-progress */
bool m_moved; /**< Icon has been moved */
/**
* Called when the widget is clicked.
*
* @param x The x coordinate of the click.
* @param y The y coordinate of the click.
*/
inline void onClick(nxgl_coord_t x, nxgl_coord_t y)
{
startDragging(x, y);
}
/**
* After the widget has been grabbed, it may be dragged then dropped,
* or it may be simply "un-grabbed". Both cases are handled here.

View File

@ -88,7 +88,9 @@ namespace Twm4Nx
* one.
*/
virtual ~IDragEvent(void) { }
virtual ~IDragEvent(void)
{
}
/**
* This function is called when there is any moved of the mouse or

View File

@ -59,9 +59,10 @@
/**
* Required settings:
*
* CONFIG_HAVE_CXX : C++ support is required
* CONFIG_NX : NX must enabled
* CONFIG_NXTERM=y : For NxTerm support
* CONFIG_HAVE_CXX : C++ support is required
* CONFIG_NX : NX must enabled
* CONFIG_NXTERM=y : For NxTerm support
* CONFIG_NXTERM_NXKBDIN=y : May be needed if Twm4Nx is managing the keyboard
*/
#ifndef CONFIG_HAVE_CXX
@ -76,6 +77,18 @@
# warning "NxTerm support is required (CONFIG_NXTERM)"
#endif
// Keyboard input can come from either /dev/console or via Twm4Nx. If
// keyboard input comes from Twm4Nx, then CONFIG_NXTERM_NXKBDIN must be
// defined to support injection of keyboard input from applications.
// Otherwise, CONFIG_NXTERM_NXKBDIN must not be defined to support use of
// /dev/console for keyboard input.
#if !defined(CONFIG_TWM4NX_NOKEYBOARD) && !defined(CONFIG_NXTERM_NXKBDIN)
# warning "Nxterm needs CONFIG_NXTERM_NXKBDIN for keyboard input"
#elif defined(CONFIG_TWM4NX_NOKEYBOARD) && defined(CONFIG_NXTERM_NXKBDIN)
# warning "Nxterm has no keyboard input. Undefine CONFIG_NXTERM_NXKBDIN
#endif
// NxTerm Window /////////////////////////////////////////////////////////////
/**