Squashed commit of the following:
apps/graphics/twm4nx: Additional redesign. Window draggin now sort of works in an unreliable hurky-gurky way. More to be done. apps/graphics/twm4nx: First cut at redesigned dragging logic
This commit is contained in:
parent
b0d39372fb
commit
d244b7a11d
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* apps/graphics/nxwidgets/src/cwidgetcontrol.cxx
|
||||
*
|
||||
* Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012-2013, 2019 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -566,9 +566,9 @@ void CWidgetControl::newMouseEvent(FAR const struct nxgl_point_s *pos, uint8_t b
|
||||
}
|
||||
#endif
|
||||
|
||||
// Notify any external logic that a keyboard event has occurred
|
||||
// Notify any external logic that a mouse event has occurred
|
||||
|
||||
m_eventHandlers.raiseMouseEvent();
|
||||
m_eventHandlers.raiseMouseEvent(pos, buttons);
|
||||
|
||||
#ifdef CONFIG_NXWIDGET_EVENTWAIT
|
||||
// Then wake up logic that may be waiting for a window event
|
||||
|
@ -137,11 +137,12 @@ void CWindowEventHandlerList::raiseGeometryEvent(void)
|
||||
* Raise an NX mouse window input event.
|
||||
*/
|
||||
|
||||
void CWindowEventHandlerList::raiseMouseEvent(void)
|
||||
void CWindowEventHandlerList::raiseMouseEvent(FAR const struct nxgl_point_s *pos,
|
||||
uint8_t buttons)
|
||||
{
|
||||
for (int i = 0; i < m_eventHandlers.size(); ++i)
|
||||
{
|
||||
m_eventHandlers.at(i)->handleMouseEvent();
|
||||
m_eventHandlers.at(i)->handleMouseEvent(pos, buttons);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -90,7 +90,8 @@ CWindowMessenger::~CWindowMessenger(void)
|
||||
* Handle an NX window mouse input event.
|
||||
*/
|
||||
|
||||
void CWindowMessenger::handleMouseEvent(void)
|
||||
void CWindowMessenger::handleMouseEvent(FAR const struct nxgl_point_s *pos,
|
||||
uint8_t buttons)
|
||||
{
|
||||
// The logic path here is tortuous but flexible:
|
||||
//
|
||||
|
@ -823,8 +823,6 @@ void CIconMgr::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
struct SEventMsg msg;
|
||||
msg.pos.x = e.getX();
|
||||
msg.pos.y = e.getY();
|
||||
msg.delta.x = 0;
|
||||
msg.delta.y = 0;
|
||||
msg.context = EVENT_CONTEXT_ICONMGR;
|
||||
msg.handler = (FAR CTwm4NxEvent *)0;
|
||||
msg.obj = (FAR void *)swin->cwin;
|
||||
|
@ -107,7 +107,8 @@ CIconWidget::CIconWidget(FAR CTwm4Nx *twm4nx,
|
||||
|
||||
// Configure the widget
|
||||
|
||||
m_flags.borderless = true; // The widget is borless (and transparent)
|
||||
m_flags.borderless = true; // The widget is borderless (and transparent)
|
||||
m_flags.draggable = true; // This widget may be dragged
|
||||
}
|
||||
|
||||
/**
|
||||
@ -461,8 +462,6 @@ void CIconWidget::handleUngrabEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
msg.eventID = EVENT_ICONWIDGET_UNGRAB;
|
||||
msg.pos.x = e.getX();
|
||||
msg.pos.y = e.getY();
|
||||
msg.delta.x = 0;
|
||||
msg.delta.y = 0;
|
||||
msg.context = EVENT_CONTEXT_ICON;
|
||||
msg.handler = (FAR CTwm4NxEvent *)0;
|
||||
msg.obj = (FAR void *)this;
|
||||
@ -490,8 +489,8 @@ void CIconWidget::handleUngrabEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
|
||||
void CIconWidget::handleDragEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
{
|
||||
// We don't care which widget is being dragged, only that we are in the
|
||||
// dragging state.
|
||||
// We don't care which component of the icon widget was clicked only that
|
||||
// we are not currently being dragged
|
||||
|
||||
if (m_drag)
|
||||
{
|
||||
@ -501,8 +500,6 @@ void CIconWidget::handleDragEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
msg.eventID = EVENT_ICONWIDGET_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_ICON;
|
||||
msg.handler = (FAR CTwm4NxEvent *)0;
|
||||
msg.obj = (FAR void *)this;
|
||||
@ -562,8 +559,6 @@ void CIconWidget::handleClickEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
msg.eventID = EVENT_ICONWIDGET_GRAB;
|
||||
msg.pos.x = e.getX();
|
||||
msg.pos.y = e.getY();
|
||||
msg.delta.x = 0;
|
||||
msg.delta.y = 0;
|
||||
msg.context = EVENT_CONTEXT_ICON;
|
||||
msg.handler = (FAR CTwm4NxEvent *)0;
|
||||
msg.obj = (FAR void *)this;
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/nx/nxglib.h>
|
||||
#include <nuttx/input/mouse.h>
|
||||
|
||||
@ -95,6 +96,8 @@ using namespace Twm4Nx;
|
||||
|
||||
CInput::CInput(CTwm4Nx *twm4nx)
|
||||
{
|
||||
// Session
|
||||
|
||||
m_twm4nx = twm4nx; // Save the NX server
|
||||
#ifndef CONFIG_TWM4NX_NOKEYBOARD
|
||||
m_kbdFd = -1; // Keyboard driver is not opened
|
||||
@ -102,14 +105,21 @@ CInput::CInput(CTwm4Nx *twm4nx)
|
||||
#ifndef CONFIG_TWM4NX_NOMOUSE
|
||||
m_mouseFd = -1; // Mouse/touchscreen driver is not opened
|
||||
#endif
|
||||
|
||||
// Listener
|
||||
|
||||
m_state = LISTENER_NOTRUNNING; // The listener thread is not running yet
|
||||
#ifdef CONFIG_TWM4NX_TOUCHSCREEN
|
||||
m_calib = false; // Use raw touches until calibrated
|
||||
#endif
|
||||
|
||||
// Initialize the semaphore used to synchronize with the listener thread
|
||||
|
||||
sem_init(&m_waitSem, 0, 0);
|
||||
sem_setprotocol(&m_waitSem, SEM_PRIO_NONE);
|
||||
|
||||
#ifdef CONFIG_TWM4NX_TOUCHSCREEN
|
||||
// Calibration
|
||||
|
||||
m_calib = false; // Use raw touches until calibrated
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,8 +180,7 @@ bool CMenus::initialize(FAR NXWidgets::CNxString &name)
|
||||
bool CMenus::addMenuItem(FAR NXWidgets::CNxString &text, FAR CMenus *subMenu,
|
||||
FAR CTwm4NxEvent *handler, uint16_t event)
|
||||
{
|
||||
twminfo("Adding menu text=\"%s\", subMenu=%p, event=%04x\n",
|
||||
text->getCharArray(), subMenu, event);
|
||||
twminfo("Adding: subMenu=%p, event=%04x\n", subMenu, event);
|
||||
|
||||
// Allocate a new menu item entry
|
||||
|
||||
@ -317,8 +316,6 @@ bool CMenus::event(FAR struct SEventMsg *eventmsg)
|
||||
newmsg.eventID = item->event;
|
||||
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.handler = item->handler;
|
||||
newmsg.obj = eventmsg->obj;
|
||||
@ -862,8 +859,6 @@ void CMenus::handleValueChangeEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
msg.eventID = item->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.handler = item->handler;
|
||||
msg.obj = (FAR void *)this;
|
||||
|
@ -161,8 +161,8 @@ CWindow::CWindow(CTwm4Nx *twm4nx)
|
||||
// Dragging
|
||||
|
||||
m_drag = false;
|
||||
m_dragOffset.x = 0;
|
||||
m_dragOffset.y = 0;
|
||||
m_dragPos.x = 0;
|
||||
m_dragPos.y = 0;
|
||||
m_dragCSize.w = 0;
|
||||
m_dragCSize.h = 0;
|
||||
|
||||
@ -675,6 +675,8 @@ bool CWindow::createMainWindow(FAR const nxgl_size_s *winsize,
|
||||
|
||||
// 3. Create a Widget control instance for the window using the default
|
||||
// style for now. CWindowEvent derives from CWidgetControl.
|
||||
// Setup the the CWindowEvent instance to use our inherited drag event
|
||||
// handler
|
||||
|
||||
FAR CWindowEvent *control = new CWindowEvent(m_twm4nx, (FAR void *)this);
|
||||
|
||||
@ -767,6 +769,7 @@ bool CWindow::createToolbar(void)
|
||||
// style for now. CWindowEvent derives from CWidgetControl.
|
||||
|
||||
FAR CWindowEvent *control = new CWindowEvent(m_twm4nx, (FAR void *)this);
|
||||
control->registerDragEventHandler(this);
|
||||
|
||||
// 3. Get the toolbar sub-window from the framed window
|
||||
|
||||
@ -1145,19 +1148,18 @@ bool CWindow::createToolbarTitle(FAR const char *name)
|
||||
* virtual event handling methods. It just combines some common event-
|
||||
* handling logic.
|
||||
*
|
||||
* @param e The event data.
|
||||
* @param x The mouse/touch X position.
|
||||
* @param y The mouse/touch y position.
|
||||
*/
|
||||
|
||||
void CWindow::handleUngrabEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
void CWindow::handleUngrabEvent(nxgl_coord_t x, nxgl_coord_t y)
|
||||
{
|
||||
// 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.pos.x = x;
|
||||
msg.pos.y = y;
|
||||
msg.context = EVENT_CONTEXT_TOOLBAR;
|
||||
msg.handler = (FAR CTwm4NxEvent *)0;
|
||||
msg.obj = (FAR void *)this;
|
||||
@ -1177,70 +1179,6 @@ void CWindow::handleUngrabEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the mouse button drag event.
|
||||
*
|
||||
* @param e The event data.
|
||||
*/
|
||||
|
||||
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 && m_tbTitle->isBeingDragged())
|
||||
{
|
||||
// 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.handler = (FAR CTwm4NxEvent *)0;
|
||||
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 runaway stack usage.
|
||||
|
||||
int ret = mq_send(m_eventq, (FAR const char *)&msg,
|
||||
sizeof(struct SEventMsg), 100);
|
||||
if (ret < 0)
|
||||
{
|
||||
twmerr("ERROR: mq_send failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override a drop event, triggered when the widget has been dragged-and-dropped.
|
||||
*
|
||||
* @param e The event data.
|
||||
*/
|
||||
|
||||
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 && !m_tbTitle->isClicked())
|
||||
{
|
||||
// Yes.. handle the drop event
|
||||
|
||||
handleUngrabEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a mouse click event.
|
||||
*
|
||||
@ -1260,8 +1198,6 @@ void CWindow::handleClickEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
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.handler = (FAR CTwm4NxEvent *)0;
|
||||
msg.obj = (FAR void *)this;
|
||||
@ -1303,7 +1239,7 @@ void CWindow::handleReleaseEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
|
||||
// Handle the non-drag drop event
|
||||
|
||||
handleUngrabEvent(e);
|
||||
handleUngrabEvent(e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1334,8 +1270,6 @@ void CWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
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.handler = (FAR CTwm4NxEvent *)0;
|
||||
msg.obj = (FAR void *)this;
|
||||
@ -1357,6 +1291,95 @@ void CWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when there is any moved of the mouse or
|
||||
* touch position that would indicate that the object is being moved.
|
||||
*
|
||||
* This function overrides the virtual IDragEvent::dragEvent method.
|
||||
*
|
||||
* @param pos The current mouse/touch X/Y position in toolbar relative
|
||||
* coordinates.
|
||||
* @return True: if the drage event was processed; false it is was
|
||||
* ignored. The event should be ignored if there is not actually
|
||||
* a drag event in progress
|
||||
*/
|
||||
|
||||
bool CWindow::dragEvent(FAR const struct nxgl_point_s &pos)
|
||||
{
|
||||
twminfo("m_drag=%u pos=(%d,%d)\n", m_drag, pos.x, pos.y);
|
||||
|
||||
// We are interested only the drag event while we are in the dragging
|
||||
// state.
|
||||
|
||||
if (m_drag)
|
||||
{
|
||||
// Conver the
|
||||
// Generate the event
|
||||
|
||||
struct SEventMsg msg;
|
||||
msg.eventID = EVENT_WINDOW_DRAG;
|
||||
msg.pos.x = pos.x;
|
||||
msg.pos.y = pos.y;
|
||||
msg.context = EVENT_CONTEXT_TOOLBAR;
|
||||
msg.handler = (FAR CTwm4NxEvent *)0;
|
||||
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 runaway stack usage.
|
||||
|
||||
int ret = mq_send(m_eventq, (FAR const char *)&msg,
|
||||
sizeof(struct SEventMsg), 100);
|
||||
if (ret < 0)
|
||||
{
|
||||
twmerr("ERROR: mq_send failed: %d\n", ret);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called if the mouse left button is released or
|
||||
* if the touchscrreen touch is lost. This indicates that the
|
||||
* dragging sequence is complete.
|
||||
*
|
||||
* This function overrides the virtual IDragEvent::dropEvent method.
|
||||
*
|
||||
* @param pos The last mouse/touch X/Y position in toolbar relative
|
||||
* coordinates.
|
||||
* @return True: if the drage event was processed; false it is was
|
||||
* ignored. The event should be ignored if there is not actually
|
||||
* a drag event in progress
|
||||
*/
|
||||
|
||||
bool CWindow::dropEvent(FAR const struct nxgl_point_s &pos)
|
||||
{
|
||||
twminfo("m_drag=%u pos=(%d,%d)\n", m_drag, pos.x, pos.y);
|
||||
|
||||
// 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)
|
||||
{
|
||||
// Yes.. handle the drop event
|
||||
|
||||
handleUngrabEvent(pos.x, pos.y);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the TOOLBAR_GRAB event. That corresponds to a left
|
||||
* mouse click on the title widget in the toolbar
|
||||
@ -1368,6 +1391,8 @@ void CWindow::handleActionEvent(const NXWidgets::CWidgetEventArgs &e)
|
||||
|
||||
bool CWindow::toolbarGrab(FAR struct SEventMsg *eventmsg)
|
||||
{
|
||||
twminfo("GRAB (%d,%d)\n", eventmsg->pos.x, eventmsg->pos.y);
|
||||
|
||||
// Promote the window to a modal window
|
||||
|
||||
m_modal = true;
|
||||
@ -1382,19 +1407,25 @@ bool CWindow::toolbarGrab(FAR struct SEventMsg *eventmsg)
|
||||
struct nxgl_point_s framePos;
|
||||
getFramePosition(&framePos);
|
||||
|
||||
// Determine the relative position of the frame and the mouse
|
||||
twminfo("Position (%d,%d)\n", framePos.x, framePos.y);
|
||||
|
||||
m_dragOffset.x = framePos.x - eventmsg->pos.x;
|
||||
m_dragOffset.y = framePos.y - eventmsg->pos.y;
|
||||
// Save the toolbar-relative mouse position in order to detect the amount
|
||||
// of movement in the next drag event.
|
||||
|
||||
m_dragPos.x = eventmsg->pos.x;
|
||||
m_dragPos.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
|
||||
|
||||
m_dragCSize.w = CONFIG_TWM4NX_GBCURSOR_IMAGE.size.w;
|
||||
m_dragCSize.h = CONFIG_TWM4NX_GBCURSOR_IMAGE.size.h;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1409,13 +1440,31 @@ bool CWindow::toolbarGrab(FAR struct SEventMsg *eventmsg)
|
||||
|
||||
bool CWindow::windowDrag(FAR struct SEventMsg *eventmsg)
|
||||
{
|
||||
twminfo("DRAG (%d,%d)\n", eventmsg->pos.x, eventmsg->pos.y);
|
||||
|
||||
if (m_drag)
|
||||
{
|
||||
// Calculate the new Window position
|
||||
// The coordinates in the eventmsg or relative to the origin
|
||||
// of the toolbar.
|
||||
|
||||
struct nxgl_point_s newpos;
|
||||
newpos.x = eventmsg->pos.x + m_dragOffset.x;
|
||||
newpos.y = eventmsg->pos.y + m_dragOffset.y;
|
||||
struct nxgl_point_s oldPos;
|
||||
if (!getFramePosition(&oldPos))
|
||||
{
|
||||
gerr("ERROR: getFramePosition() failed\n") ;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We want to set the new frame position so that it has the same
|
||||
// relative mouse position as when we grabbed the toolbar.
|
||||
|
||||
struct nxgl_point_s newPos;
|
||||
newPos.x = oldPos.x + eventmsg->pos.x - m_dragPos.x;
|
||||
newPos.y = oldPos.y + eventmsg->pos.y - m_dragPos.y;
|
||||
|
||||
// Save the new mouse position
|
||||
|
||||
m_dragPos.x = eventmsg->pos.x;
|
||||
m_dragPos.y = eventmsg->pos.y;
|
||||
|
||||
// Keep the window on the display (at least enough of it so that we
|
||||
// can still grab it)
|
||||
@ -1423,27 +1472,41 @@ bool CWindow::windowDrag(FAR struct SEventMsg *eventmsg)
|
||||
struct nxgl_size_s displaySize;
|
||||
m_twm4nx->getDisplaySize(&displaySize);
|
||||
|
||||
if (newpos.x < 0)
|
||||
if (newPos.x < 0)
|
||||
{
|
||||
newpos.x = 0;
|
||||
newPos.x = 0;
|
||||
}
|
||||
else if (newpos.x + m_dragCSize.w > displaySize.w)
|
||||
else if (newPos.x + m_dragCSize.w > displaySize.w)
|
||||
{
|
||||
newpos.x = displaySize.w - m_dragCSize.w;
|
||||
newPos.x = displaySize.w - m_dragCSize.w;
|
||||
}
|
||||
|
||||
if (newpos.y < 0)
|
||||
if (newPos.y < 0)
|
||||
{
|
||||
newpos.y = 0;
|
||||
newPos.y = 0;
|
||||
}
|
||||
else if (newpos.y + m_dragCSize.h > displaySize.h)
|
||||
else if (newPos.y + m_dragCSize.h > displaySize.h)
|
||||
{
|
||||
newpos.y = displaySize.h - m_dragCSize.h;
|
||||
newPos.y = displaySize.h - m_dragCSize.h;
|
||||
}
|
||||
|
||||
// Set the new window position
|
||||
// Set the new window position if it has changed
|
||||
|
||||
return setFramePosition(&newpos);
|
||||
twminfo("Position (%d,%d)->(%d,%d)\n",
|
||||
oldPos.x, oldPos.y, newPos.x, newPos.y);
|
||||
|
||||
if (newPos.x != oldPos.x || newPos.y != oldPos.y)
|
||||
{
|
||||
if (!setFramePosition(&newPos))
|
||||
{
|
||||
gerr("ERROR: setFramePosition failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nxWin->synchronize();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -1453,13 +1516,16 @@ bool CWindow::windowDrag(FAR struct SEventMsg *eventmsg)
|
||||
* Handle the TOOLBAR_UNGRAB event. The corresponds to a mouse
|
||||
* left button release while in the grabbed state
|
||||
*
|
||||
* @param eventmsg. The received NxWidget event message.
|
||||
* @param eventmsg. The received NxWidget event message in window relative
|
||||
* coordinates.
|
||||
* @return True if the message was properly handled. false is
|
||||
* return on any failure.
|
||||
*/
|
||||
|
||||
bool CWindow::toolbarUngrab(FAR struct SEventMsg *eventmsg)
|
||||
{
|
||||
twminfo("UNGRAB (%d,%d)\n", eventmsg->pos.x, eventmsg->pos.y);
|
||||
|
||||
// One last position update
|
||||
|
||||
if (!windowDrag(eventmsg))
|
||||
@ -1476,9 +1542,11 @@ bool CWindow::toolbarUngrab(FAR struct SEventMsg *eventmsg)
|
||||
m_modal = false;
|
||||
m_nxWin->modal(false);
|
||||
|
||||
#ifdef CONFIG_TWM4NX_MOUSE
|
||||
// Restore the normal cursor image
|
||||
|
||||
m_twm4nx->setCursorImage(&CONFIG_TWM4NX_CURSOR_IMAGE);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -42,8 +42,11 @@
|
||||
#include <cfcntl>
|
||||
#include <cerrno>
|
||||
|
||||
#include <semaphore.h>
|
||||
#include <mqueue.h>
|
||||
|
||||
#include <nuttx/input/mouse.h>
|
||||
|
||||
#include "graphics/nxwidgets/cwidgetcontrol.hxx"
|
||||
|
||||
#include "graphics/twm4nx/twm4nx_config.hxx"
|
||||
@ -72,9 +75,14 @@ CWindowEvent::CWindowEvent(FAR CTwm4Nx *twm4nx, FAR void *obj,
|
||||
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_twm4nx = twm4nx; // Cache the Twm4Nx session
|
||||
m_object = obj; // Used for event message construction
|
||||
m_isBackground = isBackground; // Background window?
|
||||
|
||||
// Dragging
|
||||
|
||||
m_dragHandler = (FAR IDragEvent *)0; // No drag handler callbacks
|
||||
m_dragging = false; // Not dragging
|
||||
|
||||
// Open a message queue to send raw NX events. This cannot fail!
|
||||
|
||||
@ -208,9 +216,84 @@ void CWindowEvent::handleRedrawEvent(FAR const nxgl_rect_s *nxRect,
|
||||
* Handle an NX window mouse input event.
|
||||
*/
|
||||
|
||||
void CWindowEvent::handleMouseEvent(void)
|
||||
void CWindowEvent::handleMouseEvent(FAR const struct nxgl_point_s *pos,
|
||||
uint8_t buttons)
|
||||
{
|
||||
twminfo("Mouse input...\n");
|
||||
twminfo("Mouse input: m_dragging=%u\n", m_dragging);
|
||||
|
||||
// Check if are dragging
|
||||
//
|
||||
// STATE LEFT BUTTON ACTION
|
||||
// dragging clicked dragEvent
|
||||
// dragging released dropEvent
|
||||
// NOT dragging clicked May be detected as a grab
|
||||
// NOT dragging released None
|
||||
|
||||
if (m_dragging)
|
||||
{
|
||||
// Save the new drag position in window relative display coordinates
|
||||
|
||||
m_dragPos.x = pos->x;
|
||||
m_dragPos.y = pos->y;
|
||||
|
||||
// Is the left button still pressed?
|
||||
|
||||
if ((buttons & MOUSE_BUTTON_1) != 0)
|
||||
{
|
||||
twminfo("Continue dragging (%d,%d) buttons=%02x m_dragHandler=%p\n",
|
||||
m_dragPos.x, m_dragPos.y, buttons, m_dragHandler);
|
||||
|
||||
// Yes.. generate a drag event if we have a drag event handler
|
||||
|
||||
if (m_dragHandler != (FAR IDragEvent *)0 &&
|
||||
m_dragHandler->dragEvent(m_dragPos))
|
||||
{
|
||||
// Skip the input poll until the drag completes
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
twminfo("Stop dragging (%d,%d) buttons=%02x m_dragHandler=%p\n",
|
||||
m_dragPos.x, m_dragPos.y, buttons, m_dragHandler);
|
||||
|
||||
// No.. then we are no longer dragging
|
||||
|
||||
m_dragging = false;
|
||||
|
||||
// Generate a dropEvent
|
||||
|
||||
if (m_dragHandler != (FAR IDragEvent *)0 &&
|
||||
m_dragHandler->dropEvent(m_dragPos))
|
||||
{
|
||||
// If the drop event was processed then skip the
|
||||
// input poll until AFTER the drag completes
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we are not currently dragging but the left button is pressed, then
|
||||
// start the drag event
|
||||
|
||||
else if ((buttons & MOUSE_BUTTON_1) != 0)
|
||||
{
|
||||
// Indicate that we are (or may be) dragging
|
||||
|
||||
m_dragging = true;
|
||||
|
||||
// Save the initial drag position
|
||||
|
||||
m_dragPos.x = pos->x;
|
||||
m_dragPos.y = pos->y;
|
||||
|
||||
twminfo("Start dragging (%d,%d) buttons=%02x m_dragHandler=%p\n",
|
||||
m_dragPos.x, m_dragPos.y, buttons, m_dragHandler);
|
||||
|
||||
// But take no other actions until the window recognizes the grab
|
||||
}
|
||||
|
||||
// Stimulate an input poll
|
||||
|
||||
|
@ -249,6 +249,7 @@ void CWindowFactory::destroyWindow(FAR CWindow *cwin)
|
||||
bool CWindowFactory::event(FAR struct SEventMsg *eventmsg)
|
||||
{
|
||||
twminfo("eventID: %d\n", eventmsg->eventID);
|
||||
|
||||
bool success = true;
|
||||
|
||||
switch (eventmsg->eventID)
|
||||
|
@ -98,7 +98,10 @@ namespace NXWidgets
|
||||
* Handle an NX window mouse input event.
|
||||
*/
|
||||
|
||||
virtual void handleMouseEvent(void) { }
|
||||
virtual void handleMouseEvent(FAR const struct nxgl_point_s *pos,
|
||||
uint8_t buttons)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NX_KBD
|
||||
|
@ -153,7 +153,8 @@ namespace NXWidgets
|
||||
* Raise an NX mouse window input event.
|
||||
*/
|
||||
|
||||
void raiseMouseEvent(void);
|
||||
void raiseMouseEvent(FAR const struct nxgl_point_s *pos,
|
||||
uint8_t buttons);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NX_KBD
|
||||
|
@ -104,7 +104,7 @@ namespace NxWM
|
||||
* Handle an NX window mouse input event.
|
||||
*/
|
||||
|
||||
void handleMouseEvent(void);
|
||||
void handleMouseEvent(FAR const struct nxgl_point_s *pos, uint8_t buttons);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NX_KBD
|
||||
|
@ -124,6 +124,8 @@ namespace Twm4Nx
|
||||
* CInput state data
|
||||
*/
|
||||
|
||||
// Session
|
||||
|
||||
CTwm4Nx *m_twm4nx; /**< The Twm4Nx session */
|
||||
#ifndef CONFIG_TWM4NX_NOKEYBOARD
|
||||
int m_kbdFd; /**< File descriptor of the opened keyboard device */
|
||||
@ -131,15 +133,21 @@ namespace Twm4Nx
|
||||
#ifndef CONFIG_TWM4NX_NOMOUSE
|
||||
int m_mouseFd; /**< File descriptor of the opened mouse device */
|
||||
#endif
|
||||
|
||||
// Listener
|
||||
|
||||
pthread_t m_thread; /**< The listener thread ID */
|
||||
volatile enum EListenerState m_state; /**< The state of the listener thread */
|
||||
sem_t m_waitSem; /**< Used to synchronize with the listener thread */
|
||||
|
||||
#ifdef CONFIG_TWM4NX_TOUCHSCREEN
|
||||
// Calibration
|
||||
|
||||
bool m_calib; /**< False: Use raw, uncalibrated touches */
|
||||
struct SCalibrationData m_calData; /**< Touchscreen calibration data */
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CONFIG_TWM4NX_NOKEYBOARD
|
||||
/**
|
||||
* Open the keyboard device. Not very interesting for the case of
|
||||
@ -278,7 +286,7 @@ namespace Twm4Nx
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Start the keyboard listener thread.
|
||||
* Start the keyboard/mouse listener thread.
|
||||
*
|
||||
* @return True if the keyboard listener thread was correctly started.
|
||||
*/
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "graphics/nxwidgets/cwidgeteventhandler.hxx"
|
||||
#include "graphics/nxwidgets/cwidgeteventargs.hxx"
|
||||
|
||||
#include "graphics/twm4nx/cwindowevent.hxx"
|
||||
#include "graphics/twm4nx/ciconwidget.hxx"
|
||||
#include "graphics/twm4nx/ctwm4nxevent.hxx"
|
||||
|
||||
@ -128,7 +129,9 @@ namespace Twm4Nx
|
||||
// The CWindow class implements a standard, framed window with a toolbar
|
||||
// containing the standard buttons and the window title.
|
||||
|
||||
class CWindow : protected NXWidgets::CWidgetEventHandler, public CTwm4NxEvent
|
||||
class CWindow : protected NXWidgets::CWidgetEventHandler,
|
||||
protected IDragEvent,
|
||||
public CTwm4NxEvent
|
||||
{
|
||||
private:
|
||||
CTwm4Nx *m_twm4nx; /**< Cached Twm4Nx session */
|
||||
@ -166,7 +169,7 @@ namespace Twm4Nx
|
||||
|
||||
// Dragging
|
||||
|
||||
struct nxgl_point_s m_dragOffset; /**< Offset from mouse to window origin */
|
||||
struct nxgl_point_s m_dragPos; /**< Last reported mouse position */
|
||||
struct nxgl_size_s m_dragCSize; /**< The grab cursor size */
|
||||
bool m_drag; /**< Drag in-progress */
|
||||
|
||||
@ -239,26 +242,11 @@ namespace Twm4Nx
|
||||
* virtual event handling methods. It just combines some common event-
|
||||
* handling logic.
|
||||
*
|
||||
* @param e The event data.
|
||||
* @param x The mouse/touch X position.
|
||||
* @param y The mouse/touch y position.
|
||||
*/
|
||||
|
||||
void handleUngrabEvent(const NXWidgets::CWidgetEventArgs &e);
|
||||
|
||||
/**
|
||||
* Override the mouse button drag event.
|
||||
*
|
||||
* @param e The event data.
|
||||
*/
|
||||
|
||||
void handleDragEvent(const NXWidgets::CWidgetEventArgs &e);
|
||||
|
||||
/**
|
||||
* Override a drop event, triggered when the widget has been dragged-and-dropped.
|
||||
*
|
||||
* @param e The event data.
|
||||
*/
|
||||
|
||||
void handleDropEvent(const NXWidgets::CWidgetEventArgs &e);
|
||||
void handleUngrabEvent(nxgl_coord_t x, nxgl_coord_t y);
|
||||
|
||||
/**
|
||||
* Handle a mouse click event.
|
||||
@ -289,6 +277,34 @@ namespace Twm4Nx
|
||||
|
||||
void handleActionEvent(const NXWidgets::CWidgetEventArgs &e);
|
||||
|
||||
/**
|
||||
* This function is called when there is any moved of the mouse or
|
||||
* touch position that would indicate that the object is being moved.
|
||||
*
|
||||
* This function overrides the virtual IDragEvent::dragEvent method.
|
||||
*
|
||||
* @param pos The current mouse/touch X/Y position.
|
||||
* @return True: if the drage event was processed; false it is was
|
||||
* ignored. The event should be ignored if there is not actually
|
||||
* a drag event in progress
|
||||
*/
|
||||
|
||||
bool dragEvent(FAR const struct nxgl_point_s &pos);
|
||||
|
||||
/**
|
||||
* This function is called if the mouse left button is released or
|
||||
* if the touchscrreen touch is lost. This indicates that the
|
||||
* dragging sequence is complete.
|
||||
*
|
||||
* This function overrides the virtual IDragEvent::dropEvent method.
|
||||
*
|
||||
* @return True: if the drage event was processed; false it is was
|
||||
* ignored. The event should be ignored if there is not actually
|
||||
* a drag event in progress
|
||||
*/
|
||||
|
||||
bool dropEvent(FAR const struct nxgl_point_s &pos);
|
||||
|
||||
/**
|
||||
* Handle the TOOLBAR_GRAB event. That corresponds to a left
|
||||
* mouse click on the toolbar (other than on an icon)
|
||||
|
@ -57,10 +57,53 @@
|
||||
// Implementation Classes
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
namespace Twm4Nx
|
||||
{
|
||||
/**
|
||||
* This abstract base class provides add on methods to support dragging
|
||||
* of a window.
|
||||
*/
|
||||
|
||||
class IDragEvent
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* A virtual destructor is required in order to override the ITextBox
|
||||
* destructor. We do this because if we delete ITextBox, we want the
|
||||
* destructor of the class that inherits from ITextBox to run, not this
|
||||
* one.
|
||||
*/
|
||||
|
||||
virtual ~IDragEvent(void) { }
|
||||
|
||||
/**
|
||||
* This function is called when there is any moved of the mouse or
|
||||
* touch position that would indicate that the object is being moved.
|
||||
*
|
||||
* @param pos The current mouse/touch X/Y position in toolbar relative
|
||||
* coordinates.
|
||||
* @return True: if the drage event was processed; false it is was
|
||||
* ignored. The event should be ignored if there is not actually
|
||||
* a drag event in progress
|
||||
*/
|
||||
|
||||
virtual bool dragEvent(FAR const struct nxgl_point_s &pos) = 0;
|
||||
|
||||
/**
|
||||
* This function is called if the mouse left button is released or
|
||||
* if the touchscrreen touch is lost. This indicates that the
|
||||
* dragging sequence is complete.
|
||||
*
|
||||
* @param pos The last mouse/touch X/Y position in toolbar relative
|
||||
* coordinates.
|
||||
* @return True: if the drage event was processed; false it is was
|
||||
* ignored. The event should be ignored if there is not actually
|
||||
* a drag event in progress
|
||||
*/
|
||||
|
||||
virtual bool dropEvent(FAR const struct nxgl_point_s &pos) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* The class CWindowEvent integrates the widget control with some special
|
||||
* handling of mouse and keyboard inputs needs by NxWM. It use used
|
||||
@ -74,10 +117,16 @@ namespace Twm4Nx
|
||||
public NXWidgets::CWidgetControl
|
||||
{
|
||||
private:
|
||||
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 */
|
||||
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 */
|
||||
|
||||
// Dragging
|
||||
|
||||
FAR IDragEvent *m_dragHandler; /**< Drag event handlers (may be NULL) */
|
||||
bool m_dragging; /**< True: dragging */
|
||||
struct nxgl_point_s m_dragPos; /**< Last mouse/touch position */
|
||||
|
||||
/**
|
||||
* Send the EVENT_MSG_POLL input event message to the Twm4Nx event loop.
|
||||
@ -101,7 +150,8 @@ namespace Twm4Nx
|
||||
* Handle an NX window mouse input event.
|
||||
*/
|
||||
|
||||
void handleMouseEvent(void);
|
||||
void handleMouseEvent(FAR const struct nxgl_point_s *pos,
|
||||
uint8_t buttons);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NX_KBD
|
||||
@ -142,9 +192,23 @@ namespace Twm4Nx
|
||||
* CWindowEvent Destructor.
|
||||
*/
|
||||
|
||||
~CWindowEvent(void);
|
||||
~CWindowEvent(void);
|
||||
|
||||
/**
|
||||
* Register an IDragEvent instance to provide callbacks when mouse
|
||||
* movement is received. A mouse movement with the left button down
|
||||
* or a touchscreen touch movement are treated as a drag event.
|
||||
* Release of the mouse left button or loss of the touchscreen touch
|
||||
* is treated as a drop event.
|
||||
*
|
||||
* @param cb A reference to the IDragEvent callback interface.
|
||||
*/
|
||||
|
||||
inline void registerDragEventHandler(FAR IDragEvent *dragHandler)
|
||||
{
|
||||
m_dragHandler = dragHandler;
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __APPS_INCLUDE_GRAPHICS_TWM4NX_CWINDOWEVENT_HXX
|
||||
|
@ -197,7 +197,6 @@ 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 */
|
||||
FAR CTwm4NxEvent *handler; /**< App event handler (APP recipient only) */
|
||||
FAR void *obj; /**< Window object (CWindow or CIconWidget) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user