diff options
author | Warwick Allison <warwick.allison@nokia.com> | 2009-09-02 05:16:25 (GMT) |
---|---|---|
committer | Warwick Allison <warwick.allison@nokia.com> | 2009-09-02 05:16:25 (GMT) |
commit | 373e090de85ee8c46cbd400d4b5fbf37d4b59eae (patch) | |
tree | 5eed8645e3c0b6e08230885cb3da184e44dad067 | |
parent | d76c52133160f4394df2d6dc4d239c54833c1ab3 (diff) | |
parent | b6e26ee808ae3ffe1c4fba03cc89baf47d65d3a8 (diff) | |
download | Qt-373e090de85ee8c46cbd400d4b5fbf37d4b59eae.zip Qt-373e090de85ee8c46cbd400d4b5fbf37d4b59eae.tar.gz Qt-373e090de85ee8c46cbd400d4b5fbf37d4b59eae.tar.bz2 |
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
32 files changed, 421 insertions, 122 deletions
diff --git a/demos/declarative/contacts/contacts.qml b/demos/declarative/contacts/contacts.qml index 81d8352..f009631 100644 --- a/demos/declarative/contacts/contacts.qml +++ b/demos/declarative/contacts/contacts.qml @@ -105,7 +105,7 @@ Rectangle { } PropertyChanges { target: contactListView - locked: 1 + interactive: 0 } PropertyChanges { target: label diff --git a/demos/declarative/samegame/SameGame.qml b/demos/declarative/samegame/SameGame.qml index 0da5679..877c1cc 100644 --- a/demos/declarative/samegame/SameGame.qml +++ b/demos/declarative/samegame/SameGame.qml @@ -34,6 +34,19 @@ Rectangle { } Dialog { id: dialog; anchors.centerIn: parent; z: 21 } + Dialog { + id: scoreName; anchors.centerIn: parent; z: 22; + TextInput { + id: Editor + onAccepted: { + if(scoreName.opacity==1&&Editor.text!="") + sendHighScore(Editor.text); + scoreName.forceClose(); + } + anchors.verticalCenter: parent.verticalCenter + x:160; width: 200; height:20; focus: true + } + } Rectangle { id: ToolBar diff --git a/demos/declarative/samegame/content/Dialog.qml b/demos/declarative/samegame/content/Dialog.qml index 72c7900..401d211 100644 --- a/demos/declarative/samegame/content/Dialog.qml +++ b/demos/declarative/samegame/content/Dialog.qml @@ -2,14 +2,20 @@ import Qt 4.6 Rectangle { id: page + function forceClose() { + page.closed(); + page.opacity = 0; + } + function show(txt) { + MyText.text = txt; + page.opacity = 1; + } + signal closed(); color: "white"; border.width: 1; width: MyText.width + 20; height: 60; - property string text: "Hello World!" opacity: 0 opacity: Behavior { - SequentialAnimation { - NumberAnimation {property: "opacity"; from: 0; duration: 1500 } - NumberAnimation {property: "opacity"; to: 0; duration: 1500 } - } + NumberAnimation { duration: 1000 } } - Text { id: MyText; anchors.centerIn: parent; text: parent.text } + Text { id: MyText; anchors.centerIn: parent; text: "Hello World!" } + MouseRegion { id: mr; anchors.fill: parent; onClicked: forceClose(); } } diff --git a/demos/declarative/samegame/content/samegame.js b/demos/declarative/samegame/content/samegame.js index f04fb4c..9914edb 100755 --- a/demos/declarative/samegame/content/samegame.js +++ b/demos/declarative/samegame/content/samegame.js @@ -6,13 +6,22 @@ var tileSize = 40; var maxIndex = maxX*maxY; var board = new Array(maxIndex); var tileSrc = "content/BoomBlock.qml"; +var scoresURL = "http://qtfx-nokia.trolltech.com.au/samegame/scores.php"; +var timer; var component; //Index function used instead of a 2D array -function index(xIdx,yIdx){ +function index(xIdx,yIdx) { return xIdx + (yIdx * maxX); } +function timeStr(msecs) { + var secs = Math.floor(msecs/1000); + var m = Math.floor(secs/60); + var ret = "" + m + "m " + (secs%60) + "s"; + return ret; +} + function initBoard() { for(i = 0; i<maxIndex; i++){ @@ -34,6 +43,7 @@ function initBoard() startCreatingBlock(xIdx,yIdx); } } + timer = new Date(); } var fillFound;//Set after a floodFill call to the number of tiles found @@ -134,8 +144,10 @@ function victoryCheck() gameCanvas.score += 500; //Checks for game over if(deservesBonus || !(floodMoveCheck(0,maxY-1, -1))){ - dialog.text = "Game Over. Your score is " + gameCanvas.score; - dialog.opacity = 1; + dialog.show("Game Over. Your score is " + gameCanvas.score); + timer = new Date() - timer; + if(scoresURL != "") + scoreName.show("Please enter your name: "); } } @@ -209,3 +221,16 @@ function startCreatingBlock(xIdx,yIdx){ component.statusChanged.connect(finishCreatingBlock()); return; } + +function sendHighScore(name) { + var postman = new XMLHttpRequest() + var postData = "name="+name+"&score="+gameCanvas.score + +"&gridSize="+maxX+"x"+maxY +"&time="+Math.floor(timer/1000); + postman.open("POST", scoresURL, true); + postman.onreadystatechange = function() { + if (postman.readyState == postman.DONE) { + dialog.show("Your score has been uploaded."); + } + } + postman.send(postData); +} diff --git a/demos/declarative/samegame/highscores/README b/demos/declarative/samegame/highscores/README new file mode 100644 index 0000000..eaa00fa --- /dev/null +++ b/demos/declarative/samegame/highscores/README @@ -0,0 +1 @@ +The SameGame example can interface with a simple PHP script to store XML high score data on a remote server. We do not have a publically accessible server available for this use, but if you have access to a PHP capable webserver you can copy the files (score_data.xml, score.php, score_style.xsl) to it and alter the highscore_server variable at the top of the samegame.js file to point to it. diff --git a/demos/declarative/samegame/highscores/score_data.xml b/demos/declarative/samegame/highscores/score_data.xml new file mode 100755 index 0000000..c3fd90d --- /dev/null +++ b/demos/declarative/samegame/highscores/score_data.xml @@ -0,0 +1,2 @@ +<record><score>1000000</score><name>Alan the Tester</name><gridSize>0x0</gridSize><seconds>0</seconds></record> +<record><score>6213</score><name>Alan</name><gridSize>12x17</gridSize><seconds>51</seconds></record> diff --git a/demos/declarative/samegame/highscores/score_style.xsl b/demos/declarative/samegame/highscores/score_style.xsl new file mode 100755 index 0000000..7dcf07e --- /dev/null +++ b/demos/declarative/samegame/highscores/score_style.xsl @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> +<xsl:template match="/"> + <html> + <head><title>SameGame High Scores</title></head> + <body> + <h2>SameGame High Scores</h2> + <table border="1"> + <tr bgcolor="lightsteelblue"> + <th>Name</th> + <th>Score</th> + <th>Grid Size</th> + <th>Time, s</th> + </tr> + <xsl:for-each select="records/record"> + <tr> + <td><xsl:value-of select="name"/></td> + <td><xsl:value-of select="score"/></td> + <td><xsl:value-of select="gridSize"/></td> + <td><xsl:value-of select="seconds"/></td> + </tr> + </xsl:for-each> + </table> + </body> + </html> +</xsl:template> +</xsl:stylesheet> diff --git a/demos/declarative/samegame/highscores/scores.php b/demos/declarative/samegame/highscores/scores.php new file mode 100755 index 0000000..3cceb2d --- /dev/null +++ b/demos/declarative/samegame/highscores/scores.php @@ -0,0 +1,34 @@ +<?php + $score = $_POST["score"]; + echo "<html>"; + echo "<head><title>SameGame High Scores</title></head><body>"; + if($score > 0){#Sending in a new high score + $name = $_POST["name"]; + $grid = $_POST["gridSize"]; + $time = $_POST["time"]; + if($name == "") + $name = "Anonymous"; + //if($grid != "10x10"){ + //Need a standard, so as to reject others? + //} + $file = fopen("score_data.xml", "a"); #It's XML. Happy? + $ret = fwrite($file, "<record><score>". $score . "</score><name>" + . $name . "</name><gridSize>" . $grid . "</gridSize><seconds>" + . $time . "</seconds></record>\n"); + echo "Your score has been recorded. Thanks for playing!"; + if($ret == False) + echo "<br/> There was an error though, so don't expect to see that score again."; + }else{#Read high score list + #Now uses XSLT to display. So just print the file. With XML cruft added. + #Note that firefox at least won't apply the XSLT on a php file. So redirecting + $file = fopen("scores.xml", "w"); + $ret = fwrite($file, '<?xml version="1.0" encoding="ISO-8859-1"?>' . "\n" + . '<?xml-stylesheet type="text/xsl" href="score_style.xsl"?>' . "\n" + . "<records>\n" . file_get_contents("score_data.xml") . "</records>\n"); + if($ret == False) + echo "There was an internal error. Sorry."; + else + echo '<script type="text/javascript">window.location.replace("scores.xml")</script>'; + } + echo "</body></html>"; +?> diff --git a/examples/declarative/listview/recipes.qml b/examples/declarative/listview/recipes.qml index eac8bb5..2148ef4 100644 --- a/examples/declarative/listview/recipes.qml +++ b/examples/declarative/listview/recipes.qml @@ -104,9 +104,9 @@ Rectangle { // Make the detailed view fill the entire list area PropertyChanges { target: wrapper; height: List.height } // Move the list so that this item is at the top. - PropertyChanges { target: wrapper.ListView.view; explicit: true; yPosition: wrapper.y } + PropertyChanges { target: wrapper.ListView.view; explicit: true; viewportY: wrapper.y } // Disallow flicking while we're in detailed view - PropertyChanges { target: wrapper.ListView.view; locked: 1 } + PropertyChanges { target: wrapper.ListView.view; interactive: false } } ] transitions: [ @@ -115,7 +115,7 @@ Rectangle { ParallelAnimation { ColorAnimation { property: "color"; duration: 500 } NumberAnimation { - duration: 300; properties: "detailsOpacity,x,yPosition,height,width" + duration: 300; properties: "detailsOpacity,x,viewportY,height,width" } } } diff --git a/examples/declarative/tutorials/contacts/3_Collections/2/ContactView.qml b/examples/declarative/tutorials/contacts/3_Collections/2/ContactView.qml index d16e3ca..8ee51c3 100644 --- a/examples/declarative/tutorials/contacts/3_Collections/2/ContactView.qml +++ b/examples/declarative/tutorials/contacts/3_Collections/2/ContactView.qml @@ -84,7 +84,7 @@ Item { } PropertyChanges { target: contactListView - locked: 1 + interactive: 0 } PropertyChanges { target: label diff --git a/examples/declarative/tutorials/contacts/3_Collections/3/ContactView.qml b/examples/declarative/tutorials/contacts/3_Collections/3/ContactView.qml index bf73367..76dc3e2 100644 --- a/examples/declarative/tutorials/contacts/3_Collections/3/ContactView.qml +++ b/examples/declarative/tutorials/contacts/3_Collections/3/ContactView.qml @@ -102,7 +102,7 @@ Item { } PropertyChanges { target: contactListView - locked: 1 + interactive: 0 } PropertyChanges { target: label diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 069bf49..a401a70 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -1,7 +1,7 @@ QML API Review ============== -The QML API is being reviewed from 17 to 28 August 2009. This +The QML API is being reviewed from 17 to 4 September 2009. This file documents the changes. Note that the changes are incremental, so a rename A->B for example may be follow by another subseqent rename B->C, if later reviews override earlier reviews. @@ -47,6 +47,7 @@ Flickable: yPosition -> viewportY Flickable: xVelocity -> horizontalVelocity Flickable: yVelocity -> verticalVelocity Flickable: velocityDecay -> reportedVelocitySmoothing +Flickable: locked -> interactive (note reversal of meaning) WebView: idealWidth -> preferredWidth WebView: idealHeight -> preferredHeight WebView: status -> statusText diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp index 118658f..cd15ac9 100644 --- a/src/declarative/fx/qfxflickable.cpp +++ b/src/declarative/fx/qfxflickable.cpp @@ -95,7 +95,7 @@ void ElasticValue::updateCurrentTime(int) QFxFlickablePrivate::QFxFlickablePrivate() : _flick(new QFxItem), _moveX(_flick, &QFxItem::setX), _moveY(_flick, &QFxItem::setY) , vWidth(-1), vHeight(-1), overShoot(true), flicked(false), moving(false), stealMouse(false) - , pressed(false), maxVelocity(-1), locked(false), dragMode(QFxFlickable::Hard) + , pressed(false), maxVelocity(-1), interactive(true), dragMode(QFxFlickable::Hard) , elasticY(_moveY), elasticX(_moveX), reportedVelocitySmoothing(100), horizontalVelocity(this), verticalVelocity(this) , vTime(0), atXEnd(false), atXBeginning(true), pageXPosition(0.), pageWidth(0.) , atYEnd(false), atYBeginning(true), pageYPosition(0.), pageHeight(0.) @@ -201,12 +201,12 @@ void QFxFlickablePrivate::fixupX() vTime = _tl.time(); if (_moveX.value() > q->minXExtent() || (q->maxXExtent() > q->maxXExtent())) { - _tl.clear(); + _tl.reset(_moveY); if (_moveX.value() != q->minXExtent()) _tl.move(_moveX, q->minXExtent(), QEasingCurve(QEasingCurve::InOutQuad), 200); //emit flickingChanged(); } else if (_moveX.value() < q->maxXExtent()) { - _tl.clear(); + _tl.reset(_moveY); _tl.move(_moveX, q->maxXExtent(), QEasingCurve(QEasingCurve::InOutQuad), 200); //emit flickingChanged(); } else { @@ -223,12 +223,12 @@ void QFxFlickablePrivate::fixupY() vTime = _tl.time(); if (_moveY.value() > q->minYExtent() || (q->maxYExtent() > q->minYExtent())) { - _tl.clear(); + _tl.reset(_moveY); if (_moveY.value() != q->minYExtent()) _tl.move(_moveY, q->minYExtent(), QEasingCurve(QEasingCurve::InOutQuad), 200); //emit flickingChanged(); } else if (_moveY.value() < q->maxYExtent()) { - _tl.clear(); + _tl.reset(_moveY); _tl.move(_moveY, q->maxYExtent(), QEasingCurve(QEasingCurve::InOutQuad), 200); //emit flickingChanged(); } else { @@ -411,24 +411,30 @@ void QFxFlickable::setViewportY(qreal pos) } /*! - \qmlproperty bool Flickable::locked + \qmlproperty bool Flickable::interactive - A user cannot drag or flick a Flickable that is locked. + A user cannot drag or flick a Flickable that is not interactive. This property is useful for temporarily disabling flicking. This allows special interaction with Flickable's children: for example, you might want to freeze a flickable map while viewing detailed information on a location popup that is a child of the Flickable. */ -bool QFxFlickable::isLocked() const +bool QFxFlickable::isInteractive() const { Q_D(const QFxFlickable); - return d->locked; + return d->interactive; } -void QFxFlickable::setLocked(bool lock) +void QFxFlickable::setInteractive(bool interactive) { Q_D(QFxFlickable); - d->locked = lock; + d->interactive = interactive; + if (!interactive && d->flicked) { + d->_tl.clear(); + d->flicked = false; + emit flickingChanged(); + emit flickEnded(); + } } /*! @@ -577,7 +583,7 @@ qreal QFxFlickable::visibleY() const void QFxFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event) { - if (!locked && _tl.isActive() && (qAbs(velocityX) > 10 || qAbs(velocityY) > 10)) + if (interactive && _tl.isActive() && (qAbs(velocityX) > 10 || qAbs(velocityY) > 10)) stealMouse = true; // If we've been flicked then steal the click. else stealMouse = false; @@ -602,7 +608,7 @@ void QFxFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event) void QFxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) { Q_Q(QFxFlickable); - if (locked || lastPosTime.isNull()) + if (!interactive || lastPosTime.isNull()) return; bool rejectY = false; bool rejectX = false; diff --git a/src/declarative/fx/qfxflickable.h b/src/declarative/fx/qfxflickable.h index c27b29f..57a01d7 100644 --- a/src/declarative/fx/qfxflickable.h +++ b/src/declarative/fx/qfxflickable.h @@ -69,7 +69,7 @@ class Q_DECLARATIVE_EXPORT QFxFlickable : public QFxItem Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged) Q_PROPERTY(bool flicking READ isFlicking NOTIFY flickingChanged) - Q_PROPERTY(bool locked READ isLocked WRITE setLocked) //### interactive, ensure flicking is stopped, etc. + Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive) Q_PROPERTY(DragMode dragMode READ dragMode WRITE setDragMode) //### remove. Consider a better way to implement different drag behavior Q_PROPERTY(bool atXEnd READ isAtXEnd NOTIFY isAtBoundaryChanged) @@ -117,8 +117,8 @@ public: qreal maximumFlickVelocity() const; void setMaximumFlickVelocity(qreal); - bool isLocked() const; - void setLocked(bool); + bool isInteractive() const; + void setInteractive(bool); Q_ENUMS(DragMode) enum DragMode { Hard, Elastic }; diff --git a/src/declarative/fx/qfxflickable_p.h b/src/declarative/fx/qfxflickable_p.h index a0ac011..ad9484f 100644 --- a/src/declarative/fx/qfxflickable_p.h +++ b/src/declarative/fx/qfxflickable_p.h @@ -121,7 +121,7 @@ public: QmlTimeLineEvent fixupXEvent; QmlTimeLineEvent fixupYEvent; qreal maxVelocity; - bool locked; + bool interactive; QFxFlickable::DragMode dragMode; ElasticValue elasticY; ElasticValue elasticX; diff --git a/src/declarative/fx/qfxgridview.cpp b/src/declarative/fx/qfxgridview.cpp index 138a8ae..6fd080b 100644 --- a/src/declarative/fx/qfxgridview.cpp +++ b/src/declarative/fx/qfxgridview.cpp @@ -1069,7 +1069,7 @@ qreal QFxGridView::maxXExtent() const void QFxGridView::keyPressEvent(QKeyEvent *event) { Q_D(QFxGridView); - if (d->model && d->model->count() && !d->locked) { + if (d->model && d->model->count() && d->interactive) { if ((d->flow == QFxGridView::LeftToRight && event->key() == Qt::Key_Up) || (d->flow == QFxGridView::TopToBottom && event->key() == Qt::Key_Left)) { if (currentIndex() >= d->columns || d->wrap) { diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index c436622..d28f531 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -928,7 +928,7 @@ private: virtual void keyPressed(QKeyEvent *event); virtual void keyReleased(QKeyEvent *event); - const char *keyToSignal(int key) { + const QByteArray keyToSignal(int key) { QByteArray keySignal; if (key >= Qt::Key_0 && key <= Qt::Key_9) { keySignal = "digit0Pressed"; diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index 147c977..34fe827 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -1344,7 +1344,7 @@ qreal QFxListView::maxXExtent() const void QFxListView::keyPressEvent(QKeyEvent *event) { Q_D(QFxListView); - if (d->model && d->model->count() && !d->locked) { + if (d->model && d->model->count() && d->interactive) { if ((d->orient == Qt::Horizontal && event->key() == Qt::Key_Left) || (d->orient == Qt::Vertical && event->key() == Qt::Key_Up)) { if (currentIndex() > 0 || d->wrap) { diff --git a/src/declarative/fx/qfxrect.cpp b/src/declarative/fx/qfxrect.cpp index f8223f2..fbd7ee8 100644 --- a/src/declarative/fx/qfxrect.cpp +++ b/src/declarative/fx/qfxrect.cpp @@ -328,63 +328,6 @@ void QFxRect::setColor(const QColor &c) update(); } -/*! - \qmlproperty color Rectangle::tintColor - This property holds The color to tint the rectangle. - - This color will be drawn over the rectangle's color when the rectangle is painted. The tint color should usually be mostly transparent, or you will not be able to see the underlying color. The below example provides a slight red tint by having the tint color be pure red which is only 1/16th opaque. - - \qml - Rectangle { x: 0; width: 80; height: 80; color: "lightsteelblue" } - Rectangle { x: 100; width: 80; height: 80; color: "lightsteelblue"; tintColor: "#10FF0000" } - \endqml - \image declarative-rect_tint.png - - This attribute is not intended to be used with a single color over the lifetime of an user interface. It is most useful when a subtle change is intended to be conveyed due to some event; you can then use the tint color to more effectively tune the visible color. -*/ -QColor QFxRect::tintColor() const -{ - Q_D(const QFxRect); - return d->tintColor; -} - -void QFxRect::setTintColor(const QColor &c) -{ - Q_D(QFxRect); - if (d->tintColor == c) - return; - - d->tintColor = c; - update(); -} - -QColor QFxRectPrivate::getColor() -{ - if (tintColor.isValid()) { - int a = tintColor.alpha(); - if (a == 0xFF) - return tintColor; - else if (a == 0x00) - return color; - else { - uint src = tintColor.rgba(); - uint dest = color.rgba(); - - uint res = (((a * (src & 0xFF00FF)) + - ((0xFF - a) * (dest & 0xFF00FF))) >> 8) & 0xFF00FF; - res |= (((a * ((src >> 8) & 0xFF00FF)) + - ((0xFF - a) * ((dest >> 8) & 0xFF00FF)))) & 0xFF00FF00; - if ((src & 0xFF000000) == 0xFF000000) - res |= 0xFF000000; - - return QColor::fromRgba(res); - } - } else { - return color; - } -} - - void QFxRect::generateRoundedRect() { Q_D(QFxRect); @@ -443,7 +386,7 @@ void QFxRect::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) bool oldAA = p->testRenderHint(QPainter::Antialiasing); if (d->smooth) p->setRenderHints(QPainter::Antialiasing, true); - p->fillRect(QRectF(0, 0, width(), height()), d->getColor()); + p->fillRect(QRectF(0, 0, width(), height()), d->color); if (d->smooth) p->setRenderHint(QPainter::Antialiasing, oldAA); } @@ -527,7 +470,7 @@ void QFxRect::drawRect(QPainter &p) // Middle if (xMiddles && yMiddles) // XXX paint errors in animation example - //p.fillRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw, d->getColor()); + //p.fillRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw, d->color); p.drawPixmap(QRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw), d->rectImage, QRect(d->rectImage.width()/2, d->rectImage.height()/2, 1, 1)); // Middle right diff --git a/src/declarative/fx/qfxrect.h b/src/declarative/fx/qfxrect.h index 359e8fc..439cc65 100644 --- a/src/declarative/fx/qfxrect.h +++ b/src/declarative/fx/qfxrect.h @@ -136,7 +136,6 @@ class Q_DECLARATIVE_EXPORT QFxRect : public QFxItem Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor) - Q_PROPERTY(QColor tintColor READ tintColor WRITE setTintColor) Q_PROPERTY(QFxGradient *gradient READ gradient WRITE setGradient) Q_PROPERTY(QFxPen * border READ border) Q_PROPERTY(qreal radius READ radius WRITE setRadius) @@ -146,9 +145,6 @@ public: QColor color() const; void setColor(const QColor &); - QColor tintColor() const; - void setTintColor(const QColor &); - QFxPen *border(); QFxGradient *gradient() const; diff --git a/src/declarative/fx/qfxrect_p.h b/src/declarative/fx/qfxrect_p.h index 25fa38d..8eb074a 100644 --- a/src/declarative/fx/qfxrect_p.h +++ b/src/declarative/fx/qfxrect_p.h @@ -81,7 +81,6 @@ public: QColor getColor(); QColor color; QFxGradient *gradient; - QColor tintColor; QFxPen *getPen() { if (!pen) { Q_Q(QFxRect); diff --git a/src/declarative/qml/qmldeclarativedata_p.h b/src/declarative/qml/qmldeclarativedata_p.h index 5a51eb7..a316c0c 100644 --- a/src/declarative/qml/qmldeclarativedata_p.h +++ b/src/declarative/qml/qmldeclarativedata_p.h @@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE class QmlCompiledData; class QmlAbstractBinding; +class QmlContext; class QmlDeclarativeData : public QDeclarativeData { public: @@ -69,6 +70,10 @@ public: QmlContext *context; QmlAbstractBinding *bindings; + QmlContext *outerContext; // Can't this be found from context? + ushort lineNumber; + ushort columnNumber; + QmlCompiledData *deferredComponent; // Can't this be found from the context? unsigned int deferredIdx; diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index d2d0590..e342d3f 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -80,6 +80,7 @@ #include <private/qmlbinding_p.h> #include <private/qmlvme_p.h> #include <private/qmlenginedebug_p.h> +#include <private/qmlstringconverters_p.h> #include <private/qmlxmlhttprequest_p.h> Q_DECLARE_METATYPE(QmlMetaProperty) @@ -107,7 +108,7 @@ QScriptValue desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e) } QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) -: rootContext(0), currentBindContext(0), currentExpression(0), +: rootContext(0), currentExpression(0), isDebugging(false), contextClass(0), objectClass(0), valueTypeClass(0), nodeListClass(0), namedNodeMapClass(0), scriptEngine(this), rootComponent(0), networkAccessManager(0), typeManager(e), uniqueId(1) @@ -121,12 +122,18 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) qt_add_qmlxmlhttprequest(&scriptEngine); + //types qtObject.setProperty(QLatin1String("rgba"), scriptEngine.newFunction(QmlEnginePrivate::rgba, 4)); qtObject.setProperty(QLatin1String("hsla"), scriptEngine.newFunction(QmlEnginePrivate::hsla, 4)); qtObject.setProperty(QLatin1String("rect"), scriptEngine.newFunction(QmlEnginePrivate::rect, 4)); qtObject.setProperty(QLatin1String("point"), scriptEngine.newFunction(QmlEnginePrivate::point, 2)); qtObject.setProperty(QLatin1String("size"), scriptEngine.newFunction(QmlEnginePrivate::size, 2)); qtObject.setProperty(QLatin1String("vector3d"), scriptEngine.newFunction(QmlEnginePrivate::vector, 3)); + + //color helpers + qtObject.setProperty(QLatin1String("lighter"), scriptEngine.newFunction(QmlEnginePrivate::lighter, 1)); + qtObject.setProperty(QLatin1String("darker"), scriptEngine.newFunction(QmlEnginePrivate::darker, 1)); + qtObject.setProperty(QLatin1String("tint"), scriptEngine.newFunction(QmlEnginePrivate::tint, 2)); } QmlEnginePrivate::~QmlEnginePrivate() @@ -199,13 +206,6 @@ void QmlEnginePrivate::init() } } -QmlContext *QmlEnginePrivate::setCurrentBindContext(QmlContext *c) -{ - QmlContext *old = currentBindContext; - currentBindContext = c; - return old; -} - QmlEnginePrivate::CapturedProperty::CapturedProperty(const QmlMetaProperty &p) : object(p.object()), coreIndex(p.coreIndex()), notifyIndex(p.property().notifySignalIndex()) { @@ -809,6 +809,111 @@ QScriptValue QmlEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine) return qScriptValueFromValue(engine, qVariantFromValue(QSizeF(w, h))); } +QScriptValue QmlEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine) +{ + if(ctxt->argumentCount() < 1) + return engine->nullValue(); + QVariant v = ctxt->argument(0).toVariant(); + QColor color; + if (v.type() == QVariant::Color) + color = v.value<QColor>(); + else if (v.type() == QVariant::String) { + bool ok; + color = QmlStringConverters::colorFromString(v.toString(), &ok); + if (!ok) + return engine->nullValue(); + } else + return engine->nullValue(); + color = color.lighter(); + return qScriptValueFromValue(engine, qVariantFromValue(color)); +} + +QScriptValue QmlEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine) +{ + if(ctxt->argumentCount() < 1) + return engine->nullValue(); + QVariant v = ctxt->argument(0).toVariant(); + QColor color; + if (v.type() == QVariant::Color) + color = v.value<QColor>(); + else if (v.type() == QVariant::String) { + bool ok; + color = QmlStringConverters::colorFromString(v.toString(), &ok); + if (!ok) + return engine->nullValue(); + } else + return engine->nullValue(); + color = color.darker(); + return qScriptValueFromValue(engine, qVariantFromValue(color)); +} + +/*! + This function allows tinting one color with another. + + The tint color should usually be mostly transparent, or you will not be able to see the underlying color. The below example provides a slight red tint by having the tint color be pure red which is only 1/16th opaque. + + \qml + Rectangle { x: 0; width: 80; height: 80; color: "lightsteelblue" } + Rectangle { x: 100; width: 80; height: 80; color: Qt.tint("lightsteelblue", "#10FF0000") } + \endqml + \image declarative-rect_tint.png + + Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color. +*/ +QScriptValue QmlEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine) +{ + if(ctxt->argumentCount() < 2) + return engine->nullValue(); + //get color + QVariant v = ctxt->argument(0).toVariant(); + QColor color; + if (v.type() == QVariant::Color) + color = v.value<QColor>(); + else if (v.type() == QVariant::String) { + bool ok; + color = QmlStringConverters::colorFromString(v.toString(), &ok); + if (!ok) + return engine->nullValue(); + } else + return engine->nullValue(); + + //get tint color + v = ctxt->argument(1).toVariant(); + QColor tintColor; + if (v.type() == QVariant::Color) + tintColor = v.value<QColor>(); + else if (v.type() == QVariant::String) { + bool ok; + tintColor = QmlStringConverters::colorFromString(v.toString(), &ok); + if (!ok) + return engine->nullValue(); + } else + return engine->nullValue(); + + //tint + QColor finalColor; + int a = tintColor.alpha(); + if (a == 0xFF) + finalColor = tintColor; + else if (a == 0x00) + finalColor = color; + else { + uint src = tintColor.rgba(); + uint dest = color.rgba(); + + uint res = (((a * (src & 0xFF00FF)) + + ((0xFF - a) * (dest & 0xFF00FF))) >> 8) & 0xFF00FF; + res |= (((a * ((src >> 8) & 0xFF00FF)) + + ((0xFF - a) * ((dest >> 8) & 0xFF00FF)))) & 0xFF00FF00; + if ((src & 0xFF000000) == 0xFF000000) + res |= 0xFF000000; + + finalColor = QColor::fromRgba(res); + } + + return qScriptValueFromValue(engine, qVariantFromValue(finalColor)); +} + QmlScriptClass::QmlScriptClass(QmlEngine *bindengine) : QScriptClass(QmlEnginePrivate::getScriptEngine(bindengine)), engine(bindengine) diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index b3c6279..a33add3 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -114,7 +114,6 @@ public: QPODVector<CapturedProperty> capturedProperties; QmlContext *rootContext; - QmlContext *currentBindContext; // ### Remove me QmlExpression *currentExpression; bool isDebugging; #ifdef QT_SCRIPTTOOLS_LIB @@ -128,9 +127,6 @@ public: QScriptClass *nodeListClass; QScriptClass *namedNodeMapClass; - QmlContext *setCurrentBindContext(QmlContext *); - QStack<QmlContext *> activeContexts; // ### Remove me - struct QmlScriptEngine : public QScriptEngine { QmlScriptEngine(QmlEnginePrivate *priv) @@ -223,6 +219,10 @@ public: static QScriptValue size(QScriptContext*, QScriptEngine*); static QScriptValue rect(QScriptContext*, QScriptEngine*); + static QScriptValue lighter(QScriptContext*, QScriptEngine*); + static QScriptValue darker(QScriptContext*, QScriptEngine*); + static QScriptValue tint(QScriptContext*, QScriptEngine*); + static QScriptEngine *getScriptEngine(QmlEngine *e) { return &e->d_func()->scriptEngine; } static QmlEngine *getEngine(QScriptEngine *e) { return static_cast<QmlScriptEngine*>(e)->p->q_func(); } static QmlEnginePrivate *get(QmlEngine *e) { return e->d_func(); } diff --git a/src/declarative/qml/qmlenginedebug.cpp b/src/declarative/qml/qmlenginedebug.cpp index 0e78cad..321fe74 100644 --- a/src/declarative/qml/qmlenginedebug.cpp +++ b/src/declarative/qml/qmlenginedebug.cpp @@ -181,9 +181,16 @@ void QmlEngineDebugServer::buildObjectList(QDataStream &message, QmlEngineDebugServer::QmlObjectData QmlEngineDebugServer::objectData(QObject *object) { + QmlDeclarativeData *ddata = QmlDeclarativeData::get(object); QmlObjectData rv; - rv.lineNumber = -1; - rv.columnNumber = -1; + if (ddata) { + rv.url = ddata->outerContext->baseUrl(); + rv.lineNumber = ddata->lineNumber; + rv.columnNumber = ddata->columnNumber; + } else { + rv.lineNumber = -1; + rv.columnNumber = -1; + } rv.objectName = object->objectName(); rv.objectType = object->metaObject()->className(); diff --git a/src/declarative/qml/qmlinfo.cpp b/src/declarative/qml/qmlinfo.cpp index 65a4298..e47b4ab 100644 --- a/src/declarative/qml/qmlinfo.cpp +++ b/src/declarative/qml/qmlinfo.cpp @@ -40,6 +40,8 @@ ****************************************************************************/ #include "qmlinfo.h" +#include <private/qmldeclarativedata_p.h> +#include <QtDeclarative/qmlcontext.h> QT_BEGIN_NAMESPACE @@ -80,7 +82,19 @@ QmlInfo::QmlInfo(QObject *object) *this << "QML"; if (object) *this << object->metaObject()->className(); - *this << "(unknown location):"; + QmlDeclarativeData *ddata = QmlDeclarativeData::get(object); + if (ddata) { + QString location = QLatin1String("("); + location += ddata->outerContext->baseUrl().toString(); + location += QLatin1String(":"); + location += QString::number(ddata->lineNumber); + location += QLatin1String(":"); + location += QString::number(ddata->columnNumber); + location += QLatin1String(")"); + *this << location.toLatin1().constData(); + } else { + *this << "(unknown location):"; + } } /*! diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h index 8861609a..ede06a2 100644 --- a/src/declarative/qml/qmlinstruction_p.h +++ b/src/declarative/qml/qmlinstruction_p.h @@ -170,6 +170,7 @@ public: struct { int type; int data; + ushort column; } create; struct { int data; diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index 930e6e4..7907195 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -174,6 +174,11 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData VME_EXCEPTION("Unable to create object of type" << types.at(instr.create.type).className); } + QmlDeclarativeData *ddata = QmlDeclarativeData::get(o); + ddata->outerContext = ctxt; + ddata->lineNumber = instr.line; + ddata->columnNumber = instr.create.column; + if (instr.create.data != -1) { QmlCustomParser *customParser = types.at(instr.create.type).type->customParser(); diff --git a/tests/auto/declarative/qfxtextinput/data/navigation.qml b/tests/auto/declarative/qfxtextinput/data/navigation.qml new file mode 100644 index 0000000..c1a6162 --- /dev/null +++ b/tests/auto/declarative/qfxtextinput/data/navigation.qml @@ -0,0 +1,23 @@ +import Qt 4.6 + +Rectangle { + property var myInput: Input + + width: 800; height: 600; color: "blue" + + Item { + id: FirstItem + KeyNavigation.right: Input + } + + TextInput { id: Input; focus: true; + KeyNavigation.left: FirstItem + KeyNavigation.right: LastItem + KeyNavigation.up: FirstItem + KeyNavigation.down: LastItem + } + Item { + id: LastItem + KeyNavigation.left: Input + } +} diff --git a/tests/auto/declarative/qfxtextinput/qfxtextinput.pro b/tests/auto/declarative/qfxtextinput/qfxtextinput.pro new file mode 100644 index 0000000..396e66d --- /dev/null +++ b/tests/auto/declarative/qfxtextinput/qfxtextinput.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative gui +SOURCES += tst_qfxtextinput.cpp + +# Define SRCDIR equal to test's source directory +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qfxtextinput/tst_qfxtextinput.cpp b/tests/auto/declarative/qfxtextinput/tst_qfxtextinput.cpp new file mode 100644 index 0000000..852a868 --- /dev/null +++ b/tests/auto/declarative/qfxtextinput/tst_qfxtextinput.cpp @@ -0,0 +1,78 @@ +#include <qtest.h> +#include <QtDeclarative/qmlengine.h> +#include <QFile> +#include <QtDeclarative/qfxview.h> +#include <qfxtextinput.h> +#include <QDebug> + +class tst_qfxtextinput : public QObject + +{ + Q_OBJECT +public: + tst_qfxtextinput(); + +private slots: + void navigation(); + +private: + void simulateKey(QFxView *, int key); + QFxView *createView(const QString &filename); + + QmlEngine engine; +}; + +tst_qfxtextinput::tst_qfxtextinput() +{ +} + +/* +TextInput element should only handle left/right keys until the cursor reaches +the extent of the text, then they should ignore the keys. +*/ +void tst_qfxtextinput::navigation() +{ + QFxView *canvas = createView(SRCDIR "/data/navigation.qml"); + canvas->execute(); + canvas->show(); + + QVERIFY(canvas->root() != 0); + + QFxItem *input = qobject_cast<QFxItem *>(qvariant_cast<QObject *>(canvas->root()->property("myInput"))); + + QVERIFY(input != 0); + QVERIFY(input->hasFocus() == true); + simulateKey(canvas, Qt::Key_Left); + QVERIFY(input->hasFocus() == false); + simulateKey(canvas, Qt::Key_Right); + QVERIFY(input->hasFocus() == true); + simulateKey(canvas, Qt::Key_Right); + QVERIFY(input->hasFocus() == false); + simulateKey(canvas, Qt::Key_Left); + QVERIFY(input->hasFocus() == true); +} + +void tst_qfxtextinput::simulateKey(QFxView *view, int key) +{ + QKeyEvent press(QKeyEvent::KeyPress, key, 0); + QKeyEvent release(QKeyEvent::KeyRelease, key, 0); + + QApplication::sendEvent(view, &press); + QApplication::sendEvent(view, &release); +} + +QFxView *tst_qfxtextinput::createView(const QString &filename) +{ + QFxView *canvas = new QFxView(0); + + QFile file(filename); + file.open(QFile::ReadOnly); + QString xml = file.readAll(); + canvas->setQml(xml, filename); + + return canvas; +} + +QTEST_MAIN(tst_qfxtextinput) + +#include "tst_qfxtextinput.moc" diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp index 36471a4..e953717 100644 --- a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp +++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp @@ -429,23 +429,25 @@ void tst_qmlparser::autoComponentCreation() void tst_qmlparser::propertyValueSource() { - QVERIFY(false); - -/* Does not compile... - QmlComponent component(&engine, TEST_FILE("propertyValueSource.qml")); VERIFY_ERRORS(0); MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); QVERIFY(object != 0); - QList<QmlPropertyValueSource *> valueSources = - object->findChildren<QmlPropertyValueSource *>(); + + QList<QObject *> valueSources; + QObjectList allChildren = object->findChildren<QObject*>(); + foreach (QObject *child, allChildren) { + QmlType *type = QmlMetaType::qmlType(child->metaObject()); + if (type && type->propertyValueSourceCast() != -1) + valueSources.append(child); + } + QCOMPARE(valueSources.count(), 1); MyPropertyValueSource *valueSource = qobject_cast<MyPropertyValueSource *>(valueSources.at(0)); QVERIFY(valueSource != 0); QCOMPARE(valueSource->prop.object(), object); QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty"))); -*/ } void tst_qmlparser::attachedProperties() |