From 914604ef465e3548849ecef253d721bd9642eea1 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 19 Jun 2012 10:27:13 -0300 Subject: Implement drop down menu for comboboxes in Snowshoe desktop. It has scrollbars and support sections. Note that the ItemSelector is deleted by WebKit whenever the popup is hidden. Reviewed-by: Caio Oliveira --- src/core/PopupWindow.cpp | 4 -- src/desktop/BrowserWindow.cpp | 13 ++++ src/desktop/BrowserWindow.h | 1 + src/desktop/qml/BookmarkBar.qml | 1 + src/desktop/qml/DropDownMenuBookmarkDelegate.qml | 11 +-- src/desktop/qml/ItemSelector.qml | 88 ++++++++++++++++++++++++ src/desktop/qml/ItemSelectorDelegate.qml | 59 ++++++++++++++++ src/desktop/qml/PageWidget.qml | 6 ++ src/desktop/qml/ScrollIndicator.qml | 71 +++++++++++++++++++ src/desktop/snowshoe.qrc | 3 + 10 files changed, 245 insertions(+), 12 deletions(-) create mode 100644 src/desktop/qml/ItemSelector.qml create mode 100644 src/desktop/qml/ItemSelectorDelegate.qml create mode 100644 src/desktop/qml/ScrollIndicator.qml diff --git a/src/core/PopupWindow.cpp b/src/core/PopupWindow.cpp index e440fe4..6978b56 100644 --- a/src/core/PopupWindow.cpp +++ b/src/core/PopupWindow.cpp @@ -37,14 +37,10 @@ void PopupWindow::showEvent(QShowEvent* ev) QTimer::singleShot(0, this, SLOT(setMouseGrab())); } -// FIXME: I couldn't make the PopupWindow show its contents when hidden then shown again. -// So we now discard during hideEvent. This is convenient if we want to dismiss the window. -// See https://bugreports.qt.nokia.com/browse/QTBUG-23571. void PopupWindow::hideEvent(QHideEvent* ev) { QQuickCanvas::hideEvent(ev); setMouseGrabEnabled(false); - deleteLater(); } void PopupWindow::mousePressEvent(QMouseEvent* ev) diff --git a/src/desktop/BrowserWindow.cpp b/src/desktop/BrowserWindow.cpp index 710adfa..a29c528 100644 --- a/src/desktop/BrowserWindow.cpp +++ b/src/desktop/BrowserWindow.cpp @@ -50,6 +50,19 @@ BrowserWindow::BrowserWindow(const QStringList& arguments) Q_ASSERT(m_browserView); } +QPoint BrowserWindow::ensureInsideScreen(int x, int y, int width, int height) +{ + QPoint newPos(x, y); + QRect availableGeometry = screen()->availableGeometry(); + int right = x + width; + int bottom = y + height; + if (right > availableGeometry.width()) + newPos.setX(x - (right - availableGeometry.width())); + if (bottom > availableGeometry.height()) + newPos.setY(y - (bottom - availableGeometry.height())); + return newPos; +} + QPoint BrowserWindow::mapToGlobal(int x, int y) { return QWindow::mapToGlobal(QPoint(x, y)); diff --git a/src/desktop/BrowserWindow.h b/src/desktop/BrowserWindow.h index ec87432..3a68118 100644 --- a/src/desktop/BrowserWindow.h +++ b/src/desktop/BrowserWindow.h @@ -30,6 +30,7 @@ public: QStringList urlsFromCommandLine() const { return m_urlsFromCommandLine; } + Q_INVOKABLE QPoint ensureInsideScreen(int x, int y, int width, int height); Q_INVOKABLE QPoint mapToGlobal(int x, int y); // FIXME: Move to appropriate object exposed to handle download. Q_INVOKABLE QString decideDownloadPath(const QString& suggestedPath); diff --git a/src/desktop/qml/BookmarkBar.qml b/src/desktop/qml/BookmarkBar.qml index 00144d4..b2e8737 100644 --- a/src/desktop/qml/BookmarkBar.qml +++ b/src/desktop/qml/BookmarkBar.qml @@ -80,6 +80,7 @@ Item { var point = mapToItem(tabWidget, x + width, height); var globalPos = BrowserWindow.mapToGlobal(point.x - 200 + width, point.y); var menu = dropDownMenuComponent.createObject(); + globalPos = BrowserWindow.ensureInsideScreen(globalPos.x, globalPos.y, menu.width, menu.height); menu.x = globalPos.x; menu.y = globalPos.y; menu.show(); diff --git a/src/desktop/qml/DropDownMenuBookmarkDelegate.qml b/src/desktop/qml/DropDownMenuBookmarkDelegate.qml index 89bcf18..f15eafa 100644 --- a/src/desktop/qml/DropDownMenuBookmarkDelegate.qml +++ b/src/desktop/qml/DropDownMenuBookmarkDelegate.qml @@ -27,13 +27,13 @@ Item { id: overlay source: "qrc:///combobox/item_over_bg" border { left: 2; top: 2; right: 2; bottom: 2 } - visible: false + visible: mouseArea.containsMouse } Text { id: text font.pixelSize: 11 - text: name + text: model.name elide: Text.ElideRight anchors { verticalCenter: parent.verticalCenter @@ -50,14 +50,9 @@ Item { } MouseArea { + id: mouseArea anchors.fill: parent hoverEnabled: true - onEntered: { - overlay.visible = true; - } - onExited: { - overlay.visible = false; - } onClicked: parent.clicked() } } diff --git a/src/desktop/qml/ItemSelector.qml b/src/desktop/qml/ItemSelector.qml new file mode 100644 index 0000000..e8fc691 --- /dev/null +++ b/src/desktop/qml/ItemSelector.qml @@ -0,0 +1,88 @@ +/**************************************************************************** + * Copyright (C) 2012 Instituto Nokia de Tecnologia (INdT) * + * * + * This file may be used under the terms of the GNU Lesser * + * General Public License version 2.1 as published by the Free Software * + * Foundation and appearing in the file LICENSE.LGPL included in the * + * packaging of this file. Please review the following information to * + * ensure the GNU Lesser General Public License version 2.1 requirements * + * will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + ****************************************************************************/ + +import QtQuick 2.0 +import Snowshoe 1.0 + +Item { + id: root + property var selectorModel: model + property var contentArea + property int maxHeight + property int margins: 8 + + PopupWindow { + id : popup + + width: listView.width + bg.border.right + bg.border.left + height: listView.height + bg.border.top + bg.border.bottom + (root.margins * 2) + + Component.onCompleted: { + var globalPos = BrowserWindow.mapToGlobal(selectorModel.elementRect.x - bg.border.left, contentArea.y + selectorModel.elementRect.y + selectorModel.elementRect.height); + globalPos = BrowserWindow.ensureInsideScreen(globalPos.x, globalPos.y, popup.width, popup.height); + popup.x = globalPos.x; + popup.y = globalPos.y; + popup.show(); + } + + onVisibleChanged : { if (!visible) selectorModel.reject(); } + + BorderImage { + id: bg + anchors.fill: parent + source: "qrc:///combobox/base_bg" + border { left: 12; top: 6; right: 12; bottom: 16 } + } + + ListView { + id: listView + property int elementHeight: 24 + + x: bg.x + bg.border.left + y: bg.y + bg.border.top + root.margins + width: selectorModel.elementRect.width + clip: true + orientation: ListView.Vertical + model: selectorModel.items + spacing: 2 + + interactive: Boolean(height == root.maxHeight) + height: Math.min(contentItem.height, root.maxHeight); + + delegate: ItemSelectorDelegate { + onClicked: selectorModel.accept(index) + } + + section.property: "group" + section.delegate: Rectangle { + width: parent.width + height: listView.elementHeight + color: "silver" + Text { + anchors.centerIn: parent + text: section + font.pixelSize: 11 + elide: Text.ElideRight + font.bold: true + } + } + } + + ScrollIndicator { + flickableItem : listView + } + } +} diff --git a/src/desktop/qml/ItemSelectorDelegate.qml b/src/desktop/qml/ItemSelectorDelegate.qml new file mode 100644 index 0000000..dfaf418 --- /dev/null +++ b/src/desktop/qml/ItemSelectorDelegate.qml @@ -0,0 +1,59 @@ +/**************************************************************************** + * Copyright (C) 2012 Instituto Nokia de Tecnologia (INdT) * + * * + * This file may be used under the terms of the GNU Lesser * + * General Public License version 2.1 as published by the Free Software * + * Foundation and appearing in the file LICENSE.LGPL included in the * + * packaging of this file. Please review the following information to * + * ensure the GNU Lesser General Public License version 2.1 requirements * + * will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + ****************************************************************************/ + +import QtQuick 2.0 + +Item { + signal clicked(int index) + + width: ListView.view.width + height: ListView.view.elementHeight + + BorderImage { + anchors.fill: parent + id: overlay + source: "qrc:///combobox/item_over_bg" + border { left: 2; top: 2; right: 2; bottom: 2 } + visible: mouseArea.containsMouse + } + + Text { + id: text + font.pixelSize: 11 + text: model.text + elide: Text.ElideRight + anchors { + verticalCenter: parent.verticalCenter + left: parent.left + leftMargin: 8 + rightMargin: 8 + right: parent.right + } + onWidthChanged: { + if (width > parent.ListView.view.width) + parent.ListView.view.width = width + } + + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + enabled: model.enabled + onClicked: parent.clicked(model.index) + } +} diff --git a/src/desktop/qml/PageWidget.qml b/src/desktop/qml/PageWidget.qml index df2e148..92788d0 100644 --- a/src/desktop/qml/PageWidget.qml +++ b/src/desktop/qml/PageWidget.qml @@ -81,6 +81,12 @@ Item { experimental.preferences.fullScreenEnabled: true experimental.preferences.developerExtrasEnabled: true + experimental.itemSelector: ItemSelector { + contentArea: root.parent + // FIXME: We should be able to use Screen.height from QtQuick.Window to + // calculate this but it isn't working yet. + maxHeight: 600 + } experimental.onDownloadRequested: { downloadItem.destinationPath = BrowserWindow.decideDownloadPath(downloadItem.suggestedFilename) diff --git a/src/desktop/qml/ScrollIndicator.qml b/src/desktop/qml/ScrollIndicator.qml new file mode 100644 index 0000000..c9a254c --- /dev/null +++ b/src/desktop/qml/ScrollIndicator.qml @@ -0,0 +1,71 @@ +/**************************************************************************** + * Copyright (C) 2012 Instituto Nokia de Tecnologia (INdT) * + * * + * This file may be used under the terms of the GNU Lesser * + * General Public License version 2.1 as published by the Free Software * + * Foundation and appearing in the file LICENSE.LGPL included in the * + * packaging of this file. Please review the following information to * + * ensure the GNU Lesser General Public License version 2.1 requirements * + * will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + ****************************************************************************/ + +import QtQuick 2.0 +Item { + id : root + property Flickable flickableItem + property int hideTimeout: 600 + property real size: 4 + + anchors.fill: flickableItem + + Item { + id: verticalIndicator + opacity: 0 + width: root.size + height: flickableItem.height - size + + anchors.right: root.right + + Rectangle { + x: 0 + y: Math.min(parent.height - height, Math.max(0, flickableItem.visibleArea.yPosition * verticalIndicator.height)) + + radius: 10 + color: "black" + border.color: "gray" + border.width: 1 + opacity: 0.5 + smooth: true; + + width: root.size + height: flickableItem.visibleArea.heightRatio * verticalIndicator.height; + } + + states: [ + State { + name: "active" + when: flickableItem.movingVertically + PropertyChanges { + target: verticalIndicator + opacity: 1 + } + } + ] + + transitions: [ + Transition { + NumberAnimation { + target: verticalIndicator + properties: "opacity" + duration: hideTimeout + } + } + ] + } + +} diff --git a/src/desktop/snowshoe.qrc b/src/desktop/snowshoe.qrc index 5209f57..114117f 100644 --- a/src/desktop/snowshoe.qrc +++ b/src/desktop/snowshoe.qrc @@ -68,5 +68,8 @@ images/urlbar/component_btn_nav_refresh_disable.png images/pagewidget/link_status_bg_left.png images/pagewidget/link_status_bg_right.png + qml/ItemSelector.qml + qml/ItemSelectorDelegate.qml + qml/ScrollIndicator.qml -- cgit v1.2.3