From 1ccca16e3e032cb90d09dc4a161fe35114d8360d Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 2 Sep 2009 12:59:09 +1000 Subject: SameGame high score server support. This commit contains all the functionality for sending high scores to a server, and the server. The server files have been installed at http://qtfx-nokia.trolltech.com.au/samegame for internal testing. --- demos/declarative/samegame/content/samegame.js | 46 +++++++++++++++++++++- demos/declarative/samegame/highscores/README | 1 + .../declarative/samegame/highscores/score_data.xml | 2 + .../samegame/highscores/score_style.xsl | 27 +++++++++++++ demos/declarative/samegame/highscores/scores.php | 34 ++++++++++++++++ 5 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 demos/declarative/samegame/highscores/README create mode 100755 demos/declarative/samegame/highscores/score_data.xml create mode 100755 demos/declarative/samegame/highscores/score_style.xsl create mode 100755 demos/declarative/samegame/highscores/scores.php diff --git a/demos/declarative/samegame/content/samegame.js b/demos/declarative/samegame/content/samegame.js index f04fb4c..355dbfd 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; i1000000Alan the Tester0x00 +6213Alan12x1751 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 @@ + + + + + SameGame High Scores + +

SameGame High Scores

+ + + + + + + + + + + + + + + +
NameScoreGrid SizeTime, s
+ + +
+
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 @@ +"; + echo "SameGame High Scores"; + 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, "". $score . "" + . $name . "" . $grid . "" + . $time . "\n"); + echo "Your score has been recorded. Thanks for playing!"; + if($ret == False) + echo "
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, '' . "\n" + . '' . "\n" + . "\n" . file_get_contents("score_data.xml") . "\n"); + if($ret == False) + echo "There was an internal error. Sorry."; + else + echo ''; + } + echo ""; +?> -- cgit v0.12 From 9c831fc9a405dcfefbbf4bad09a8f95bd682c0eb Mon Sep 17 00:00:00 2001 From: "Mehul R. Patel" Date: Wed, 2 Sep 2009 13:16:35 +1000 Subject: =?UTF-8?q?Fixed=20crash=20in=20keyPressed.=20keyToSignal=20functi?= =?UTF-8?q?on=20suppose=20to=20return=20=E2=80=9Cconst=20QbyteArray?= =?UTF-8?q?=E2=80=9D=20not=20=E2=80=9Cconst=20char=20*=E2=80=9D.=20Crash?= =?UTF-8?q?=20was=20coming=20because=20keyPressed=20was=20getting=20invali?= =?UTF-8?q?d=20memory=20pointer=20from=20keyToSignal=20function.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 1374 Reviewed-by: Martin Jones --- src/declarative/fx/qfxitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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"; -- cgit v0.12 From c67b9e5e9925d422dca0c5243f91c3e08fe90304 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 2 Sep 2009 13:25:52 +1000 Subject: SameGame now asks for a name and saves your score. Included a rewriting of the Dialog item to be half-decent. Watch http://qtfx-nokia.trolltech.com.au/samegame/scores.php on the internal network for highscores! --- demos/declarative/samegame/SameGame.qml | 13 +++++++++++++ demos/declarative/samegame/content/Dialog.qml | 18 ++++++++++++------ demos/declarative/samegame/content/samegame.js | 12 +++++------- 3 files changed, 30 insertions(+), 13 deletions(-) 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 355dbfd..d890cd2 100755 --- a/demos/declarative/samegame/content/samegame.js +++ b/demos/declarative/samegame/content/samegame.js @@ -144,10 +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 != "") sendHighScore(name); + if(scoresURL != "") + scoreName.show("Please enter your name: "); } } @@ -233,8 +233,7 @@ function tweetHighScore(twitterName, twitterPass) { postman.open("POST", "http://twitter.com/statuses/update.xml", true, twitterName, twitterPass); postman.onreadystatechange = function() { if (postman.readyState == postman.DONE) { - dialog.text = "Your score has been tweeted for you."; - dialog.opacity = 1; + dialog.show("Your score has been tweeted for you."); } } postman.send(postData); @@ -247,8 +246,7 @@ function sendHighScore(name) { postman.open("POST", scoresURL, true); postman.onreadystatechange = function() { if (postman.readyState == postman.DONE) { - dialog.text = "Your score has been uploaded."; - dialog.opacity = 1; + dialog.show("Your score has been uploaded."); } } postman.send(postData); -- cgit v0.12 From 5477cb3bbc97e4b419c5ea5bbe4f137959b9140d Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 2 Sep 2009 13:29:08 +1000 Subject: Don't need to tweet high scores too --- demos/declarative/samegame/content/samegame.js | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/demos/declarative/samegame/content/samegame.js b/demos/declarative/samegame/content/samegame.js index d890cd2..9914edb 100755 --- a/demos/declarative/samegame/content/samegame.js +++ b/demos/declarative/samegame/content/samegame.js @@ -222,23 +222,6 @@ function startCreatingBlock(xIdx,yIdx){ return; } -function tweetHighScore(twitterName, twitterPass) { - if(twitterName == '' || twitterPass == '') - return false;//Can't login like that - - var scoreStr = "I just played the QML SameGame, and got " + gameCanvas.score + " points on a " - + maxX + "x" + maxY + " grid. It took me " + timeStr(timer) + "."; - var postData = "status=" + scoreStr; - var postman = new XMLHttpRequest(); - postman.open("POST", "http://twitter.com/statuses/update.xml", true, twitterName, twitterPass); - postman.onreadystatechange = function() { - if (postman.readyState == postman.DONE) { - dialog.show("Your score has been tweeted for you."); - } - } - postman.send(postData); -} - function sendHighScore(name) { var postman = new XMLHttpRequest() var postData = "name="+name+"&score="+gameCanvas.score -- cgit v0.12 From 9e7bd55bde0d614719c67977507b270dc7326f05 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 2 Sep 2009 13:34:07 +1000 Subject: Save object creation line and column number This info is used by the debugger interface, and by the qmlInfo() stream. --- src/declarative/qml/qmldeclarativedata_p.h | 5 +++++ src/declarative/qml/qmlenginedebug.cpp | 11 +++++++++-- src/declarative/qml/qmlinfo.cpp | 16 +++++++++++++++- src/declarative/qml/qmlinstruction_p.h | 1 + src/declarative/qml/qmlvme.cpp | 5 +++++ 5 files changed, 35 insertions(+), 3 deletions(-) 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/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 +#include 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 &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(); -- cgit v0.12 From c3af2cb805d1ac5f7a5a944a23dc4c4238f8f530 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 2 Sep 2009 15:02:46 +1000 Subject: Provide some color manipulation functions. These may not be the final location for these, but it allows us to start testing. --- src/declarative/fx/qfxrect.cpp | 61 +-------------------- src/declarative/fx/qfxrect.h | 4 -- src/declarative/fx/qfxrect_p.h | 1 - src/declarative/qml/qmlengine.cpp | 112 ++++++++++++++++++++++++++++++++++++++ src/declarative/qml/qmlengine_p.h | 4 ++ 5 files changed, 118 insertions(+), 64 deletions(-) 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/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index d2d0590..0bd3931 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -80,6 +80,7 @@ #include #include #include +#include #include Q_DECLARE_METATYPE(QmlMetaProperty) @@ -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() @@ -809,6 +816,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(); + 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(); + 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(); + 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(); + 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..1e251cc 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -223,6 +223,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(e)->p->q_func(); } static QmlEnginePrivate *get(QmlEngine *e) { return e->d_func(); } -- cgit v0.12