diff options
author | Daniel Molkentin <daniel.molkentin@nokia.com> | 2011-08-02 17:11:29 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@nokia.com> | 2011-08-03 16:12:35 +0200 |
commit | 9743b43663f2dac99df0e1e5219b0d65bee2d7f2 (patch) | |
tree | a41f3e18eaae73aac5cebc7150f7aed5662974e9 /lib | |
parent | 6c8edcf99ed0cd77a3667e61417a224461060ab7 (diff) | |
download | qt-creator-9743b43663f2dac99df0e1e5219b0d65bee2d7f2.tar.gz |
Make Components installable. Fix Shadow Build.
Task-Number: QTCREATORBUG-5672
Done-with: Oswald Buddenhagen
Change-Id: I61f8a83205bc338ba12e43b7471eaa957da2b004
Reviewed-on: http://codereview.qt.nokia.com/2451
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Reviewed-by: Eike Ziller <eike.ziller@nokia.com>
Diffstat (limited to 'lib')
48 files changed, 5099 insertions, 0 deletions
diff --git a/lib/qtcreator/qtcomponents/Button.qml b/lib/qtcreator/qtcomponents/Button.qml new file mode 100644 index 0000000000..d7a3490f59 --- /dev/null +++ b/lib/qtcreator/qtcomponents/Button.qml @@ -0,0 +1,95 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +Components.Button { + id:button + + // dm: this is wrong + width: Math.max(sizehint.width, button.iconSource !== "" ? labelItem.contentsWidth + 8 : 0 ) + height: Math.max(22, sizehint.height) + + property variant sizehint: backgroundItem.sizeFromContents(80, 6) + property bool defaultbutton + property string hint + + background: QStyleItem { + id: styleitem + anchors.fill: parent + elementType: "button" + sunken: pressed || checked + raised: !(pressed || checked) + hover: containsMouse + text: button.iconSource === "" ? button.text : "" + focus: button.focus + hint: button.hint + + // If no icon, let the style do the drawing + activeControl: focus ? "default" : "" + Connections{ + target: button + onToolTipTriggered: styleitem.showTip() + } + function showTip(){ + showToolTip(tooltip); + } + } + + label: Item { + // Used as a fallback since I can't pass the imageURL + // directly to the style object + visible: button.iconSource !== "" + property int contentsWidth : row.width + Row { + id: row + anchors.centerIn: parent + anchors.verticalCenterOffset: -1 + spacing: 4 + Image { + source: iconSource + anchors.verticalCenter: parent.verticalCenter + fillMode: Image.Stretch //mm Image should shrink if button is too small, depends on QTBUG-14957 + } + Text { + id:text + color: textColor + anchors.verticalCenter: parent.verticalCenter + text: button.text + horizontalAlignment: Text.Center + } + } + } + Keys.onSpacePressed:clicked() +} + diff --git a/lib/qtcreator/qtcomponents/ButtonRow.qml b/lib/qtcreator/qtcomponents/ButtonRow.qml new file mode 100644 index 0000000000..b2cba92849 --- /dev/null +++ b/lib/qtcreator/qtcomponents/ButtonRow.qml @@ -0,0 +1,37 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +Components.ButtonRow { +} diff --git a/lib/qtcreator/qtcomponents/CheckBox.qml b/lib/qtcreator/qtcomponents/CheckBox.qml new file mode 100644 index 0000000000..b8b94ca77f --- /dev/null +++ b/lib/qtcreator/qtcomponents/CheckBox.qml @@ -0,0 +1,57 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +// jb : Size should not depend on background, we should make it consistent + +Components.CheckBox{ + id:checkbox + property string text + property string hint + height:20 + width: Math.max(110, backgroundItem.textWidth(text) + 40) + + background: QStyleItem { + elementType:"checkbox" + sunken:pressed + on:checked || pressed + hover:containsMouse + text:checkbox.text + enabled:checkbox.enabled + focus:checkbox.focus + hint:checkbox.hint + } + Keys.onSpacePressed:checked = !checked +} + diff --git a/lib/qtcreator/qtcomponents/ChoiceList.qml b/lib/qtcreator/qtcomponents/ChoiceList.qml new file mode 100644 index 0000000000..cf72493421 --- /dev/null +++ b/lib/qtcreator/qtcomponents/ChoiceList.qml @@ -0,0 +1,92 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +Components.ChoiceList { + + id: choicelist + + property int buttonHeight: backgroundItem.sizeFromContents(100, 18).height + property int buttonWidth: backgroundItem.sizeFromContents(100, 18).width + + property string hint + + height: buttonHeight + width: buttonWidth + topMargin: 4 + bottomMargin: 4 + + background: QStyleItem { + anchors.fill: parent + elementType: "combobox" + sunken: pressed + raised: !pressed + hover: containsMouse + enabled: choicelist.enabled + text: currentItemText + focus: choicelist.focus + hint: choicelist.hint + } + + listItem: Item { + id:item + + height: 22 + anchors.left: parent.left + width: choicelist.width + QStyleItem { + anchors.fill: parent + elementType: "comboboxitem" + text: itemText + selected: highlighted + + } + } + popupFrame: QStyleItem { + property string popupLocation: backgroundItem.styleHint("comboboxpopup") ? "center" : "below" + property int fw: backgroundItem.pixelMetric("menupanelwidth"); + anchors.leftMargin: backgroundItem.pixelMetric("menuhmargin") + fw + anchors.rightMargin: backgroundItem.pixelMetric("menuhmargin") + fw + anchors.topMargin: backgroundItem.pixelMetric("menuvmargin") + fw + anchors.bottomMargin: backgroundItem.pixelMetric("menuvmargin") + fw + elementType: "menu" + + effect: DropShadow { + blurRadius: 18 + color: "#90000000" + xOffset: 1 + yOffset: 1 + } + } +} diff --git a/lib/qtcreator/qtcomponents/ContextMenu.qml b/lib/qtcreator/qtcomponents/ContextMenu.qml new file mode 100644 index 0000000000..9592a2068c --- /dev/null +++ b/lib/qtcreator/qtcomponents/ContextMenu.qml @@ -0,0 +1,40 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +MenuBase { + id: choiceList + + property ListModel model +} diff --git a/lib/qtcreator/qtcomponents/Dial.qml b/lib/qtcreator/qtcomponents/Dial.qml new file mode 100644 index 0000000000..9793b46be1 --- /dev/null +++ b/lib/qtcreator/qtcomponents/Dial.qml @@ -0,0 +1,144 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +// jens: ContainsMouse breaks drag functionality + +QStyleItem { + id: dial + + width:100 + height:100 + + property alias maximumValue: range.maximumValue + property alias minimumValue: range.minimumValue + property alias containsMouse: mouseArea.containsMouse + property alias value: range.value + + property bool wrapping: false + property bool tickmarks: true // not implemented + + RangeModel { + id: range + minimumValue: 0.0 + maximumValue: 1.0 + stepSize: 0.0 + value: 0 + } + + MouseArea { + id: mouseArea + anchors.fill:parent + property bool inDrag + hoverEnabled:true + + onPositionChanged: { + if (pressed) { + value = valueFromPoint(mouseX, mouseY) + inDrag = true + } + } + onPressed: { + value = valueFromPoint(mouseX, mouseY) + dial.focus = true + } + + onReleased:inDrag = false; + function bound(val) { return Math.max(minimumValue, Math.min(maximumValue, val)); } + + function valueFromPoint(x, y) + { + var yy = height/2.0 - y; + var xx = x - width/2.0; + var a = (xx || yy) ? Math.atan2(yy, xx) : 0; + + if (a < Math.PI/ -2) + a = a + Math.PI * 2; + + var dist = 0; + var minv = minimumValue*100, maxv = maximumValue*100; + + if (minimumValue < 0) { + dist = -minimumValue; + minv = 0; + maxv = maximumValue + dist; + } + + var r = maxv - minv; + var v; + if (wrapping) + v = (0.5 + minv + r * (Math.PI * 3 / 2 - a) / (2 * Math.PI)); + else + v = (0.5 + minv + r* (Math.PI * 4 / 3 - a) / (Math.PI * 10 / 6)); + + if (dist > 0) + v -= dist; + return maximumValue - bound(v/100) + } + } + + WheelArea { + id: wheelarea + anchors.fill: parent + horizontalMinimumValue: dial.minimumValue + horizontalMaximumValue: dial.maximumValue + verticalMinimumValue: dial.minimumValue + verticalMaximumValue: dial.maximumValue + property double step: (dial.maximumValue - dial.minimumValue)/100 + + onVerticalWheelMoved: { + value += verticalDelta/4*step + } + + onHorizontalWheelMoved: { + value += horizontalDelta/4*step + } + } + + elementType:"dial" + sunken: mouseArea.pressed + maximum: range.maximumValue*90 + minimum: range.minimumValue*90 + focus:dial.focus + value: visualPos*90 + enabled: dial.enabled + property double visualPos : range.value + Behavior on visualPos { + enabled: !mouseArea.inDrag + NumberAnimation { + duration: 300 + easing.type: Easing.OutSine + } + } +} diff --git a/lib/qtcreator/qtcomponents/Frame.qml b/lib/qtcreator/qtcomponents/Frame.qml new file mode 100644 index 0000000000..f101cb6b01 --- /dev/null +++ b/lib/qtcreator/qtcomponents/Frame.qml @@ -0,0 +1,56 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + + +QStyleBackground { + + width: 100 + height: 100 + + default property alias children: content.children + + style: QStyleItem { + id: styleitem + elementType: "frame" + } + + Item { + id: content + anchors.fill: parent + anchors.margins: frameWidth + property int frameWidth: styleitem.pixelMetric("defaultframewidth"); + } +} + diff --git a/lib/qtcreator/qtcomponents/GroupBox.qml b/lib/qtcreator/qtcomponents/GroupBox.qml new file mode 100644 index 0000000000..b9de3ad662 --- /dev/null +++ b/lib/qtcreator/qtcomponents/GroupBox.qml @@ -0,0 +1,53 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +Components.GroupBox { + id: groupbox + width: Math.max(200, contentWidth + sizeHint.width) + height: contentHeight + sizeHint.height + 4 + property variant sizeHint: backgroundItem.sizeFromContents(0, 24) + property bool flat: false + background : QStyleItem { + id: styleitem + elementType: "groupbox" + anchors.fill: parent + text: groupbox.title + hover: checkbox.containsMouse + on: checkbox.checked + focus: checkbox.activeFocus + activeControl: checkable ? "checkbox" : "" + sunken: !flat + } +} diff --git a/lib/qtcreator/qtcomponents/Menu.qml b/lib/qtcreator/qtcomponents/Menu.qml new file mode 100644 index 0000000000..8db25dbcae --- /dev/null +++ b/lib/qtcreator/qtcomponents/Menu.qml @@ -0,0 +1,37 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 + +MenuBase { + +} diff --git a/lib/qtcreator/qtcomponents/MenuItem.qml b/lib/qtcreator/qtcomponents/MenuItem.qml new file mode 100644 index 0000000000..d02b3500a6 --- /dev/null +++ b/lib/qtcreator/qtcomponents/MenuItem.qml @@ -0,0 +1,37 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 + +MenuItemBase { + +} diff --git a/lib/qtcreator/qtcomponents/ProgressBar.qml b/lib/qtcreator/qtcomponents/ProgressBar.qml new file mode 100644 index 0000000000..358993554d --- /dev/null +++ b/lib/qtcreator/qtcomponents/ProgressBar.qml @@ -0,0 +1,60 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +Components.ProgressBar { + id:progressbar + + property variant sizehint: backgroundItem.sizeFromContents(23, 23) + property int orientation: Qt.Horizontal + property string hint + + height: orientation === Qt.Horizontal ? sizehint.height : 200 + width: orientation === Qt.Horizontal ? 200 : sizehint.height + + background: QStyleItem { + anchors.fill: parent + elementType: "progressbar" + // XXX: since desktop uses int instead of real, the progressbar + // range [0..1] must be stretched to a good precision + property int factor : 1000 + value: indeterminate ? 0 : progressbar.value * factor // does indeterminate value need to be 1 on windows? + minimum: indeterminate ? 0 : progressbar.minimumValue * factor + maximum: indeterminate ? 0 : progressbar.maximumValue * factor + enabled: progressbar.enabled + horizontal: progressbar.orientation == Qt.Horizontal + hint: progressbar.hint + } +} + diff --git a/lib/qtcreator/qtcomponents/RadioButton.qml b/lib/qtcreator/qtcomponents/RadioButton.qml new file mode 100644 index 0000000000..9045158fb6 --- /dev/null +++ b/lib/qtcreator/qtcomponents/RadioButton.qml @@ -0,0 +1,57 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +// jb : Size should not depend on background, we should make it consistent + +Components.CheckBox { + id:radiobutton + property string text + property string hint + width:110 + height:20 + + background: QStyleItem { + elementType:"radiobutton" + sunken:pressed + on:checked || pressed + hover:containsMouse + text:radiobutton.text + enabled:radiobutton.enabled + focus:radiobutton.focus + hint:radiobutton.hint + } + Keys.onSpacePressed:clicked() +} + diff --git a/lib/qtcreator/qtcomponents/ScrollArea.qml b/lib/qtcreator/qtcomponents/ScrollArea.qml new file mode 100644 index 0000000000..497239e28a --- /dev/null +++ b/lib/qtcreator/qtcomponents/ScrollArea.qml @@ -0,0 +1,174 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +FocusScope { + id: scrollarea + width: 100 + height: 100 + + property int frameWidth: frame ? styleitem.pixelMetric("defaultframewidth") : 0; + property int contentHeight : content.childrenRect.height + property int contentWidth: content.childrenRect.width + property alias color: colorRect.color + property bool frame: true + property bool highlightOnFocus: false + property bool frameAroundContents: styleitem.styleHint("framearoundcontents") + property alias verticalValue: vscrollbar.value + property alias horizontalValue: hscrollbar.value + + property alias horizontalScrollBar: hscrollbar + property alias verticalScrollBar: vscrollbar + + default property alias data: content.data + + property int contentY + property int contentX + + onContentYChanged: { + vscrollbar.value = contentY + wheelarea.verticalValue = contentY + } + onContentXChanged: { + hscrollbar.value = contentX + wheelarea.horizontalValue = contentX + } + + Rectangle { + id: colorRect + color: "transparent" + anchors.fill:styleitem + anchors.margins: frameWidth + } + + QStyleItem { + id: styleitem + elementType: "frame" + onElementTypeChanged: scrollarea.frameWidth = styleitem.pixelMetric("defaultframewidth"); + sunken: true + visible: frame + anchors.fill: parent + anchors.rightMargin: frame ? (frameAroundContents ? (vscrollbar.visible ? vscrollbar.width + 2 * frameMargins : 0) : -frameWidth) : 0 + anchors.bottomMargin: frame ? (frameAroundContents ? (hscrollbar.visible ? hscrollbar.height + 2 * frameMargins : 0) : -frameWidth) : 0 + anchors.topMargin: frame ? (frameAroundContents ? 0 : -frameWidth) : 0 + property int scrollbarspacing: styleitem.pixelMetric("scrollbarspacing"); + property int frameMargins : frame ? scrollbarspacing : 0 + property int frameoffset: style === "mac" ? -1 : 0 + } + + Item { + id: flickable + anchors.fill: styleitem + anchors.margins: frameWidth + clip: true + + Item { + id: content + x: -scrollarea.contentX + y: -scrollarea.contentY + } + } + + WheelArea { + id: wheelarea + anchors.fill: parent + horizontalMinimumValue: hscrollbar.minimumValue + horizontalMaximumValue: hscrollbar.maximumValue + verticalMinimumValue: vscrollbar.minimumValue + verticalMaximumValue: vscrollbar.maximumValue + + onVerticalValueChanged: { + contentY = verticalValue + } + + onHorizontalValueChanged: { + contentX = horizontalValue + } + } + + ScrollBar { + id: hscrollbar + orientation: Qt.Horizontal + property int availableWidth : scrollarea.width - (frame ? (vscrollbar.width) : 0) + visible: contentWidth > availableWidth + maximumValue: contentWidth > availableWidth ? scrollarea.contentWidth - availableWidth: 0 + minimumValue: 0 + anchors.bottom: parent.bottom + anchors.bottomMargin: styleitem.frameoffset + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: (frame ? frameWidth : 0) + anchors.rightMargin: { vscrollbar.visible ? scrollbarExtent : (frame ? 1 : 0) } + onValueChanged: contentX = value + property int scrollbarExtent : styleitem.pixelMetric("scrollbarExtent"); + } + + ScrollBar { + id: vscrollbar + orientation: Qt.Vertical + property int availableHeight : scrollarea.height - (frame ? (hscrollbar.height) : 0) + visible: contentHeight > availableHeight + maximumValue: contentHeight > availableHeight ? scrollarea.contentHeight - availableHeight : 0 + minimumValue: 0 + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.topMargin: styleitem.style == "mac" ? 1 : 0 + onValueChanged: contentY = value + anchors.rightMargin: styleitem.frameoffset + anchors.bottomMargin: hscrollbar.visible ? hscrollbar.height : styleitem.frameoffset + } + + Rectangle { + // This is the filled corner between scrollbars + id: cornerFill + anchors.left: vscrollbar.left + anchors.right: vscrollbar.right + anchors.top: hscrollbar.top + anchors.bottom: hscrollbar.bottom + visible: hscrollbar.visible && vscrollbar.visible + SystemPalette { id: syspal } + color: syspal.window + } + + QStyleItem { + z: 2 + anchors.fill: parent + anchors.margins: -3 + anchors.rightMargin: -4 + anchors.bottomMargin: -4 + visible: highlightOnFocus && parent.activeFocus && styleitem.styleHint("focuswidget") + elementType: "focusframe" + } +} diff --git a/lib/qtcreator/qtcomponents/ScrollBar.qml b/lib/qtcreator/qtcomponents/ScrollBar.qml new file mode 100644 index 0000000000..18ed13bd54 --- /dev/null +++ b/lib/qtcreator/qtcomponents/ScrollBar.qml @@ -0,0 +1,198 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components +import "plugin" + +Item { + id: scrollbar + + property int orientation : Qt.Horizontal + property alias minimumValue: slider.minimumValue + property alias maximumValue: slider.maximumValue + property int pageStep: styleitem.horizontal ? width : height + property int singleStep: 20 + property alias value: slider.value + property bool scrollToClickposition: styleitem.styleHint("scrollToClickPosition") + + width: orientation == Qt.Horizontal ? 200 : internal.scrollbarExtent + height: orientation == Qt.Horizontal ? internal.scrollbarExtent : 200 + + onValueChanged: internal.updateHandle() + + MouseArea { + id: internal + + anchors.fill: parent + property bool upPressed + property bool downPressed + property bool pageUpPressed + property bool pageDownPressed + + property bool autoincrement: false + property int scrollbarExtent : styleitem.pixelMetric("scrollbarExtent"); + property bool handlePressed + + // Update hover item + onEntered: styleitem.activeControl = styleitem.hitTest(mouseX, mouseY) + onExited: styleitem.activeControl = "none" + onMouseXChanged: styleitem.activeControl = styleitem.hitTest(mouseX, mouseY) + hoverEnabled: true + + property variant control + property variant pressedX + property variant pressedY + property int oldPosition + property int grooveSize + + Timer { + running: internal.upPressed || internal.downPressed || internal.pageUpPressed || internal.pageDownPressed + interval: 350 + onTriggered: internal.autoincrement = true + } + + Timer { + running: internal.autoincrement + interval: 60 + repeat: true + onTriggered: internal.upPressed ? internal.decrement() : internal.downPressed ? internal.increment() : + internal.pageUpPressed ? internal.decrementPage() : + internal.incrementPage() + } + + onMousePositionChanged: { + if (pressed && control === "handle") { + //slider.positionAtMaximum = grooveSize + if (!styleitem.horizontal) + slider.position = oldPosition + (mouseY - pressedY) + else + slider.position = oldPosition + (mouseX - pressedX) + } + } + + onPressed: { + control = styleitem.hitTest(mouseX,mouseY) + scrollToClickposition = styleitem.styleHint("scrollToClickPosition") + grooveSize = styleitem.horizontal? styleitem.subControlRect("groove").width - + styleitem.subControlRect("handle").width: + styleitem.subControlRect("groove").height - + styleitem.subControlRect("handle").height; + if (control == "handle") { + pressedX = mouseX + pressedY = mouseY + oldPosition = slider.position + } else if (control == "up") { + decrement(); + upPressed = true + } else if (control == "down") { + increment(); + downPressed = true + } else if (!scrollToClickposition){ + if (control == "upPage") { + decrementPage(); + pageUpPressed = true + } else if (control == "downPage") { + incrementPage(); + pageDownPressed = true + } + } else { + slider.position = styleitem.horizontal ? mouseX - handleRect.width/2 + : mouseY - handleRect.height/2 + } + } + + onReleased: { + autoincrement = false; + upPressed = false; + downPressed = false; + pageUpPressed = false + pageDownPressed = false + control = "" + } + + function incrementPage() { + value += pageStep + if (value > maximumValue) + value = maximumValue + } + + function decrementPage() { + value -= pageStep + if (value < minimumValue) + value = minimumValue + } + + function increment() { + value += singleStep + if (value > maximumValue) + value = maximumValue + } + + function decrement() { + value -= singleStep + if (value < minimumValue) + value = minimumValue + } + + QStyleItem { + id: styleitem + anchors.fill:parent + elementType: "scrollbar" + hover: activeControl != "none" + activeControl: "none" + sunken: internal.upPressed | internal.downPressed + minimum: slider.minimumValue + maximum: slider.maximumValue + value: slider.value + horizontal: orientation == Qt.Horizontal + enabled: parent.enabled + } + + property variant handleRect: Qt.rect(0,0,0,0) + property variant grooveRect: Qt.rect(0,0,0,0) + function updateHandle() { + internal.handleRect = styleitem.subControlRect("handle") + grooveRect = styleitem.subControlRect("groove"); + } + + RangeModel { + id: slider + minimumValue: 0.0 + maximumValue: 1.0 + value: 0 + stepSize: 0.0 + inverted: false + positionAtMaximum: internal.grooveSize + } + } +} diff --git a/lib/qtcreator/qtcomponents/Slider.qml b/lib/qtcreator/qtcomponents/Slider.qml new file mode 100644 index 0000000000..ca2c5a49fe --- /dev/null +++ b/lib/qtcreator/qtcomponents/Slider.qml @@ -0,0 +1,91 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +// jens: ContainsMouse breaks drag functionality + +Components.Slider{ + id: slider + + property bool tickmarksEnabled: true + property string tickPosition: "Below" // "Top", "Below", "BothSides" + + QStyleItem { id:buttonitem; elementType: "slider" } + + property variant sizehint: buttonitem.sizeFromContents(23, 23) + property int orientation: Qt.Horizontal + + height: orientation === Qt.Horizontal ? sizehint.height : 200 + width: orientation === Qt.Horizontal ? 200 : sizehint.height + property string hint; + + groove: QStyleItem { + anchors.fill:parent + elementType: "slider" + sunken: pressed + maximum: slider.maximumValue*100 + minimum: slider.minimumValue*100 + value: slider.value*100 + horizontal: slider.orientation == Qt.Horizontal + enabled: slider.enabled + focus: slider.focus + hint: slider.hint + activeControl: tickmarksEnabled ? tickPosition.toLowerCase() : "" + } + + handle: null + valueIndicator: null + + Keys.onRightPressed: value += (maximumValue - minimumValue)/10.0 + Keys.onLeftPressed: value -= (maximumValue - minimumValue)/10.0 + + WheelArea { + id: wheelarea + anchors.fill: parent + horizontalMinimumValue: slider.minimumValue + horizontalMaximumValue: slider.maximumValue + verticalMinimumValue: slider.minimumValue + verticalMaximumValue: slider.maximumValue + property double step: (slider.maximumValue - slider.minimumValue)/100 + + onVerticalWheelMoved: { + value += verticalDelta/4*step + } + + onHorizontalWheelMoved: { + value += horizontalDelta/4*step + } + } + +} diff --git a/lib/qtcreator/qtcomponents/SpinBox.qml b/lib/qtcreator/qtcomponents/SpinBox.qml new file mode 100644 index 0000000000..a929adfa72 --- /dev/null +++ b/lib/qtcreator/qtcomponents/SpinBox.qml @@ -0,0 +1,127 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +Components.SpinBox { + id:spinbox + + property variant __upRect; + property variant __downRect; + property int __margin: (height -16)/2 + property string hint + + // Align height with button + topMargin:__margin + bottomMargin:__margin + + leftMargin:6 + rightMargin:6 + + QStyleItem { id:edititem ; elementType:"edit" ; visible:false } + property int buttonHeight: edititem.sizeFromContents(70, 20).height + property int buttonWidth: edititem.sizeFromContents(70, 20).width + + height: buttonHeight + width: buttonWidth + clip:false + + background: Item { + anchors.fill: parent + property variant __editRect + + Rectangle { + id: editBackground + x: __editRect.x - 1 + y: __editRect.y + width: __editRect.width + 1 + height: __editRect.height + } + + Item { + id: focusFrame + anchors.fill: editBackground + visible: frameitem.styleHint("focuswidget") + QStyleItem { + id: frameitem + anchors.margins: -6 + anchors.leftMargin: -6 + anchors.rightMargin: -7 + anchors.fill: parent + visible: spinbox.activeFocus + elementType: "focusframe" + } + } + + function updateRect() { + __upRect = styleitem.subControlRect("up"); + __downRect = styleitem.subControlRect("down"); + __editRect = styleitem.subControlRect("edit"); + spinbox.leftMargin = __editRect.x + 2 + spinbox.rightMargin = spinbox.width -__editRect.width - __editRect.x + } + + Component.onCompleted: updateRect() + onWidthChanged: updateRect() + onHeightChanged: updateRect() + + QStyleItem { + id: styleitem + anchors.fill: parent + elementType: "spinbox" + sunken: (downEnabled && downPressed) | (upEnabled && upPressed) + hover: containsMouse + focus: spinbox.focus + enabled: spinbox.enabled + value: (upPressed ? 1 : 0) | + (downPressed == 1 ? 1<<1 : 0) | + (upEnabled ? (1<<2) : 0) | + (downEnabled == 1 ? (1<<3) : 0) + hint: spinbox.hint + } + } + + up: Item { + x: __upRect.x + y: __upRect.y + width: __upRect.width + height: __upRect.height + } + + down: Item { + x: __downRect.x + y: __downRect.y + width: __downRect.width + height: __downRect.height + } +} diff --git a/lib/qtcreator/qtcomponents/SplitterRow.qml b/lib/qtcreator/qtcomponents/SplitterRow.qml new file mode 100644 index 0000000000..ced970e27f --- /dev/null +++ b/lib/qtcreator/qtcomponents/SplitterRow.qml @@ -0,0 +1,56 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +Components.SplitterRow { + handleBackground: QStyleItem { + id: styleitem + elementType: "splitter" + width: pixelMetric("splitterwidth") + + MouseArea { + anchors.fill: parent + anchors.leftMargin: (parent.width <= 1) ? -2 : 0 + anchors.rightMargin: (parent.width <= 1) ? -2 : 0 + drag.axis: Qt.YAxis + drag.target: handleDragTarget + onMouseXChanged: handleDragged(handleIndex) + + QStyleItem { + anchors.fill: parent + cursor: "splithcursor" + } + } + } +} diff --git a/lib/qtcreator/qtcomponents/Switch.qml b/lib/qtcreator/qtcomponents/Switch.qml new file mode 100644 index 0000000000..fcc54094c1 --- /dev/null +++ b/lib/qtcreator/qtcomponents/Switch.qml @@ -0,0 +1,53 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +Components.Switch { + id:widget + minimumWidth:100 + minimumHeight:30 + + groove:QStyleItem { + elementType:"edit" + sunken: true + } + + handle: QStyleItem { + elementType:"button" + width:widget.width/2 + height:widget.height-4 + hover:containsMouse + } +} + diff --git a/lib/qtcreator/qtcomponents/Tab.qml b/lib/qtcreator/qtcomponents/Tab.qml new file mode 100644 index 0000000000..520f07db75 --- /dev/null +++ b/lib/qtcreator/qtcomponents/Tab.qml @@ -0,0 +1,40 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import Qt 4.7 + +Item { + id:tab + anchors.fill: parent + property string title + property int contentMargin +} diff --git a/lib/qtcreator/qtcomponents/TabBar.qml b/lib/qtcreator/qtcomponents/TabBar.qml new file mode 100644 index 0000000000..27d648f0b1 --- /dev/null +++ b/lib/qtcreator/qtcomponents/TabBar.qml @@ -0,0 +1,142 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + + +Item { + id: tabbar + property int tabHeight: tabrow.height + property int tabWidth: tabrow.width + + Keys.onRightPressed: { + if (tabFrame && tabFrame.current < tabFrame.count - 1) + tabFrame.current = tabFrame.current + 1 + } + Keys.onLeftPressed: { + if (tabFrame && tabFrame.current > 0) + tabFrame.current = tabFrame.current - 1 + } + + height: tabHeight + + property Item tabFrame + onTabFrameChanged:parent = tabFrame + visible: tabFrame ? tabFrame.tabsVisible : true + property int __overlap : styleitem.pixelMetric("tabvshift"); + property string position: tabFrame ? tabFrame.position : "North" + property string tabBarAlignment: styleitem.styleHint("tabbaralignment"); + property int tabOverlap: styleitem.pixelMetric("taboverlap"); + property int tabBaseOverlap: styleitem.pixelMetric("tabbaseoverlap"); + property int tabHSpace: styleitem.pixelMetric("tabhspace"); + property int tabVSpace: styleitem.pixelMetric("tabvspace"); + + function tab(index) { + for (var i = 0; i < tabrow.children.length; ++i) { + if (tabrow.children[i].tabindex == index) { + return tabrow.children[i] + } + } + return null; + } + + QStyleItem { + visible:false + id:styleitem + elementType: "tab" + text: "generic" + } + + Row { + id: tabrow + focus: true + property int paintMargins: 1 + states: + State { + when: tabBarAlignment == "center" + name: "centered" + AnchorChanges { + target:tabrow + anchors.horizontalCenter: tabbar.horizontalCenter + } + } + + Repeater { + id:repeater + focus:true + model: tabFrame ? tabFrame.tabs.length : null + delegate: Item { + id:tab + focus:true + property int tabindex: index + property bool selected : tabFrame.current == index + z: selected ? 1 : -1 + function updateRect() { + var rect = style.sizeFromContents(textitem.width + tabHSpace + 2, Math.max(style.fontHeight + tabVSpace + 6, 0)) + width = rect.width + height = rect.height + } + // Component.onCompleted: print("taboverlap" + tabOverlap + " tabbaseoverlap " + tabBaseOverlap + " overlap " +__overlap + " hspace " + tabHSpace) + QStyleItem { + id: style + elementType: "tab" + selected: tab.selected + info: tabbar.position + text: tabFrame.tabs[index].title + hover: mousearea.containsMouse + focus: tabbar.focus && selected + property bool first: index === 0 + paintMargins: tabrow.paintMargins + activeControl: tabFrame.count == 1 ? "only" : index === 0 ? "beginning" : + index == tabFrame.count-1 ? "end" : "middle" + anchors.fill: parent + anchors.margins: -paintMargins + Text { + id: textitem + // Used for size hint + visible: false + onWidthChanged: updateRect() + onHeightChanged: updateRect() + text: tabFrame.tabs[index].title + } + } + MouseArea { + id: mousearea + anchors.fill: parent + hoverEnabled: true + onPressed: tabFrame.current = index + } + } + } + } +} diff --git a/lib/qtcreator/qtcomponents/TabFrame.qml b/lib/qtcreator/qtcomponents/TabFrame.qml new file mode 100644 index 0000000000..d9e730dade --- /dev/null +++ b/lib/qtcreator/qtcomponents/TabFrame.qml @@ -0,0 +1,108 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +Item { + id: tabWidget + width: 100 + height: 100 + focus: true + property TabBar tabbar + property int current: 0 + property int count: stack.children.length + property bool frame:true + property bool tabsVisible: true + property string position: "North" + default property alias tabs : stack.children + + onCurrentChanged: __setOpacities() + Component.onCompleted: __setOpacities() + onTabbarChanged: { + tabbar.tabFrame = tabWidget + tabbar.anchors.top = tabWidget.top + tabbar.anchors.left = tabWidget.left + tabbar.anchors.right = tabWidget.right + } + + property int __baseOverlap : frameitem.pixelMetric("tabbaseoverlap")// add paintmargins; + function __setOpacities() { + for (var i = 0; i < stack.children.length; ++i) { + stack.children[i].visible = (i == current ? true : false) + } + } + + QStyleItem { + id: frameitem + z: style == "oxygen" ? 1 : 0 + elementType: "tabframe" + info: position + value: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).x : 0 + minimum: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).width : 0 + maximum: tabbar && tabsVisible ? tabbar.tabWidth : width + anchors.fill: parent + + property int frameWidth: pixelMetric("defaultframewidth") + + Item { + id: stack + anchors.fill: parent + anchors.margins: (frame ? frameitem.frameWidth : 0) + anchors.topMargin: anchors.margins + (frameitem.style =="mac" ? 6 : 0) + anchors.bottomMargin: anchors.margins + (frameitem.style =="mac" ? 6 : 0) + } + + anchors.topMargin: tabbar && tabsVisible && position == "North" ? tabbar.height - __baseOverlap : 0 + + states: [ + State { + name: "South" + when: position == "South" && tabbar!= undefined + PropertyChanges { + target: frameitem + anchors.topMargin: 0 + anchors.bottomMargin: tabbar ? tabbar.height - __baseOverlap: 0 + } + PropertyChanges { + target: tabbar + anchors.topMargin: -__baseOverlap + } + AnchorChanges { + target: tabbar + anchors.top: frameitem.bottom + anchors.bottom: undefined + } + } + ] + } +} diff --git a/lib/qtcreator/qtcomponents/TableColumn.qml b/lib/qtcreator/qtcomponents/TableColumn.qml new file mode 100644 index 0000000000..9081f6af13 --- /dev/null +++ b/lib/qtcreator/qtcomponents/TableColumn.qml @@ -0,0 +1,41 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 + +QtObject { + property string caption + property string property + property int width: 160 + property bool visible: true + property int elideMode: Text.ElideRight +} diff --git a/lib/qtcreator/qtcomponents/TableView.qml b/lib/qtcreator/qtcomponents/TableView.qml new file mode 100644 index 0000000000..132610c3f6 --- /dev/null +++ b/lib/qtcreator/qtcomponents/TableView.qml @@ -0,0 +1,604 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 + +/* +* +* TableView +* +* This component provides an item-view with resizable +* header sections. +* +* You can style the drawn delegate by overriding the itemDelegate +* property. The following properties are supported for custom +* delegates: +* +* Note: Currently only row selection is available for this component +* +* itemheight - default platform size of item +* itemwidth - default platform width of item +* itemselected - if the row is currently selected +* itemvalue - The text for this item +* itemforeground - The default text color for an item +* +* For example: +* itemDelegate: Item { +* Text { +* anchors.verticalCenter: parent.verticalCenter +* color: itemForeground +* elide: Text.ElideRight +* text: itemValue +* } +* } +* +* Data for each row is provided through a model: +* +* ListModel { +* ListElement{ column1: "value 1"; column2: "value 2"} +* ListElement{ column1: "value 3"; column2: "value 4"} +* } +* +* You provide title and size properties on TableColumns +* by setting the default header property : +* +* TableView { +* TableColumn{ property: "column1" ; caption: "Column 1" ; width:100} +* TableColumn{ property: "column2" ; caption: "Column 2" ; width:200} +* model: datamodel +* } +* +* The header sections are attached to values in the datamodel by defining +* the listmodel property they attach to. Each property in the model, will +* then be shown in each column section. +* +* The view itself does not provide sorting. This has to +* be done on the model itself. However you can provide sorting +* on the model and enable sort indicators on headers. +* +* sortColumn - The index of the currently selected sort header +* sortIndicatorVisible - If sort indicators should be enabled +* sortIndicatorDirection - "up" or "down" depending on state +* +*/ + +FocusScope{ + id: root + property variant model + property int frameWidth: frame ? styleitem.pixelMetric("defaultframewidth") : 0; + property alias contentHeight : tree.contentHeight + property alias contentWidth: tree.contentWidth + property bool frame: true + property bool highlightOnFocus: false + property bool frameAroundContents: styleitem.styleHint("framearoundcontents") + property int sortColumn // Index of currently selected sort column + + property bool sortIndicatorVisible: false // enables or disables sort indicator + property string sortIndicatorDirection: "down" // "up" or "down" depending on current state + + property bool alternateRowColor: true + property alias contentX: tree.contentX + property alias contentY: tree.contentY + + property alias currentIndex: tree.currentIndex // Should this be currentRowIndex? + + property int headerHeight: headerrow.height + + property Component itemDelegate: standardDelegate + property Component rowDelegate: rowDelegate + property Component headerDelegate: headerDelegate + property alias cacheBuffer: tree.cacheBuffer + + property bool headerVisible: true + + default property alias header: tree.header + + signal activated + + Component { + id: standardDelegate + Item { + property int implicitWidth: sizehint.paintedWidth + 4 + Text { + width: parent.width + anchors.margins: 4 + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + elide: itemElideMode + text: itemValue ? itemValue : "" + color: itemForeground + } + Text { + id: sizehint + text: itemValue ? itemValue : "" + visible:false + } + } + } + + Component { + id: nativeDelegate + // This gives more native styling, but might be less performant + QStyleItem { + elementType: "item" + text: itemValue + selected: itemSelected + } + } + + Component { + id: headerDelegate + QStyleItem { + elementType: "header" + activeControl: itemSort + raised: true + sunken: itemPressed + text: itemValue + hover: itemContainsMouse + } + } + + Component { + id: rowDelegate + QStyleItem { + id: rowstyle + elementType: "itemrow" + activeControl: itemAlternateBackground ? "alternate" : "" + selected: itemSelected ? "true" : "false" + } + } + + Rectangle { + id: colorRect + color: "white" + anchors.fill: frameitem + anchors.margins: frameWidth + anchors.rightMargin: (!frameAroundContents && vscrollbar.visible ? vscrollbar.width : 0) + frameWidth + anchors.bottomMargin: (!frameAroundContents && hscrollbar.visible ? hscrollbar.height : 0) +frameWidth + } + + QStyleItem { + id: frameitem + elementType: "frame" + onElementTypeChanged: scrollarea.frameWidth = styleitem.pixelMetric("defaultframewidth"); + sunken: true + visible: frame + anchors.fill: parent + anchors.rightMargin: frame ? (frameAroundContents ? (vscrollbar.visible ? vscrollbar.width + 2 * frameMargins : 0) : -frameWidth) : 0 + anchors.bottomMargin: frame ? (frameAroundContents ? (hscrollbar.visible ? hscrollbar.height + 2 * frameMargins : 0) : -frameWidth) : 0 + anchors.topMargin: frame ? (frameAroundContents ? 0 : -frameWidth) : 0 + property int scrollbarspacing: styleitem.pixelMetric("scrollbarspacing"); + property int frameMargins : frame ? scrollbarspacing : 0 + } + MouseArea { + id: mousearea + + anchors.fill: tree + + property bool autoincrement: false + property bool autodecrement: false + + onReleased: { + autoincrement = false + autodecrement = false + } + + // Handle vertical scrolling whem dragging mouse outside boundraries + + Timer { running: mousearea.autoincrement; repeat: true; interval: 30 ; onTriggered: tree.incrementCurrentIndex()} + Timer { running: mousearea.autodecrement; repeat: true; interval: 30 ; onTriggered: tree.decrementCurrentIndex()} + + onMousePositionChanged: { + if (mouseY > tree.height) { + autodecrement = false + autoincrement = true + } else if (mouseY < 0) { + autoincrement = false + autodecrement = true + } else { + autoincrement = false + autodecrement = false + } + + var y = Math.min(contentY + tree.height - 5, Math.max(mouseY + contentY, contentY)) + + var newIndex = tree.indexAt(0, y) + if (newIndex > 0) + tree.currentIndex = tree.indexAt(0, y) + } + onPressed: { + tree.forceActiveFocus() + var x = Math.min(contentWidth - 5, Math.max(mouseX + contentX, 0)) + var y = Math.min(contentHeight - 5, Math.max(mouseY + contentY, 0)) + tree.currentIndex = tree.indexAt(x, y) + } + + onDoubleClicked: { + parent.activated() + } + } + + ListView { + id: tree + property list<TableColumn> header + property bool blockUpdates: false + highlightFollowsCurrentItem: true + model: root.model + + interactive: false + anchors.top: tableColumn.bottom + anchors.topMargin: -frameWidth + anchors.left: frameitem.left + anchors.right: frameitem.right + anchors.bottom: frameitem.bottom + anchors.margins: frameWidth + + anchors.rightMargin: (!frameAroundContents && vscrollbar.visible ? vscrollbar.width: 0) + frameWidth + anchors.bottomMargin: (!frameAroundContents && hscrollbar.visible ? hscrollbar.height : 0) + frameWidth + + focus: true + clip: true + + Keys.onUpPressed: { + blockUpdates = true + if (currentIndex > 0) currentIndex = currentIndex - 1 + wheelarea.verticalValue = contentY/wheelarea.scale + blockUpdates = false + } + Keys.onDownPressed: { + blockUpdates = true + if (currentIndex< count - 1) currentIndex = currentIndex + 1 + wheelarea.verticalValue = contentY/wheelarea.scale + blockUpdates = false + } + Keys.onPressed: { + if (event.key == Qt.Key_PageUp) { + vscrollbar.value = vscrollbar.value - tree.height + } else if (event.key == Qt.Key_PageDown) + vscrollbar.value = vscrollbar.value + tree.height + } + + onContentYChanged: { + // positionViewAtIndex(currentIndex, ListView.Visible) + // highlight follows item + blockUpdates = true + vscrollbar.value = tree.contentY + blockUpdates = false + } + + delegate: Item { + id: rowitem + width: row.width + height: row.height + anchors.margins: frameWidth + property int rowIndex: model.index + property bool itemAlternateBackground: alternateRowColor && rowIndex % 2 == 1 + Loader { + id: rowstyle + // row delegate + sourceComponent: root.rowDelegate + // Row fills the tree width regardless of item size + // But scrollbar should not adjust to it + width: frameitem.width + height: row.height + x: contentX + + property bool itemAlternateBackground: rowitem.itemAlternateBackground + property bool itemSelected: rowitem.ListView.isCurrentItem + } + Row { + id: row + anchors.left: parent.left + + Repeater { + id: repeater + model: root.header.length + Loader { + id: itemDelegateLoader + visible: header[index].visible + sourceComponent: itemDelegate + property variant model: tree.model + property variant itemProperty: header[index].property + + width: header[index].width + height: item ? item.height : Math.max(16, styleitem.sizeFromContents(16, 16).height) + + function getValue() { + if (index < header.length && + root.model.get(rowIndex).hasOwnProperty(header[index].property)) + return root.model.get(rowIndex)[ header[index].property] + } + property variant itemValue: root.model.get(rowIndex)[ header[index].property] + property bool itemSelected: rowitem.ListView.isCurrentItem + property color itemForeground: itemSelected ? rowstyleitem.highlightedTextColor : rowstyleitem.textColor + property int rowIndex: rowitem.rowIndex + property int columnIndex: index + property int itemElideMode: header[index].elideMode + } + } + onWidthChanged: tree.contentWidth = width + } + } + } + Text{ id:text } + + Item { + id: tableColumn + clip: true + anchors.top: frameitem.top + anchors.left: frameitem.left + anchors.right: frameitem.right + anchors.margins: frameWidth + visible: headerVisible + Behavior on height { NumberAnimation{duration:80}} + height: headerVisible ? styleitem.sizeFromContents(text.font.pixelSize, styleitem.fontHeight).height : frameWidth + + Row { + id: headerrow + + anchors.top: parent.top + height:parent.height + x: -tree.contentX + + Repeater { + id: repeater + model: header.length + property int targetIndex: -1 + property int dragIndex: -1 + delegate: Item { + z:-index + width: header[index].width + visible: header[index].visible + height: headerrow.height + + Loader { + sourceComponent: root.headerDelegate + anchors.fill: parent + property string itemValue: header[index].caption + property string itemSort: (sortIndicatorVisible && index == sortColumn) ? (sortIndicatorDirection == "up" ? "up" : "down") : ""; + property bool itemPressed: headerClickArea.pressed + property bool itemContainsMouse: headerClickArea.containsMouse + } + Rectangle{ + id: targetmark + width: parent.width + height:parent.height + opacity: (index == repeater.targetIndex && repeater.targetIndex != repeater.dragIndex) ? 0.5 : 0 + Behavior on opacity { NumberAnimation{duration:160}} + color: palette.highlight + } + + MouseArea{ + id: headerClickArea + drag.axis: Qt.YAxis + hoverEnabled: true + anchors.fill: parent + onClicked: { + if (sortColumn == index) + sortIndicatorDirection = sortIndicatorDirection === "up" ? "down" : "up" + sortColumn = index + } + // Here we handle moving header sections + onMousePositionChanged: { + if (pressed) { // only do this while dragging + for (var h = 0 ; h < header.length ; ++h) { + if (drag.target.x > headerrow.children[h].x - 10) { + repeater.targetIndex = header.length - h - 1 + break + } + } + } + } + + onPressed: { + repeater.dragIndex = index + draghandle.x = parent.x + } + + onReleased: { + if (repeater.targetIndex >= 0 && repeater.targetIndex != index ) { + // Rearrange the header sections + var items = new Array + for (var i = 0 ; i< header.length ; ++i) + items.push(header[i]) + items.splice(index, 1); + items.splice(repeater.targetIndex, 0, header[index]); + header = items + if (sortColumn == index) + sortColumn = repeater.targetIndex + } + repeater.targetIndex = -1 + } + drag.maximumX: 1000 + drag.minimumX: -1000 + drag.target: draghandle + } + + Loader { + id: draghandle + parent: tableColumn + sourceComponent: root.headerDelegate + width: header[index].width + height: parent.height + property string itemValue: header[index].caption + property string itemSort: (sortIndicatorVisible && index == sortColumn) ? (sortIndicatorDirection == "up" ? "up" : "down") : ""; + property bool itemPressed: headerClickArea.pressed + property bool itemContainsMouse: headerClickArea.containsMouse + visible: headerClickArea.pressed + opacity: 0.5 + } + + + MouseArea { + id: headerResizeHandle + property int offset: 0 + property int minimumSize: 20 + anchors.rightMargin: -width/2 + width: 16 ; height: parent.height + anchors.right: parent.right + onPositionChanged: { + var newHeaderWidth = header[index].width + (mouseX - offset) + header[index].width = Math.max(minimumSize, newHeaderWidth) + } + property bool found:false + + onDoubleClicked: { + var row + var minWidth = 0 + var listdata = tree.children[0] + for (row = 0 ; row < listdata.children.length ; ++row){ + var item = listdata.children[row+1] + if (item && item.children[1] && item.children[1].children[index] && + item.children[1].children[index].children[0].hasOwnProperty("implicitWidth")) + minWidth = Math.max(minWidth, item.children[1].children[index].children[0].implicitWidth) + } + if (minWidth) + header[index].width = minWidth + } + onPressedChanged: if(pressed)offset=mouseX + QStyleItem { + anchors.fill: parent + cursor: "splithcursor" + } + } + } + } + } + Loader { + id: loader + z:-1 + sourceComponent: root.headerDelegate + anchors.top: parent.top + anchors.right: parent.right + anchors.bottom: headerrow.bottom + anchors.rightMargin: -2 + width: root.width - headerrow.width + property string itemValue + property string itemSort + property bool itemPressed + property bool itemContainsMouse + } + } + + WheelArea { + id: wheelarea + anchors.fill: parent + property int scale: 5 + horizontalMinimumValue: hscrollbar.minimumValue/scale + horizontalMaximumValue: hscrollbar.maximumValue/scale + verticalMinimumValue: vscrollbar.minimumValue/scale + verticalMaximumValue: vscrollbar.maximumValue/scale + + verticalValue: contentY/scale + horizontalValue: contentX/scale + + onVerticalValueChanged: { + if(!tree.blockUpdates) { + contentY = verticalValue * scale + vscrollbar.value = contentY + } + } + + onHorizontalValueChanged: { + if(!tree.blockUpdates) { + contentX = horizontalValue * scale + hscrollbar.value = contentX + } + } + } + + ScrollBar { + id: hscrollbar + orientation: Qt.Horizontal + property int availableWidth: root.width - vscrollbar.width + visible: contentWidth > availableWidth + maximumValue: contentWidth > availableWidth ? tree.contentWidth - availableWidth : 0 + minimumValue: 0 + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: frameWidth + anchors.bottomMargin: styleitem.frameoffset + anchors.rightMargin: vscrollbar.visible ? scrollbarExtent : (frame ? 1 : 0) + onValueChanged: { + if (!tree.blockUpdates) + contentX = value + } + property int scrollbarExtent : styleitem.pixelMetric("scrollbarExtent"); + } + + ScrollBar { + id: vscrollbar + orientation: Qt.Vertical + // We cannot bind directly to tree.height due to binding loops so we have to redo the calculation here + property int availableHeight : root.height - (hscrollbar.visible ? hscrollbar.height : 0) - tableColumn.height + visible: contentHeight > availableHeight + maximumValue: contentHeight > availableHeight ? tree.contentHeight - availableHeight : 0 + minimumValue: 0 + anchors.rightMargin: styleitem.frameoffset + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.topMargin: styleitem.style == "mac" ? tableColumn.height : 0 + onValueChanged: { + if(!tree.blockUpdates) + contentY = value + } + anchors.bottomMargin: hscrollbar.visible ? hscrollbar.height : styleitem.frameoffset + + Keys.onUpPressed: if (tree.currentIndex > 0) tree.currentIndex = tree.currentIndex - 1 + Keys.onDownPressed: if (tree.currentIndex< tree.count - 1) tree.currentIndex = tree.currentIndex + 1 + } + + QStyleItem { + z: 2 + anchors.fill: parent + anchors.margins: -4 + visible: highlightOnFocus && parent.activeFocus && styleitem.styleHint("focuswidget") + elementType: "focusframe" + } + + QStyleItem { + id: styleitem + elementType: "header" + visible:false + property int frameoffset: style === "mac" ? -1 : 0 + } + QStyleItem { + id: rowstyleitem + elementType: "item" + visible:false + property color textColor: styleHint("textColor") + property color highlightedTextColor: styleHint("highlightedTextColor") + } + SystemPalette{id:palette} +} diff --git a/lib/qtcreator/qtcomponents/TextArea.qml b/lib/qtcreator/qtcomponents/TextArea.qml new file mode 100644 index 0000000000..c222e9ecc3 --- /dev/null +++ b/lib/qtcreator/qtcomponents/TextArea.qml @@ -0,0 +1,82 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +ScrollArea { + id:area + color: "white" + width: 280 + height: 120 + contentWidth: 200 + + property alias text: edit.text + property alias wrapMode: edit.wrapMode + property alias readOnly: edit.readOnly + + highlightOnFocus: true + property int documentMargins: 4 + frame: true + + Item { + anchors.left: parent.left + anchors.top: parent.top + height: edit.height - 8 + anchors.margins: documentMargins + + TextEdit { + id: edit + text: loremIpsum + loremIpsum; + wrapMode: TextEdit.WordWrap; + width: area.contentWidth + selectByMouse: true + readOnly: false + focus: true + + // keep textcursor within scrollarea + onCursorPositionChanged: { + if (cursorRectangle.y >= area.contentY + area.height - 1.5*cursorRectangle.height) + area.contentY = cursorRectangle.y - area.height + 1.5*cursorRectangle.height + else if (cursorRectangle.y < area.contentY) + area.contentY = cursorRectangle.y + } + } + } + + Keys.onPressed: { + if (event.key == Qt.Key_PageUp) { + verticalValue = verticalValue - area.height + } else if (event.key == Qt.Key_PageDown) + verticalValue = verticalValue + area.height + } +} diff --git a/lib/qtcreator/qtcomponents/TextField.qml b/lib/qtcreator/qtcomponents/TextField.qml new file mode 100644 index 0000000000..c9ce0959f1 --- /dev/null +++ b/lib/qtcreator/qtcomponents/TextField.qml @@ -0,0 +1,76 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +Components.TextField { + id: textfield + minimumWidth: 200 + + placeholderText: "" + topMargin: 2 + bottomMargin: 2 + leftMargin: 6 + rightMargin: 6 + + property string hint + + height: backgroundItem.sizeFromContents(200, 25).height + width: 200 + clip: false + + background: QStyleItem { + anchors.fill: parent + elementType: "edit" + sunken: true + focus: textfield.activeFocus + hover: containsMouse + hint: textfield.hint + } + + Item{ + id: focusFrame + anchors.fill: textfield + parent: textfield + visible: framestyle.styleHint("focuswidget") + QStyleItem { + id: framestyle + anchors.margins: -2 + anchors.rightMargin:-4 + anchors.bottomMargin:-4 + anchors.fill: parent + visible: textfield.activeFocus + elementType: "focusframe" + } + } +} diff --git a/lib/qtcreator/qtcomponents/ToolBar.qml b/lib/qtcreator/qtcomponents/ToolBar.qml new file mode 100644 index 0000000000..a33fd69e3b --- /dev/null +++ b/lib/qtcreator/qtcomponents/ToolBar.qml @@ -0,0 +1,42 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +QStyleItem{ + id: toolbar + width: 200 + height: sizeFromContents(32, 32).height + elementType: "toolbar" +} + diff --git a/lib/qtcreator/qtcomponents/ToolButton.qml b/lib/qtcreator/qtcomponents/ToolButton.qml new file mode 100644 index 0000000000..2747947d5d --- /dev/null +++ b/lib/qtcreator/qtcomponents/ToolButton.qml @@ -0,0 +1,65 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "custom" as Components + +Components.Button { + id:button + + height: 40; //styleitem.sizeFromContents(32, 32).height + width: 40; //styleitem.sizeFromContents(32, 32).width + + QStyleItem {elementType: "toolbutton"; id:styleitem } + + background: QStyleItem { + anchors.fill: parent + id: styleitem + elementType: "toolbutton" + on: pressed | checked + sunken: pressed + raised: containsMouse + hover: containsMouse + + Text { + text: button.text + anchors.centerIn: parent + visible: button.iconSource == "" + } + + Image { + source: button.iconSource + anchors.centerIn: parent + opacity: enabled ? 1 : 0.5 + } + } +} diff --git a/lib/qtcreator/qtcomponents/custom/BasicButton.qml b/lib/qtcreator/qtcomponents/custom/BasicButton.qml new file mode 100644 index 0000000000..79ceb40b51 --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/BasicButton.qml @@ -0,0 +1,83 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "./behaviors" // ButtonBehavior + +Item { + id: button + + signal clicked + property alias pressed: behavior.pressed + property alias containsMouse: behavior.containsMouse + property alias checkable: behavior.checkable // button toggles between checked and !checked + property alias checked: behavior.checked + + property Component background: null + property Item backgroundItem: backgroundLoader.item + + property color textColor: syspal.text; + property bool activeFocusOnPress: true + property string tooltip + + signal toolTipTriggered + + // implementation + + property string __position: "only" + width: backgroundLoader.item.width + height: backgroundLoader.item.height + + Loader { + id: backgroundLoader + anchors.fill: parent + sourceComponent: background + property alias styledItem: button + property alias position: button.__position + } + + ButtonBehavior { + id: behavior + anchors.fill: parent + onClicked: button.clicked() + onPressedChanged: if (activeFocusOnPress) button.focus = true + onMouseMoved: {tiptimer.restart()} + Timer{ + id: tiptimer + interval:1000 + running:containsMouse && tooltip.length + onTriggered: button.toolTipTriggered() + } + } + + SystemPalette { id: syspal } +} diff --git a/lib/qtcreator/qtcomponents/custom/Button.qml b/lib/qtcreator/qtcomponents/custom/Button.qml new file mode 100644 index 0000000000..f3a4af3adf --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/Button.qml @@ -0,0 +1,53 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 + +BasicButton { + id: button + + property string text + property url iconSource + property Component label: null + + // implementation + + background: defaultStyle.background + property Item labelItem: labelLoader.item + + Loader { + id: labelLoader + anchors.fill: parent + property alias styledItem: button + sourceComponent: label + } +} diff --git a/lib/qtcreator/qtcomponents/custom/ButtonColumn.qml b/lib/qtcreator/qtcomponents/custom/ButtonColumn.qml new file mode 100644 index 0000000000..4a1fe634eb --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/ButtonColumn.qml @@ -0,0 +1,76 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import Qt 4.7 +import "ButtonGroup.js" as Behavior + +/* + Class: ButtonColumn + A ButtonColumn allows you to group Buttons in a column. It provides a selection-behavior as well. + + Note: This component don't support the enabled property. + If you need to disable it you should disable all the buttons inside it. + + <code> + ButtonColumn { + Button { text: "Top" } + Button { text: "Bottom" } + } + </code> +*/ +Column { + id: root + + /* + * Property: exclusive + * [bool=true] Specifies the grouping behavior. If enabled, the checked property on buttons contained + * in the group will be exclusive. + * + * Note that a button in an exclusive group will allways be checkable + */ + property bool exclusive: true + + /* + * Property: checkedButton + * [string] Contains the last checked Button. + */ + property Item checkedButton; + + Component.onCompleted: { + Behavior.create(root, {direction: Qt.Vertical}); + } + + Component.onDestruction: { + Behavior.destroy(); + } + +} diff --git a/lib/qtcreator/qtcomponents/custom/ButtonGroup.js b/lib/qtcreator/qtcomponents/custom/ButtonGroup.js new file mode 100644 index 0000000000..19d05fee33 --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/ButtonGroup.js @@ -0,0 +1,137 @@ +var self; +var checkHandlers = []; +var visibleButtons = []; +var nonVisibleButtons = []; +var direction; + +function create(that, options) { + self = that; + direction = options.direction || Qt.Horizontal; + self.childrenChanged.connect(rebuild); +// self.widthChanged.connect(resizeChildren); + build(); +} + +function isButton(item) { + if (item && item.hasOwnProperty("__position")) + return true; + return false; +} + +function hasChecked(item) { + return (item && item.hasOwnProperty("checked")); +} + +function destroy() { + self.childrenChanged.disconnect(rebuild); +// self.widthChanged.disconnect(resizeChildren); + cleanup(); +} + +function build() { + visibleButtons = []; + nonVisibleButtons = []; + + for (var i = 0, item; (item = self.children[i]); i++) { + if (!hasChecked(item)) + continue; + + item.visibleChanged.connect(rebuild); // Not optimal, but hardly a bottleneck in your app + if (!item.visible) { + nonVisibleButtons.push(item); + continue; + } + visibleButtons.push(item); + + if (self.exclusive && item.hasOwnProperty("checkable")) + item.checkable = true; + + if (self.exclusive) { + item.checked = false; + checkHandlers.push(checkExclusive(item)); + item.checkedChanged.connect(checkHandlers[checkHandlers.length - 1]); + } + } + + var nrButtons = visibleButtons.length; + if (nrButtons == 0) + return; + + if (self.checkedButton) + self.checkedButton.checked = true; + else if (self.exclusive) { + self.checkedButton = visibleButtons[0]; + self.checkedButton.checked = true; + } + + if (nrButtons == 1) { + finishButton(visibleButtons[0], "only"); + } else { + finishButton(visibleButtons[0], direction == Qt.Horizontal ? "leftmost" : "top"); + for (var i = 1; i < nrButtons - 1; i++) + finishButton(visibleButtons[i], direction == Qt.Horizontal ? "h_middle": "v_middle"); + finishButton(visibleButtons[nrButtons - 1], direction == Qt.Horizontal ? "rightmost" : "bottom"); + } +} + +function finishButton(button, position) { + if (isButton(button)) { + button.__position = position; + if (direction == Qt.Vertical) { + button.anchors.left = self.left //mm How to make this not cause binding loops? see QTBUG-17162 + button.anchors.right = self.right + } + } +} + +function cleanup() { + visibleButtons.forEach(function(item, i) { + if (checkHandlers[i]) + item.checkedChanged.disconnect(checkHandlers[i]); + item.visibleChanged.disconnect(rebuild); + }); + checkHandlers = []; + + nonVisibleButtons.forEach(function(item, i) { + item.visibleChanged.disconnect(rebuild); + }); +} + +function rebuild() { + if (self == undefined) + return; + + cleanup(); + build(); +} + +function resizeChildren() { + if (direction != Qt.Horizontal) + return; + + var extraPixels = self.width % visibleButtons; + var buttonSize = (self.width - extraPixels) / visibleButtons; + visibleButtons.forEach(function(item, i) { + if (!item || !item.visible) + return; + item.width = buttonSize + (extraPixels > 0 ? 1 : 0); + if (extraPixels > 0) + extraPixels--; + }); +} + +function checkExclusive(item) { + var button = item; + return function() { + for (var i = 0, ref; (ref = visibleButtons[i]); i++) { + if (ref.checked == (button === ref)) + continue; + + // Disconnect the signal to avoid recursive calls + ref.checkedChanged.disconnect(checkHandlers[i]); + ref.checked = !ref.checked; + ref.checkedChanged.connect(checkHandlers[i]); + } + self.checkedButton = button; + } +} diff --git a/lib/qtcreator/qtcomponents/custom/ButtonRow.qml b/lib/qtcreator/qtcomponents/custom/ButtonRow.qml new file mode 100644 index 0000000000..1f1ceeb5b2 --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/ButtonRow.qml @@ -0,0 +1,75 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import Qt 4.7 +import "ButtonGroup.js" as Behavior + +/* + Class: ButtonRow + A ButtonRow allows you to group Buttons in a row. It provides a selection-behavior as well. + + Note: This component don't support the enabled property. + If you need to disable it you should disable all the buttons inside it. + + <code> + ButtonRow { + Button { text: "Left" } + Button { text: "Right" } + } + </code> +*/ +Row { + id: root + + /* + * Property: exclusive + * [bool=true] Specifies the grouping behavior. If enabled, the checked property on buttons contained + * in the group will be exclusive. + * + * Note that a button in an exclusive group will allways be checkable + */ + property bool exclusive: true + + /* + * Property: checkedButton + * [string] Contains the last checked Button. + */ + property Item checkedButton; + + Component.onCompleted: { + Behavior.create(root, {direction: Qt.Horizontal}); + } + + Component.onDestruction: { + Behavior.destroy(); + } +} diff --git a/lib/qtcreator/qtcomponents/custom/CheckBox.qml b/lib/qtcreator/qtcomponents/custom/CheckBox.qml new file mode 100644 index 0000000000..851b032dcc --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/CheckBox.qml @@ -0,0 +1,64 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "./behaviors" + +Item { + id: checkBox + + signal clicked + property alias pressed: behavior.pressed + property alias checked: behavior.checked + property alias containsMouse: behavior.containsMouse + property bool activeFocusOnPress: true + property Component background: null + property Item backgroundItem: backgroundLoader.item + + // implementation + + Loader { + id: backgroundLoader + anchors.fill: parent + property alias styledItem: checkBox + sourceComponent: background + } + + ButtonBehavior { + id: behavior + anchors.fill: parent + checkable: true + onClicked: {if (activeFocusOnPress)checkBox.focus = true; checkBox.clicked()} + } + + SystemPalette { id: syspal } +} diff --git a/lib/qtcreator/qtcomponents/custom/ChoiceList.qml b/lib/qtcreator/qtcomponents/custom/ChoiceList.qml new file mode 100644 index 0000000000..4da78ffa7d --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/ChoiceList.qml @@ -0,0 +1,81 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "./private" as Private + +Item { + id: choiceList + + property alias model: popup.model + property alias currentIndex: popup.currentIndex + property alias currentText: popup.currentText + property alias popupOpen: popup.popupOpen + property alias containsMouse: popup.containsMouse + property alias pressed: popup.buttonPressed + + property Component background: null + property Item backgroundItem: backgroundLoader.item + property Component listItem: null + property Component popupFrame: null + + property int leftMargin: 0 + property int topMargin: 0 + property int rightMargin: 0 + property int bottomMargin: 0 + + property string popupBehavior + width: 0 + height: 0 + + property bool activeFocusOnPress: true + + Loader { + id: backgroundLoader + property alias styledItem: choiceList + sourceComponent: background + anchors.fill: parent + property string currentItemText: model.get(currentIndex).text + } + + Private.ChoiceListPopup { + // NB: This ChoiceListPopup is also the mouse area + // for the component (to enable drag'n'release) + id: popup + listItem: choiceList.listItem + popupFrame: choiceList.popupFrame + } + + Keys.onSpacePressed: { choiceList.popupOpen = !choiceList.popupOpen } + Keys.onUpPressed: { if (currentIndex < model.count - 1) currentIndex++ } + Keys.onDownPressed: {if (currentIndex > 0) currentIndex-- } +} diff --git a/lib/qtcreator/qtcomponents/custom/GroupBox.qml b/lib/qtcreator/qtcomponents/custom/GroupBox.qml new file mode 100644 index 0000000000..87b471074c --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/GroupBox.qml @@ -0,0 +1,86 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 + +FocusScope { + id: groupbox + + width: Math.max(200, contentWidth + loader.leftMargin + loader.rightMargin) + height: contentHeight + loader.topMargin + loader.bottomMargin + + default property alias children: content.children + + property string title + property bool checkable: false + property int contentWidth: content.childrenRect.width + property int contentHeight: content.childrenRect.height + property double contentOpacity: 1 + + property Component background: null + property Item backgroundItem: loader.item + + property CheckBox checkbox: check + property alias checked: check.checked + + Loader { + id: loader + anchors.fill: parent + property int topMargin: 22 + property int bottomMargin: 4 + property int leftMargin: 4 + property int rightMargin: 4 + + property alias styledItem: groupbox + sourceComponent: background + + Item { + id:content + z: 1 + opacity: contentOpacity + anchors.topMargin: loader.topMargin + anchors.leftMargin: 8 + anchors.top:parent.top + anchors.left:parent.left + enabled: (!checkable || checkbox.checked) + } + + CheckBox { + id: check + checked: true + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: loader.topMargin + } + } +} diff --git a/lib/qtcreator/qtcomponents/custom/ProgressBar.qml b/lib/qtcreator/qtcomponents/custom/ProgressBar.qml new file mode 100644 index 0000000000..995d477fda --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/ProgressBar.qml @@ -0,0 +1,85 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 + +Item { + id: progressBar + + property real value: 0 + property real minimumValue: 0 + property real maximumValue: 1 + property bool indeterminate: false + property bool containsMouse: mouseArea.containsMouse + + property int leftMargin: 0 + property int topMargin: 0 + property int rightMargin: 0 + property int bottomMargin: 0 + + property int minimumWidth: 0 + property int minimumHeight: 0 + + width: minimumWidth + height: minimumHeight + + property Component background: null + property Item backgroundItem: groove.item + + property color backgroundColor: syspal.base + property color progressColor: syspal.highlight + + Loader { + id: groove + property alias indeterminate:progressBar.indeterminate + property alias value:progressBar.value + property alias maximumValue:progressBar.maximumValue + property alias minimumValue:progressBar.minimumValue + + sourceComponent: background + anchors.fill: parent + } + + Item { + anchors.fill: parent + anchors.leftMargin: leftMargin + anchors.rightMargin: rightMargin + anchors.topMargin: topMargin + anchors.bottomMargin: bottomMargin + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + } +} diff --git a/lib/qtcreator/qtcomponents/custom/Slider.qml b/lib/qtcreator/qtcomponents/custom/Slider.qml new file mode 100644 index 0000000000..3e20b5582d --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/Slider.qml @@ -0,0 +1,292 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "../" + +Item { + id: slider + + // COMMON API + property int orientation: Qt.Horizontal + property alias minimumValue: range.minimumValue + property alias maximumValue: range.maximumValue + property alias inverted: range.inverted + property bool updateValueWhileDragging: true + property alias pressed: mouseArea.pressed + property alias stepSize: range.stepSize + property alias hoverEnabled: mouseArea.hoverEnabled + + // NOTE: this property is in/out, the user can set it, create bindings to it, and + // at the same time the slider wants to update. There's no way in QML to do this kind + // of updates AND allow the user bind it (without a Binding object). That's the + // reason this is an alias to a C++ property in range model. + property alias value: range.value + property bool containsMouse: mouseArea.containsMouse + + // CONVENIENCE TO BE USED BY STYLES + + property int leftMargin: 0 + property int rightMargin: 0 + + // EXTENSIONS + // Indicate that we want animations in the Slider, people customizing should + // look at it to decide whether or not active animations. + property bool animated: true + property bool activeFocusOnPress: true + + // Value indicator displays the current value near the slider + property bool valueIndicatorVisible: true + property int valueIndicatorMargin: 10 + property string valueIndicatorPosition: _isVertical ? "Left" : "Top" + + // Reimplement this function to control how the value is shown in the + // indicator. + function formatValue(v) { + return Math.round(v); + } + + // Hooks for customizing the pieces of the slider + property Component groove: null + property Component handle: null + property Component valueIndicator: null + + // PRIVATE/CONVENIENCE + property bool _isVertical: orientation == Qt.Vertical + + // This is a template slider, so every piece can be modified by passing a + // different Component. The main elements in the implementation are + // + // - the 'range' does the calculations to map position to/from value, + // it also serves as a data storage for both properties; + // + // - the 'fakeHandle' is what the mouse area drags on the screen, it feeds + // the 'range' position and also reads it when convenient; + // + // - the real 'handle' it is the visual representation of the handle, that + // just follows the 'fakeHandle' position. + // + // When the 'updateValueWhileDragging' is false and we are dragging, we stop + // feeding the range with position information, delaying until the next + // mouse release. + // + // Everything is encapsulated in a contents Item, so for the + // vertical slider, we just swap the height/width, make it + // horizontal, and then use rotation to make it vertical again. + + Item { + id: contents + + width: _isVertical ? slider.height : slider.width + height: _isVertical ? slider.width : slider.height + rotation: _isVertical ? -90 : 0 + + anchors.centerIn: slider + + RangeModel { + id: range + minimumValue: 0.0 + maximumValue: 1.0 + value: 0 + stepSize: 0.0 + inverted: false + + positionAtMinimum: leftMargin + positionAtMaximum: contents.width - rightMargin + } + + Loader { + id: grooveLoader + anchors.fill: parent + sourceComponent: groove + + property real handlePosition : handleLoader.x + function positionForValue(value) { + return range.positionForValue(value) - leftMargin; + } + } + + Loader { + id: handleLoader + transform: Translate { x: - handleLoader.width / 2 } + + anchors.verticalCenter: grooveLoader.verticalCenter + + sourceComponent: handle + + x: fakeHandle.x + Behavior on x { + id: behavior + enabled: !mouseArea.drag.active && slider.animated + + PropertyAnimation { + duration: behavior.enabled ? 150 : 0 + easing.type: Easing.OutSine + } + } + } + + Item { + id: fakeHandle + width: handleLoader.width + height: handleLoader.height + transform: Translate { x: - handleLoader.width / 2 } + } + + MouseArea { + id: mouseArea + hoverEnabled: true + anchors.centerIn: parent + anchors.horizontalCenterOffset: (slider.leftMargin - slider.rightMargin) / 2 + + width: parent.width + handleLoader.width - slider.rightMargin - slider.leftMargin + height: parent.height + + drag.target: fakeHandle + drag.axis: Drag.XAxis + drag.minimumX: range.positionAtMinimum + drag.maximumX: range.positionAtMaximum + + onPressed: { + + if (activeFocusOnPress) + slider.focus = true; + + // Clamp the value + var newX = Math.max(mouse.x, drag.minimumX); + newX = Math.min(newX, drag.maximumX); + + // Debounce the press: a press event inside the handler will not + // change its position, the user needs to drag it. + + // Note this really messes up things for scrollbar + // if (Math.abs(newX - fakeHandle.x) > handleLoader.width / 2) + range.position = newX; + } + + onReleased: { + // If we don't update while dragging, this is the only + // moment that the range is updated. + if (!slider.updateValueWhileDragging) + range.position = fakeHandle.x; + } + } + + Loader { + id: valueIndicatorLoader + + transform: Translate { x: - handleLoader.width / 2 } + rotation: _isVertical ? 90 : 0 + visible: valueIndicatorVisible + + // Properties available for the delegate component. Note that the indicatorText + // shows the value for the position the handle is, which is not necessarily the + // available as the current slider.value, since updateValueWhileDragging can + // be set to 'false'. + property string indicatorText: slider.formatValue(range.valueForPosition(handleLoader.x)) + property bool dragging: mouseArea.drag.active + + sourceComponent: valueIndicator + + state: { + if (!_isVertical) + return slider.valueIndicatorPosition; + + if (valueIndicatorPosition == "Right") + return "Bottom"; + if (valueIndicatorPosition == "Top") + return "Right"; + if (valueIndicatorPosition == "Bottom") + return "Left"; + + return "Top"; + } + + anchors.margins: valueIndicatorMargin + + states: [ + State { + name: "Top" + AnchorChanges { + target: valueIndicatorLoader + anchors.bottom: handleLoader.top + anchors.horizontalCenter: handleLoader.horizontalCenter + } + }, + State { + name: "Bottom" + AnchorChanges { + target: valueIndicatorLoader + anchors.top: handleLoader.bottom + anchors.horizontalCenter: handleLoader.horizontalCenter + } + }, + State { + name: "Right" + AnchorChanges { + target: valueIndicatorLoader + anchors.left: handleLoader.right + anchors.verticalCenter: handleLoader.verticalCenter + } + }, + State { + name: "Left" + AnchorChanges { + target: valueIndicatorLoader + anchors.right: handleLoader.left + anchors.verticalCenter: handleLoader.verticalCenter + } + } + ] + } + } + + // Range position normally follow fakeHandle, except when + // 'updateValueWhileDragging' is false. In this case it will only follow + // if the user is not pressing the handle. + Binding { + when: updateValueWhileDragging || !mouseArea.pressed + target: range + property: "position" + value: fakeHandle.x + } + + // During the drag, we simply ignore position set from the range, this + // means that setting a value while dragging will not "interrupt" the + // dragging activity. + Binding { + when: !mouseArea.drag.active + target: fakeHandle + property: "x" + value: range.position + } +} diff --git a/lib/qtcreator/qtcomponents/custom/SpinBox.qml b/lib/qtcreator/qtcomponents/custom/SpinBox.qml new file mode 100644 index 0000000000..e17b56c931 --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/SpinBox.qml @@ -0,0 +1,196 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 + +FocusScope { + id: spinbox + SystemPalette{id:syspal} + + property int minimumWidth: 0 + property int minimumHeight: 0 + + property int leftMargin: 0 + property int topMargin: 0 + property int rightMargin: 0 + property int bottomMargin: 0 + + width: Math.max(minimumWidth, + input.width + leftMargin + rightMargin) + + height: Math.max(minimumHeight, + input.height + topMargin + bottomMargin) + + property real value: 0.0 + property real maximumValue: 99 + property real minimumValue: 0 + property real singleStep: 1 + property string postfix + + property bool upEnabled: value != maximumValue; + property bool downEnabled: value != minimumValue; + property alias upPressed: mouseUp.pressed + property alias downPressed: mouseDown.pressed + property alias upHovered: mouseUp.containsMouse + property alias downHovered: mouseDown.containsMouse + property alias containsMouse: mouseArea.containsMouse + property color textColor: syspal.text + property alias font: input.font + + property Component background: null + property Item backgroundItem: backgroundComponent.item + property Component up: null + property Component down: null + + QtObject { + id: componentPrivate + property bool valueUpdate: false + } + + function increment() { + setValue(input.text) + value += singleStep + if (value > maximumValue) + value = maximumValue + input.text = value + } + + function decrement() { + setValue(input.text) + value -= singleStep + if (value < minimumValue) + value = minimumValue + input.text = value + } + + function setValue(v) { + var newval = parseFloat(v) + if (newval > maximumValue) + newval = maximumValue + else if (v < minimumValue) + newval = minimumValue + value = newval + input.text = value + } + + Component.onCompleted: setValue(value) + + onValueChanged: { + componentPrivate.valueUpdate = true + input.text = value + componentPrivate.valueUpdate = false + } + + // background + Loader { + id: backgroundComponent + anchors.fill: parent + sourceComponent: background + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + } + + TextInput { + id: input + + font.pixelSize: 14 + anchors.margins: 5 + anchors.leftMargin: leftMargin + anchors.topMargin: topMargin + anchors.rightMargin: rightMargin + anchors.bottomMargin: bottomMargin + anchors.fill: parent + selectByMouse: true + + // validator: DoubleValidator { bottom: minimumValue; top: maximumValue; } + onAccepted: {setValue(input.text)} + onActiveFocusChanged: setValue(input.text) + color: textColor + opacity: parent.enabled ? 1 : 0.5 + Text { + text: postfix + anchors.rightMargin: 4 + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + } + } + + Loader { + id: upButton + property alias pressed : spinbox.upPressed + property alias hover : spinbox.upHovered + property alias enabled : spinbox.upEnabled + sourceComponent: up + MouseArea { + id: mouseUp + anchors.fill: upButton.item + onClicked: increment() + + property bool autoincrement: false; + onReleased: autoincrement = false + Timer { running: mouseUp.pressed; interval: 350 ; onTriggered: mouseUp.autoincrement = true } + Timer { running: mouseUp.autoincrement; interval: 60 ; repeat: true ; onTriggered: increment() } + } + onLoaded: { + item.parent = spinbox + mouseUp.parent = item + } + } + + Loader { + id: downButton + property alias pressed : spinbox.downPressed + property alias hover : spinbox.downHovered + property alias enabled : spinbox.downEnabled + sourceComponent: down + MouseArea { + id: mouseDown + anchors.fill: downButton.item + onClicked: decrement() + + property bool autoincrement: false; + onReleased: autoincrement = false + Timer { running: mouseDown.pressed; interval: 350 ; onTriggered: mouseDown.autoincrement = true } + Timer { running: mouseDown.autoincrement; interval: 60 ; repeat: true ; onTriggered: decrement() } + } + onLoaded: { + item.parent = spinbox + mouseDown.parent = item + } + } + Keys.onUpPressed: increment() + Keys.onDownPressed: decrement() +} diff --git a/lib/qtcreator/qtcomponents/custom/SplitterRow.qml b/lib/qtcreator/qtcomponents/custom/SplitterRow.qml new file mode 100644 index 0000000000..7c70931159 --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/SplitterRow.qml @@ -0,0 +1,360 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "private" + +/* +* +* SplitterRow +* +* SplitterRow is a component that provides a way to layout items horisontally with +* a draggable splitter added in-between each item. +* +* Add items to the SplitterRow by inserting them as child items. The splitter handle +* is outsourced as a delegate (handleBackground). For this delegate to work properly, +* it will need to contain a mouse area that communicates with the SplitterRow by binding +* 'onMouseXChanged: handleDragged(handleIndex)', and 'drag.target: dragTarget'. +* +* The SplitterRow contains the followin API: +* +* Component handleBackground - delegate that will be instanciated between each +* child item. Inside the delegate, the following properties are available: +* int handleIndex - specifies the index of the splitter handle. The handle +* between the first and the second item will get index 0, the next handle index 1 etc. +* Item handleDragTarget - convenience property that tells which drag target any +* inner mouse areas that controls the handle should bind to. +* function handleDragged(handleIndex) - function that should be called whenever +* the handle is dragged to a new position +* +* The following properties can optionally be added for each direct child item of SplitterRow: +* +* real minimumWidth - if present, ensures that the item cannot be resized below the +* given value. A value of -1 will disable it. +* real maximumWidth - if present, ensures that the item cannot be resized above the +* given value. A value of -1 will disable it. +* real percentageWidth - if present, should be a value between 0-100. This value specifies +* a percentage of the width of the SplitterRow width. If the width of the SplitterRow +* change, the width of the item will change as well. 'percentageWidth' have precedence +* over 'width', which means that SplitterRow will ignore any assignments done to 'width'. +* A value of -1 disables it. +* bool expanding - if present, the item will consume all extra space in the SplitterRow, down to +* minimumWidth. This means that that 'width', 'percentageWidth' and 'maximumWidth' will be ignored. +* There will always be one (and only one) item in the SplitterRow that has this behaviour, and by +* default, it will be the last child item of the SplitterRow. Also note that which item that gets +* resized upon dragging a handle depends on whether the expanding item is located towards the left +* or the right of the handle. +* +* Example: +* +* To create a SplitterRow with three items, and let +* the center item be the one that should be expanding, one +* could do the following: +* +* SplitterRow { +* anchors.fill: parent +* +* handleBackground: Rectangle { +* width: 1 +* color: "black" +* +* MouseArea { +* anchors.fill: parent +* anchors.leftMargin: -2 +* anchors.rightMargin: -2 +* drag.axis: Qt.YAxis +* drag.target: handleDragTarget +* onMouseXChanged: handleDragged(handleIndex) +* } +* } +* +* Rectangle { +* color: "gray" +* width: 200 +* } +* Rectangle { +* property real minimumWidth: 50 +* property real maximumWidth: 400 +* property bool expanding: true +* color: "darkgray" +* } +* Rectangle { +* color: "gray" +* width: 200 +* } +* } +*/ + +Item { + id: root + default property alias items: splitterItems.children + property alias handles: splitterHandles.children + property Component handleBackground: Rectangle { width:3; color: "black" } + clip: true + + Component.onCompleted: d.init(); + onWidthChanged: d.updateLayout(); + + QtObject { + id: d + property int expandingIndex: items.length-1 + property bool updateOptimizationBlock: true + property bool bindingRecursionGuard: false + + function init() + { + for (var i=0; i<items.length-1; ++i) { + // Anchor each item to fill out all space vertically: + var item = items[i]; + item.anchors.top = splitterItems.top + item.anchors.bottom = splitterItems.bottom + // Listen for changes to width and expanding: + propertyChangeListener.createObject(item); + // Create a handle for the item: + var handle = handleBackgroundLoader.createObject(splitterHandles, {"handleIndex":i}); + handle.anchors.top = splitterHandles.top + handle.anchors.bottom = splitterHandles.bottom + } + item = items[i] + if (item) { + // Do the same for the last item as well, since + // the for-loop skipped the last item: + items[i].anchors.top = splitterItems.top + items[i].anchors.bottom = splitterItems.bottom + propertyChangeListener.createObject(items[i]); + } + d.updateOptimizationBlock = false + d.updateLayout() + } + + function accumulatedWidth(firstIndex, lastIndex, includeExpandingMinimum) + { + // Go through items and handles, and + // calculate their acummulated width. + var w = 0 + for (var i=firstIndex; i<lastIndex; ++i) { + var item = items[i] + if (i !== d.expandingIndex) + w += item.width; + else if (includeExpandingMinimum && item.minimumWidth != undefined && item.minimumWidth != -1) + w += item.minimumWidth + if (handles[i] && (i !== d.expandingIndex || includeExpandingMinimum === false)) + w += handles[i].width + } + return w + } + + function updateLayout() + { + if (items.length === 0) + return; + if (d.updateOptimizationBlock === true) + return + d.updateOptimizationBlock = true + + // This function will reposition both handles and + // items according to the _width of the each item_ + var item, prevItem + var handle, prevHandle + var newValue + + // Ensure all items within min/max: + for (var i=0; i<items.length; ++i) { + if (i !== d.expandingIndex) { + item = items[i]; + // If the item is using percentage width, convert + // that number to real width now: + if (item.percentageWidth != undefined && item.percentageWidth !== -1) { + newValue = item.percentageWidth * (root.width / 100) + if (newValue !== item.width) + item.width = newValue + } + // Ensure item width is not more than maximumWidth: + if (item.maximumWidth != undefined && item.maximumWidth != -1) { + newValue = Math.min(item.width, item.maximumWidth) + if (newValue !== item.width) + item.width = newValue + } + // Ensure item width is not more less minimumWidth: + if (item.minimumWidth != undefined && item.minimumWidth != -1) { + newValue = Math.max(item.width, item.minimumWidth) + if (newValue !== item.width) + item.width = newValue + } + } + } + + // Special case: set width of expanding item to available space: + newValue = root.width - d.accumulatedWidth(0, items.length, false); + var expandingItem = items[d.expandingIndex] + if (expandingItem.minimumWidth != undefined && expandingItem.minimumWidth != -1) + newValue = Math.max(newValue, expandingItem.minimumWidth) + if (expandingItem.width !== newValue) + expandingItem.width = newValue + + // Then, position items and handles according to their width: + for (i=0; i<items.length; ++i) { + item = items[i]; + handle = handles[i] + + // Position item to the right of the previus handle: + if (prevHandle) { + newValue = prevHandle.x + prevHandle.width + if (newValue !== item.x) + item.x = newValue + } + + // Position handle to the right of item: + if (handle) { + newValue = item.x + Math.max(0, item.width) + if (newValue !== handle.x) + handle.x = newValue + } + + prevItem = item + prevHandle = handle + } + + d.updateOptimizationBlock = false + } + } + + Component { + id: handleBackgroundLoader + Loader { + id: loader + property int handleIndex: 0 + property Item handleDragTarget: loader + sourceComponent: handleBackground + + function handleDragged(handleIndex) + { + // Moving the handle means resizing an item. Which one, + // left or right, depends on where the expanding item is. + // 'updateLayout' will override in case new width violates max/min. + // And 'updateLayout will be triggered when an item changes width. + + var leftHandle, leftItem, handle, rightItem, rightHandle + var leftEdge, rightEdge, newWidth + + handle = handles[handleIndex] + + if (d.expandingIndex > handleIndex) { + // Resize item to the left. + // Ensure that the handle is not crossing other handles: + leftHandle = handles[handleIndex-1] + leftItem = items[handleIndex] + leftEdge = leftHandle ? (leftHandle.x + leftHandle.width) : 0 + handle.x = Math.max(leftEdge, handle.x) + newWidth = handle.x - leftEdge + if (root.width != 0 && leftItem.percentageWidth != undefined && leftItem.percentageWidth !== -1) + leftItem.percentageWidth = newWidth * (100 / root.width) + // The next line will trigger 'updateLayout' inside 'propertyChangeListener': + leftItem.width = newWidth + } else { + // Resize item to the right: + // Since the first item in the splitter always will have x=0, we need + // to ensure that the user cannot drag the handle more left than what + // we got space for: + var min = d.accumulatedWidth(0, handleIndex+1, true) + // Ensure that the handle is not crossing other handles: + rightItem = items[handleIndex+1] + rightHandle = handles[handleIndex+1] + rightEdge = (rightHandle ? rightHandle.x : root.width) + handle.x = Math.max(min, Math.max(Math.min((rightEdge - handle.width), handle.x))) + newWidth = rightEdge - (handle.x + handle.width) + if (root.width != 0 && rightItem.percentageWidth != undefined && rightItem.percentageWidth !== -1) + rightItem.percentageWidth = newWidth * (100 / root.width) + // The next line will trigger 'updateLayout' inside 'propertyChangeListener': + rightItem.width = newWidth + } + } + } + } + + Item { + id: splitterItems + anchors.fill: parent + } + Item { + id: splitterHandles + anchors.fill: parent + } + + Component { + // This dummy item becomes a child of all + // items it the splitter, just to provide a way + // to listed for changes to their width, expanding etc. + id: propertyChangeListener + Item { + id: target + width: parent.width + property bool expanding: (parent.expanding != undefined) ? parent.expanding : false + property real percentageWidth: (parent.percentageWidth != undefined) ? parent.percentageWidth : -1 + property real minimumWidth: (parent.minimumWidth != undefined) ? parent.minimumWidth : -1 + property real maximumWidth: (parent.maximumWidth != undefined) ? parent.maximumWidth : -1 + + onPercentageWidthChanged: d.updateLayout(); + onMinimumWidthChanged: d.updateLayout(); + onMaximumWidthChanged: d.updateLayout(); + + onExpandingChanged: { + // Find out which item that has the expanding flag: + for (var i=0; i<items.length; ++i) { + var item = items[i] + if (item.expanding && item.expanding === true) { + d.expandingIndex = i + d.updateLayout(); + return + } + } + d.expandingIndex = i-1 + updateLayout(); + } + + onWidthChanged: { + // We need to update the layout: + if (d.bindingRecursionGuard === true) + return + d.bindingRecursionGuard = true + + // Break binding: + width = 0 + d.updateLayout() + // Restablish binding: + width = function() { return parent.width; } + + d.bindingRecursionGuard = false + } + } + } +} diff --git a/lib/qtcreator/qtcomponents/custom/TextField.qml b/lib/qtcreator/qtcomponents/custom/TextField.qml new file mode 100644 index 0000000000..4790e54f4e --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/TextField.qml @@ -0,0 +1,158 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 +import "./behaviors" // TextEditMouseBehavior + +// KNOWN ISSUES +// 1) TextField does not loose focus when !enabled if it is a FocusScope (see QTBUG-16161) + +FocusScope { + id: textField + + property alias text: textInput.text + property alias font: textInput.font + + property int inputHint // values tbd + property bool acceptableInput: textInput.acceptableInput // read only + property bool readOnly: textInput.readOnly // read only + property alias placeholderText: placeholderTextComponent.text + property bool passwordMode: false + property alias selectedText: textInput.selectedText + property alias selectionEnd: textInput.selectionEnd + property alias selectionStart: textInput.selectionStart + property alias validator: textInput.validator + property alias inputMask: textInput.inputMask + property alias horizontalalignment: textInput.horizontalAlignment + property alias echoMode: textInput.echoMode + property alias cursorPosition: textInput.cursorPosition + property alias inputMethodHints: textInput.inputMethodHints + + property color textColor: syspal.text + property color backgroundColor: syspal.base + property alias containsMouse: mouseArea.containsMouse + + property Component background: null + property Component hints: null + property Item backgroundItem: backgroundLoader.item + + property int minimumWidth: 0 + property int minimumHeight: 0 + + property int leftMargin: 0 + property int topMargin: 0 + property int rightMargin: 0 + property int bottomMargin: 0 + + function copy() { + textInput.copy() + } + + function paste() { + textInput.paste() + } + + function cut() { + textInput.cut() + } + + function select(start, end) { + textInput.select(start, end) + } + + function selectAll() { + textInput.selectAll() + } + + function selectWord() { + textInput.selectWord() + } + + function positionAt(x) { + var p = mapToItem(textInput, x, 0); + return textInput.positionAt(p.x); + } + + function positionToRectangle(pos) { + var p = mapToItem(textInput, pos.x, pos.y); + return textInput.positionToRectangle(p); + } + + width: Math.max(minimumWidth, + textInput.width + leftMargin + rightMargin) + + height: Math.max(minimumHeight, + textInput.height + topMargin + bottomMargin) + + // Implementation + clip: true + + SystemPalette { id: syspal } + Loader { id: hintsLoader; sourceComponent: hints } + Loader { id: backgroundLoader; sourceComponent: background; anchors.fill:parent} + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + } + + TextInput { // see QTBUG-14936 + id: textInput + selectByMouse:true + font.pixelSize: hintsLoader.item != null ? hintsLoader.item.fontPixelSize: 14 + font.bold: hintsLoader.item != null ? hintsLoader.item.fontBold : false + + anchors.leftMargin: leftMargin + anchors.topMargin: topMargin + anchors.rightMargin: rightMargin + anchors.bottomMargin: bottomMargin + + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + + color: enabled ? textColor : Qt.tint(textColor, "#80ffffff") + echoMode: passwordMode ? _hints.passwordEchoMode : TextInput.Normal + } + + Text { + id: placeholderTextComponent + anchors.fill: textInput + font: textInput.font + opacity: !textInput.text.length && !textInput.activeFocus ? 1 : 0 + color: "gray" + text: "Enter text" + elide: Text.ElideRight + Behavior on opacity { NumberAnimation { duration: 90 } } + } +} diff --git a/lib/qtcreator/qtcomponents/custom/behaviors/ButtonBehavior.qml b/lib/qtcreator/qtcomponents/custom/behaviors/ButtonBehavior.qml new file mode 100644 index 0000000000..da8c49149b --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/behaviors/ButtonBehavior.qml @@ -0,0 +1,65 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 + +Item { + id: behavior + + signal clicked + property bool pressed: false // Can't be alias of mouseArea.pressed because the latter is read-only + property alias containsMouse: mouseArea.containsMouse + property bool checkable: false + property bool checked: false + property bool triState: false + signal mouseMoved + + onCheckableChanged: { if(!checkable) checked = false } + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + onPositionChanged: behavior.mouseMoved() + onPressed: behavior.pressed = true // needed when hover is enabled + onEntered: if(pressed && enabled) behavior.pressed = true + onExited: behavior.pressed = false + onCanceled: behavior.pressed = false // mouse stolen e.g. by Flickable + onReleased: { + if(behavior.pressed && behavior.enabled) { // No click if release outside area + behavior.pressed = false + if(behavior.checkable) + behavior.checked = !behavior.checked; + behavior.clicked() + } + } + } +} diff --git a/lib/qtcreator/qtcomponents/custom/behaviors/ModalPopupBehavior.qml b/lib/qtcreator/qtcomponents/custom/behaviors/ModalPopupBehavior.qml new file mode 100644 index 0000000000..0e5da2c311 --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/behaviors/ModalPopupBehavior.qml @@ -0,0 +1,122 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 + +// KNOWN ISSUES +// none + +Item { + id: popupBehavior + + property bool showing: false + property bool whenAlso: true // modifier to the "showing" property + property bool consumeCancelClick: true + property int delay: 0 // delay before popout becomes visible + property int deallocationDelay: 3000 // 3 seconds + + property Component popupComponent + + property alias popup: popupLoader.item // read-only + property alias window: popupBehavior.root // read-only + + signal prepareToShow + signal prepareToHide + signal cancelledByClick + + // implementation + + anchors.fill: parent + + onShowingChanged: notifyChange() + onWhenAlsoChanged: notifyChange() + function notifyChange() { + if(showing && whenAlso) { + if(popupLoader.sourceComponent == undefined) { + popupLoader.sourceComponent = popupComponent; + } + } else { + mouseArea.enabled = false; // disable before opacity is changed in case it has fading behavior + if(Qt.isQtObject(popupLoader.item)) { + popupBehavior.prepareToHide(); + popupLoader.item.opacity = 0; + } + } + } + + property Item root: findRoot() + function findRoot() { + var p = parent; + while(p.parent != undefined) + p = p.parent; + + return p; + } + + MouseArea { + id: mouseArea + anchors.fill: parent + enabled: false // enabled only when popout is showing + onPressed: { + popupBehavior.showing = false; + mouse.accepted = consumeCancelClick; + cancelledByClick(); + } + } + + Loader { + id: popupLoader + } + + Timer { // visibility timer + running: Qt.isQtObject(popupLoader.item) && showing && whenAlso + interval: delay + onTriggered: { + popupBehavior.prepareToShow(); + mouseArea.enabled = true; + popup.opacity = 1; + } + } + + Timer { // deallocation timer + running: Qt.isQtObject(popupLoader.item) && popupLoader.item.opacity == 0 + interval: deallocationDelay + onTriggered: popupLoader.sourceComponent = undefined + } + + states: State { + name: "active" + when: Qt.isQtObject(popupLoader.item) && popupLoader.item.opacity > 0 + ParentChange { target: popupBehavior; parent: root } + } + } + diff --git a/lib/qtcreator/qtcomponents/custom/components.pro b/lib/qtcreator/qtcomponents/custom/components.pro new file mode 100644 index 0000000000..be0663d709 --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/components.pro @@ -0,0 +1,49 @@ +TEMPLATE = subdirs # XXX: Avoid call the linker +TARGETPATH = Qt/labs/components/custom + +symbian { + INSTALL_IMPORTS = /resource/qt/imports +} else { + INSTALL_IMPORTS = $$[QT_INSTALL_IMPORTS] +} + +QML_FILES = \ + qmldir \ + BasicButton.qml \ + BusyIndicator.qml \ + ButtonBlock.qml \ + ButtonColumn.qml \ + ButtonRow.qml \ + ButtonGroup.js \ + Button.qml \ + CheckBox.qml \ + ChoiceList.qml \ + ProgressBar.qml \ + RadioButton.qml \ + ScrollDecorator.qml \ + ScrollIndicator.qml \ + Slider.qml \ + SpinBox.qml \ + Switch.qml \ + TextArea.qml \ + TextField.qml + +QML_DIRS = \ + behaviors \ + private \ + styles \ + visuals + +qmlfiles.files = $$QML_FILES +qmlfiles.sources = $$QML_FILES +qmlfiles.path = $$INSTALL_IMPORTS/$$TARGETPATH + +qmldirs.files = $$QML_DIRS +qmldirs.sources = $$QML_DIRS +qmldirs.path = $$INSTALL_IMPORTS/$$TARGETPATH + +INSTALLS += qmlfiles qmldirs + +symbian { + DEPLOYMENT += qmlfiles qmldirs +} diff --git a/lib/qtcreator/qtcomponents/custom/private/ChoiceListPopup.qml b/lib/qtcreator/qtcomponents/custom/private/ChoiceListPopup.qml new file mode 100644 index 0000000000..5445fdc165 --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/private/ChoiceListPopup.qml @@ -0,0 +1,355 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +import QtQuick 1.0 + +MouseArea { + id: popup + + // There is no global z-ordering that can stack this popup in front, so we + // need to reparent it to the root item to fake it upon showing the popup. + // In that case, the popup will also fill the whole window to allow the user to + // close the popup by clicking anywhere in the window. Letting the popup act as the mouse + // area for the button that 'owns' it is also nessesary to support drag'n'release behavior. + + // The 'popupframe' delegate will be told to show or hide by assigning + // opacity to 1 or 0, respectively. + + anchors.fill: parent + hoverEnabled: true + + + + // Set 'popupOpen' to show/hide the popup. The 'state' property is more + // internal, and contains additional states used to protect the popup from + // e.g. receiving mouse clicks while its about to hide etc. + property bool popupOpen: false + + property bool desktopBehavior: true + property int previousCurrentIndex: -1 + property alias model: listView.model + property alias currentIndex: listView.currentIndex + property string currentText: model && currentIndex >= 0 ? model.get(currentIndex).text : "" + + // buttonPressed will be true when the mouse press starts + // while the popup is closed. At that point, this component can be + // seen as a button, and not yet a popup menu: + property bool buttonPressed: false + + property Component listItem + property Component listHighlight + property Component popupFrame + + property Item originalParent: parent + + onPopupOpenChanged: { + if (popupFrameLoader.item === null) + return; + if (popupOpen) { + var oldMouseX = mouseX + + // Reparent to root, so the popup stacks in front: + originalParent = parent; + var p = parent; + while (p.parent != undefined) + p = p.parent + parent = p; + + previousCurrentIndex = currentIndex; + positionPopup(); + popupFrameLoader.item.opacity = 1; + if (oldMouseX === mouseX){ + // Work around bug: mouseX and mouseY does not immidiatly + // update after reparenting and resizing the mouse area: + var pos = originalParent.mapToItem(parent, mouseX, mouseY) + highlightItemAt(pos.x, pos.y); + } else { + highlightItemAt(mouseX, mouseY); + } + listView.forceActiveFocus(); + state = "popupOpen" + } else { + popupFrameLoader.item.opacity = 0; + popup.hideHighlight(); + state = "popupClosed" + } + } + + Component.onCompleted: { + // In case 'popupOpen' was set to 'true' before + // 'popupFrameLoader' was finished, we open the popup now instead: + if (popup.popupOpen){ + popup.popupOpen = false + popup.popupOpen = true + } + } + + function highlightItemAt(posX, posY) + { + var mappedPos = mapToItem(listView.contentItem, posX, posY); + var indexAt = listView.indexAt(mappedPos.x, mappedPos.y); + if (indexAt == listView.highlightedIndex) + return; + if (indexAt >= 0) { + listView.highlightedIndex = indexAt; + } else { + if(posY > listView.y+listView.height && listView.highlightedIndex+1 < listView.count ) { + listView.highlightedIndex++; + } else if(posY < listView.y && listView.highlightedIndex > 0) { + listView.highlightedIndex--; + } else if(posX < popupFrameLoader.x || posX > popupFrameLoader.x+popupFrameLoader.width) { + popup.hideHighlight(); + } + } + } + + function hideHighlight() { + listView.highlightedIndex = -1; + listView.highlightedItem = null; // will trigger positionHighlight() what will hide the highlight + } + + function positionPopup() { + // Set initial values to top left corner of original parent: + var globalPos = mapFromItem(originalParent, 0, 0); + var newX = globalPos.x; + var newY = globalPos.y + var newW = originalParent.width; + var newH = listView.contentHeight + + switch (popupFrameLoader.item.popupLocation) { + case "center": + // Show centered over original parent with respect to selected item: + var itemHeight = Math.max(listView.contentHeight/listView.count, 0); + var currentItemY = Math.max(currentIndex*itemHeight, 0); + currentItemY += Math.floor(itemHeight/2 - choiceList.height/2); // correct for choiceLists that are higher than items in the list + newY -= currentItemY; + break; + case "below": + case "": + // Show below original parent: + newX -= popupFrameLoader.anchors.leftMargin; + newY += originalParent.height - popupFrameLoader.anchors.topMargin; + break; + } + + // Ensure the popup is inside the window: + if (newX < popupFrameLoader.anchors.leftMargin) + newX = popupFrameLoader.anchors.leftMargin; + else if (newX + newW > popup.width - popupFrameLoader.anchors.rightMargin) + newX = popup.width - popupFrameLoader.anchors.rightMargin - newW; + + if (newY < popupFrameLoader.anchors.topMargin) + newY = popupFrameLoader.anchors.topMargin; + else if (newY + newH > popup.height - popupFrameLoader.anchors.bottomMargin) + newY = popup.height - popupFrameLoader.anchors.bottomMargin - newH; + + // Todo: handle case when the list itself is larger than the window... + + listView.x = newX + listView.y = newY + listView.width = newW + listView.height = newH + } + + Loader { + id: popupFrameLoader + property alias styledItem: popup.originalParent + anchors.fill: listView + anchors.leftMargin: -item.anchors.leftMargin + anchors.rightMargin: -item.anchors.rightMargin + anchors.topMargin: -item.anchors.topMargin + anchors.bottomMargin: -item.anchors.bottomMargin + sourceComponent: popupFrame + onItemChanged: item.opacity = 0 + } + + ListView { + id: listView + focus: true + opacity: popupFrameLoader.item.opacity + boundsBehavior: desktopBehavior ? ListView.StopAtBounds : ListView.DragOverBounds + keyNavigationWraps: !desktopBehavior + highlightFollowsCurrentItem: false // explicitly handled below + + interactive: !desktopBehavior // disable flicking. also disables key handling + onCurrentItemChanged: { + if(desktopBehavior) { + positionViewAtIndex(currentIndex, ListView.Contain); + } + } + + property int highlightedIndex: -1 + onHighlightedIndexChanged: positionViewAtIndex(highlightedIndex, ListView.Contain) + + property variant highlightedItem: null + onHighlightedItemChanged: { + if(desktopBehavior) { + positionHighlight(); + } + } + + function positionHighlight() { + if(!Qt.isQtObject(highlightItem)) + return; + + if(!Qt.isQtObject(highlightedItem)) { + highlightItem.opacity = 0; // hide when no item is highlighted + } else { + highlightItem.x = highlightedItem.x; + highlightItem.y = highlightedItem.y; + highlightItem.width = highlightedItem.width; + highlightItem.height = highlightedItem.height; + highlightItem.opacity = 1; // show once positioned + } + } + + delegate: Item { + id: itemDelegate + width: delegateLoader.item.width + height: delegateLoader.item.height + property int theIndex: index // for some reason the loader can't bind directly to 'index' + + Loader { + id: delegateLoader + property variant model: listView.model + property alias index: itemDelegate.theIndex + property Item styledItem: choiceList + property bool highlighted: theIndex == listView.highlightedIndex + property string itemText: popup.model.get(theIndex).text + sourceComponent: listItem + } + + states: State { + name: "highlighted" + when: index == listView.highlightedIndex + StateChangeScript { + script: { + if(Qt.isQtObject(listView.highlightedItem)) { + listView.highlightedItem.yChanged.disconnect(listView.positionHighlight); + } + listView.highlightedItem = itemDelegate; + listView.highlightedItem.yChanged.connect(listView.positionHighlight); + } + } + + } + } + + function firstVisibleItem() { return indexAt(contentX+10,contentY+10); } + function lastVisibleItem() { return indexAt(contentX+width-10,contentY+height-10); } + function itemsPerPage() { return lastVisibleItem() - firstVisibleItem(); } + + Keys.onPressed: { + // with the ListView !interactive (non-flicking) we have to handle arrow keys + if (event.key == Qt.Key_Up) { + if(!highlightedItem) highlightedIndex = lastVisibleItem(); + else if(highlightedIndex > 0) highlightedIndex--; + } else if (event.key == Qt.Key_Down) { + if(!highlightedItem) highlightedIndex = firstVisibleItem(); + else if(highlightedIndex+1 < model.count) highlightedIndex++; + } else if (event.key == Qt.Key_PageUp) { + if(!highlightedItem) highlightedIndex = lastVisibleItem(); + else highlightedIndex = Math.max(highlightedIndex-itemsPerPage(), 0); + } else if (event.key == Qt.Key_PageDown) { + if(!highlightedItem) highlightedIndex = firstVisibleItem(); + else highlightedIndex = Math.min(highlightedIndex+itemsPerPage(), model.count-1); + } else if (event.key == Qt.Key_Home) { + highlightedIndex = 0; + } else if (event.key == Qt.Key_End) { + highlightedIndex = model.count-1; + } else if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { + if(highlightedIndex != -1) { + listView.currentIndex = highlightedIndex; + } else { + listView.currentIndex = popup.previousCurrentIndex; + } + + popup.popupOpen = false; + } else if (event.key == Qt.Key_Escape) { + listView.currentIndex = popup.previousCurrentIndex; + popup.popupOpen = false; + } + event.accepted = true; // consume all keys while popout has focus + } + + highlight: popup.listHighlight + } + + Timer { + // This is the time-out value for when we consider the + // user doing a press'n'release, and not just a click to + // open the popup: + id: pressedTimer + interval: 400 // Todo: fetch value from style object + } + + onPressed: { + if (state == "popupClosed") { + // Show the popup: + pressedTimer.running = true + popup.popupOpen = true + popup.buttonPressed = true + } + } + + onReleased: { + if (state == "popupOpen" && pressedTimer.running === false) { + // Either we have a 'new' click on the popup, or the user has + // done a drag'n'release. In either case, the user has done a selection: + var mappedPos = mapToItem(listView.contentItem, mouseX, mouseY); + var indexAt = listView.indexAt(mappedPos.x, mappedPos.y); + if(indexAt != -1) + listView.currentIndex = indexAt; + popup.popupOpen = false + } + popup.buttonPressed = false + } + + onPositionChanged: { + if (state == "popupOpen") + popup.highlightItemAt(mouseX, mouseY) + } + + states: [ + State { + name: "popupClosed" + when: popupFrameLoader.item.opacity === 0; + StateChangeScript { + script: parent = originalParent; + } + } + ] +} + + + + diff --git a/lib/qtcreator/qtcomponents/custom/qmldir b/lib/qtcreator/qtcomponents/custom/qmldir new file mode 100644 index 0000000000..8da1fd80f0 --- /dev/null +++ b/lib/qtcreator/qtcomponents/custom/qmldir @@ -0,0 +1,14 @@ +RangeModel 1.0 RangeModel.qml +BasicButton 1.0 BasicButton.qml +BusyIndicator 1.0 BusyIndicator.qml +ButtonBlock 1.0 ButtonBlock.qml +Button 1.0 Button.qml +ButtonColumn 1.0 ButtonColumn.qml +ButtonRow 1.0 ButtonRow.qml +CheckBox 1.0 CheckBox.qml +ChoiceList 1.0 ChoiceList.qml +ProgressBar 1.0 ProgressBar.qml +Slider 1.0 Slider.qml +SpinBox 1.0 SpinBox.qml +TextField 1.0 TextField.qml +GroupBox 1.0 GroupBox.qml diff --git a/lib/qtcreator/qtcomponents/images/folder_new.png b/lib/qtcreator/qtcomponents/images/folder_new.png Binary files differnew file mode 100644 index 0000000000..8d8bb9bd76 --- /dev/null +++ b/lib/qtcreator/qtcomponents/images/folder_new.png diff --git a/lib/qtcreator/qtcomponents/qmldir b/lib/qtcreator/qtcomponents/qmldir new file mode 100644 index 0000000000..d33a7971d7 --- /dev/null +++ b/lib/qtcreator/qtcomponents/qmldir @@ -0,0 +1,27 @@ +Slider 1.0 Slider.qml +SpinBox 1.0 SpinBox.qml +GroupBox 1.0 GroupBox.qml +Button 1.0 Button.qml +ToolBar 1.0 ToolBar.qml +TabFrame 1.0 TabFrame.qml +TabBar 1.0 TabBar.qml +Tab 1.0 Tab.qml +ScrollArea 1.0 ScrollArea.qml +ScrollBar 1.0 ScrollBar.qml +ChoiceList 1.0 ChoiceList.qml +ToolButton 1.0 ToolButton.qml +TextArea 1.0 TextArea.qml +TextField 1.0 TextField.qml +ProgressBar 1.0 ProgressBar.qml +ButtonRow 1.0 ButtonRow.qml +ButtonColumn 1.0 ButtonColumn.qml +SplitterRow 1.0 SplitterRow.qml +Dial 1.0 Dial.qml +TableView 1.0 TableView.qml +CheckBox 1.0 CheckBox.qml +RadioButton 1.0 RadioButton.qml +plugin styleplugin plugin +TableColumn 1.0 TableColumn.qml +ContextMenu 1.0 ContextMenu.qml +Menu 1.0 Menu.qml +MenuItem 1.0 MenuItem.qml diff --git a/lib/qtcreator/qtcomponents/qtcomponents.pro b/lib/qtcreator/qtcomponents/qtcomponents.pro new file mode 100644 index 0000000000..9a3dc0e67f --- /dev/null +++ b/lib/qtcreator/qtcomponents/qtcomponents.pro @@ -0,0 +1,57 @@ +include(../../../qtcreator.pri) + +TEMPLATE = app +TARGET = phony_target3 +CONFIG -= qt separate_debug_info gdb_dwarf_index +QT = +LIBS = +macx:CONFIG -= app_bundle + +isEmpty(vcproj) { + QMAKE_LINK = @: IGNORE THIS LINE + OBJECTS_DIR = + win32:CONFIG -= embed_manifest_exe +} else { + CONFIG += console + PHONY_DEPS = . + phony_src.input = PHONY_DEPS + phony_src.output = phony.c + phony_src.variable_out = GENERATED_SOURCES + phony_src.commands = echo int main() { return 0; } > phony.c + phony_src.name = CREATE phony.c + phony_src.CONFIG += combine + QMAKE_EXTRA_COMPILERS += phony_src +} + +DATA_FILE_PATTERNS = \ + $$PWD/*.qml \ + $$PWD/qmldir \ + $$PWD/images/* \ + $$PWD/custom/* \ + $$PWD/custom/behaviors/* \ + $$PWD/custom/private/* + +!isEmpty(copydata) { + + for(data_file, DATA_FILE_PATTERNS) { + files = $$files($$data_file, false) + win32:files ~= s|\\\\|/|g + for(file, files):!exists($$file/*):FILES += $$file + } + + OTHER_FILES += $$FILES + copy2build.input = FILES + copy2build.output = $$IDE_LIBRARY_PATH/qtcomponents/${QMAKE_FUNC_FILE_IN_stripSrcDir} + isEmpty(vcproj):copy2build.variable_out = PRE_TARGETDEPS + win32:copy2build.commands = $$QMAKE_COPY \"${QMAKE_FILE_IN}\" \"${QMAKE_FILE_OUT}\" + unix:copy2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} + copy2build.name = COPY ${QMAKE_FILE_IN} + copy2build.CONFIG += no_link + QMAKE_EXTRA_COMPILERS += copy2build +} + +!macx { + qmlfiles.files = $$PWD/*.qml $$PWD/qmldir $$PWD/images $$PWD/custom + qmlfiles.path = /lib/qtcreator/qtcomponents + INSTALLS += qmlfiles +} |