summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qdnd_s60.cpp
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@sosco.com>2009-09-15 14:12:08 +0200
committerShane Kearns <shane.kearns@sosco.com>2009-09-15 16:05:53 +0200
commit56cec4cf9a8b04c979ced28cab89ce6232d4184a (patch)
treea9701f13161810d1e9bfbf7ef9cd8430a77580be /src/gui/kernel/qdnd_s60.cpp
parentf42f5c457b3368adb4c92e521dc56969f138bdd3 (diff)
QCursor support for Symbian OS
Reviewed-By: Jason Barron Reviewed-By: Alessandro Portale Summary: QT_NO_CURSOR is now not defined for symbian builds Existing QCursor APIs are all supported New public API, QApplication::setNavigationMode, to allow the navigation mode to be set. I.E. on an S60 3.2 phone, some applications will want a virtual mouse cursor (web browser), while others are designed for keypad navigation. Symbian HAL is used for detecting input capabilities. Fix DND, code cleanup & comment QCursor visibility now uses a refcount, and is called from DND and the setNavigationMode so they are both simpler and don't interfere with each other. QApplication::setNavigationMode New public API for configuring cursor/keypad navi style. This links in with ongoing work on the 4-way keypad navi branch, but 2-way and 4-way modes both act as 2-way mode until that is integrated Some of the demos/examples have cursor switched on (those that were not usable with keypad) Virtual mouse support for non touch, non mouse phones (tested on N78) add *.d and .metadata (carbide debug file / workspace dir) to .gitignore System pointers are unavailable when using sprite workaround, so the system cursor shapes are compiled into qtgui as resources. MAC port does this also for shapes that aren't standard on the MAC. Refactor Drag'n'Drop to use QCursor Add test case to check all system cursor shapes Simply a mainwindow containing a label widget for each cursor shape, with the cursor property set appropriately QCursor(QBitmap,QBitmap) supported Fixed problem with the image & mask being inverted when using the QCursor constructor that takes two mono bitmaps. add .make.cache files to .gitignore Correct implementation of QApplication::setOverrideCursor QApplication::restoreOverrideCursor and QApplication::setOverrideCursor are now working correctly on Symbian platform. Performance will be slower compared with other platforms, because the Symbian window server has a cursor associated with each native window. Add test case for custom cursors Create a pixmap cursor and associate it with a widget. No changes to production code, since test passed 1st time ;) Add manual test for QCursor Make cursor independent of construction order Updated to work around window server issue where contruction order affects what cursor is displayed in child windows. Also changed to effectiveWinId following review comments Also fixed a problem which would make qcursor not link if configured with QT_NO_CURSOR Moved some multiply declared extern functions from cpp to _p.h files Implemented Symbian versions of the cursor functions. Merged in work I'd done based on tower. Fill in bits of stub functions based on windows port Removed QT_NO_CURSOR from list of config options forced on symbian Recompiled configure.exe Added stub functions for the missing functions in s60 port
Diffstat (limited to 'src/gui/kernel/qdnd_s60.cpp')
-rw-r--r--src/gui/kernel/qdnd_s60.cpp148
1 files changed, 51 insertions, 97 deletions
diff --git a/src/gui/kernel/qdnd_s60.cpp b/src/gui/kernel/qdnd_s60.cpp
index fb2e4266f4..24561850c8 100644
--- a/src/gui/kernel/qdnd_s60.cpp
+++ b/src/gui/kernel/qdnd_s60.cpp
@@ -50,11 +50,14 @@
#include "qevent.h"
#include "qpainter.h"
#include "qdnd_p.h"
+#include "qt_s60_p.h"
#include <COECNTRL.H>
// pointer cursor
#include <w32std.h>
#include <gdi.h>
+#include <QCursor>
+
QT_BEGIN_NAMESPACE
//### artistic impression of Symbians default DnD cursor ?
@@ -89,82 +92,24 @@ static bool qt_symbian_dnd_dragging = false;
static Qt::KeyboardModifiers oldstate;
-class QShapedPixmapWidget
-{
-public:
- QShapedPixmapWidget(RWsSession aWsSession,RWindowTreeNode* aNode)
- {
- sprite = RWsSprite(aWsSession);
- cursorSprite.iBitmap = 0;
- cursorSprite.iMaskBitmap = 0;
- cursorSprite.iInvertMask = EFalse;
- cursorSprite.iOffset = TPoint(0,0);
- cursorSprite.iInterval = TTimeIntervalMicroSeconds32(0);
- cursorSprite.iDrawMode = CGraphicsContext::EDrawModePEN;
- sprite.Construct(*aNode,TPoint(0,0), ESpriteNoShadows | ESpriteNoChildClip);
- sprite.AppendMember(cursorSprite);
- sprite.Activate();
- }
- ~QShapedPixmapWidget()
- {
- sprite.Close();
- cursorSprite.iBitmap = 0;
- delete cursorBitmap;
- cursorBitmap = 0; //redundant...
- }
- void disableCursor()
- {
- cursorSprite.iBitmap = 0;
- sprite.UpdateMember(0,cursorSprite);
- }
- void enableCursor()
- {
- cursorSprite.iBitmap = cursorBitmap;
- sprite.UpdateMember(0,cursorSprite);
- }
- void setPixmap(QPixmap pm)
- {
- //### heaplock centralized.
- QImage temp = pm.toImage();
- QSize size = pm.size();
- temp.bits();
- CFbsBitmap *curbm = q_check_ptr(new CFbsBitmap()); // CBase derived object needs check on new
- curbm->Create(TSize(size.width(),size.height()),EColor16MA);
- curbm->LockHeap(ETrue);
- memcpy((uchar*)curbm->DataAddress(),temp.bits(),temp.numBytes());
- curbm->UnlockHeap(ETrue);
- delete cursorSprite.iBitmap;
- cursorSprite.iBitmap = curbm;
- cursorBitmap = curbm;
- sprite.UpdateMember(0,cursorSprite);
- }
- CFbsBitmap *cursorBitmap;
- RWsPointerCursor pointerCursor;
- RWsSprite sprite;
- TSpriteMember cursorSprite;
-
-};
-
-
-static QShapedPixmapWidget *qt_symbian_dnd_deco = 0;
-
void QDragManager::updatePixmap()
{
- if (qt_symbian_dnd_deco) {
- QPixmap pm;
- QPoint pm_hot(default_pm_hotx,default_pm_hoty);
- if (drag_object) {
- pm = drag_object->pixmap();
- if (!pm.isNull())
- pm_hot = drag_object->hotSpot();
- }
- if (pm.isNull()) {
- if (!defaultPm)
- defaultPm = new QPixmap(default_pm);
- pm = *defaultPm;
- }
- qt_symbian_dnd_deco->setPixmap(pm);
+ QPixmap pm;
+ QPoint pm_hot(default_pm_hotx,default_pm_hoty);
+ if (drag_object) {
+ pm = drag_object->pixmap();
+ if (!pm.isNull())
+ pm_hot = drag_object->hotSpot();
+ }
+ if (pm.isNull()) {
+ if (!defaultPm)
+ defaultPm = new QPixmap(default_pm);
+ pm = *defaultPm;
}
+#ifndef QT_NO_CURSOR
+ QCursor cursor(pm, pm_hot.x(), pm_hot.y());
+ overrideCursor = cursor;
+#endif
}
void QDragManager::timerEvent(QTimerEvent *) { }
@@ -174,6 +119,16 @@ void QDragManager::move(const QPoint&) {
void QDragManager::updateCursor()
{
+#ifndef QT_NO_CURSOR
+ QCursor cursor = willDrop ? overrideCursor : Qt::ForbiddenCursor;
+ if (!restoreCursor) {
+ QApplication::setOverrideCursor(cursor);
+ restoreCursor = true;
+ }
+ else {
+ QApplication::changeOverrideCursor(cursor);
+ }
+#endif
}
@@ -210,20 +165,19 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
// map the Coords relative to the window.
if (!cw)
return true;
- TPoint windowPos = cw->effectiveWinId()->PositionRelativeToScreen();
- qt_symbian_dnd_deco->sprite.SetPosition(TPoint(me->globalX()- windowPos.iX,me->globalY()- windowPos.iY));
while (cw && !cw->acceptDrops() && !cw->isWindow())
cw = cw->parentWidget();
+ bool oldWillDrop = willDrop;
if (object->target() != cw) {
if (object->target()) {
QDragLeaveEvent dle;
QApplication::sendEvent(object->target(), &dle);
willDrop = false;
global_accepted_action = Qt::IgnoreAction;
- updateCursor();
- restoreCursor = true;
+ if (oldWillDrop != willDrop)
+ updateCursor();
object->d_func()->target = 0;
}
if (cw && cw->acceptDrops()) {
@@ -233,8 +187,8 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
QApplication::sendEvent(object->target(), &dee);
willDrop = dee.isAccepted() && dee.dropAction() != Qt::IgnoreAction;
global_accepted_action = willDrop ? dee.dropAction() : Qt::IgnoreAction;
- updateCursor();
- restoreCursor = true;
+ if (oldWillDrop != willDrop)
+ updateCursor();
}
} else if (cw) {
QDragMoveEvent dme(cw->mapFromGlobal(me->globalPos()), possible_actions, dropData,
@@ -246,8 +200,10 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
QApplication::sendEvent(cw, &dme);
willDrop = dme.isAccepted();
global_accepted_action = willDrop ? dme.dropAction() : Qt::IgnoreAction;
- updatePixmap();
- updateCursor();
+ if (oldWillDrop != willDrop) {
+ updatePixmap();
+ updateCursor();
+ }
}
if (global_accepted_action != prevAction)
emitActionChanged(global_accepted_action);
@@ -259,7 +215,7 @@ bool QDragManager::eventFilter(QObject *o, QEvent *e)
{
qApp->removeEventFilter(this);
if (restoreCursor) {
- qt_symbian_dnd_deco->disableCursor();
+ QApplication::restoreOverrideCursor();
willDrop = false;
restoreCursor = false;
}
@@ -305,23 +261,15 @@ Qt::DropAction QDragManager::drag(QDrag *o)
}
object = drag_object = o;
- RWsSession winSession = o->source()->effectiveWinId()->ControlEnv()->WsSession();
- Q_ASSERT(!qt_symbian_dnd_deco);
- qt_symbian_dnd_deco = new QShapedPixmapWidget(winSession, o->source()->effectiveWinId()->DrawableWindow());
oldstate = Qt::NoModifier; // #### Should use state that caused the drag
willDrop = false;
updatePixmap();
updateCursor();
- restoreCursor = true;
- object->d_func()->target = 0;
- TPoint windowPos = source()->effectiveWinId()->PositionRelativeToScreen();
- qt_symbian_dnd_deco->sprite.SetPosition(TPoint(QCursor::pos().x()- windowPos.iX ,QCursor::pos().y() - windowPos.iY));
+ qt_symbian_set_cursor_visible(true); //force cursor on even for touch phone
- QPoint hotspot = drag_object->hotSpot();
- qt_symbian_dnd_deco->cursorSprite.iOffset = TPoint(- hotspot.x(),- hotspot.y());
- qt_symbian_dnd_deco->sprite.UpdateMember(0,qt_symbian_dnd_deco->cursorSprite);
+ object->d_func()->target = 0;
qApp->installEventFilter(this);
@@ -334,11 +282,11 @@ Qt::DropAction QDragManager::drag(QDrag *o)
delete eventLoop;
eventLoop = 0;
- delete qt_symbian_dnd_deco;
- qt_symbian_dnd_deco = 0;
+ qt_symbian_set_cursor_visible(false);
+
+ overrideCursor = QCursor(); //deref the cursor data
qt_symbian_dnd_dragging = false;
-
return global_accepted_action;
}
@@ -358,8 +306,10 @@ void QDragManager::cancel(bool deleteSource)
drag_object = object = 0;
}
- delete qt_symbian_dnd_deco;
- qt_symbian_dnd_deco = 0;
+ if (restoreCursor) {
+ QApplication::restoreOverrideCursor();
+ restoreCursor = false;
+ }
global_accepted_action = Qt::IgnoreAction;
}
@@ -367,6 +317,10 @@ void QDragManager::cancel(bool deleteSource)
void QDragManager::drop()
{
+ if (restoreCursor) {
+ QApplication::restoreOverrideCursor();
+ restoreCursor = false;
+ }
}
QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const