add Dialogs

CommonDialog
QueryDialog
SelectionDialog

the base Dialog is still not exported
in future version on the desktop, QueryDialog will create a standard qt dialog instead
This commit is contained in:
Marco Martin 2011-11-03 14:46:05 +01:00
parent 2bb8101e6f
commit 478cd9d3f0
7 changed files with 654 additions and 15 deletions

View File

@ -201,17 +201,40 @@ void DialogProxy::setVisible(const bool visible)
}
}
QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const
QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment)
{
if (!item) {
return QPoint();
QGraphicsObject *actualItem = item;
//if no item is passed search the root item in order to figure out the view
if (!actualItem) {
actualItem = qobject_cast<QGraphicsObject *>(parent());
//search the root object
while (true) {
QGraphicsObject *ancestor = qobject_cast<QGraphicsObject *>(actualItem->parent());
if (ancestor) {
actualItem = ancestor;
} else {
break;
}
}
if (!actualItem) {
return QPoint();
}
}
Plasma::Corona *corona = qobject_cast<Plasma::Corona *>(item->scene());
if (corona) {
return corona->popupPosition(item, m_dialog->size(), (Qt::AlignmentFlag)alignment);
//ensure the dialog has the proper size
syncMainItem();
m_dialog->syncToGraphicsWidget();
Plasma::Corona *corona = qobject_cast<Plasma::Corona *>(actualItem->scene());
if (corona && item) {
return corona->popupPosition(actualItem, m_dialog->size(), (Qt::AlignmentFlag)alignment);
} else {
QList<QGraphicsView*> views = item->scene()->views();
QList<QGraphicsView*> views = actualItem->scene()->views();
if (views.size() < 1) {
return QPoint();
@ -223,9 +246,10 @@ QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const
} else {
QGraphicsView *found = 0;
QGraphicsView *possibleFind = 0;
foreach (QGraphicsView *v, views) {
if (v->sceneRect().intersects(item->sceneBoundingRect()) ||
v->sceneRect().contains(item->scenePos())) {
if (v->sceneRect().intersects(actualItem->sceneBoundingRect()) ||
v->sceneRect().contains(actualItem->scenePos())) {
if (v->isActiveWindow()) {
found = v;
} else {
@ -240,6 +264,11 @@ QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const
return QPoint();
}
//if no item was explicitly specified, align the dialog in the center of the parent view
if (!item) {
return view->geometry().center() - QPoint(m_dialog->width()/2, m_dialog->height()/2);
}
//swap direction if necessary
if (QApplication::isRightToLeft() && alignment != Qt::AlignCenter) {
if (alignment == Qt::AlignRight) {
@ -252,16 +281,16 @@ QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const
int xOffset = 0;
if (alignment == Qt::AlignCenter) {
xOffset = item->boundingRect().width()/2 - m_dialog->width()/2;
xOffset = actualItem->boundingRect().width()/2 - m_dialog->width()/2;
} else if (alignment == Qt::AlignRight) {
xOffset = item->boundingRect().width() - m_dialog->width();
xOffset = actualItem->boundingRect().width() - m_dialog->width();
}
const QRect avail = QApplication::desktop()->availableGeometry(view);
QPoint menuPos = view->mapToGlobal(view->mapFromScene(item->scenePos()+QPoint(xOffset, item->boundingRect().height())));
QPoint menuPos = view->mapToGlobal(view->mapFromScene(actualItem->scenePos()+QPoint(xOffset, actualItem->boundingRect().height())));
if (menuPos.y() + m_dialog->height() > avail.bottom()) {
menuPos = view->mapToGlobal(view->mapFromScene(item->scenePos() - QPoint(-xOffset, m_dialog->height())));
menuPos = view->mapToGlobal(view->mapFromScene(actualItem->scenePos() - QPoint(-xOffset, m_dialog->height())));
}
return menuPos;
}

View File

@ -119,8 +119,13 @@ public:
QObject *margins() const;
/**
* @returns The suggested screen position for the popup
* @arg item the item the popup has to be positioned relatively to. if null, the popup will be positioned in the center of the window
* @arg alignment alignment of the popup compared to the item
*/
//FIXME: alignment should be Qt::AlignmentFlag
Q_INVOKABLE QPoint popupPosition(QGraphicsObject *item, int alignment=Qt::AlignLeft) const;
Q_INVOKABLE QPoint popupPosition(QGraphicsObject *item, int alignment=Qt::AlignLeft) ;
//FIXME:: Qt::WidgetAttribute should be already
Q_INVOKABLE void setAttribute(int attribute, bool on);

View File

@ -0,0 +1,185 @@
/****************************************************************************
**
** Copyright (C) 2011 Marco Martin <mart@kde.org>
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Components project.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 1.1
import org.kde.plasma.core 0.1 as PlasmaCore
import "." 0.1
Dialog {
id: root
property alias titleText: titleAreaText.text
property url titleIcon
property variant buttonTexts: []
property bool privateCloseIcon: false
signal buttonClicked(int index)
onButtonTextsChanged: {
for (var i = buttonRow.children.length; i > 0; --i) {
buttonRow.children[i - 1].destroy()
}
for (var j = 0; j < buttonTexts.length; ++j) {
var button = buttonComponent.createObject(buttonRow)
button.text = buttonTexts[j]
button.index = j
}
}
Component {
id: buttonComponent
Button {
property int index
onClicked: {
if (root.status == DialogStatus.Open) {
root.buttonClicked(index)
root.close()
}
}
}
}
QtObject {
id: internal
function buttonWidth() {
switch (buttonTexts.length) {
case 0: return 0
case 1: return Math.round((800 - 3 * 4) / 2)
default: return (buttonContainer.width - (buttonTexts.length + 1) *
4) / buttonTexts.length
}
}
function iconSource() {
return root.titleIcon
}
}
title: PlasmaCore.FrameSvgItem {
imagePath: "widgets/extender-dragger"
prefix: "root"
anchors.left: parent.left
anchors.right: parent.right
//FIXME: +5 because of Plasma::Dialog margins
height: titleAreaText.paintedHeight + margins.top + margins.bottom
LayoutMirroring.enabled: privateCloseIcon ? false : undefined
LayoutMirroring.childrenInherit: true
Item {
id: titleLayoutHelper // needed to make the text mirror correctly
anchors {
left: parent.left
right: titleAreaIcon.source == "" ? parent.right : titleAreaIcon.left
top: parent.top
bottom: parent.bottom
leftMargin: parent.margins.left
rightMargin: parent.margins.right
topMargin: parent.margins.top
bottomMargin: parent.margins.bottom
}
Label {
id: titleAreaText
LayoutMirroring.enabled: root.LayoutMirroring.enabled
anchors.fill: parent
elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
Image {
id: titleAreaIcon
anchors.right: parent.right
anchors.rightMargin: 4
anchors.verticalCenter: parent.verticalCenter
source: internal.iconSource()
sourceSize.height: 16
sourceSize.width: 16
MouseArea {
id: iconMouseArea
property bool pressCancelled
anchors.centerIn: parent
width: parent.width + 4
height: parent.height + 4
enabled: privateCloseIcon && root.status == DialogStatus.Open
onPressed: {
pressCancelled = false
}
onClicked: {
if (!pressCancelled)
root.reject()
}
onExited: pressCancelled = true
}
}
}
buttons: Item {
id: buttonContainer
LayoutMirroring.enabled: false
LayoutMirroring.childrenInherit: true
width: parent.width
height: buttonTexts.length ? 48 + 2 * 2 : 0
Row {
id: buttonRow
objectName: "buttonRow"
anchors.centerIn: parent
spacing: 4
}
}
}

View File

@ -0,0 +1,161 @@
/****************************************************************************
**
** Copyright (C) 2011 Marco Martin <mart@kde.org>
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Components project.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 1.0
import org.kde.plasma.core 0.1 as PlasmaCore
import "AppManager.js" as Utils
import "." 0.1
Item {
id: root
property alias title: titleBar.children
property alias content: contentItem.children
property alias buttons: buttonItem.children
// property alias visualParent: dialog.visualParent
property int status: DialogStatus.Closed
property alias privateTitleHeight: titleBar.height
property alias privateButtonsHeight: buttonItem.height
signal accepted
signal rejected
signal clickedOutside
function open()
{
var pos = dialog.popupPosition(null, Qt.alignCenter)
dialog.x = pos.x
dialog.y = pos.y
dialog.visible = true
dialog.focus = true
}
function accept()
{
if (status == DialogStatus.Open) {
dialog.visible = false
accepted()
}
}
function reject() {
if (status == DialogStatus.Open) {
dialog.visible = false
rejected()
}
}
function close() {
dialog.visible = false
}
visible: false
PlasmaCore.Dialog {
id: dialog
//onFaderClicked: root.clickedOutside()
property Item rootItem
//state: "Hidden"
visible: false
onVisibleChanged: {
if (visible) {
status = DialogStatus.Open
} else {
status = DialogStatus.Closed
}
}
mainItem: Item {
width: theme.defaultFont.mSize.width * 40
height: titleBar.childrenRect.height + contentItem.childrenRect.height + buttonItem.childrenRect.height
// Consume all key events that are not processed by children
Keys.onPressed: event.accepted = true
Keys.onReleased: event.accepted = true
Item {
id: titleBar
height: childrenRect.height
anchors {
top: parent.top
left: parent.left
right: parent.right
}
}
Item {
id: contentItem
clip: true
anchors {
top: titleBar.bottom
left: parent.left
right: parent.right
bottom: buttonItem.top
}
}
Item {
id: buttonItem
height: childrenRect.height
clip: true
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
}
}
}
Component.onCompleted: {
rootItem = Utils.rootObject()
}
}
}

View File

@ -0,0 +1,122 @@
/****************************************************************************
**
** Copyright (C) 2011 Marco Martin <mart@kde.org>
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Components project.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 1.1
import "." 0.1
CommonDialog {
id: root
objectName: "root"
property string message
property string acceptButtonText
property string rejectButtonText
property alias icon: root.titleIcon // for backwards compatibility
onAcceptButtonTextChanged: internal.updateButtonTexts()
onRejectButtonTextChanged: internal.updateButtonTexts()
onButtonClicked: {
if (acceptButtonText && index == 0)
accepted()
else
rejected()
}
content: Item {
implicitHeight: Math.min(theme.defaultFont.mSize.height*12, label.paintedHeight+12)
width: parent.width
Item {
anchors {
top: parent.top; topMargin: 6
bottom: parent.bottom; bottomMargin: 6
left: parent.left; leftMargin: 6
right: parent.right
}
Flickable {
id: flickable
width: parent.width
height: parent.height
anchors { left: parent.left; top: parent.top }
contentHeight: label.paintedHeight
flickableDirection: Flickable.VerticalFlick
clip: true
interactive: contentHeight > height
Label {
id: label
anchors { right: parent.right }
width: flickable.width
wrapMode: Text.WordWrap
text: root.message
horizontalAlignment: Text.AlignLeft
}
}
ScrollBar {
id: scrollBar
height: parent.height
anchors { top: flickable.top; right: flickable.right }
flickableItem: flickable
interactive: false
orientation: Qt.Vertical
//platformInverted: root.platformInverted
}
}
}
QtObject {
id: internal
function updateButtonTexts() {
var newButtonTexts = []
if (acceptButtonText)
newButtonTexts.push(acceptButtonText)
if (rejectButtonText)
newButtonTexts.push(rejectButtonText)
root.buttonTexts = newButtonTexts
}
}
}

View File

@ -0,0 +1,135 @@
/****************************************************************************
**
** Copyright (C) 2011 Marco Martin <mart@kde.org>
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Components project.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 1.1
import "." 0.1
CommonDialog {
id: root
// Common API
property alias model: listView.model
property int selectedIndex: -1
property Component delegate: defaultDelegate
privateCloseIcon: true
Component {
id: defaultDelegate
Label {
//platformInverted: root.platformInverted
text: modelData
MouseArea {
anchors.fill: parent
onClicked: {
selectedIndex = index
root.accept()
}
}
Keys.onPressed: {
if (event.key == Qt.Key_Up || event.key == Qt.Key_Down)
scrollBar.flash()
}
}
}
content: Item {
id: contentItem
width: theme.defaultFont.mSize.width * 80
height: theme.defaultFont.mSize.height * 12
Item {
// Clipping item with bottom margin added to align content with rounded background graphics
id: clipItem
anchors.fill: parent
anchors.bottomMargin: 4
clip: true
ListView {
id: listView
currentIndex : -1
width: contentItem.width
height: contentItem.height
delegate: root.delegate
clip: true
Keys.onPressed: {
if (event.key == Qt.Key_Up || event.key == Qt.Key_Down
|| event.key == Qt.Key_Left || event.key == Qt.Key_Right
|| event.key == Qt.Key_Select || event.key == Qt.Key_Enter
|| event.key == Qt.Key_Return) {
listView.currentIndex = 0
event.accepted = true
}
}
}
}
ScrollBar {
id: scrollBar
flickableItem: listView
visible: listView.contentHeight > contentItem.height
//platformInverted: root.platformInverted
anchors { top: clipItem.top; right: clipItem.right }
}
}
onClickedOutside: {
reject()
}
onStatusChanged: {
if (status == DialogStatus.Opening) {
if (listView.currentItem != null) {
listView.currentItem.focus = false
}
listView.currentIndex = -1
listView.positionViewAtIndex(0, ListView.Beginning)
}
else if (status == DialogStatus.Open) {
listView.focus = true
}
}
}

View File

@ -24,7 +24,9 @@ ToolBar 0.1 ToolBar.qml
ToolButton 0.1 ToolButton.qml
ListItem 0.1 ListItem.qml
CommonDialog 0.1 CommonDialog.qml
QueryDialog 0.1 QueryDialog.qml
SelectionDialog 0.1 SelectionDialog.qml
Page 0.1 Page.qml
PageStack 0.1 PageStack.qml