diff options
-rw-r--r-- | models/symbianNonTouch/n95landscape.png | bin | 12349 -> 13437 bytes | |||
-rw-r--r-- | models/symbianNonTouch/n95portrait.png | bin | 20339 -> 21398 bytes | |||
-rw-r--r-- | models/symbianNonTouch/symbianNonTouch.config | 4 | ||||
-rw-r--r-- | models/symbianTouch/menu_landscape.png | bin | 25282 -> 23415 bytes | |||
-rw-r--r-- | models/symbianTouch/menu_portrait.png | bin | 9239 -> 7337 bytes | |||
-rw-r--r-- | models/symbianTouch/symbianTouch.config | 7 | ||||
-rw-r--r-- | src/other/application.cpp | 66 | ||||
-rw-r--r-- | src/other/application.h | 6 | ||||
-rw-r--r-- | src/other/configurationreader.cpp | 14 | ||||
-rw-r--r-- | src/other/deviceitem.cpp | 106 | ||||
-rw-r--r-- | src/other/deviceitem.h | 47 | ||||
-rw-r--r-- | src/other/widgetmanager.cpp | 22 | ||||
-rw-r--r-- | src/other/widgetmanager.h | 8 | ||||
-rw-r--r-- | src/ui/mainwindow.cpp | 2 |
14 files changed, 275 insertions, 7 deletions
diff --git a/models/symbianNonTouch/n95landscape.png b/models/symbianNonTouch/n95landscape.png Binary files differindex e549bbf..159a628 100644 --- a/models/symbianNonTouch/n95landscape.png +++ b/models/symbianNonTouch/n95landscape.png diff --git a/models/symbianNonTouch/n95portrait.png b/models/symbianNonTouch/n95portrait.png Binary files differindex 2f2d6b6..33021bd 100644 --- a/models/symbianNonTouch/n95portrait.png +++ b/models/symbianNonTouch/n95portrait.png diff --git a/models/symbianNonTouch/symbianNonTouch.config b/models/symbianNonTouch/symbianNonTouch.config index a663d3f..bae6153 100644 --- a/models/symbianNonTouch/symbianNonTouch.config +++ b/models/symbianNonTouch/symbianNonTouch.config @@ -37,3 +37,7 @@ menuLandscape:n95landscape.png menuPortrait:n95portrait.png availableGeometryLandscape:0,21,320,198 availableGeometryPortrait:0,58,240,235 +symbianSoftKeyButtonPortrait:0,0,293,120,27 +symbianSoftKeyButtonPortrait:1,120,293,120,27 +symbianSoftKeyButtonLandscape:1,220,0,100,21 +symbianSoftKeyButtonLandscape:0,220,219,100,21 diff --git a/models/symbianTouch/menu_landscape.png b/models/symbianTouch/menu_landscape.png Binary files differindex a4fd9c2..25d80d5 100644 --- a/models/symbianTouch/menu_landscape.png +++ b/models/symbianTouch/menu_landscape.png diff --git a/models/symbianTouch/menu_portrait.png b/models/symbianTouch/menu_portrait.png Binary files differindex 3f4b6df..c954310 100644 --- a/models/symbianTouch/menu_portrait.png +++ b/models/symbianTouch/menu_portrait.png diff --git a/models/symbianTouch/symbianTouch.config b/models/symbianTouch/symbianTouch.config index 4ca89d7..ed9eb25 100644 --- a/models/symbianTouch/symbianTouch.config +++ b/models/symbianTouch/symbianTouch.config @@ -15,3 +15,10 @@ availableGeometryPortrait:0,92,360,487 menuLandscape:menu_landscape.png availableGeometryLandscape:0,73,502,288 nativeOrientation:portrait +symbianSoftKeyButtonPortrait:0,0,579,180,61 +symbianSoftKeyButtonPortrait:1,180,579,180,61 +symbianSoftKeyButtonLandscape:1,503,0,137,72 +symbianSoftKeyButtonLandscape:2,503,72,137,72 +symbianSoftKeyButtonLandscape:3,503,144,137,72 +symbianSoftKeyButtonLandscape:4,503,216,137,72 +symbianSoftKeyButtonLandscape:0,503,288,137,72 diff --git a/src/other/application.cpp b/src/other/application.cpp index 840709a..36b345c 100644 --- a/src/other/application.cpp +++ b/src/other/application.cpp @@ -33,6 +33,7 @@ #include "phononmanager.h" #include "widgetmanager.h" #include "widget.h" +#include "deviceitem.h" #include <QtCore/QTimer> #include <QtGui/QDesktopWidget> @@ -268,6 +269,57 @@ void Application::menuBarRemoveAction(QtSimulatorPrivate::RemotePointer remoteMe delete action; } +void Application::setSymbianSoftKeys(QVariantList softKeys) +{ + if (softKeys.size() % 2 == 1) { + qWarning("Application::setSymbianSoftKeys got invalid data"); + return; + } + + QListIterator<QVariant> it(softKeys); + QMultiHash<int, QtSimulatorPrivate::RemoteQAction> allSoftKeys; + while (it.hasNext()) { + int priority = it.next().toInt(); + QtSimulatorPrivate::RemoteQAction action = it.next().value<QtSimulatorPrivate::RemoteQAction>(); + allSoftKeys.insert(priority, action); + } + + // find the actual soft keys to be displayed, this code is based on + // QSoftKeyManagerPrivateS60::highestPrioritySoftkey + mSymbianSoftKeys.clear(); + + for (int buttonNr = 0; buttonNr < SymbianSoftKeyButtonData::MaxButtons; ++buttonNr) { + QAction::SoftKeyRole role; + switch (buttonNr) { + case SymbianSoftKeyButtonData::PositiveButton: role = QAction::PositiveSoftKey; break; + case SymbianSoftKeyButtonData::NegativeButton: role = QAction::NegativeSoftKey; break; + default: continue; + } + + // Priority look up is two level + // 1. First widget with softkeys always has highest priority + for (int level = 0; ; level++) { + // 2. Highest priority action within widget + QList<QtSimulatorPrivate::RemoteQAction> actions = allSoftKeys.values(level); + if (actions.isEmpty()) + break; + + foreach (const QtSimulatorPrivate::RemoteQAction &action, actions) { + if (action.softKeyRole != role) + continue; + if (mSymbianSoftKeys.contains(buttonNr) && mSymbianSoftKeys.value(buttonNr).priority >= action.priority) + continue; + mSymbianSoftKeys.insert(buttonNr, action); + } + + if (mSymbianSoftKeys.contains(buttonNr)) + break; + } + } + + mWidgetManager->updateSymbianSoftKeys(); +} + QMenu* Application::provideMenu(QtSimulatorPrivate::RemotePointer remoteMenu) { QMenu* menu = mMenuHash.value(remoteMenu, 0); @@ -347,3 +399,17 @@ void Application::onMenuActionTriggered() QtSimulatorPrivate::RemoteMetacall<void>::call(sendSocket, QtSimulatorPrivate::NoSync, "triggerAction", v); } + +QString Application::symbianSoftKeyText(int buttonNr) const +{ + return mSymbianSoftKeys.value(buttonNr).text; +} + +void Application::triggerSymbianSoftKeyAction(int buttonNr) +{ + if (!mSymbianSoftKeys.contains(buttonNr)) + return; + + QtSimulatorPrivate::RemoteMetacall<void>::call(sendSocket, QtSimulatorPrivate::NoSync, + "triggerSymbianSoftKeyAction", mSymbianSoftKeys.value(buttonNr).ptr); +} diff --git a/src/other/application.h b/src/other/application.h index fc75ff2..bd4f9fc 100644 --- a/src/other/application.h +++ b/src/other/application.h @@ -57,6 +57,8 @@ public: DisplayWidget* display() const; QLocalSocket *socket() { return sendSocket; } + QString symbianSoftKeyText(int buttonNr) const; + signals: void widgetUpdate(); void widgetDestroyed(); @@ -64,6 +66,7 @@ signals: public slots: void readData(); void kill(); + void triggerSymbianSoftKeyAction(int buttonNr); private slots: // called remotely @@ -79,6 +82,8 @@ private slots: void menuBarSyncAction(QVariantList actionData); void menuBarRemoveAction(QtSimulatorPrivate::RemotePointer remoteMenuBar, QtSimulatorPrivate::RemotePointer action); + void setSymbianSoftKeys(QVariantList softKeys); + private: QMenu* provideMenu(QtSimulatorPrivate::RemotePointer remoteMenu); private slots: @@ -116,6 +121,7 @@ private: QHash<QtSimulatorPrivate::RemotePointer, QAction*> mActionHash; QHash<QtSimulatorPrivate::RemotePointer, QMenuBar*> mMenuBarHash; QHash<QtSimulatorPrivate::RemotePointer, QMenu*> mMenuHash; + QHash<int, QtSimulatorPrivate::RemoteQAction> mSymbianSoftKeys; QTimer *killTimer; }; diff --git a/src/other/configurationreader.cpp b/src/other/configurationreader.cpp index 27883d1..17af3bc 100644 --- a/src/other/configurationreader.cpp +++ b/src/other/configurationreader.cpp @@ -159,6 +159,20 @@ bool ConfigurationReader::processLine(const QByteArray &line, DeviceData *device deviceData->closeButtonPortrait = toSet; else deviceData->closeButtonLandscape = toSet; + } else if (parameter == "symbianSoftKeyButtonPortrait" || parameter == "symbianSoftKeyButtonLandscape") { + QList<QByteArray> values = value.split(','); + if (values.count() != 5) { + errorMsg = tr("ConfigurationReader: symbianSoftKeyButton property requires five comma separated values\n" + " closeButton:buttonnr,x,y,width,height\n" + " where buttonnr: 0: positive, 1: negative, 2: middle, 3: middle, 4: middle"); + return false; + } + SymbianSoftKeyButtonData key; + key.buttonNumber = values[0].toInt(); + key.area = QRectF(values[1].toFloat(), values[2].toFloat(), + values[3].toFloat(), values[4].toFloat()); + key.landscape = parameter.endsWith("Landscape"); + deviceData->symbianSoftKeys.append(key); } else if (parameter == "availableGeometryPortrait" || parameter == "availableGeometryLandscape") { QList<QByteArray> values = value.split(','); if (values.count() != 4) { diff --git a/src/other/deviceitem.cpp b/src/other/deviceitem.cpp index 41825f2..6d41ae7 100644 --- a/src/other/deviceitem.cpp +++ b/src/other/deviceitem.cpp @@ -265,6 +265,14 @@ void DeviceItem::changeScaleFactor(qreal newScaleFactor) newViewSize(); } +void DeviceItem::setSymbianSoftKeyText(int buttonNumber, const QString &text) +{ + foreach (SymbianSoftKeyButton *b, mSymbianSoftKeyButtons) { + if (b->buttonData().buttonNumber == buttonNumber) + b->setText(text); + } +} + void DeviceItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { mDragOffset = event->scenePos().toPoint(); @@ -331,6 +339,22 @@ void DeviceItem::updateMenuPositionAndSize() mCloseButton->setPos(mDeviceData.closeButtonPortrait.topLeft()); mCloseButton->setSize(mDeviceData.closeButtonPortrait.size()); } + + QHash<int, QString> oldSoftKeyTexts; + foreach (SymbianSoftKeyButton *button, mSymbianSoftKeyButtons) + oldSoftKeyTexts.insert(button->buttonData().buttonNumber, button->text()); + qDeleteAll(mSymbianSoftKeyButtons); + mSymbianSoftKeyButtons.clear(); + foreach (const SymbianSoftKeyButtonData &data, mDeviceData.symbianSoftKeys) { + if (data.landscape != mLandscape) + continue; + + SymbianSoftKeyButton *button = new SymbianSoftKeyButton(data, mMenu); + connect(button, SIGNAL(clicked(int)), this, SIGNAL(symbianSoftKeyClicked(int))); + button->setText(oldSoftKeyTexts.value(data.buttonNumber)); + mSymbianSoftKeyButtons.append(button); + } + emit offsetChanged(mAvailableGeometry.topLeft()); } @@ -404,14 +428,12 @@ QRectF KeyButton::boundingRect() const void KeyButton::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + Q_UNUSED(option); + Q_UNUSED(widget); if (mMouseOver) { painter->setBrush(QColor(255, 255, 0, 50)); painter->drawRoundedRect(boundingRect(), 5, 5); - } else { - Q_UNUSED(painter); } - Q_UNUSED(option); - Q_UNUSED(widget); } void KeyButton::hoverEnterEvent(QGraphicsSceneHoverEvent *event) @@ -439,3 +461,79 @@ void KeyButton::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_UNUSED(event); emit released(mButton.key); } + +SymbianSoftKeyButton::SymbianSoftKeyButton(const SymbianSoftKeyButtonData &button, QGraphicsItem *parent) + : QGraphicsObject(parent) + , mButton(button) + , mMouseOver(false) +{ + setFlag(QGraphicsItem::ItemIsFocusable); + setFocusProxy(parent); + setPos(button.area.topLeft()); + setCursor(Qt::PointingHandCursor); + setAcceptHoverEvents(true); +} + +SymbianSoftKeyButton::~SymbianSoftKeyButton() +{ + setFocusProxy(0); +} + +QRectF SymbianSoftKeyButton::boundingRect() const +{ + return QRectF(QPointF(), mButton.area.size()); +} + +void SymbianSoftKeyButton::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + painter->setPen(Qt::white); + painter->drawText(boundingRect(), Qt::AlignHCenter | Qt::AlignVCenter, mText); + if (mMouseOver) { + painter->setPen(Qt::NoPen); + painter->setBrush(QColor(255, 255, 0, 50)); + painter->drawRoundedRect(boundingRect(), 5, 5); + } +} + +SymbianSoftKeyButtonData SymbianSoftKeyButton::buttonData() const +{ + return mButton; +} + +void SymbianSoftKeyButton::setText(const QString &text) +{ + mText = text; + update(); +} + +QString SymbianSoftKeyButton::text() const +{ + return mText; +} + +void SymbianSoftKeyButton::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event); + mMouseOver = true; + update(); +} + +void SymbianSoftKeyButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event); + mMouseOver = false; + update(); +} + +void SymbianSoftKeyButton::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); +} + +void SymbianSoftKeyButton::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); + emit clicked(mButton.buttonNumber); +} diff --git a/src/other/deviceitem.h b/src/other/deviceitem.h index 9d86cba..ec83f16 100644 --- a/src/other/deviceitem.h +++ b/src/other/deviceitem.h @@ -54,6 +54,17 @@ struct MenuData { QRect availableGeometry; }; +struct SymbianSoftKeyButtonData { + enum ButtonType { + PositiveButton = 0, + NegativeButton = 1, + MaxButtons = 5 + }; + bool landscape; + QRectF area; + int buttonNumber; +}; + struct DeviceData { DeviceData() @@ -80,6 +91,7 @@ struct DeviceData Orientation nativeOrientation; MenuData landscapeMenu; MenuData portraitMenu; + QList<SymbianSoftKeyButtonData> symbianSoftKeys; }; class DisplayWidget; @@ -92,7 +104,7 @@ public: : QGraphicsPixmapItem(pixmap, parent) {} enum {MenuType = UserType + 2}; - int type() const {return MenuType;}; + int type() const {return MenuType;} }; class DeviceButton: public QGraphicsObject @@ -145,6 +157,36 @@ signals: void released(Qt::Key) const; }; +class SymbianSoftKeyButton: public QGraphicsObject +{ + Q_OBJECT +public: + explicit SymbianSoftKeyButton(const SymbianSoftKeyButtonData &button, QGraphicsItem *parent = 0); + virtual ~SymbianSoftKeyButton(); + + virtual QRectF boundingRect() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + + SymbianSoftKeyButtonData buttonData() const; + + void setText(const QString &text); + QString text() const; + +protected: + virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + +signals: + void clicked(int buttonNr); + +private: + SymbianSoftKeyButtonData mButton; + QString mText; + bool mMouseOver; +}; + class DeviceItem: public QGraphicsObject { Q_OBJECT @@ -163,6 +205,7 @@ public slots: void toggleOrientation(); void setInitialRotation(bool rotate); void changeScaleFactor(qreal newScaleFactor); + void setSymbianSoftKeyText(int buttonNumber, const QString &text); protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); @@ -191,6 +234,7 @@ private: QList<KeyButton*> mButtons; DeviceButton *mCloseButton; + QList<SymbianSoftKeyButton *> mSymbianSoftKeyButtons; MenuPixmapItem *mMenu; private slots: @@ -210,6 +254,7 @@ signals: void buttonPressed(Qt::Key key, QString text); void buttonReleased(Qt::Key key); void closeWindowPressed(); + void symbianSoftKeyClicked(int buttonNr); void orientationChanged(Orientation current, Orientation native); void deviceChanged(Orientation current, Orientation currentNative, Orientation targetNative); diff --git a/src/other/widgetmanager.cpp b/src/other/widgetmanager.cpp index 29eb896..903c5b9 100644 --- a/src/other/widgetmanager.cpp +++ b/src/other/widgetmanager.cpp @@ -119,11 +119,13 @@ int WidgetManager::widgetAt(const QPoint &p) const return 0; } +/*! Widget that has keyboard focus */ Widget *WidgetManager::focusWidget() const { return mFocusWidget; } +/*! The 'current' widget. The one with focus or otherwise the topmost one. */ Widget *WidgetManager::activeWidget() const { if (mFocusWidget) @@ -132,6 +134,7 @@ Widget *WidgetManager::activeWidget() const else return topWidget(); } +/*! The topmost widget. */ Widget *WidgetManager::topWidget() const { Widget *top = 0; @@ -546,3 +549,22 @@ void WidgetManager::setZBefore(Widget *w, Widget *other) } } } + +void WidgetManager::updateSymbianSoftKeys() +{ + Widget *active = activeWidget(); + if (!active) + return; + + for (int i = 0; i < SymbianSoftKeyButtonData::MaxButtons; ++i) + emit symbianSoftKeyTextChanged(i, active->owner->symbianSoftKeyText(i)); +} + +void WidgetManager::triggerSymbianSoftKeyAction(int buttonNr) +{ + Widget *active = activeWidget(); + if (!active) + return; + + active->owner->triggerSymbianSoftKeyAction(buttonNr); +} diff --git a/src/other/widgetmanager.h b/src/other/widgetmanager.h index 9a3d4f3..6111082 100644 --- a/src/other/widgetmanager.h +++ b/src/other/widgetmanager.h @@ -84,14 +84,18 @@ public slots: void sendKeyPress(Qt::Key key, const QString &text = ""); void sendKeyRelease(Qt::Key key); void closeCurrentWindow(); + void triggerSymbianSoftKeyAction(int buttonNr); void changeOffset(const QPoint &offset); - private slots: - void handleUpdateRequests(); + void updateSymbianSoftKeys(); + +private slots: + void handleUpdateRequests(); signals: void topWidgetChanged(Widget *); + void symbianSoftKeyTextChanged(int buttonNr, QString text); private: void updateLogItem(int id); diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index c18d253..a478796 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -128,12 +128,14 @@ MainWindow::MainWindow(QWidget *parent) applicationManager->setWidgetManager(widgetManager); connect(applicationManager, SIGNAL(applicationUnRegistered(int)), widgetManager, SLOT(onApplicationUnregistered(int))); + connect(widgetManager, SIGNAL(symbianSoftKeyTextChanged(int,QString)), deviceItem, SLOT(setSymbianSoftKeyText(int,QString))); connect(deviceItem, SIGNAL(deviceChanged(QSize,DeviceData)), applicationManager, SLOT(updateDisplayInformation(QSize,DeviceData))); connect(deviceItem, SIGNAL(drag(QPoint)), this, SLOT(dragFromView(QPoint))); connect(deviceItem, SIGNAL(viewSizeRequired(QSize)), this, SLOT(setViewSize(QSize))); connect(deviceItem, SIGNAL(buttonPressed(Qt::Key, QString)), widgetManager, SLOT(sendKeyPress(Qt::Key, QString))); connect(deviceItem, SIGNAL(buttonReleased(Qt::Key)), widgetManager, SLOT(sendKeyRelease(Qt::Key))); connect(deviceItem, SIGNAL(closeWindowPressed()), widgetManager, SLOT(closeCurrentWindow())); + connect(deviceItem, SIGNAL(symbianSoftKeyClicked(int)), widgetManager, SLOT(triggerSymbianSoftKeyAction(int))); connect(deviceItem, SIGNAL(offsetChanged(const QPoint &)), widgetManager, SLOT(changeOffset(const QPoint &))); connect(deviceItem, SIGNAL(orientationChanged(Orientation, Orientation)), mobility, SLOT(rotateDevice(Orientation, Orientation))); connect(deviceItem, SIGNAL(deviceChanged(Orientation, Orientation, Orientation)), |