diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-11-25 07:49:42 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-11-25 07:49:42 (GMT) |
commit | 4c7df87f77c1bfda4290f729dd2ed993eadb5362 (patch) | |
tree | aa9ca0d0114ffa9e7e65311a80b4f01d72c2d1eb | |
parent | 75dc9f4475f93e149376c680cc23655b16774174 (diff) | |
parent | b74e226c09bc37043a06b24029e0e22e4f3cdd16 (diff) | |
download | Qt-4c7df87f77c1bfda4290f729dd2ed993eadb5362.zip Qt-4c7df87f77c1bfda4290f729dd2ed993eadb5362.tar.gz Qt-4c7df87f77c1bfda4290f729dd2ed993eadb5362.tar.bz2 |
Merge branch 'kinetic-declarativeui' of scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
41 files changed, 494 insertions, 203 deletions
diff --git a/demos/declarative/webbrowser/webbrowser.qml b/demos/declarative/webbrowser/webbrowser.qml index bfc0749..105bb07 100644 --- a/demos/declarative/webbrowser/webbrowser.qml +++ b/demos/declarative/webbrowser/webbrowser.qml @@ -222,6 +222,8 @@ Item { onDoubleClick: { if (!heuristicZoom(clickX,clickY,2.5)) { var zf = flickable.width > 980 ? 1 : flickable.width/980; + if (zf > zoomFactor) + zf = 2.0 // zoom in (else zooming out) doZoom(zf,clickX/zoomFactor*zf,clickY/zoomFactor*zf) } } diff --git a/doc/src/declarative/advtutorial2.qdoc b/doc/src/declarative/advtutorial2.qdoc index 40a760d..dcc7c70 100644 --- a/doc/src/declarative/advtutorial2.qdoc +++ b/doc/src/declarative/advtutorial2.qdoc @@ -93,7 +93,7 @@ To hook this code up to the \e{New Game} button, you alter it as below: \snippet declarative/tutorials/samegame/samegame2/samegame.qml 1 -We have just replaced the \c{onClicked: print("Implement me!")} with \c{onClicked: initBoard()}. +We have just replaced the \c{onClicked: console.log("Implement me!")} with \c{onClicked: initBoard()}. Note that in order to have the function available, you'll need to include the script in the main file, by adding a script element to it. diff --git a/doc/src/declarative/animation.qdoc b/doc/src/declarative/animation.qdoc index d05a444..bf5907d 100644 --- a/doc/src/declarative/animation.qdoc +++ b/doc/src/declarative/animation.qdoc @@ -49,6 +49,8 @@ real, int, color, rect, point, and size can all be animated. QML supports three different forms of animation - basic property animation, transitions, and property behaviors. +\tableofcontents + \section1 Basic Property Animation The simplest form of animation is directly using \l PropertyAnimation, which can animate all of the property diff --git a/doc/src/declarative/ecmascriptblocks.qdoc b/doc/src/declarative/ecmascriptblocks.qdoc index 815c68c..6ee5a8e 100644 --- a/doc/src/declarative/ecmascriptblocks.qdoc +++ b/doc/src/declarative/ecmascriptblocks.qdoc @@ -168,7 +168,7 @@ is illegal in QML. // Illegal modification of undeclared variable a = 1; for (var ii = 1; ii < 10; ++ii) a = a * ii; -print("Result: " + a); + console.log("Result: " + a); \endcode It can be trivially modified to this legal code. @@ -176,7 +176,7 @@ It can be trivially modified to this legal code. \code var a = 1; for (var ii = 1; ii < 10; ++ii) a = a * ii; -print("Result: " + a); + console.log("Result: " + a); \endcode Any attempt to modify the global object - either implicitly or explicitly - will diff --git a/doc/src/declarative/example-slideswitch.qdoc b/doc/src/declarative/example-slideswitch.qdoc index c942918..492a8ea 100644 --- a/doc/src/declarative/example-slideswitch.qdoc +++ b/doc/src/declarative/example-slideswitch.qdoc @@ -127,8 +127,11 @@ For more information on scripts see \l{qmlecmascript.html}{ECMAScript Blocks}. \snippet examples/declarative/slideswitch/content/Switch.qml 7 At this point, when the switch toggles between the two states the knob will instantly change its \c x position between 1 and 78. -In order for the the knob to move smoothly we add a transistion that will animate the \c x property with an easing curve for a duration of 200ms. +In order for the the knob to move smoothly we add a transition that will animate the \c x property with an easing curve for a duration of 200ms. For more information on transitions see \l{state-transitions}{QML Transitions}. +\section1 Usage +The switch can be used in a QML file, like this: +\snippet examples/declarative/slideswitch/slideswitch.qml 0 */ diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 7a9de60..056b8ab 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -531,7 +531,7 @@ in the bind engine for allowing an object to access the binding directly. If a binding is assigned to a property with a type of QmlBinding pointer (ie. \c {QmlBinding *}), each time the binding value changes, -a QmlBinding instance is assigned to that property. The QmlBinding instance +a QmlBinding instance is assigned to that property. The QmlBinding instance allows the object to read the binding and to evaluate the binding's current value. \section1 Extension Objects @@ -548,16 +548,16 @@ directly, if this is either not possible or is complicated by some other concerns, extension objects allow limited extension possibilities without direct modifications. -Extension objects are used to add additional properties to an existing type. -Extension objects can only add properties, not signals or methods. An extended -type definition allows the programmer to supply an additional type - known as the -extension type - when registering the target class whose properties are +Extension objects are used to add additional properties to an existing type. +Extension objects can only add properties, not signals or methods. An extended +type definition allows the programmer to supply an additional type - known as the +extension type - when registering the target class whose properties are transparently merged with the original target class when used from within QML. -An extension class is a regular QObject, with a constructor that takes a QObject -pointer. When needed (extension classes are delay created until the first extended -property is accessed) the extension class is created and the target object is -passed in as the parent. When an extended property on the original is accessed, +An extension class is a regular QObject, with a constructor that takes a QObject +pointer. When needed (extension classes are delay created until the first extended +property is accessed) the extension class is created and the target object is +passed in as the parent. When an extended property on the original is accessed, the appropriate property on the extension object is used instead. When an extended type is installed, one of the @@ -565,22 +565,22 @@ When an extended type is installed, one of the #define QML_DEFINE_EXTENDED_TYPE(URI, VMAJ, VFROM, VTO, QmlName,T, ExtendedT) #define QML_DEFINE_EXTENDED_NOCREATE_TYPE(T, ExtendedT) \endcode -macros should be used instead of the regular \c QML_DEFINE_TYPE or -\c QML_DEFINE_NOCREATE_TYPE. The arguments are identical to the corresponding -non-extension object macro, except for the ExtendedT parameter which is the type +macros should be used instead of the regular \c QML_DEFINE_TYPE or +\c QML_DEFINE_NOCREATE_TYPE. The arguments are identical to the corresponding +non-extension object macro, except for the ExtendedT parameter which is the type of the extension object. \section1 Optimization -Often to develop high performance elements it is helpful to know more about the -status of the QML engine. For example, it might be beneficial to delay -initializing some costly data structures until after all the properties have been +Often to develop high performance elements it is helpful to know more about the +status of the QML engine. For example, it might be beneficial to delay +initializing some costly data structures until after all the properties have been set. The QML engine defines an interface class called QmlParserStatus, which contains a -number of virtual methods that are invoked at various stages during component -instantiation. To receive these notifications, an element implementation inherits -QmlParserStatus and notifies the Qt meta system using the Q_INTERFACES() macro. +number of virtual methods that are invoked at various stages during component +instantiation. To receive these notifications, an element implementation inherits +QmlParserStatus and notifies the Qt meta system using the Q_INTERFACES() macro. For example, @@ -636,7 +636,7 @@ declaring a new property, and the corresponding C++ type. \row \o variant \o QVariant \endtable -QML supports two methods for adding a new property to a type - a new property +QML supports two methods for adding a new property to a type: a new property definition, and a property alias. \section2 Property definitions @@ -691,6 +691,7 @@ controls the color of the inner rectangle. } \endcode +\target qml-property-aliases \section2 Property aliases Property aliases are a more advanced form of property declaration. Unlike a @@ -714,11 +715,12 @@ binding, the alias reference syntax is highly restricted. An alias reference takes one of the following forms \code - <Id>.<property> - <Id> + <id>.<property> + <id> \endcode -where <Id> must refer to an object id within the same component as the type -declaring the alias, and, optionally, <property> refers to a property on that object. + +where <id> must refer to an object id within the same component as the type +declaring the alias, and, optionally, <property> refers to a property on that object. Here is the property definition example rewritten to use property aliases. \code @@ -843,7 +845,7 @@ This example adds a new method that behaves like a child: \code Item { function say(text) { - print("You said " + text); + console.log("You said " + text); } } \endcode diff --git a/doc/src/declarative/focus.qdoc b/doc/src/declarative/focus.qdoc index 8061a7c..46bfc38 100644 --- a/doc/src/declarative/focus.qdoc +++ b/doc/src/declarative/focus.qdoc @@ -49,6 +49,8 @@ focused QML \l Item. To facilitate the construction of reusable components and to address some of the cases unique to fluid user interfaces, the QML items add a \e scope based extension to Qt's traditional keyboard focus model. +\tableofcontents + \section1 Key Handling Overview When the user presses or releases a key, the following occurs: @@ -65,7 +67,7 @@ item and thus subsequently be \l {QEvent::ignore()}{ignored}. \code Item { Item { - Keys.onPressed: if (event.key == Qt.Key_A) { print('Key A was pressed'); event.accepted = true } + Keys.onPressed: if (event.key == Qt.Key_A) { console.log('Key A was pressed'); event.accepted = true } Rectangle {} } } @@ -305,7 +307,7 @@ Rectangle { Text { focus: true text: name - Keys.onReturnPressed: print(name) + Keys.onReturnPressed: console.log(name) } } } diff --git a/doc/src/declarative/globalobject.qdoc b/doc/src/declarative/globalobject.qdoc index e3c8b9a..3eadec2 100644 --- a/doc/src/declarative/globalobject.qdoc +++ b/doc/src/declarative/globalobject.qdoc @@ -182,7 +182,7 @@ such as ListView, \l Repeater and \l Loader. sprite = component.createObject(); if(sprite == 0){ // Error Handling - print(component.errorsString()); + console.log(component.errorsString()); }else{ sprite.parent = page; sprite.x = 200; diff --git a/doc/src/declarative/qmlintro.qdoc b/doc/src/declarative/qmlintro.qdoc index 78462db..76d915f 100644 --- a/doc/src/declarative/qmlintro.qdoc +++ b/doc/src/declarative/qmlintro.qdoc @@ -311,7 +311,7 @@ any visual Item, for example: \code Item { focus: true - Keys.onSelectPressed: print("Selected") + Keys.onSelectPressed: console.log("Selected") } \endcode @@ -323,7 +323,7 @@ and click: \code MouseRegion { - onPressed: print("mouse button pressed") + onPressed: console.log("mouse button pressed") } \endcode @@ -335,7 +335,7 @@ the MouseRegion onPressed signal handler has a \e mouse parameter: \code MouseRegion { acceptedButtons: Qt.LeftButton | Qt.RightButton - onPressed: if (mouse.button == Qt.RightButton) print("Right mouse button pressed") + onPressed: if (mouse.button == Qt.RightButton) console.log("Right mouse button pressed") } \endcode diff --git a/doc/src/declarative/qmlstates.qdoc b/doc/src/declarative/qmlstates.qdoc index ddb0fc8..245a57f 100644 --- a/doc/src/declarative/qmlstates.qdoc +++ b/doc/src/declarative/qmlstates.qdoc @@ -3,6 +3,8 @@ \target qmlstates \title QML States +\section1 Overview + QML states typically describe user interface configurations, including: \list \o What UI elements are present @@ -14,10 +16,12 @@ A state can also be thought of as a set of batched changes from a default config Examples of states in modern UI: \list -\o A Contacts application has a 'View Contact' state and an 'Edit Contact' State. In the first state the information presented is static (using labels), and in the second it is editable (using editors). -\o A button has a pressed and unpressed state. When pressed the text moves down and to the right, and the button has a slightly darker appearance. +\o An Address Book application with a 'View Contact' state and an 'Edit Contact' State. In the first state the contact information presented is read-only (using labels), and in the second it is editable (using editors). +\o A button with a pressed and unpressed state. When pressed the text moves slightly down and to the right, and the button has a slightly darker appearance. \endlist +\section1 States in QML + In QML: \list \o Any object can use states. @@ -25,29 +29,38 @@ In QML: \o A state can affect the properties of other objects, not just the object owning the state (and not just that object's children). \endlist -The following example shows a simple use of states. In the default state \c myrect is positioned at 0,0. In the 'moved' state it is positioned at 50,50. +Here is an example of using states. In the default state \c myRect is positioned at 0,0. In the 'moved' state it is positioned at 50,50. Clicking within the mouse region changes the state from the default state to the 'moved' state. -\code +\qml Item { + id: myItem + Rectangle { - id: myrect + id: myRect width: 100 height: 100 + color: "red" } + states: [ State { name: "moved" PropertyChanges { - target: myrect + target: myRect x: 50 y: 50 } } ] + + MouseRegion { + anchors.fill: parent + onClicked: myItem.state = 'moved' + } } -\endcode +\endqml -To animate state changes, you can use \l{state-transitions}{transitions}. +State changes can be animated using \l{state-transitions}{transitions}. Other things you can do in a state change: \list diff --git a/doc/src/declarative/scope.qdoc b/doc/src/declarative/scope.qdoc index f7f25f5..ef30f94 100644 --- a/doc/src/declarative/scope.qdoc +++ b/doc/src/declarative/scope.qdoc @@ -43,6 +43,8 @@ \page qmlscope.html \title QML Scope +\tableofcontents + \l {Property Binding}s and \l {ECMAScript Blocks} are executed in a scope chain automatically established by QML when a component instance is constructed. QML is a \e {dynamically scoped} language. Different object instances instantiated from the same component can exist in diff --git a/examples/declarative/progressbar/ProgressBar.qml b/examples/declarative/progressbar/content/ProgressBar.qml index 302caa9..bfc801c 100644 --- a/examples/declarative/progressbar/ProgressBar.qml +++ b/examples/declarative/progressbar/content/ProgressBar.qml @@ -11,17 +11,17 @@ Item { property alias secondColor: g2.color BorderImage { - source: "images/lineedit-bg.png" + source: "background.png" width: parent.width; height: parent.height border.left: 4; border.top: 4; border.right: 4; border.bottom: 4 } Rectangle { - property int widthDest: (progressbar.width * (value - minimum)) / (maximum - minimum) - 6 - id: highlight; radius: 2 + property int widthDest: ((progressbar.width * (value - minimum)) / (maximum - minimum) - 6) + id: highlight; radius: 1 anchors.left: parent.left; anchors.top: parent.top; anchors.bottom: parent.bottom anchors.leftMargin: 3; anchors.topMargin: 3; anchors.bottomMargin: 3 - width: EaseFollow { source: highlight.widthDest; duration: 1000 } + width: EaseFollow { source: highlight.widthDest; velocity: 1200 } gradient: Gradient { GradientStop { id: g1; position: 0.0 } GradientStop { id: g2; position: 1.0 } diff --git a/examples/declarative/progressbar/images/lineedit-bg.png b/examples/declarative/progressbar/content/background.png Binary files differindex 9044226..9044226 100644 --- a/examples/declarative/progressbar/images/lineedit-bg.png +++ b/examples/declarative/progressbar/content/background.png diff --git a/examples/declarative/progressbar/main.qml b/examples/declarative/progressbar/main.qml deleted file mode 100644 index 32353fc..0000000 --- a/examples/declarative/progressbar/main.qml +++ /dev/null @@ -1,23 +0,0 @@ -import Qt 4.6 - -Rectangle { - id: main - width: 800; height: 580; color: "#edecec" - - Flickable { - anchors.fill: parent; viewportHeight: column.height - Column { - id: column; spacing: 4 - Repeater { - model: 50 - ProgressBar { - property int r: Math.floor(Math.random() * 4000 + 1000) - width: main.width - value: NumberAnimation { duration: r; from: 0; to: 100; running: true; repeat: true } - color: ColorAnimation { duration: r; from: "lightsteelblue"; to: "thistle"; running: true; repeat: true } - secondColor: ColorAnimation { duration: r; from: "steelblue"; to: "#CD96CD"; running: true; repeat: true } - } - } - } - } -} diff --git a/examples/declarative/progressbar/progressbars.qml b/examples/declarative/progressbar/progressbars.qml new file mode 100644 index 0000000..6de8ecf --- /dev/null +++ b/examples/declarative/progressbar/progressbars.qml @@ -0,0 +1,24 @@ +import Qt 4.6 +import "content" + +Rectangle { + id: main + width: 600; height: 405; color: "#edecec" + + Flickable { + anchors.fill: parent; viewportHeight: column.height + 20 + Column { + id: column; x: 10; y: 10; spacing: 10 + Repeater { + model: 25 + ProgressBar { + property int r: Math.floor(Math.random() * 5000 + 1000) + width: main.width - 20 + value: NumberAnimation { duration: r; from: 0; to: 100; running: true; repeat: true } + color: ColorAnimation { duration: r; from: "lightsteelblue"; to: "thistle"; running: true; repeat: true } + secondColor: ColorAnimation { duration: r; from: "steelblue"; to: "#CD96CD"; running: true; repeat: true } + } + } + } + } +} diff --git a/examples/declarative/slideswitch/slideswitch.qml b/examples/declarative/slideswitch/slideswitch.qml index 9b46cd1..396749f 100644 --- a/examples/declarative/slideswitch/slideswitch.qml +++ b/examples/declarative/slideswitch/slideswitch.qml @@ -5,7 +5,7 @@ Rectangle { color: "white" width: 400; height: 250 - Switch { - anchors.centerIn: parent - } +//![0] + Switch { anchors.centerIn: parent; on: false } +//![0] } diff --git a/examples/declarative/tutorials/helloworld/Cell.qml b/examples/declarative/tutorials/helloworld/Cell.qml index ab6e565..c38b40e 100644 --- a/examples/declarative/tutorials/helloworld/Cell.qml +++ b/examples/declarative/tutorials/helloworld/Cell.qml @@ -8,7 +8,7 @@ Item { property alias color: rectangle.color //![4] //![5] - signal clicked(string color) + signal clicked(color color) //![5] width: 40; height: 25 diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp index 61b6ecc..8642476 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp @@ -349,9 +349,13 @@ QmlGraphicsItem *QmlGraphicsAnchors::fill() const void QmlGraphicsAnchors::setFill(QmlGraphicsItem *f) { Q_D(QmlGraphicsAnchors); + if (d->fill == f) + return; + if (!f) { d->remDepend(d->fill); d->fill = f; + emit fillChanged(); return; } if (f != d->item->parentItem() && f->parentItem() != d->item->parentItem()){ @@ -361,10 +365,15 @@ void QmlGraphicsAnchors::setFill(QmlGraphicsItem *f) d->remDepend(d->fill); d->fill = f; d->addDepend(d->fill); - + emit fillChanged(); d->fillChanged(); } +void QmlGraphicsAnchors::resetFill() +{ + setFill(0); +} + QmlGraphicsItem *QmlGraphicsAnchors::centerIn() const { Q_D(const QmlGraphicsAnchors); @@ -374,9 +383,13 @@ QmlGraphicsItem *QmlGraphicsAnchors::centerIn() const void QmlGraphicsAnchors::setCenterIn(QmlGraphicsItem* c) { Q_D(QmlGraphicsAnchors); + if (d->centerIn == c) + return; + if (!c) { d->remDepend(d->centerIn); d->centerIn = c; + emit centerInChanged(); return; } if (c != d->item->parentItem() && c->parentItem() != d->item->parentItem()){ @@ -387,10 +400,15 @@ void QmlGraphicsAnchors::setCenterIn(QmlGraphicsItem* c) d->remDepend(d->centerIn); d->centerIn = c; d->addDepend(d->centerIn); - + emit centerInChanged(); d->centerInChanged(); } +void QmlGraphicsAnchors::resetCenterIn() +{ + setCenterIn(0); +} + bool QmlGraphicsAnchorsPrivate::calcStretch(const QmlGraphicsAnchorLine &edge1, const QmlGraphicsAnchorLine &edge2, int offset1, @@ -553,7 +571,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::top() const void QmlGraphicsAnchors::setTop(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkVAnchorValid(edge)) + if (!d->checkVAnchorValid(edge) || d->top == edge) return; d->usedAnchors |= HasTopAnchor; @@ -566,6 +584,7 @@ void QmlGraphicsAnchors::setTop(const QmlGraphicsAnchorLine &edge) d->remDepend(d->top.item); d->top = edge; d->addDepend(d->top.item); + emit topChanged(); d->updateVerticalAnchors(); } @@ -575,6 +594,7 @@ void QmlGraphicsAnchors::resetTop() d->usedAnchors &= ~HasTopAnchor; d->remDepend(d->top.item); d->top = QmlGraphicsAnchorLine(); + emit topChanged(); d->updateVerticalAnchors(); } @@ -587,7 +607,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::bottom() const void QmlGraphicsAnchors::setBottom(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkVAnchorValid(edge)) + if (!d->checkVAnchorValid(edge) || d->bottom == edge) return; d->usedAnchors |= HasBottomAnchor; @@ -600,6 +620,7 @@ void QmlGraphicsAnchors::setBottom(const QmlGraphicsAnchorLine &edge) d->remDepend(d->bottom.item); d->bottom = edge; d->addDepend(d->bottom.item); + emit bottomChanged(); d->updateVerticalAnchors(); } @@ -609,6 +630,7 @@ void QmlGraphicsAnchors::resetBottom() d->usedAnchors &= ~HasBottomAnchor; d->remDepend(d->bottom.item); d->bottom = QmlGraphicsAnchorLine(); + emit bottomChanged(); d->updateVerticalAnchors(); } @@ -621,7 +643,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::verticalCenter() const void QmlGraphicsAnchors::setVerticalCenter(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkVAnchorValid(edge)) + if (!d->checkVAnchorValid(edge) || d->vCenter == edge) return; d->usedAnchors |= HasVCenterAnchor; @@ -634,6 +656,7 @@ void QmlGraphicsAnchors::setVerticalCenter(const QmlGraphicsAnchorLine &edge) d->remDepend(d->vCenter.item); d->vCenter = edge; d->addDepend(d->vCenter.item); + emit verticalCenterChanged(); d->updateVerticalAnchors(); } @@ -643,6 +666,7 @@ void QmlGraphicsAnchors::resetVerticalCenter() d->usedAnchors &= ~HasVCenterAnchor; d->remDepend(d->vCenter.item); d->vCenter = QmlGraphicsAnchorLine(); + emit verticalCenterChanged(); d->updateVerticalAnchors(); } @@ -655,7 +679,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::baseline() const void QmlGraphicsAnchors::setBaseline(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkVAnchorValid(edge)) + if (!d->checkVAnchorValid(edge) || d->baseline == edge) return; d->usedAnchors |= HasBaselineAnchor; @@ -668,6 +692,7 @@ void QmlGraphicsAnchors::setBaseline(const QmlGraphicsAnchorLine &edge) d->remDepend(d->baseline.item); d->baseline = edge; d->addDepend(d->baseline.item); + emit baselineChanged(); d->updateVerticalAnchors(); } @@ -677,6 +702,7 @@ void QmlGraphicsAnchors::resetBaseline() d->usedAnchors &= ~HasBaselineAnchor; d->remDepend(d->baseline.item); d->baseline = QmlGraphicsAnchorLine(); + emit baselineChanged(); d->updateVerticalAnchors(); } @@ -689,7 +715,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::left() const void QmlGraphicsAnchors::setLeft(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkHAnchorValid(edge)) + if (!d->checkHAnchorValid(edge) || d->left == edge) return; d->usedAnchors |= HasLeftAnchor; @@ -702,6 +728,7 @@ void QmlGraphicsAnchors::setLeft(const QmlGraphicsAnchorLine &edge) d->remDepend(d->left.item); d->left = edge; d->addDepend(d->left.item); + emit leftChanged(); d->updateHorizontalAnchors(); } @@ -711,6 +738,7 @@ void QmlGraphicsAnchors::resetLeft() d->usedAnchors &= ~HasLeftAnchor; d->remDepend(d->left.item); d->left = QmlGraphicsAnchorLine(); + emit leftChanged(); d->updateHorizontalAnchors(); } @@ -723,7 +751,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::right() const void QmlGraphicsAnchors::setRight(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkHAnchorValid(edge)) + if (!d->checkHAnchorValid(edge) || d->right == edge) return; d->usedAnchors |= HasRightAnchor; @@ -736,7 +764,7 @@ void QmlGraphicsAnchors::setRight(const QmlGraphicsAnchorLine &edge) d->remDepend(d->right.item); d->right = edge; d->addDepend(d->right.item); - + emit rightChanged(); d->updateHorizontalAnchors(); } @@ -746,6 +774,7 @@ void QmlGraphicsAnchors::resetRight() d->usedAnchors &= ~HasRightAnchor; d->remDepend(d->right.item); d->right = QmlGraphicsAnchorLine(); + emit rightChanged(); d->updateHorizontalAnchors(); } @@ -758,7 +787,7 @@ QmlGraphicsAnchorLine QmlGraphicsAnchors::horizontalCenter() const void QmlGraphicsAnchors::setHorizontalCenter(const QmlGraphicsAnchorLine &edge) { Q_D(QmlGraphicsAnchors); - if (!d->checkHAnchorValid(edge)) + if (!d->checkHAnchorValid(edge) || d->hCenter == edge) return; d->usedAnchors |= HasHCenterAnchor; @@ -771,6 +800,7 @@ void QmlGraphicsAnchors::setHorizontalCenter(const QmlGraphicsAnchorLine &edge) d->remDepend(d->hCenter.item); d->hCenter = edge; d->addDepend(d->hCenter.item); + emit horizontalCenterChanged(); d->updateHorizontalAnchors(); } @@ -780,6 +810,7 @@ void QmlGraphicsAnchors::resetHorizontalCenter() d->usedAnchors &= ~HasHCenterAnchor; d->remDepend(d->hCenter.item); d->hCenter = QmlGraphicsAnchorLine(); + emit horizontalCenterChanged(); d->updateHorizontalAnchors(); } diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors_p.h b/src/declarative/graphicsitems/qmlgraphicsanchors_p.h index bdddafe..507b4d8 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsanchors_p.h @@ -58,13 +58,13 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsAnchors : public QObject { Q_OBJECT - Q_PROPERTY(QmlGraphicsAnchorLine left READ left WRITE setLeft RESET resetLeft) - Q_PROPERTY(QmlGraphicsAnchorLine right READ right WRITE setRight RESET resetRight) - Q_PROPERTY(QmlGraphicsAnchorLine horizontalCenter READ horizontalCenter WRITE setHorizontalCenter RESET resetHorizontalCenter) - Q_PROPERTY(QmlGraphicsAnchorLine top READ top WRITE setTop RESET resetTop) - Q_PROPERTY(QmlGraphicsAnchorLine bottom READ bottom WRITE setBottom RESET resetBottom) - Q_PROPERTY(QmlGraphicsAnchorLine verticalCenter READ verticalCenter WRITE setVerticalCenter RESET resetVerticalCenter) - Q_PROPERTY(QmlGraphicsAnchorLine baseline READ baseline WRITE setBaseline RESET resetBaseline) + Q_PROPERTY(QmlGraphicsAnchorLine left READ left WRITE setLeft RESET resetLeft NOTIFY leftChanged) + Q_PROPERTY(QmlGraphicsAnchorLine right READ right WRITE setRight RESET resetRight NOTIFY rightChanged) + Q_PROPERTY(QmlGraphicsAnchorLine horizontalCenter READ horizontalCenter WRITE setHorizontalCenter RESET resetHorizontalCenter NOTIFY horizontalCenterChanged) + Q_PROPERTY(QmlGraphicsAnchorLine top READ top WRITE setTop RESET resetTop NOTIFY topChanged) + Q_PROPERTY(QmlGraphicsAnchorLine bottom READ bottom WRITE setBottom RESET resetBottom NOTIFY bottomChanged) + Q_PROPERTY(QmlGraphicsAnchorLine verticalCenter READ verticalCenter WRITE setVerticalCenter RESET resetVerticalCenter NOTIFY verticalCenterChanged) + Q_PROPERTY(QmlGraphicsAnchorLine baseline READ baseline WRITE setBaseline RESET resetBaseline NOTIFY baselineChanged) Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin NOTIFY leftMarginChanged) Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin NOTIFY rightMarginChanged) Q_PROPERTY(qreal horizontalCenterOffset READ horizontalCenterOffset WRITE setHorizontalCenterOffset NOTIFY horizontalCenterOffsetChanged()) @@ -72,8 +72,8 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsAnchors : public QObject Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged) Q_PROPERTY(qreal verticalCenterOffset READ verticalCenterOffset WRITE setVerticalCenterOffset NOTIFY verticalCenterOffsetChanged()) Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged()) - Q_PROPERTY(QmlGraphicsItem *fill READ fill WRITE setFill) - Q_PROPERTY(QmlGraphicsItem *centerIn READ centerIn WRITE setCenterIn) + Q_PROPERTY(QmlGraphicsItem *fill READ fill WRITE setFill RESET resetFill NOTIFY fillChanged) + Q_PROPERTY(QmlGraphicsItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged) public: QmlGraphicsAnchors(QObject *parent=0); @@ -143,9 +143,11 @@ public: QmlGraphicsItem *fill() const; void setFill(QmlGraphicsItem *); + void resetFill(); QmlGraphicsItem *centerIn() const; void setCenterIn(QmlGraphicsItem *); + void resetCenterIn(); UsedAnchors usedAnchors() const; @@ -155,6 +157,15 @@ public: void componentComplete(); Q_SIGNALS: + void leftChanged(); + void rightChanged(); + void topChanged(); + void bottomChanged(); + void verticalCenterChanged(); + void horizontalCenterChanged(); + void baselineChanged(); + void fillChanged(); + void centerInChanged(); void leftMarginChanged(); void rightMarginChanged(); void topMarginChanged(); diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h b/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h index d21d9c5..2156565 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h @@ -80,9 +80,16 @@ public: QmlGraphicsItem *item; AnchorLine anchorLine; + + bool operator==(const QmlGraphicsAnchorLine& other) const + { + return item == other.item && anchorLine == other.anchorLine; + } }; Q_DECLARE_METATYPE(QmlGraphicsAnchorLine) + + class QmlGraphicsAnchorsPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QmlGraphicsAnchors) diff --git a/src/declarative/graphicsitems/qmlgraphicseffects.cpp b/src/declarative/graphicsitems/qmlgraphicseffects.cpp index 2f0aae7..0523fd5 100644 --- a/src/declarative/graphicsitems/qmlgraphicseffects.cpp +++ b/src/declarative/graphicsitems/qmlgraphicseffects.cpp @@ -51,10 +51,10 @@ QML_DEFINE_TYPE(Qt,4,6,Blur,QGraphicsBlurEffect) \qmlclass Blur QGraphicsBlurEffect \brief The Blur object provides a blur effect. - A blur effect blurs the source item. This effect is useful for reducing details, - such as when the source loses focus and you want to draw attention to other - elements. The level of detail can be modified using the blurRadius property. - Use blurHint to choose the quality or performance blur hints. + A blur effect blurs the source item. This effect is useful for reducing details; + for example, when the a source loses focus and attention should be drawn to other + elements. Use blurRadius to control the level of detail and blurHint to control + the quality of the blur. By default, the blur radius is 5 pixels. @@ -64,21 +64,22 @@ QML_DEFINE_TYPE(Qt,4,6,Blur,QGraphicsBlurEffect) /*! \qmlproperty real Blur::blurRadius - blurRadius controls how blurry an item will appear. - Using a smaller radius results in a sharper appearance, whereas a bigger - radius results in a more blurred appearance. + This controls how blurry an item will appear. - By default, the blur radius is 5 pixels. + A smaller radius produces a sharper appearance, and a larger radius produces + a more blurred appearance. + + The default radius is 5 pixels. */ /*! \qmlproperty enumeration Blur::blurHint - Use the Qt.PerformanceHint hint to say that you want a faster blur, - and the Qt.QualityHint hint to say that you prefer a higher quality blur. - - When animating the blur radius it's recommended to use Qt.PerformanceHint. + Use Qt.PerformanceHint to specify a faster blur or Qt.QualityHint hint + to specify a higher quality blur. + + If the blur radius is animated, it is recommended you use Qt.PerformanceHint. - By default, the blur hint is Qt.PerformanceHint. + The default hint is Qt.PerformanceHint. */ QML_DECLARE_TYPE(QGraphicsColorizeEffect) diff --git a/src/declarative/graphicsitems/qmlgraphicsimage.cpp b/src/declarative/graphicsitems/qmlgraphicsimage.cpp index 2161ed6..38df0c7 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimage.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsimage.cpp @@ -171,8 +171,10 @@ void QmlGraphicsImagePrivate::setPixmap(const QPixmap &pixmap) q->setImplicitWidth(pix.width()); q->setImplicitHeight(pix.height()); + status = pix.isNull() ? QmlGraphicsImageBase::Null : QmlGraphicsImageBase::Ready; q->update(); + emit q->pixmapChanged(); } /*! diff --git a/src/declarative/graphicsitems/qmlgraphicsimage_p.h b/src/declarative/graphicsitems/qmlgraphicsimage_p.h index 76b8da5..47cdcd6 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimage_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsimage_p.h @@ -56,7 +56,7 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsImage : public QmlGraphicsImageBase Q_OBJECT Q_ENUMS(FillMode) - Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap DESIGNABLE false) + Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap NOTIFY pixmapChanged DESIGNABLE false) Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged) public: diff --git a/src/declarative/graphicsitems/qmlgraphicsimagebase.cpp b/src/declarative/graphicsitems/qmlgraphicsimagebase.cpp index 6cd1c05..8374c9f 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimagebase.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsimagebase.cpp @@ -106,6 +106,7 @@ void QmlGraphicsImageBase::setSource(const QUrl &url) setImplicitHeight(0); emit statusChanged(d->status); emit sourceChanged(d->url); + emit pixmapChanged(); update(); } else { d->status = Loading; @@ -131,6 +132,7 @@ void QmlGraphicsImageBase::setSource(const QUrl &url) emit statusChanged(d->status); emit sourceChanged(d->url); emit progressChanged(d->progress); + emit pixmapChanged(); update(); } } @@ -155,6 +157,7 @@ void QmlGraphicsImageBase::requestFinished() emit statusChanged(d->status); emit sourceChanged(d->url); emit progressChanged(1.0); + emit pixmapChanged(); update(); } diff --git a/src/declarative/graphicsitems/qmlgraphicsimagebase_p.h b/src/declarative/graphicsitems/qmlgraphicsimagebase_p.h index bab93b7..4936794 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimagebase_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsimagebase_p.h @@ -71,6 +71,7 @@ Q_SIGNALS: void sourceChanged(const QUrl &); void statusChanged(Status); void progressChanged(qreal progress); + void pixmapChanged(); protected: QmlGraphicsImageBase(QmlGraphicsImageBasePrivate &dd, QmlGraphicsItem *parent); diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.cpp b/src/declarative/graphicsitems/qmlgraphicsitem.cpp index 263aea5..5b4f1f1 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsitem.cpp @@ -168,7 +168,7 @@ QML_DEFINE_TYPE(Qt,4,6,Rotation,QGraphicsRotation) \qmlproperty real Rotation::axis.z The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis, - as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 0 } }). + as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }). For a typical 3D-like rotation you will usually specify both the origin and the axis. @@ -656,7 +656,7 @@ void QmlGraphicsKeyNavigationAttached::keyReleased(QKeyEvent *event) focus: true Keys.onPressed: { if (event.key == Qt.Key_Left) { - print("move left"); + console.log("move left"); event.accepted = true; } } @@ -670,7 +670,7 @@ void QmlGraphicsKeyNavigationAttached::keyReleased(QKeyEvent *event) \code Item { focus: true - Keys.onLeftPressed: print("move left") + Keys.onLeftPressed: console.log("move left") } \endcode @@ -1359,11 +1359,11 @@ QmlGraphicsKeysAttached *QmlGraphicsKeysAttached::qmlAttachedProperties(QObject focus: true Keys.onPressed: { if (event.key == Qt.Key_Left) { - print("move left"); + console.log("move left"); event.accepted = true; } } - Keys.onSelectPressed: print("Selected"); + Keys.onSelectPressed: console.log("Selected"); } \endqml @@ -1943,8 +1943,8 @@ void QmlGraphicsItem::setClip(bool c) Whether the item is visible. By default this is true. - \note visible is not linked to actual visibility; if you item - goes off screen, or the opacity changes to 0, etc this will + \note visible is not linked to actual visibility; if an item + moves off screen, or the opacity changes to 0, this will not affect the visible property. */ @@ -2930,6 +2930,8 @@ bool QmlGraphicsItem::heightValid() const \qmlproperty bool Item::wantsFocus This property indicates whether the item has has an active focus request. + + \sa {qmlfocus}{Keyboard Focus} */ /*! \internal */ @@ -2942,6 +2944,8 @@ bool QmlGraphicsItem::wantsFocus() const \qmlproperty bool Item::focus This property indicates whether the item has keyboard input focus. Set this property to true to request focus. + + \sa {qmlfocus}{Keyboard Focus} */ /*! \internal */ diff --git a/src/declarative/graphicsitems/qmlgraphicspainteditem.cpp b/src/declarative/graphicsitems/qmlgraphicspainteditem.cpp index 2f467e7..948f69a 100644 --- a/src/declarative/graphicsitems/qmlgraphicspainteditem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspainteditem.cpp @@ -289,7 +289,7 @@ void QmlGraphicsPaintedItem::paint(QPainter *p, const QStyleOptionGraphicsItem * } cachesize -= d->imagecache[oldest]->area.width()*d->imagecache[oldest]->area.height(); uncached += d->imagecache[oldest]->area; - d->imagecache.removeAt(oldest); + delete d->imagecache.takeAt(oldest); } const QRegion bigger = QRegion(biggerrect) & uncached; const QVector<QRect> rects = bigger.rects(); @@ -366,7 +366,7 @@ void QmlGraphicsPaintedItem::setPixelCacheSize(int pixels) } } cachesize -= d->imagecache[oldest]->area.width()*d->imagecache[oldest]->area.height(); - d->imagecache.removeAt(oldest); + delete d->imagecache.takeAt(oldest); } } d->max_imagecache_size = pixels; diff --git a/src/declarative/graphicsitems/qmlgraphicstextedit.cpp b/src/declarative/graphicsitems/qmlgraphicstextedit.cpp index 2588f7d..bec2ff8 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextedit.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstextedit.cpp @@ -563,7 +563,7 @@ QString QmlGraphicsTextEdit::selectedText() const \qmlproperty bool TextEdit::focusOnPress Whether the TextEdit should gain focus on a mouse press. By default this is - set to false; + set to false. */ bool QmlGraphicsTextEdit::focusOnPress() const { diff --git a/src/declarative/graphicsitems/qmlgraphicswebview.cpp b/src/declarative/graphicsitems/qmlgraphicswebview.cpp index aedf787..e21bda3 100644 --- a/src/declarative/graphicsitems/qmlgraphicswebview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicswebview.cpp @@ -79,6 +79,7 @@ public: : QmlGraphicsPaintedItemPrivate(), page(0), preferredwidth(0), preferredheight(0), progress(1.0), status(QmlGraphicsWebView::Null), pending(PendingNone), newWindowComponent(0), newWindowParent(0), + pressTime(400), windowObjects(this), rendering(true) { @@ -99,6 +100,11 @@ public: QmlComponent *newWindowComponent; QmlGraphicsItem *newWindowParent; + QBasicTimer pressTimer; + QPoint pressPoint; + int pressTime; // milliseconds before it's a "hold" XXX not currently settable + static const int pressDragLength = 15; // XXX #pixels before it's no longer a "hold"; device-specific + void updateWindowObjects(); class WindowObjectList : public QmlConcreteList<QObject *> { @@ -613,8 +619,15 @@ bool QmlGraphicsWebView::heuristicZoom(int clickX, int clickY, qreal maxzoom) void QmlGraphicsWebView::mousePressEvent(QGraphicsSceneMouseEvent *event) { + Q_D(QmlGraphicsWebView); + setFocus (true); QMouseEvent *me = sceneMouseEventToMouseEvent(event); + + d->pressPoint = me->pos(); + d->pressTimer.start(d->pressTime,this); + setKeepMouseGrab(false); + page()->event(me); event->setAccepted( /* @@ -636,8 +649,11 @@ void QmlGraphicsWebView::mousePressEvent(QGraphicsSceneMouseEvent *event) void QmlGraphicsWebView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { + Q_D(QmlGraphicsWebView); + QMouseEvent *me = sceneMouseEventToMouseEvent(event); page()->event(me); + d->pressTimer.stop(); event->setAccepted( /* It is not correct to send the press event upwards, if it is not accepted by WebKit @@ -653,24 +669,45 @@ void QmlGraphicsWebView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if (!event->isAccepted()) { QmlGraphicsPaintedItem::mouseReleaseEvent(event); } + setKeepMouseGrab(false); + ungrabMouse(); +} + +void QmlGraphicsWebView::timerEvent(QTimerEvent *event) +{ + Q_D(QmlGraphicsWebView); + if (event->timerId() == d->pressTimer.timerId()) { + d->pressTimer.stop(); + grabMouse(); + setKeepMouseGrab(true); + } } void QmlGraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { + Q_D(QmlGraphicsWebView); + QMouseEvent *me = sceneMouseEventToMouseEvent(event); - page()->event(me); - event->setAccepted( + if (d->pressTimer.isActive()) { + if ((me->pos() - d->pressPoint).manhattanLength() > d->pressDragLength) { + d->pressTimer.stop(); + } + } + if (keepMouseGrab()) { + page()->event(me); + event->setAccepted( /* It is not correct to send the press event upwards, if it is not accepted by WebKit e.g. push button does not work, if done so as QGraphicsScene will not send the release event at all to WebKit Might be a bug in WebKit, though */ #if 1 // QT_VERSION <= 0x040500 // XXX see bug 230835 - true + true #else - me->isAccepted() + me->isAccepted() #endif - ); + ); + } delete me; if (!event->isAccepted()) QmlGraphicsPaintedItem::mouseMoveEvent(event); @@ -722,7 +759,6 @@ bool QmlGraphicsWebView::sceneEvent(QEvent *event) } - /*! \qmlproperty action WebView::back This property holds the action for causing the previous URL in the history to be displayed. @@ -1161,6 +1197,8 @@ void QmlGraphicsWebPage::javaScriptConsoleMessage(const QString& message, int li QString QmlGraphicsWebPage::chooseFile(QWebFrame *originatingFrame, const QString& oldFile) { // Not supported (it's modal) + Q_UNUSED(originatingFrame) + Q_UNUSED(oldFile) return oldFile; } @@ -1172,6 +1210,8 @@ void QmlGraphicsWebPage::javaScriptAlert(QWebFrame *originatingFrame, const QStr bool QmlGraphicsWebPage::javaScriptConfirm(QWebFrame *originatingFrame, const QString& msg) { // Not supported (it's modal) + Q_UNUSED(originatingFrame) + Q_UNUSED(msg) return false; } diff --git a/src/declarative/graphicsitems/qmlgraphicswebview_p.h b/src/declarative/graphicsitems/qmlgraphicswebview_p.h index 17546c1..7ff51f3 100644 --- a/src/declarative/graphicsitems/qmlgraphicswebview_p.h +++ b/src/declarative/graphicsitems/qmlgraphicswebview_p.h @@ -89,7 +89,7 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsWebView : public QmlGraphicsPaintedItem { Q_OBJECT - Q_ENUMS(Status) + Q_ENUMS(Status SelectionMode) Q_PROPERTY(QString title READ title NOTIFY titleChanged) Q_PROPERTY(QPixmap icon READ icon NOTIFY iconChanged) @@ -220,6 +220,7 @@ protected: void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); + void timerEvent(QTimerEvent *event); void hoverMoveEvent (QGraphicsSceneHoverEvent * event); void keyPressEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event); diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp index 7f8836a..5f8b816 100644 --- a/src/declarative/qml/qmlcomponent.cpp +++ b/src/declarative/qml/qmlcomponent.cpp @@ -112,9 +112,9 @@ Item { \qml Rectangle { - Component.onCompleted: print("Completed Running!") + Component.onCompleted: console.log("Completed Running!") Rectangle { - Component.onCompleted: print("Nested Completed Running!") + Component.onCompleted: console.log("Nested Completed Running!") } } \endqml diff --git a/src/declarative/qml/qmlscript.cpp b/src/declarative/qml/qmlscript.cpp index 7242498..ba62898 100644 --- a/src/declarative/qml/qmlscript.cpp +++ b/src/declarative/qml/qmlscript.cpp @@ -43,40 +43,45 @@ /*! \qmlclass Script QmlScript - \brief The Script element adds JavaScript snippets. + \brief The Script element provides a way to add JavaScript code snippets in QML. \ingroup group_utility - QmlScript is used to add convenient JavaScript "glue" methods to - your Qt Declarative application or component. While you can have any JavaScript code - within a QmlScript, it is best to limit yourself to defining functions. + The Script element is used to add convenient JavaScript "glue" methods to + your Qt Declarative application or component. + + An example: \qml Script { function debugMyComponent() { - print(text.text); - print(otherinterestingitem.property); + console.log(text.text); + console.log(otherinterestingitem.property); } } MouseRegion { onClicked: debugMyComponent() } \endqml - \note QmlScript executes JavaScript as soon as it is specified. - When defining a component, this may be before the execution context is - fully specified. As a result some properties or items may not be - accessible. By limiting your JavaScript to defining functions that are - only executed later once the context is fully defined, this problem is - avoided. + \note While it is possible to use any JavaScript code within a Script element, + it is recommended that the code be limited to defining functions. The Script + element executes JavaScript as soon as it is specified, so + when defining a component, this may be done before the execution context is + fully specified. As a result, some properties or items may not be + accessible. You can avoid this problem by limiting your JavaScript to + defining functions that are only executed later once the context is fully + defined. + + \sa {ECMAScript Blocks} */ /*! \qmlproperty string Script::script \default - JavaScript code to execute. + The JavaScript code to be executed. */ /*! \qmlproperty url Script::source - Setting this property causes the Script element to read JavaScript code from - the file specified. + Specifies a source file containing JavaScript code. This can be used instead + of providing inline JavaScript code in the Script element. */ diff --git a/src/declarative/qml/qmlscriptstring.cpp b/src/declarative/qml/qmlscriptstring.cpp index 6f669d5..1ccad53 100644 --- a/src/declarative/qml/qmlscriptstring.cpp +++ b/src/declarative/qml/qmlscriptstring.cpp @@ -60,12 +60,12 @@ public: The QmlScriptString is used by properties that want to accept a script "assignment" from QML. Normally, the following code would result in a binding being established for the \c script -property. If the property had a type of QmlScriptString, the script - \e {print(1921)} - itself +property. If the property had a type of QmlScriptString, the script - \e {console.log(1921)} - itself would be passed to the property and it could choose how to handle it. \code MyType { - script: print(1921) + script: console.log(1921) } \endcode */ diff --git a/src/declarative/util/qmlconnection.cpp b/src/declarative/util/qmlconnection.cpp index b1771d4..3e72ab8 100644 --- a/src/declarative/util/qmlconnection.cpp +++ b/src/declarative/util/qmlconnection.cpp @@ -65,7 +65,18 @@ public: \qmlclass Connection QmlConnection \brief A Connection object describes generalized connections to signals. - JavaScript-in-HTML style signal properties do not allow: + When connecting to signals in QML, the usual way is to create an + "on<Signal>" handler that reacts when a signal is received, like this: + + \qml + MouseRegion { + onClicked: { foo(x+123,y+456) } + } + \endqml + + However, in some cases, it is not possible to connect to a signal in this + way. For example, JavaScript-in-HTML style signal properties do not allow: + \list \i connecting to signals with the same name but different parameters \i conformance checking that parameters are correctly named @@ -74,39 +85,33 @@ public: \i signals in classes with coincidentally-named on<Signal> properties \endlist - When any of these is needed, the Connection object can be used instead. - Where a signal could be connected like this: + When any of these are needed, the Connection object can be used instead. - \qml -MouseRegion { - onClicked: { foo(x+123,y+456) } -} - \endqml - - An equivalent binding can be made with a Connection object: + For example, the above code can be changed to use a Connection object, + like this: \qml -MouseRegion { - Connection { - signal: "clicked(x,y)" - script: { foo(x+123,y+456) } + MouseRegion { + Connection { + signal: "clicked(x,y)" + script: { foo(x+123,y+456) } + } } -} \endqml More generally, the Connection object can be a child of some other object than the sender of the signal, and the script is the default attribute: \qml -MouseRegion { - id: mr -} -... -Connection { - sender: mr - signal: "clicked(x,y)" - script: { foo(x+123,y+456) } -} + MouseRegion { + id: mr + } + ... + Connection { + sender: mr + signal: "clicked(x,y)" + script: { foo(x+123,y+456) } + } \endqml */ @@ -249,7 +254,7 @@ void QmlConnection::setScript(const QmlScriptString& script) \qmlproperty string Connection::signal This property holds the signal from the sender to which the script is attached. - The signal must have its formal parameter names given in parentheses: + The signal's formal parameter names must be given in parentheses: \qml Connection { diff --git a/src/declarative/util/qmlpropertychanges.cpp b/src/declarative/util/qmlpropertychanges.cpp index 6a393ee..9ca6db8 100644 --- a/src/declarative/util/qmlpropertychanges.cpp +++ b/src/declarative/util/qmlpropertychanges.cpp @@ -56,19 +56,32 @@ QT_BEGIN_NAMESPACE \qmlclass PropertyChanges QmlPropertyChanges \brief The PropertyChanges element describes new property values for a state. - PropertyChanges changes the properties of an item. It allows you to specify the property - names and values for a state similar to how you normally would specify them for the - actual item: + PropertyChanges provides a state change that modifies the properties of an item. - \code - PropertyChanges { - target: myRect - x: 52 - y: 300 - width: 48 - } - \endcode + Here is a property change that modifies the text and color of a Text element + when it is clicked: + + \qml + Text { + id: myText + width: 100; height: 100 + text: "Hello" + color: "blue" + + states: State { + name: "myState" + + PropertyChanges { + target: myText + text: "Goodbye" + color: "red" + } + } + MouseRegion { anchors.fill: parent; onClicked: myText.state = 'myState' } + } + \endqml + State-specific script for signal handlers can also be specified: \qml @@ -92,7 +105,7 @@ QT_BEGIN_NAMESPACE /*! \qmlproperty Object PropertyChanges::target - This property holds the object that the properties to change belong to + This property holds the object which contains the properties to be changed. */ class QmlReplaceSignalHandler : public ActionEvent diff --git a/src/declarative/util/qmlstategroup.cpp b/src/declarative/util/qmlstategroup.cpp index 4dfa34a..f206f5c 100644 --- a/src/declarative/util/qmlstategroup.cpp +++ b/src/declarative/util/qmlstategroup.cpp @@ -331,8 +331,10 @@ void QmlStateGroupPrivate::setCurrentStateInternal(const QString &state, bool ignoreTrans) { Q_Q(QmlStateGroup); - if (!componentComplete) + if (!componentComplete) { + currentState = state; return; + } if (applyingState) { qWarning() << "Can't apply a state change as part of a state definition."; diff --git a/src/declarative/util/qmltimer.cpp b/src/declarative/util/qmltimer.cpp index 0be62f4..da60193 100644 --- a/src/declarative/util/qmltimer.cpp +++ b/src/declarative/util/qmltimer.cpp @@ -55,7 +55,7 @@ class QmlTimerPrivate : public QObjectPrivate public: QmlTimerPrivate() : interval(1000), running(false), repeating(false), triggeredOnStart(false) - , classBegun(false), componentComplete(false) {} + , classBegun(false), componentComplete(false), firstTick(true) {} int interval; QPauseAnimation pause; bool running : 1; @@ -63,6 +63,7 @@ public: bool triggeredOnStart : 1; bool classBegun : 1; bool componentComplete : 1; + bool firstTick : 1; }; /*! @@ -72,6 +73,9 @@ public: A timer can be used to trigger an action either once, or repeatedly at a given interval. + Here is a timer that shows the current date and time, and updates + the text every 500 milliseconds: + \qml Timer { interval: 500; running: true; repeat: true @@ -85,6 +89,12 @@ public: QmlTimer is synchronized with the animation timer. Since the animation timer is usually set to 60fps, the resolution of QmlTimer will be at best 16ms. + + If the Timer is running and one of its properties is changed, the + elapsed time will be reset. For example, if a Timer with interval of + 1000ms has its \e repeat property changed 500ms after starting, the + elapsed time will be reset to 0, and the Timer will be triggered + 1000ms later. */ QmlTimer::QmlTimer(QObject *parent) @@ -92,8 +102,7 @@ QmlTimer::QmlTimer(QObject *parent) { Q_D(QmlTimer); connect(&d->pause, SIGNAL(currentLoopChanged(int)), this, SLOT(ticked())); - connect(&d->pause, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)) - , this, SLOT(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State))); + connect(&d->pause, SIGNAL(finished()), this, SLOT(finished())); d->pause.setLoopCount(1); d->pause.setDuration(d->interval); } @@ -101,7 +110,7 @@ QmlTimer::QmlTimer(QObject *parent) /*! \qmlproperty int Timer::interval - Sets the \a interval in milliseconds between triggering. + Sets the \a interval between triggers, in milliseconds. The default interval is 1000 milliseconds. */ @@ -124,7 +133,7 @@ int QmlTimer::interval() const \qmlproperty bool Timer::running If set to true, starts the timer; otherwise stops the timer. - For a non-repeating timer, \a running will be set to false after the + For a non-repeating timer, \a running is set to false after the timer has been triggered. \a running defaults to false. @@ -142,6 +151,7 @@ void QmlTimer::setRunning(bool running) Q_D(QmlTimer); if (d->running != running) { d->running = running; + d->firstTick = true; emit runningChanged(); update(); } @@ -150,7 +160,7 @@ void QmlTimer::setRunning(bool running) /*! \qmlproperty bool Timer::repeat - If \a repeat is true the timer will be triggered repeatedly at the + If \a repeat is true the timer is triggered repeatedly at the specified interval; otherwise, the timer will trigger once at the specified interval and then stop (i.e. running will be set to false). @@ -176,15 +186,15 @@ void QmlTimer::setRepeating(bool repeating) /*! \qmlproperty bool Timer::triggeredOnStart - When the Timer is started the first trigger is normally after the specified - interval has elapsed. It is sometimes desireable to trigger immediately - when the timer is started, for example to establish an initial + When a timer is started, the first trigger is usually after the specified + interval has elapsed. It is sometimes desirable to trigger immediately + when the timer is started; for example, to establish an initial state. - If \a triggeredOnStart is true, the timer will be triggered immediately - when started, and subsequently at the specified interval. Note that for - a Timer with \e repeat set to false, this will result in the timer being - triggered twice; once on start, and again at the interval. + If \a triggeredOnStart is true, the timer is triggered immediately + when started, and subsequently at the specified interval. Note that if + \e repeat is set to false, the timer is triggered twice; once on start, + and again at the interval. \a triggeredOnStart defaults to false. @@ -219,7 +229,7 @@ void QmlTimer::start() /*! \qmlmethod Timer::stop() - \brief stops the timer. + \brief Stops the timer. If the timer is not running, calling this method has no effect. The \c running property will be false following a call to \c stop(). @@ -229,6 +239,20 @@ void QmlTimer::stop() setRunning(false); } +/*! + \qmlmethod Timer::restart() + \brief Restarts the timer. + + If the Timer is not running it will be started, otherwise it will be + stopped, reset to initial state and started. The \c running property + will be true following a call to \c restart(). +*/ +void QmlTimer::restart() +{ + setRunning(false); + setRunning(true); +} + void QmlTimer::update() { Q_D(QmlTimer); @@ -236,10 +260,11 @@ void QmlTimer::update() return; d->pause.stop(); if (d->running) { + d->pause.setCurrentTime(0); d->pause.setLoopCount(d->repeating ? -1 : 1); d->pause.setDuration(d->interval); d->pause.start(); - if (d->triggeredOnStart) { + if (d->triggeredOnStart && d->firstTick) { QCoreApplication::removePostedEvents(this, QEvent::MetaCall); QMetaObject::invokeMethod(this, "ticked", Qt::QueuedConnection); } @@ -267,18 +292,18 @@ void QmlTimer::componentComplete() void QmlTimer::ticked() { Q_D(QmlTimer); - if (d->running) + if (d->running && (d->pause.currentTime() > 0 || (d->triggeredOnStart && d->firstTick))) emit triggered(); + d->firstTick = false; } -void QmlTimer::stateChanged(QAbstractAnimation::State state, QAbstractAnimation::State) +void QmlTimer::finished() { Q_D(QmlTimer); - if (d->running && state != QAbstractAnimation::Running) { - d->running = false; - emit triggered(); - emit runningChanged(); - } + if (d->repeating || !d->running) + return; + emit triggered(); + d->firstTick = false; } QT_END_NAMESPACE diff --git a/src/declarative/util/qmltimer_p.h b/src/declarative/util/qmltimer_p.h index bd96d4a..50cae2b 100644 --- a/src/declarative/util/qmltimer_p.h +++ b/src/declarative/util/qmltimer_p.h @@ -85,6 +85,7 @@ protected: public Q_SLOTS: void start(); void stop(); + void restart(); Q_SIGNALS: void triggered(); @@ -95,7 +96,7 @@ private: private Q_SLOTS: void ticked(); - void stateChanged(QAbstractAnimation::State,QAbstractAnimation::State); + void finished(); }; QT_END_NAMESPACE diff --git a/tests/auto/declarative/anchors/tst_anchors.cpp b/tests/auto/declarative/anchors/tst_anchors.cpp index 3011fdc..44e812a 100644 --- a/tests/auto/declarative/anchors/tst_anchors.cpp +++ b/tests/auto/declarative/anchors/tst_anchors.cpp @@ -67,6 +67,7 @@ private slots: void illegalSets_data(); void reset(); void reset_data(); + void resetConvenience(); void nullItem(); void nullItem_data(); void crash1(); @@ -312,6 +313,27 @@ void tst_anchors::reset_data() QTest::newRow("baseline") << "baseline" << QmlGraphicsAnchorLine::Baseline << QmlGraphicsAnchors::HasBaselineAnchor; } +void tst_anchors::resetConvenience() +{ + QmlGraphicsItem *baseItem = new QmlGraphicsItem; + QmlGraphicsItem *item = new QmlGraphicsItem; + + //fill + item->anchors()->setFill(baseItem); + QVERIFY(item->anchors()->fill() == baseItem); + item->anchors()->resetFill(); + QVERIFY(item->anchors()->fill() == 0); + + //centerIn + item->anchors()->setCenterIn(baseItem); + QVERIFY(item->anchors()->centerIn() == baseItem); + item->anchors()->resetCenterIn(); + QVERIFY(item->anchors()->centerIn() == 0); + + delete item; + delete baseItem; +} + void tst_anchors::nullItem() { QFETCH(QString, side); diff --git a/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp b/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp index 784ad42..c8a2d3f 100644 --- a/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp +++ b/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp @@ -81,6 +81,7 @@ private slots: void clearSource(); void resized(); void smooth(); + void pixmap(); private: QmlEngine engine; @@ -207,6 +208,35 @@ void tst_qmlgraphicsimage::smooth() delete obj; } +void tst_qmlgraphicsimage::pixmap() +{ + QString componentStr = "import Qt 4.6\nImage { pixmap: testPixmap }"; + + QPixmap pixmap; + QmlContext *ctxt = engine.rootContext(); + ctxt->setContextProperty("testPixmap", pixmap); + + QmlComponent component(&engine, componentStr.toLatin1(), QUrl("file://")); + + QmlGraphicsImage *obj = qobject_cast<QmlGraphicsImage*>(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->source(), QUrl()); + QVERIFY(obj->status() == QmlGraphicsImage::Null); + QCOMPARE(obj->width(), 0.); + QCOMPARE(obj->height(), 0.); + QCOMPARE(obj->fillMode(), QmlGraphicsImage::Stretch); + QCOMPARE(obj->progress(), 0.0); + QVERIFY(obj->pixmap().isNull()); + + pixmap = QPixmap(SRCDIR "/data/colors.png"); + ctxt->setContextProperty("testPixmap", pixmap); + QCOMPARE(obj->width(), 120.); + QCOMPARE(obj->height(), 120.); + QVERIFY(obj->status() == QmlGraphicsImage::Ready); + + delete obj; +} + QTEST_MAIN(tst_qmlgraphicsimage) #include "tst_qmlgraphicsimage.moc" diff --git a/tests/auto/declarative/qmltimer/tst_qmltimer.cpp b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp index cf54647..63a9a09 100644 --- a/tests/auto/declarative/qmltimer/tst_qmltimer.cpp +++ b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp @@ -42,6 +42,7 @@ #include <QtDeclarative/qmlengine.h> #include <QtDeclarative/qmlcomponent.h> #include <private/qmltimer_p.h> +#include <QDebug> class tst_qmltimer : public QObject { @@ -56,6 +57,8 @@ private slots: void noTriggerIfNotRunning(); void triggeredOnStart(); void triggeredOnStartRepeat(); + void changeDuration(); + void restart(); }; class TimerHelper : public QObject @@ -123,6 +126,8 @@ void tst_qmltimer::notRepeatingStart() QCOMPARE(helper.count, 1); QTest::qWait(TIMEOUT_TIMEOUT); QCOMPARE(helper.count, 1); + + delete timer; } void tst_qmltimer::repeat() @@ -147,6 +152,8 @@ void tst_qmltimer::repeat() timer->stop(); QTest::qWait(TIMEOUT_TIMEOUT); QVERIFY(helper.count == oldCount); + + delete timer; } void tst_qmltimer::triggeredOnStart() @@ -166,6 +173,8 @@ void tst_qmltimer::triggeredOnStart() QCOMPARE(helper.count, 2); QTest::qWait(TIMEOUT_TIMEOUT); QCOMPARE(helper.count, 2); + + delete timer; } void tst_qmltimer::triggeredOnStartRepeat() @@ -185,6 +194,8 @@ void tst_qmltimer::triggeredOnStartRepeat() int oldCount = helper.count; QTest::qWait(TIMEOUT_TIMEOUT); QVERIFY(helper.count > oldCount); + + delete timer; } void tst_qmltimer::noTriggerIfNotRunning() @@ -201,6 +212,55 @@ void tst_qmltimer::noTriggerIfNotRunning() QVERIFY(item != 0); QTest::qWait(TIMEOUT_TIMEOUT); QCOMPARE(item->property("ok").toBool(), true); + + delete item; +} + +void tst_qmltimer::changeDuration() +{ + QmlEngine engine; + QmlComponent component(&engine, QByteArray("import Qt 4.6\nTimer { interval: 200; repeat: true; running: true }"), QUrl("file://")); + QmlTimer *timer = qobject_cast<QmlTimer*>(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QCOMPARE(helper.count, 0); + + QTest::qWait(500); + QCOMPARE(helper.count, 2); + + timer->setInterval(500); + + QTest::qWait(600); + QCOMPARE(helper.count, 3); + + delete timer; +} + +void tst_qmltimer::restart() +{ + QmlEngine engine; + QmlComponent component(&engine, QByteArray("import Qt 4.6\nTimer { interval: 500; repeat: true; running: true }"), QUrl("file://")); + QmlTimer *timer = qobject_cast<QmlTimer*>(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QCOMPARE(helper.count, 0); + + QTest::qWait(600); + QCOMPARE(helper.count, 1); + + QTest::qWait(300); + + timer->restart(); + + QTest::qWait(700); + + QCOMPARE(helper.count, 2); + + delete timer; } QTEST_MAIN(tst_qmltimer) |