From 68690c3703b151e95eb5dfd8d9db7afda49c7c6f Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Fri, 29 Aug 2014 11:33:28 +0200 Subject: Bump version Change-Id: I54ace3320d63c54119084b27eb2c1797166f0b37 --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index effef04600..a118d53139 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -2,4 +2,4 @@ load(qt_build_config) CONFIG += qt_example_installs CONFIG += warning_clean -MODULE_VERSION = 5.3.2 +MODULE_VERSION = 5.3.3 -- cgit v1.2.3 From 8f3311276e4ca44acb69c8870ccfc3167682b898 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 28 Aug 2014 11:27:02 +0200 Subject: Fix crash with cleanup of animators. We had several separate issues relating to how the jobs were cleaned up. The first was that upon getting setWindow(0), the animator did not reset m_controller to 0, leading to the starts() coming after that to post null jobs to the controller. This would later crash in beforeNodeSync as the starting job was null. The second issue was that during shutdown, QQuickAnimatorProxy would try to delete jobs on the controller which was already deleted. The controller is deleted on the GUI thread regardless of render loop, so this was solved with a QPointer. The third was that we were a bit too aggressive in trying to clean up jobs on the GUI thread, so we introduced a new bool which gets set to true in startJob() so that Proxy::deleteJob() knows who owns the job. Task-number: QTBUG-37833 Change-Id: I1b6221a2c1ce2bfd0758801b950cda00ff6899d0 Reviewed-by: Michael Brasser --- src/quick/util/qquickanimatorcontroller.cpp | 1 + src/quick/util/qquickanimatorjob.cpp | 14 ++++++++++---- src/quick/util/qquickanimatorjob_p.h | 4 +++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp index 697c25b211..f8e24bf9fb 100644 --- a/src/quick/util/qquickanimatorcontroller.cpp +++ b/src/quick/util/qquickanimatorcontroller.cpp @@ -262,6 +262,7 @@ void QQuickAnimatorController::requestSync() // These functions are called on the GUI thread. void QQuickAnimatorController::startJob(QQuickAnimatorProxyJob *proxy, QAbstractAnimationJob *job) { + proxy->markJobManagedByController(); m_starting[job] = proxy; requestSync(); } diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index 9f81f28b7a..d61066babe 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -57,6 +57,7 @@ QQuickAnimatorProxyJob::QQuickAnimatorProxyJob(QAbstractAnimationJob *job, QObje : m_controller(0) , m_job(job) , m_internalState(State_Stopped) + , m_jobManagedByController(false) { m_isRenderThreadProxy = true; m_animation = qobject_cast(item); @@ -101,7 +102,10 @@ void QQuickAnimatorProxyJob::deleteJob() // so delete it through the controller to clean up properly. if (m_controller) m_controller->deleteJob(m_job); - else + + // We explicitly delete the job if the animator controller has never touched + // it. If it has, it will have ownership as well. + else if (!m_jobManagedByController) delete m_job; m_job = 0; } @@ -149,11 +153,13 @@ void QQuickAnimatorProxyJob::controllerWasDeleted() void QQuickAnimatorProxyJob::setWindow(QQuickWindow *window) { if (!window) { - // Stop will trigger syncBackCurrentValues so best to do it before - // we delete m_job. stop(); deleteJob(); - return; + + // Upon leaving a window, we reset the controller. This means that + // animators will only enter the Starting phase and won't be making + // calls to QQuickAnimatorController::startjob(). + m_controller = 0; } else if (!m_controller && m_job) { m_controller = QQuickWindowPrivate::get(window)->animationController; diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h index 03b13bcd30..1ebf12faab 100644 --- a/src/quick/util/qquickanimatorjob_p.h +++ b/src/quick/util/qquickanimatorjob_p.h @@ -77,6 +77,7 @@ public: void startedByController(); void controllerWasDeleted(); + void markJobManagedByController() { m_jobManagedByController = true; } protected: bool event(QEvent *); @@ -95,7 +96,7 @@ private: void setWindow(QQuickWindow *window); static QObject *findAnimationContext(QQuickAbstractAnimation *); - QQuickAnimatorController *m_controller; + QPointer m_controller; QQuickAbstractAnimation *m_animation; QAbstractAnimationJob *m_job; int m_duration; @@ -108,6 +109,7 @@ private: }; InternalState m_internalState; + bool m_jobManagedByController; }; class Q_QUICK_PRIVATE_EXPORT QQuickAnimatorJob : public QAbstractAnimationJob -- cgit v1.2.3 From cf44ee7761f2e4175f9193b42ee7296a2f3b694a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 29 Aug 2014 15:40:52 +0200 Subject: Support padding in images stored in atlas texture If the stride does not match the width of the image, we upload it line-by-line instead of as one big rect. Change-Id: I5e08afcf5c35dc810fed25e45255d55d932b2a4c Reviewed-by: Gunnar Sletta --- src/quick/scenegraph/util/qsgatlastexture.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp index 782beca1de..53b31104b3 100644 --- a/src/quick/scenegraph/util/qsgatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgatlastexture.cpp @@ -319,7 +319,16 @@ void Atlas::uploadBgra(Texture *texture) glTexSubImage2D(GL_TEXTURE_2D, 0, r.x() + iw + 1, r.y() + 1, 1, ih, m_externalFormat, GL_UNSIGNED_BYTE, dst); // Inner part of the image.... - glTexSubImage2D(GL_TEXTURE_2D, 0, r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2, m_externalFormat, GL_UNSIGNED_BYTE, src); + if (bpl != iw) { + int sy = r.y() + 1; + int ey = sy + r.height() - 2; + for (int y = sy; y < ey; ++y) { + glTexSubImage2D(GL_TEXTURE_2D, 0, r.x() + 1, y, r.width() - 2, 1, m_externalFormat, GL_UNSIGNED_BYTE, src); + src += bpl; + } + } else { + glTexSubImage2D(GL_TEXTURE_2D, 0, r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2, m_externalFormat, GL_UNSIGNED_BYTE, src); + } } -- cgit v1.2.3 From 210475565969ca5381174016b47cd32ddc96eaed Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 12 Jun 2014 14:35:53 +0200 Subject: Fix crashes when calling Array.sort with imperfect sort functions We can't use std::sort to implement Array.sort. The reason is that std::sort expects a conformant compare function, and can do weird things (esp. crash) when the sort function isn't conformant. Falling back to qSort is not possible, as the method has been deprecated. So add a copy of the qSort implementation here, and use that one instead. Fix the sortint test in tst_qqmlecmascript to have a consistent sort function for strings, as the result of calling sort is otherwise undefined according to the ecma standard. Task-number: QTBUG-39072 Change-Id: I0602b3aa1ffa4de5006da58396f166805cf4a5e2 Reviewed-by: Robin Burchell Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4arraydata.cpp | 56 +++++++++++++++++++++- tests/auto/qml/qjsengine/tst_qjsengine.cpp | 19 ++++++++ .../auto/qml/qqmlecmascript/data/sequenceSort.qml | 2 +- 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index 7d76a10ad6..9627848102 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -674,6 +674,60 @@ bool ArrayElementLessThan::operator()(Value v1, Value v2) const return p1s->toQString() < p2s->toQString(); } +template +void sortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan) +{ +top: + int span = int(end - start); + if (span < 2) + return; + + --end; + RandomAccessIterator low = start, high = end - 1; + RandomAccessIterator pivot = start + span / 2; + + if (lessThan(*end, *start)) + qSwap(*end, *start); + if (span == 2) + return; + + if (lessThan(*pivot, *start)) + qSwap(*pivot, *start); + if (lessThan(*end, *pivot)) + qSwap(*end, *pivot); + if (span == 3) + return; + + qSwap(*pivot, *end); + + while (low < high) { + while (low < high && lessThan(*low, *end)) + ++low; + + while (high > low && lessThan(*end, *high)) + --high; + + if (low < high) { + qSwap(*low, *high); + ++low; + --high; + } else { + break; + } + } + + if (lessThan(*low, *end)) + ++low; + + qSwap(*end, *low); + sortHelper(start, low, t, lessThan); + + start = low + 1; + ++end; + goto top; +} + + void ArrayData::sort(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn, uint len) { if (!len) @@ -765,7 +819,7 @@ void ArrayData::sort(ExecutionContext *context, ObjectRef thisObject, const Valu ArrayElementLessThan lessThan(context, thisObject, comparefn); Value *begin = thisObject->arrayData->data; - std::sort(begin, begin + len, lessThan); + sortHelper(begin, begin + len, *begin, lessThan); #ifdef CHECK_SPARSE_ARRAYS thisObject->initSparseArray(); diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 51cd69998a..4b47e55b55 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -135,6 +135,7 @@ private slots: void reentrancy_objectCreation(); void jsIncDecNonObjectProperty(); void JSONparse(); + void arraySort(); void qRegExpInport_data(); void qRegExpInport(); @@ -2729,6 +2730,24 @@ void tst_QJSEngine::JSONparse() QVERIFY(ret.isObject()); } +void tst_QJSEngine::arraySort() +{ + // tests that calling Array.sort with a bad sort function doesn't cause issues + // Using std::sort is e.g. not safe when used with a bad sort function and causes + // crashes + QJSEngine eng; + eng.evaluate("function crashMe() {" + " var data = [];" + " for (var i = 0; i < 50; i++) {" + " data[i] = 'whatever';" + " }" + " data.sort(function(a, b) {" + " return -1;" + " });" + "}" + "crashMe();"); +} + static QRegExp minimal(QRegExp r) { r.setMinimal(true); return r; } void tst_QJSEngine::qRegExpInport_data() diff --git a/tests/auto/qml/qqmlecmascript/data/sequenceSort.qml b/tests/auto/qml/qqmlecmascript/data/sequenceSort.qml index 5e2892a31d..b130408c18 100644 --- a/tests/auto/qml/qqmlecmascript/data/sequenceSort.qml +++ b/tests/auto/qml/qqmlecmascript/data/sequenceSort.qml @@ -23,7 +23,7 @@ Item { } function compareStrings(a, b) { - return (a < b) ? 1 : -1; + return (a == b) ? 0 : ((a < b) ? 1 : -1); } function compareNumbers(a, b) { -- cgit v1.2.3 From f7c3035fa1d965dceb36892122683a5ceb6cab89 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Thu, 28 Aug 2014 13:12:53 +0200 Subject: QML: parse .js files as JavaScript, not QML. When importing a JS library into a QML file with the "import" keyword, that JS file was parsed in QML mode, disallowing QML keywords like "as". Task-number: QTBUG-40143 Change-Id: Ie98adceb27544732c2e96657d41170db36bff288 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4script.cpp | 2 +- .../qml/qqmlecmascript/data/importScriptsWithoutQmlMode.js | 7 +++++++ .../qml/qqmlecmascript/data/importScriptsWithoutQmlMode.qml | 10 ++++++++++ tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 11 +++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/auto/qml/qqmlecmascript/data/importScriptsWithoutQmlMode.js create mode 100644 tests/auto/qml/qqmlecmascript/data/importScriptsWithoutQmlMode.qml diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 36f61a1df5..4d6e069d1f 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -349,7 +349,7 @@ QV4::CompiledData::CompilationUnit *Script::precompile(IR::Module *module, Compi QQmlJS::Engine ee; QQmlJS::Lexer lexer(&ee); - lexer.setCode(source, /*line*/1, /*qml mode*/true); + lexer.setCode(source, /*line*/1, /*qml mode*/false); QQmlJS::Parser parser(&ee); parser.parseProgram(); diff --git a/tests/auto/qml/qqmlecmascript/data/importScriptsWithoutQmlMode.js b/tests/auto/qml/qqmlecmascript/data/importScriptsWithoutQmlMode.js new file mode 100644 index 0000000000..aabcc9f3b8 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/importScriptsWithoutQmlMode.js @@ -0,0 +1,7 @@ +.pragma library + +var as = undefined +function isLegal() { + var as = true; + return as; +} diff --git a/tests/auto/qml/qqmlecmascript/data/importScriptsWithoutQmlMode.qml b/tests/auto/qml/qqmlecmascript/data/importScriptsWithoutQmlMode.qml new file mode 100644 index 0000000000..17d12199d7 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/importScriptsWithoutQmlMode.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +import "importScriptsWithoutQmlMode.js" as Export + +Rectangle { + id: root + property bool success: false + + Component.onCompleted: success = Export.isLegal() +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 34413b23de..7e9adeadcc 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -321,6 +321,7 @@ private slots: void lazyBindingEvaluation(); void varPropertyAccessOnObjectWithInvalidContext(); void importedScriptsAccessOnObjectWithInvalidContext(); + void importedScriptsWithoutQmlMode(); void contextObjectOnLazyBindings(); void garbageCollectionDuringCreation(); @@ -7609,6 +7610,16 @@ void tst_qqmlecmascript::importedScriptsAccessOnObjectWithInvalidContext() QTRY_VERIFY(obj->property("success") == true); } +void tst_qqmlecmascript::importedScriptsWithoutQmlMode() +{ + QQmlComponent component(&engine, testFileUrl("importScriptsWithoutQmlMode.qml")); + QScopedPointer obj(component.create()); + if (obj.isNull()) + qDebug() << component.errors().first().toString(); + QVERIFY(!obj.isNull()); + QTRY_VERIFY(obj->property("success") == true); +} + void tst_qqmlecmascript::contextObjectOnLazyBindings() { QQmlComponent component(&engine, testFileUrl("contextObjectOnLazyBindings.qml")); -- cgit v1.2.3 From 7ec11872a925a1087a2fe6891eb70045922b22c8 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 9 Sep 2014 10:27:47 +0200 Subject: autotests: fix build on iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Idf854ad4f868e873582731dfa6b0253ac5b17c5c Reviewed-by: Tor Arne Vestbø --- tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp | 2 +- tests/auto/shared/platformquirks.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index 096a191398..5c8d86f840 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -50,7 +50,7 @@ #include #include -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX #include #endif diff --git a/tests/auto/shared/platformquirks.h b/tests/auto/shared/platformquirks.h index d5413f9db9..70a3e016a6 100644 --- a/tests/auto/shared/platformquirks.h +++ b/tests/auto/shared/platformquirks.h @@ -36,7 +36,7 @@ #include -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX #include #endif @@ -46,7 +46,7 @@ struct PlatformQuirks { #if defined(QT_NO_CLIPBOARD) return false; -#elif defined(Q_OS_MAC) +#elif defined(Q_OS_OSX) PasteboardRef pasteboard; OSStatus status = PasteboardCreate(0, &pasteboard); if (status == noErr) -- cgit v1.2.3 From 4a9650233e8c01048f4058ed32999daec96c77fd Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 8 Sep 2014 11:11:50 +0200 Subject: Fix broken QJSEngine snippet in documentation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit toBoolean() isn't even a function in that class, and declaring the button on the stack causes crashes upon closing the application. Change-Id: I063cac2bb144cfb9786f20bbc122d5af92a4c2c0 Reviewed-by: Jędrzej Nowacki --- src/qml/doc/snippets/code/src_script_qjsengine.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qml/doc/snippets/code/src_script_qjsengine.cpp b/src/qml/doc/snippets/code/src_script_qjsengine.cpp index b836fabf3d..7428cedcaf 100644 --- a/src/qml/doc/snippets/code/src_script_qjsengine.cpp +++ b/src/qml/doc/snippets/code/src_script_qjsengine.cpp @@ -79,12 +79,12 @@ if (result.isError()) //! [5] -QPushButton button; -QJSValue scriptButton = myEngine.newQObject(&button); +QPushButton *button = new QPushButton; +QJSValue scriptButton = myEngine.newQObject(button); myEngine.globalObject().setProperty("button", scriptButton); myEngine.evaluate("button.checkable = true"); -qDebug() << scriptButton.property("checkable").toBoolean(); +qDebug() << scriptButton.property("checkable").toBool(); scriptButton.property("show").call(); // call the show() slot //! [5] -- cgit v1.2.3 From d723a28f0c6b0f9b031cc04eb509c11565f2244c Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Sun, 7 Sep 2014 18:12:00 +0200 Subject: Improve Drag documentation. Change-Id: Ifba60b729c8ad02009cd5c8caa5d58e20a76c73b Reviewed-by: J-P Nurmi --- src/quick/items/qquickdrag.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp index adf4c678dc..5641c323ab 100644 --- a/src/quick/items/qquickdrag.cpp +++ b/src/quick/items/qquickdrag.cpp @@ -112,23 +112,23 @@ public: \ingroup qtquick-input \brief For specifying drag and drop events for moved Items - Using the Drag attached property any Item can be made a source of drag and drop + Using the Drag attached property, any Item can be made a source of drag and drop events within a scene. - When a drag is \l active on an item any change in that item's position will + When a drag is \l active on an item, any change in that item's position will generate a drag event that will be sent to any DropArea that intersects with the new position of the item. Other items which implement drag and drop event handlers can also receive these events. The following snippet shows how an item can be dragged with a MouseArea. - However, dragging is not limited to mouse drags, anything that can move an item - can generate drag events, this can include touch events, animations and bindings. + However, dragging is not limited to mouse drags; anything that can move an item + can generate drag events, including touch events, animations and bindings. \snippet qml/drag.qml 0 A drag can be terminated either by canceling it with Drag.cancel() or setting Drag.active to false, or it can be terminated with a drop event by calling - Drag.drop(). If the drop event is accepted Drag.drop() will return the + Drag.drop(). If the drop event is accepted, Drag.drop() will return the \l {supportedActions}{drop action} chosen by the recipient of the event, otherwise it will return Qt.IgnoreAction. @@ -314,7 +314,8 @@ void QQuickDragAttached::setActive(bool active) \qmlattachedproperty Object QtQuick::Drag::source This property holds an object that is identified to recipients of drag events as - the source of the events. By default this is the item Drag property is attached to. + the source of the events. By default this is the item that the Drag + property is attached to. Changing the source while a drag is active will reset the sequence of drag events by sending a drag leave event followed by a drag enter event with the new source. -- cgit v1.2.3 From 1c6633ff127c59075a53732cb64a3aa9e7b0e1cf Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 9 Sep 2014 15:31:15 +0200 Subject: Improve KeyNavigation documentation. Change-Id: I07e66deb4b21eca191c17532749eeccd33d83fb0 Reviewed-by: Mitch Curtis --- src/quick/items/qquickitem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index d45fb31fd9..1992398938 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -397,7 +397,7 @@ void QQuickItemKeyFilter::componentComplete() \c KeyNavigation.BeforeItem allows the event to be used for key navigation before the item, rather than after. - If item to which the focus is switching is not enabled or visible, an attempt will + If the item to which the focus is switching is not enabled or visible, an attempt will be made to skip this item and focus on the next. This is possible if there are a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled or visible, they will also be skipped. @@ -405,7 +405,7 @@ void QQuickItemKeyFilter::componentComplete() KeyNavigation will implicitly set the other direction to return focus to this item. So if you set \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this item. However, if that item's KeyNavigation has had right explicitly set then no change will occur. - This means that the above example could have been written, with the same behaviour, without specifying + This means that the example above could achieve the same behavior without specifying KeyNavigation.right or KeyNavigation.down for any of the items. \sa {Keys}{Keys attached property} -- cgit v1.2.3 From 8fab54a5495226b8c06d7708357a23e83444abc0 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 10 Sep 2014 13:18:39 +0200 Subject: Fix failing assertion when compiling self-referencing QML singleton When a QML singleton file accesses itself, we would hit incomplete type data. Task-number: QTBUG-41220 Change-Id: Id0bd5fd71cf9be21f7e4ad8527fa8724a718d702 Reviewed-by: Michael Brasser --- src/qml/compiler/qqmlirbuilder.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 34db06ca4c..d22116fc83 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1805,13 +1805,14 @@ static QV4::IR::Type resolveQmlType(QQmlEnginePrivate *qmlEngine, QV4::IR::Membe } if (type->isCompositeSingleton()) { - QQmlTypeData *tdata = qmlEngine->typeLoader.getType(type->singletonInstanceInfo()->url); + QQmlRefPointer tdata = qmlEngine->typeLoader.getType(type->singletonInstanceInfo()->url); Q_ASSERT(tdata); - Q_ASSERT(tdata->isComplete()); - initMetaObjectResolver(resolver, qmlEngine->propertyCacheForType(tdata->compiledData()->metaTypeId)); - tdata->release(); - resolver->flags |= AllPropertiesAreFinal; - return resolver->resolveMember(qmlEngine, resolver, member); + // When a singleton tries to reference itself, it may not be complete yet. + if (tdata->isComplete()) { + initMetaObjectResolver(resolver, qmlEngine->propertyCacheForType(tdata->compiledData()->metaTypeId)); + resolver->flags |= AllPropertiesAreFinal; + return resolver->resolveMember(qmlEngine, resolver, member); + } } else if (type->isSingleton()) { const QMetaObject *singletonMeta = type->singletonInstanceInfo()->instanceMetaObject; if (singletonMeta) { // QJSValue-based singletons cannot be accelerated -- cgit v1.2.3 From 91d6a63ab317817990c3b2306860adbd8916cca4 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 8 Sep 2014 14:06:22 +0200 Subject: Fix roundtrip conversion between JS var and QVariant Always convert null to a QVariant(VoidStar) as documented in QJSValue. Make sure the reverse conversion will lead back to a null JS value. Adjusted two test cases that expected an invalid QVariant when setting the property to null, and added test cases for the correct conversion. Task-number: QTBUG-40880 Change-Id: I6eb01f0067f2c89779c53fd2cd0a1193047ed2cc Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlproperty.cpp | 7 ++- src/qml/qml/v8/qv8engine.cpp | 8 +++- .../data/scarceResourceFunction.var.qml | 2 +- .../data/scarceResourceFunction.variant.qml | 2 +- tests/auto/qml/qqmlecmascript/data/variants.qml | 55 ++++++++++++++++++++++ .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 24 ++++++++++ 6 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 tests/auto/qml/qqmlecmascript/data/variants.qml diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 42bf0dd657..09b735ae9e 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -1585,11 +1585,14 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object, propertyType = propertyMetaObject.className(); } } else if (value.userType() != QVariant::Invalid) { - valueType = QMetaType::typeName(value.userType()); + if (value.userType() == QMetaType::VoidStar) + valueType = "null"; + else + valueType = QMetaType::typeName(value.userType()); } if (!valueType) - valueType = "null"; + valueType = "undefined"; if (!propertyType) propertyType = QMetaType::typeName(type); if (!propertyType) diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 35d31e4f1f..b56af2e7f6 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -240,6 +240,8 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant) case QMetaType::UnknownType: case QMetaType::Void: return QV4::Encode::undefined(); + case QMetaType::VoidStar: + return QV4::Encode::null(); case QMetaType::Bool: return QV4::Encode(*reinterpret_cast(ptr)); case QMetaType::Int: @@ -379,8 +381,10 @@ QQmlContextData *QV8Engine::callingContext() // [Any other object] -> QVariantMap(...) QVariant QV8Engine::toBasicVariant(const QV4::ValueRef value) { - if (value->isNullOrUndefined()) + if (value->isUndefined()) return QVariant(); + if (value->isNull()) + return QVariant(QMetaType::VoidStar, (void *)0); if (value->isBoolean()) return value->booleanValue(); if (value->isInteger()) @@ -644,6 +648,8 @@ QV4::ReturnedValue QV8Engine::metaTypeToJS(int type, const void *data) case QMetaType::UnknownType: case QMetaType::Void: return QV4::Encode::undefined(); + case QMetaType::VoidStar: + return QV4::Encode::null(); case QMetaType::Bool: return QV4::Encode(*reinterpret_cast(data)); case QMetaType::Int: diff --git a/tests/auto/qml/qqmlecmascript/data/scarceResourceFunction.var.qml b/tests/auto/qml/qqmlecmascript/data/scarceResourceFunction.var.qml index 23e4c8d15e..bb6ddc7876 100644 --- a/tests/auto/qml/qqmlecmascript/data/scarceResourceFunction.var.qml +++ b/tests/auto/qml/qqmlecmascript/data/scarceResourceFunction.var.qml @@ -17,7 +17,7 @@ QtObject { } function releaseScarceResource() { - root.scarceResourceCopy = null; + root.scarceResourceCopy = undefined; } } diff --git a/tests/auto/qml/qqmlecmascript/data/scarceResourceFunction.variant.qml b/tests/auto/qml/qqmlecmascript/data/scarceResourceFunction.variant.qml index fe3707b5d3..e147188230 100644 --- a/tests/auto/qml/qqmlecmascript/data/scarceResourceFunction.variant.qml +++ b/tests/auto/qml/qqmlecmascript/data/scarceResourceFunction.variant.qml @@ -17,7 +17,7 @@ QtObject { } function releaseScarceResource() { - root.scarceResourceCopy = null; + root.scarceResourceCopy = undefined; } } diff --git a/tests/auto/qml/qqmlecmascript/data/variants.qml b/tests/auto/qml/qqmlecmascript/data/variants.qml new file mode 100644 index 0000000000..d38c5a1b49 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/variants.qml @@ -0,0 +1,55 @@ +import QtQuick 2.2 + +ListView +{ + property variant undefinedVariant: undefined + property variant nullVariant: null + property variant intVariant: 1 + property variant doubleVariant: 1.2 + + property var testVar + property variant testVariant + + function checkNull() { + var result = [{'test': null}]; + model = result; + if (model[0].test !== null) + return false; + testVar = null; + testVariant = testVar; + if (testVariant !== null) + return false; + testVar = testVariant; + if (testVar !== null) + return false; + return true; + } + function checkUndefined() { + var result = [{'test': undefined}]; + model = result; + if (model[0].test !== undefined) + return false; + testVar = undefined; + testVariant = testVar; + if (testVariant !== undefined) + return false; + testVar = testVariant; + if (testVar !== undefined) + return false; + return true; + } + function checkNumber() { + var result = [{'test': 1}]; + model = result; + if (model[0].test !== 1) + return false; + testVar = 1; + testVariant = testVar; + if (testVariant !== 1) + return false; + testVar = testVariant; + if (testVar !== 1) + return false; + return true; + } +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 06d061a9fa..01125f86f6 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -213,6 +213,7 @@ private slots: void deletedEngine(); void libraryScriptAssert(); void variantsAssignedUndefined(); + void variants(); void qtbug_9792(); void qtcreatorbug_1289(); void noSpuriousWarningsAtShutdown(); @@ -5737,6 +5738,29 @@ void tst_qqmlecmascript::variantsAssignedUndefined() delete object; } +void tst_qqmlecmascript::variants() +{ + QQmlComponent component(&engine, testFileUrl("variants.qml")); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QVERIFY(object->property("undefinedVariant").type() == QVariant::Invalid); + QVERIFY(object->property("nullVariant").type() == (int)QMetaType::VoidStar); + QVERIFY(object->property("intVariant").type() == QVariant::Int); + QVERIFY(object->property("doubleVariant").type() == QVariant::Double); + + QVariant result; + QMetaObject::invokeMethod(object, "checkNull", Q_RETURN_ARG(QVariant, result)); + QCOMPARE(result.toBool(), true); + + QMetaObject::invokeMethod(object, "checkUndefined", Q_RETURN_ARG(QVariant, result)); + QCOMPARE(result.toBool(), true); + + QMetaObject::invokeMethod(object, "checkNumber", Q_RETURN_ARG(QVariant, result)); + QCOMPARE(result.toBool(), true); +} + void tst_qqmlecmascript::qtbug_9792() { QQmlComponent component(&engine, testFileUrl("qtbug_9792.qml")); -- cgit v1.2.3 From 046cce32d9f818809382fcbbff0cfa4adfe8d3f7 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 9 Sep 2014 15:39:11 +0200 Subject: Fix setUTCXxx methods in Date The methods where converting doing a localtime->UTC conversion even though the input was already in UTC. Task-number: QTBUG-38448 Change-Id: I4409275fade0dd2a677af2293edc87445f853879 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4dateobject.cpp | 27 ++++++----------- tests/auto/qml/qqmlecmascript/data/utcdate.qml | 34 ++++++++++++++++++++++ .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 16 ++++++++++ 3 files changed, 59 insertions(+), 18 deletions(-) create mode 100644 tests/auto/qml/qqmlecmascript/data/utcdate.qml diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index 67d247de28..66601b64e5 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -550,16 +550,7 @@ static inline QDateTime ToDateTime(double t, Qt::TimeSpec spec) { if (std::isnan(t)) return QDateTime(); - if (spec == Qt::LocalTime) - t = LocalTime(t); - int year = int(YearFromTime(t)); - int month = int(MonthFromTime(t) + 1); - int day = int(DateFromTime(t)); - int hours = HourFromTime(t); - int mins = MinFromTime(t); - int secs = SecFromTime(t); - int ms = msFromTime(t); - return QDateTime(QDate(year, month, day), QTime(hours, mins, secs, ms), spec); + return QDateTime::fromMSecsSinceEpoch(t, spec); } static inline QString ToString(double t) @@ -586,7 +577,7 @@ static inline QString ToUTCString(double t) { if (std::isnan(t)) return QStringLiteral("Invalid Date"); - return ToDateTime(t, Qt::UTC).toString() + QStringLiteral(" GMT"); + return ToDateTime(t, Qt::UTC).toString(); } static inline QString ToDateString(double t) @@ -1029,7 +1020,7 @@ ReturnedValue DatePrototype::method_setUTCMilliseconds(CallContext *ctx) double t = self->date().asDouble(); double ms = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN(); - self->date().setDouble(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms))))); + self->date().setDouble(TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))); return self->date().asReturnedValue(); } @@ -1056,7 +1047,7 @@ ReturnedValue DatePrototype::method_setUTCSeconds(CallContext *ctx) double t = self->date().asDouble(); double sec = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN(); double ms = (ctx->d()->callData->argc < 2) ? msFromTime(t) : ctx->d()->callData->args[1].toNumber(); - t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)))); + t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))); self->date().setDouble(t); return self->date().asReturnedValue(); } @@ -1086,7 +1077,7 @@ ReturnedValue DatePrototype::method_setUTCMinutes(CallContext *ctx) double min = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN(); double sec = (ctx->d()->callData->argc < 2) ? SecFromTime(t) : ctx->d()->callData->args[1].toNumber(); double ms = (ctx->d()->callData->argc < 3) ? msFromTime(t) : ctx->d()->callData->args[2].toNumber(); - t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)))); + t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))); self->date().setDouble(t); return self->date().asReturnedValue(); } @@ -1118,7 +1109,7 @@ ReturnedValue DatePrototype::method_setUTCHours(CallContext *ctx) double min = (ctx->d()->callData->argc < 2) ? MinFromTime(t) : ctx->d()->callData->args[1].toNumber(); double sec = (ctx->d()->callData->argc < 3) ? SecFromTime(t) : ctx->d()->callData->args[2].toNumber(); double ms = (ctx->d()->callData->argc < 4) ? msFromTime(t) : ctx->d()->callData->args[3].toNumber(); - t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms)))); + t = TimeClip(MakeDate(Day(t), MakeTime(hour, min, sec, ms))); self->date().setDouble(t); return self->date().asReturnedValue(); } @@ -1144,7 +1135,7 @@ ReturnedValue DatePrototype::method_setUTCDate(CallContext *ctx) double t = self->date().asDouble(); double date = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN(); - t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t)))); + t = TimeClip(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))); self->date().setDouble(t); return self->date().asReturnedValue(); } @@ -1172,7 +1163,7 @@ ReturnedValue DatePrototype::method_setUTCMonth(CallContext *ctx) double t = self->date().asDouble(); double month = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN(); double date = (ctx->d()->callData->argc < 2) ? DateFromTime(t) : ctx->d()->callData->args[1].toNumber(); - t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)))); + t = TimeClip(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))); self->date().setDouble(t); return self->date().asReturnedValue(); } @@ -1213,7 +1204,7 @@ ReturnedValue DatePrototype::method_setUTCFullYear(CallContext *ctx) double year = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN(); double month = (ctx->d()->callData->argc < 2) ? MonthFromTime(t) : ctx->d()->callData->args[1].toNumber(); double date = (ctx->d()->callData->argc < 3) ? DateFromTime(t) : ctx->d()->callData->args[2].toNumber(); - t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)))); + t = TimeClip(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))); self->date().setDouble(t); return self->date().asReturnedValue(); } diff --git a/tests/auto/qml/qqmlecmascript/data/utcdate.qml b/tests/auto/qml/qqmlecmascript/data/utcdate.qml new file mode 100644 index 0000000000..7f66ee3f23 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/utcdate.qml @@ -0,0 +1,34 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +Item { + MyDateClass { + id: mdc + } + + function check_utc(utcstr) { + var datetimeutc = utcstr.split('T') + var dateutc = datetimeutc[0].split('-') + var timeutc = datetimeutc[1].split(':') + var utcDate = new Date(0) + utcDate.setUTCFullYear(Number(dateutc[0])) + utcDate.setUTCMonth(Number(dateutc[1])-1) + utcDate.setUTCDate(Number(dateutc[2])) + utcDate.setUTCHours(Number(timeutc[0])) + utcDate.setUTCMinutes(Number(timeutc[1])) + utcDate.setUTCSeconds(Number(timeutc[2])) + if (utcDate.getUTCFullYear() != Number(dateutc[0])) + return false; + if (utcDate.getUTCMonth() != Number(dateutc[1])-1) + return false; + if (utcDate.getUTCDate() != Number(dateutc[2])) + return false; + if (utcDate.getUTCHours() != Number(timeutc[0])) + return false; + if (utcDate.getUTCMinutes() != Number(timeutc[1])) + return false; + if (utcDate.getUTCSeconds() != Number(timeutc[2])) + return false; + return true; + } +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 01125f86f6..c246647325 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -199,6 +199,7 @@ private slots: void sequenceSort_data(); void sequenceSort(); void dateParse(); + void utcDate(); void qtbug_22464(); void qtbug_21580(); void singleV8BindingDestroyedDuringEvaluation(); @@ -7362,6 +7363,21 @@ void tst_qqmlecmascript::dateParse() } +void tst_qqmlecmascript::utcDate() +{ + QQmlComponent component(&engine, testFileUrl("utcdate.qml")); + + QObject *object = component.create(); + if (object == 0) + qDebug() << component.errorString(); + QVERIFY(object != 0); + + QVariant q; + QVariant val = QString::fromLatin1("2014-07-16T23:30:31"); + QMetaObject::invokeMethod(object, "check_utc", Q_RETURN_ARG(QVariant, q), Q_ARG(QVariant, val)); + QVERIFY(q.toBool() == true); +} + void tst_qqmlecmascript::concatenatedStringPropertyAccess() { QQmlComponent component(&engine, testFileUrl("concatenatedStringPropertyAccess.qml")); -- cgit v1.2.3 From 63e6c9ada82dc8f16e705cef5f89292784b7ace4 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 8 Sep 2014 12:38:02 +0200 Subject: Snap native glyphs to pixel grid in vertex shader. The implementation relied on the full matrix, but did not set the RequiresFullMatrix flag. Setting the flag would have serious negative performance impact as it prevents batching, so we solve it in the vertex shader instead. Task-number: QTBUG-38702 Change-Id: I0c245ea9e18b0b29dd9e3073a2648a7f4e061685 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/quick/scenegraph/qsgdefaultglyphnode_p.cpp | 24 ++--------------------- src/quick/scenegraph/shaders/styledtext.vert | 4 ++-- src/quick/scenegraph/shaders/styledtext_core.vert | 4 ++-- src/quick/scenegraph/shaders/textmask.vert | 2 +- src/quick/scenegraph/shaders/textmask_core.vert | 2 +- 5 files changed, 8 insertions(+), 28 deletions(-) diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index 16feafe02f..802c92be9f 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp @@ -128,28 +128,8 @@ void QSGTextMaskShader::updateState(const RenderState &state, QSGMaterial *newEf } } - if (state.isMatrixDirty()) { - QMatrix4x4 transform = state.modelViewMatrix(); - qreal xTranslation = transform(0, 3); - qreal yTranslation = transform(1, 3); - - // Remove translation and check identity to see if matrix is only translating. - // If it is, we can round the translation to make sure the text is pixel aligned, - // which is the only thing that works with GL_NEAREST filtering. Adding rotations - // and scales to native rendered text is not a prioritized use case, since the - // default rendering type is designed for that. - transform(0, 3) = 0.0; - transform(1, 3) = 0.0; - if (transform.isIdentity()) { - transform(0, 3) = qRound(xTranslation); - transform(1, 3) = qRound(yTranslation); - - transform = state.projectionMatrix() * transform; - program()->setUniformValue(m_matrix_id, transform); - } else { - program()->setUniformValue(m_matrix_id, state.combinedMatrix()); - } - } + if (state.isMatrixDirty()) + program()->setUniformValue(m_matrix_id, state.combinedMatrix()); } class QSG8BitTextMaskShader : public QSGTextMaskShader diff --git a/src/quick/scenegraph/shaders/styledtext.vert b/src/quick/scenegraph/shaders/styledtext.vert index 3ad9497b65..14fefc2564 100644 --- a/src/quick/scenegraph/shaders/styledtext.vert +++ b/src/quick/scenegraph/shaders/styledtext.vert @@ -12,5 +12,5 @@ void main() { sampleCoord = tCoord * textureScale; shiftedSampleCoord = (tCoord - shift) * textureScale; - gl_Position = matrix * vCoord; -} \ No newline at end of file + gl_Position = matrix * floor(vCoord + 0.5); +} diff --git a/src/quick/scenegraph/shaders/styledtext_core.vert b/src/quick/scenegraph/shaders/styledtext_core.vert index b7a3ecc667..65bdb66814 100644 --- a/src/quick/scenegraph/shaders/styledtext_core.vert +++ b/src/quick/scenegraph/shaders/styledtext_core.vert @@ -14,5 +14,5 @@ void main() { sampleCoord = tCoord * textureScale; shiftedSampleCoord = (tCoord - shift) * textureScale; - gl_Position = matrix * vCoord; -} \ No newline at end of file + gl_Position = matrix * round(vCoord); +} diff --git a/src/quick/scenegraph/shaders/textmask.vert b/src/quick/scenegraph/shaders/textmask.vert index 1f45e9cf71..dd8918839e 100644 --- a/src/quick/scenegraph/shaders/textmask.vert +++ b/src/quick/scenegraph/shaders/textmask.vert @@ -9,5 +9,5 @@ varying highp vec2 sampleCoord; void main() { sampleCoord = tCoord * textureScale; - gl_Position = matrix * vCoord; + gl_Position = matrix * floor(vCoord + 0.5); } diff --git a/src/quick/scenegraph/shaders/textmask_core.vert b/src/quick/scenegraph/shaders/textmask_core.vert index 619248dccb..d145d33195 100644 --- a/src/quick/scenegraph/shaders/textmask_core.vert +++ b/src/quick/scenegraph/shaders/textmask_core.vert @@ -11,5 +11,5 @@ uniform vec2 textureScale; void main() { sampleCoord = tCoord * textureScale; - gl_Position = matrix * vCoord; + gl_Position = matrix * round(vCoord); } -- cgit v1.2.3 From 85627c26afb087975fe2e57f91837c9314d54ba7 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 9 Sep 2014 07:12:31 +0200 Subject: Fix debug output from renderer. It was wrong when we ran without depth buffer or when we used the separate ibo code path. Change-Id: Ie6e4bfc99ee2a4a593e45be7d9af9af17896bcba Reviewed-by: Laszlo Agocs --- src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 83234bd32c..ecd450bcc8 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -1875,9 +1875,12 @@ void Renderer::uploadBatch(Batch *b) vd += g->sizeOfVertex(); } - const quint16 *id = (const quint16 *) (b->vbo.data - + b->vertexCount * g->sizeOfVertex() - + (b->merged ? b->vertexCount * sizeof(float) : 0)); + const quint16 *id = +#ifdef QSG_SEPARATE_INDEX_BUFFER + (const quint16 *) (b->ibo.data); +#else + (const quint16 *) (b->vbo.data + b->drawSets.at(0).indices); +#endif { QDebug iDump = qDebug(); iDump << " -- Index Data, count:" << b->indexCount; -- cgit v1.2.3 From 1de6e7b8e0ee465f642e1b2f5a14611e52a7e8c2 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 3 Sep 2014 19:28:35 +0200 Subject: Select specific features to be recorded when profiling QML Some features, like the memory profiler, create huge amounts of data. Often enough, we're not actually interested in all the data available from the profiler and collecting it all can lead to excessive memory consumption. This change enables us to optionally turn various aspects of QML profiling off. Task-number: QTBUG-41118 Change-Id: I7bb223414e24eb903124ffa6e0896af6ce974e49 Reviewed-by: Gunnar Sletta --- src/qml/debugger/qqmlabstractprofileradapter.cpp | 10 +++--- src/qml/debugger/qqmlabstractprofileradapter_p.h | 13 +++---- src/qml/debugger/qqmlprofiler.cpp | 14 ++++---- src/qml/debugger/qqmlprofiler_p.h | 41 +++++++++++++---------- src/qml/debugger/qqmlprofilerdefinitions_p.h | 16 +++++++++ src/qml/debugger/qqmlprofilerservice.cpp | 25 ++++++++------ src/qml/debugger/qqmlprofilerservice_p.h | 4 +-- src/qml/debugger/qv4profileradapter.cpp | 7 ++-- src/qml/jsruntime/qv4profiling.cpp | 38 +++++++++++---------- src/qml/jsruntime/qv4profiling_p.h | 18 +++++++--- src/qml/qml/qqmlobjectcreator.cpp | 2 +- src/quick/items/qquickview.cpp | 10 +++--- src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 4 +-- src/quick/scenegraph/coreapi/qsgrenderer.cpp | 6 ++-- src/quick/scenegraph/qsgadaptationlayer.cpp | 3 +- src/quick/scenegraph/qsgrenderloop.cpp | 3 +- src/quick/scenegraph/qsgthreadedrenderloop.cpp | 6 ++-- src/quick/scenegraph/qsgwindowsrenderloop.cpp | 2 +- src/quick/scenegraph/util/qsgatlastexture.cpp | 3 +- src/quick/scenegraph/util/qsgtexture.cpp | 3 +- src/quick/util/qquickpixmapcache.cpp | 28 +++++++++------- src/quick/util/qquickprofiler.cpp | 18 +++++----- src/quick/util/qquickprofiler_p.h | 21 ++++++++---- src/quickwidgets/qquickwidget.cpp | 14 ++++---- 24 files changed, 181 insertions(+), 128 deletions(-) diff --git a/src/qml/debugger/qqmlabstractprofileradapter.cpp b/src/qml/debugger/qqmlabstractprofileradapter.cpp index 1267503226..165772335a 100644 --- a/src/qml/debugger/qqmlabstractprofileradapter.cpp +++ b/src/qml/debugger/qqmlabstractprofileradapter.cpp @@ -69,13 +69,13 @@ QT_BEGIN_NAMESPACE * If the profiler's thread is waiting for an initial start signal we can emit the signal over a * \c Qt::DirectConnection to avoid the delay of the event loop. */ -void QQmlAbstractProfilerAdapter::startProfiling() +void QQmlAbstractProfilerAdapter::startProfiling(quint64 features) { if (waiting) - emit profilingEnabledWhileWaiting(); + emit profilingEnabledWhileWaiting(features); else - emit profilingEnabled(); - running = true; + emit profilingEnabled(features); + featuresEnabled = features; } /*! @@ -90,7 +90,7 @@ void QQmlAbstractProfilerAdapter::stopProfiling() { emit profilingDisabledWhileWaiting(); else emit profilingDisabled(); - running = false; + featuresEnabled = 0; } /*! diff --git a/src/qml/debugger/qqmlabstractprofileradapter_p.h b/src/qml/debugger/qqmlabstractprofileradapter_p.h index f06d51e8f7..03f6645178 100644 --- a/src/qml/debugger/qqmlabstractprofileradapter_p.h +++ b/src/qml/debugger/qqmlabstractprofileradapter_p.h @@ -59,12 +59,12 @@ class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapter : public QObject, public public: QQmlAbstractProfilerAdapter(QQmlProfilerService *service) : - service(service), waiting(true), running(false) {} + service(service), waiting(true), featuresEnabled(0) {} virtual ~QQmlAbstractProfilerAdapter() {} virtual qint64 sendMessages(qint64 until, QList &messages) = 0; - void startProfiling(); + void startProfiling(quint64 features); void stopProfiling(); @@ -73,13 +73,14 @@ public: void stopWaiting() { waiting = false; } void startWaiting() { waiting = true; } - bool isRunning() const { return running; } + bool isRunning() const { return featuresEnabled != 0; } + quint64 features() const { return featuresEnabled; } void synchronize(const QElapsedTimer &t) { emit referenceTimeKnown(t); } signals: - void profilingEnabled(); - void profilingEnabledWhileWaiting(); + void profilingEnabled(quint64 features); + void profilingEnabledWhileWaiting(quint64 features); void profilingDisabled(); void profilingDisabledWhileWaiting(); @@ -92,7 +93,7 @@ protected: private: bool waiting; - bool running; + quint64 featuresEnabled; }; QT_END_NAMESPACE diff --git a/src/qml/debugger/qqmlprofiler.cpp b/src/qml/debugger/qqmlprofiler.cpp index 3a647e704d..b102201ff1 100644 --- a/src/qml/debugger/qqmlprofiler.cpp +++ b/src/qml/debugger/qqmlprofiler.cpp @@ -82,9 +82,9 @@ QQmlProfilerAdapter::QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEngin QQmlAbstractProfilerAdapter(service) { engine->enableProfiler(); - connect(this, SIGNAL(profilingEnabled()), engine->profiler, SLOT(startProfiling())); - connect(this, SIGNAL(profilingEnabledWhileWaiting()), - engine->profiler, SLOT(startProfiling()), Qt::DirectConnection); + connect(this, SIGNAL(profilingEnabled(quint64)), engine->profiler, SLOT(startProfiling(quint64))); + connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)), + engine->profiler, SLOT(startProfiling(quint64)), Qt::DirectConnection); connect(this, SIGNAL(profilingDisabled()), engine->profiler, SLOT(stopProfiling())); connect(this, SIGNAL(profilingDisabledWhileWaiting()), engine->profiler, SLOT(stopProfiling()), Qt::DirectConnection); @@ -111,21 +111,21 @@ void QQmlProfilerAdapter::receiveData(const QList &new_data) } -QQmlProfiler::QQmlProfiler() : enabled(false) +QQmlProfiler::QQmlProfiler() : featuresEnabled(0) { static int metatype = qRegisterMetaType >(); Q_UNUSED(metatype); m_timer.start(); } -void QQmlProfiler::startProfiling() +void QQmlProfiler::startProfiling(quint64 features) { - enabled = true; + featuresEnabled = features; } void QQmlProfiler::stopProfiling() { - enabled = false; + featuresEnabled = false; reportData(); m_data.clear(); } diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h index 02cdbf0a4e..13e6b8ddae 100644 --- a/src/qml/debugger/qqmlprofiler_p.h +++ b/src/qml/debugger/qqmlprofiler_p.h @@ -56,14 +56,14 @@ QT_BEGIN_NAMESPACE -#define Q_QML_PROFILE_IF_ENABLED(profiler, Code)\ - if (profiler && profiler->enabled) {\ +#define Q_QML_PROFILE_IF_ENABLED(feature, profiler, Code)\ + if (profiler && (profiler->featuresEnabled & (1 << feature))) {\ Code;\ } else\ (void)0 -#define Q_QML_PROFILE(profiler, Method)\ - Q_QML_PROFILE_IF_ENABLED(profiler, profiler->Method) +#define Q_QML_PROFILE(feature, profiler, Method)\ + Q_QML_PROFILE_IF_ENABLED(feature, profiler, profiler->Method) // This struct is somewhat dangerous to use: // The messageType is a bit field. You can pack multiple messages into @@ -162,10 +162,10 @@ public: QQmlProfiler(); - bool enabled; + quint64 featuresEnabled; public slots: - void startProfiling(); + void startProfiling(quint64 features); void stopProfiling(); void reportData(); void setTimer(const QElapsedTimer &timer) { m_timer = timer; } @@ -204,12 +204,14 @@ struct QQmlBindingProfiler : public QQmlProfilerHelper { QQmlBindingProfiler(QQmlProfiler *profiler, const QString &url, int line, int column) : QQmlProfilerHelper(profiler) { - Q_QML_PROFILE(profiler, startBinding(url, line, column)); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler, + startBinding(url, line, column)); } ~QQmlBindingProfiler() { - Q_QML_PROFILE(profiler, endRange()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler, + endRange()); } }; @@ -217,12 +219,14 @@ struct QQmlHandlingSignalProfiler : public QQmlProfilerHelper { QQmlHandlingSignalProfiler(QQmlProfiler *profiler, QQmlBoundSignalExpression *expression) : QQmlProfilerHelper(profiler) { - Q_QML_PROFILE(profiler, startHandlingSignal(expression->sourceLocation())); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileHandlingSignal, profiler, + startHandlingSignal(expression->sourceLocation())); } ~QQmlHandlingSignalProfiler() { - Q_QML_PROFILE(profiler, endRange()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileHandlingSignal, profiler, + endRange()); } }; @@ -230,12 +234,12 @@ struct QQmlCompilingProfiler : public QQmlProfilerHelper { QQmlCompilingProfiler(QQmlProfiler *profiler, const QString &name) : QQmlProfilerHelper(profiler) { - Q_QML_PROFILE(profiler, startCompiling(name)); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, startCompiling(name)); } ~QQmlCompilingProfiler() { - Q_QML_PROFILE(profiler, endRange()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, endRange()); } }; @@ -278,20 +282,20 @@ private: QFiniteStack ranges; }; -#define Q_QML_OC_PROFILE(profilerMember, Code)\ - Q_QML_PROFILE_IF_ENABLED(profilerMember.profiler, Code) +#define Q_QML_OC_PROFILE(member, Code)\ + Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, member.profiler, Code) class QQmlObjectCreationProfiler : public QQmlVmeProfiler::Data { public: QQmlObjectCreationProfiler(QQmlProfiler *profiler) : profiler(profiler) { - Q_QML_PROFILE(profiler, startCreating()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, startCreating()); } ~QQmlObjectCreationProfiler() { - Q_QML_PROFILE(profiler, endRange()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, endRange()); } void update(const QString &typeName, const QUrl &url, int line, int column) @@ -312,7 +316,7 @@ public: QQmlObjectCompletionProfiler(QQmlVmeProfiler *parent) : profiler(parent->profiler) { - Q_QML_PROFILE_IF_ENABLED(profiler, { + Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler, { QQmlVmeProfiler::Data data = parent->pop(); profiler->startCreating(data.m_typeName, data.m_url, data.m_line, data.m_column); }); @@ -320,7 +324,8 @@ public: ~QQmlObjectCompletionProfiler() { - Q_QML_PROFILE(profiler, endRange()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, + endRange()); } private: QQmlProfiler *profiler; diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h index 92bab93300..e8ee98433d 100644 --- a/src/qml/debugger/qqmlprofilerdefinitions_p.h +++ b/src/qml/debugger/qqmlprofilerdefinitions_p.h @@ -122,6 +122,22 @@ struct QQmlProfilerDefinitions { }; typedef QV4::Profiling::MemoryType MemoryType; + + enum ProfileFeature { + ProfileJavaScript = QV4::Profiling::FeatureFunctionCall, + ProfileMemory = QV4::Profiling::FeatureMemoryAllocation, + ProfilePixmapCache, + ProfileSceneGraph, + ProfileAnimations, + ProfilePainting, + ProfileCompiling, + ProfileCreating, + ProfileBinding, + ProfileHandlingSignal, + ProfileInputEvents, + + MaximumProfileFeature + }; }; QT_END_NAMESPACE diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp index 6157d2f191..5ec8178f32 100644 --- a/src/qml/debugger/qqmlprofilerservice.cpp +++ b/src/qml/debugger/qqmlprofilerservice.cpp @@ -171,12 +171,12 @@ void QQmlProfilerService::addGlobalProfiler(QQmlAbstractProfilerAdapter *profile // Global profiler, not connected to a specific engine. // Global profilers are started whenever any engine profiler is started and stopped when // all engine profilers are stopped. - foreach (QQmlAbstractProfilerAdapter *engineProfiler, m_engineProfilers) { - if (engineProfiler->isRunning()) { - profiler->startProfiling(); - break; - } - } + quint64 features = 0; + foreach (QQmlAbstractProfilerAdapter *engineProfiler, m_engineProfilers) + features |= engineProfiler->features(); + + if (features != 0) + profiler->startProfiling(features); } void QQmlProfilerService::removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) @@ -206,7 +206,7 @@ void QQmlProfilerService::removeProfilerFromStartTimes(const QQmlAbstractProfile * * If any engine profiler is started like that also start all global profilers. */ -void QQmlProfilerService::startProfiling(QQmlEngine *engine) +void QQmlProfilerService::startProfiling(QQmlEngine *engine, quint64 features) { QMutexLocker lock(configMutex()); @@ -218,7 +218,7 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine) if (engine != 0) { foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine)) { if (!profiler->isRunning()) { - profiler->startProfiling(); + profiler->startProfiling(features); startedAny = true; } } @@ -230,7 +230,7 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine) i != m_engineProfilers.end(); ++i) { if (!i.value()->isRunning()) { engines << i.key(); - i.value()->startProfiling(); + i.value()->startProfiling(features); startedAny = true; } } @@ -241,7 +241,7 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine) if (startedAny) { foreach (QQmlAbstractProfilerAdapter *profiler, m_globalProfilers) { if (!profiler->isRunning()) - profiler->startProfiling(); + profiler->startProfiling(features); } } @@ -359,14 +359,17 @@ void QQmlProfilerService::messageReceived(const QByteArray &message) QQmlDebugStream stream(&rwData, QIODevice::ReadOnly); int engineId = -1; + quint64 features = std::numeric_limits::max(); bool enabled; stream >> enabled; if (!stream.atEnd()) stream >> engineId; + if (!stream.atEnd()) + stream >> features; // If engineId == -1 objectForId() and then the cast will return 0. if (enabled) - startProfiling(qobject_cast(objectForId(engineId))); + startProfiling(qobject_cast(objectForId(engineId)), features); else stopProfiling(qobject_cast(objectForId(engineId))); diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h index 5405905861..c4c40adc4f 100644 --- a/src/qml/debugger/qqmlprofilerservice_p.h +++ b/src/qml/debugger/qqmlprofilerservice_p.h @@ -78,8 +78,8 @@ public: void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler); void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler); - void startProfiling(QQmlEngine *engine = 0); - void stopProfiling(QQmlEngine *engine = 0); + void startProfiling(QQmlEngine *engine, quint64 features = std::numeric_limits::max()); + void stopProfiling(QQmlEngine *engine); QQmlProfilerService(); ~QQmlProfilerService(); diff --git a/src/qml/debugger/qv4profileradapter.cpp b/src/qml/debugger/qv4profileradapter.cpp index 19a6ea3e74..a5492ce805 100644 --- a/src/qml/debugger/qv4profileradapter.cpp +++ b/src/qml/debugger/qv4profileradapter.cpp @@ -41,9 +41,10 @@ QV4ProfilerAdapter::QV4ProfilerAdapter(QQmlProfilerService *service, QV4::Execut QQmlAbstractProfilerAdapter(service) { engine->enableProfiler(); - connect(this, SIGNAL(profilingEnabled()), engine->profiler, SLOT(startProfiling())); - connect(this, SIGNAL(profilingEnabledWhileWaiting()), engine->profiler, SLOT(startProfiling()), - Qt::DirectConnection); + connect(this, SIGNAL(profilingEnabled(quint64)), + engine->profiler, SLOT(startProfiling(quint64))); + connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)), + engine->profiler, SLOT(startProfiling(quint64)), Qt::DirectConnection); connect(this, SIGNAL(profilingDisabled()), engine->profiler, SLOT(stopProfiling())); connect(this, SIGNAL(profilingDisabledWhileWaiting()), engine->profiler, SLOT(stopProfiling()), Qt::DirectConnection); diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp index 693af854da..f1bd1d55d9 100644 --- a/src/qml/jsruntime/qv4profiling.cpp +++ b/src/qml/jsruntime/qv4profiling.cpp @@ -53,7 +53,7 @@ FunctionCallProperties FunctionCall::resolve() const } -Profiler::Profiler(QV4::ExecutionEngine *engine) : enabled(false), m_engine(engine) +Profiler::Profiler(QV4::ExecutionEngine *engine) : featuresEnabled(0), m_engine(engine) { static int metatype = qRegisterMetaType >(); static int metatype2 = qRegisterMetaType >(); @@ -69,7 +69,7 @@ struct FunctionCallComparator { void Profiler::stopProfiling() { - enabled = false; + featuresEnabled = 0; reportData(); } @@ -85,27 +85,29 @@ void Profiler::reportData() emit dataReady(resolved, m_memory_data); } -void Profiler::startProfiling() +void Profiler::startProfiling(quint64 features) { - if (!enabled) { + if (featuresEnabled == 0) { m_data.clear(); m_memory_data.clear(); - qint64 timestamp = m_timer.nsecsElapsed(); - MemoryAllocationProperties heap = {timestamp, - (qint64)m_engine->memoryManager->getAllocatedMem(), - HeapPage}; - m_memory_data.append(heap); - MemoryAllocationProperties small = {timestamp, - (qint64)m_engine->memoryManager->getUsedMem(), - SmallItem}; - m_memory_data.append(small); - MemoryAllocationProperties large = {timestamp, - (qint64)m_engine->memoryManager->getLargeItemsMem(), - LargeItem}; - m_memory_data.append(large); + if (features & (1 << FeatureMemoryAllocation)) { + qint64 timestamp = m_timer.nsecsElapsed(); + MemoryAllocationProperties heap = {timestamp, + (qint64)m_engine->memoryManager->getAllocatedMem(), + HeapPage}; + m_memory_data.append(heap); + MemoryAllocationProperties small = {timestamp, + (qint64)m_engine->memoryManager->getUsedMem(), + SmallItem}; + m_memory_data.append(small); + MemoryAllocationProperties large = {timestamp, + (qint64)m_engine->memoryManager->getLargeItemsMem(), + LargeItem}; + m_memory_data.append(large); + } - enabled = true; + featuresEnabled = features; } } diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h index f115137c86..8224f8a851 100644 --- a/src/qml/jsruntime/qv4profiling_p.h +++ b/src/qml/jsruntime/qv4profiling_p.h @@ -46,6 +46,11 @@ namespace QV4 { namespace Profiling { +enum Features { + FeatureFunctionCall, + FeatureMemoryAllocation +}; + enum MemoryType { HeapPage, LargeItem, @@ -106,15 +111,18 @@ private: }; #define Q_V4_PROFILE_ALLOC(engine, size, type)\ - (engine->profiler && engine->profiler->enabled ?\ + (engine->profiler &&\ + (engine->profiler->featuresEnabled & (1 << Profiling::FeatureMemoryAllocation)) ?\ engine->profiler->trackAlloc(size, type) : size) #define Q_V4_PROFILE_DEALLOC(engine, pointer, size, type) \ - (engine->profiler && engine->profiler->enabled ?\ + (engine->profiler &&\ + (engine->profiler->featuresEnabled & (1 << Profiling::FeatureMemoryAllocation)) ?\ engine->profiler->trackDealloc(pointer, size, type) : pointer) #define Q_V4_PROFILE(engine, ctx, function)\ - ((engine->profiler && engine->profiler->enabled) ?\ + (engine->profiler &&\ + (engine->profiler->featuresEnabled & (1 << Profiling::FeatureFunctionCall)) ?\ Profiling::FunctionCallProfiler::profileCall(engine->profiler, ctx, function) :\ function->code(ctx, function->codeData)) @@ -138,11 +146,11 @@ public: return pointer; } - bool enabled; + quint64 featuresEnabled; public slots: void stopProfiling(); - void startProfiling(); + void startProfiling(quint64 features); void reportData(); void setTimer(const QElapsedTimer &timer) { m_timer = timer; } diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 0ad60e01ab..a827e96ab1 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -93,7 +93,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile sharedState->rootContext = 0; QQmlProfiler *profiler = QQmlEnginePrivate::get(engine)->profiler; - Q_QML_PROFILE_IF_ENABLED(profiler, + Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler, sharedState->profiler.init(profiler, compiledData->totalParserStatusCount)); } diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index 91a6468593..a55d056c75 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -594,7 +594,7 @@ void QQuickView::resizeEvent(QResizeEvent *e) /*! \reimp */ void QQuickView::keyPressEvent(QKeyEvent *e) { - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QQuickWindow::keyPressEvent(e); } @@ -602,7 +602,7 @@ void QQuickView::keyPressEvent(QKeyEvent *e) /*! \reimp */ void QQuickView::keyReleaseEvent(QKeyEvent *e) { - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QQuickWindow::keyReleaseEvent(e); } @@ -610,7 +610,7 @@ void QQuickView::keyReleaseEvent(QKeyEvent *e) /*! \reimp */ void QQuickView::mouseMoveEvent(QMouseEvent *e) { - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QQuickWindow::mouseMoveEvent(e); } @@ -618,7 +618,7 @@ void QQuickView::mouseMoveEvent(QMouseEvent *e) /*! \reimp */ void QQuickView::mousePressEvent(QMouseEvent *e) { - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QQuickWindow::mousePressEvent(e); } @@ -626,7 +626,7 @@ void QQuickView::mousePressEvent(QMouseEvent *e) /*! \reimp */ void QQuickView::mouseReleaseEvent(QMouseEvent *e) { - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QQuickWindow::mouseReleaseEvent(e); } diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index ecd450bcc8..0a39188b24 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -124,7 +124,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material) if (shader) return shader; - if (QSG_LOG_TIME_COMPILATION().isDebugEnabled() || QQuickProfiler::enabled) + if (QSG_LOG_TIME_COMPILATION().isDebugEnabled() || QQuickProfiler::profilingSceneGraph()) qsg_renderer_timer.start(); QSGMaterialShader *s = material->createShader(); @@ -169,7 +169,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate if (shader) return shader; - if (QSG_LOG_TIME_COMPILATION().isDebugEnabled() || QQuickProfiler::enabled) + if (QSG_LOG_TIME_COMPILATION().isDebugEnabled() || QQuickProfiler::profilingSceneGraph()) qsg_renderer_timer.start(); QSGMaterialShader *s = static_cast(material->createShader()); diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index d62802e854..dd089425f6 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -176,7 +176,8 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) m_is_rendering = true; - bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled() || QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled() || + QQuickProfiler::profilingSceneGraph(); if (profileFrames) frameTimer.start(); qint64 bindTime = 0; @@ -272,7 +273,8 @@ void QSGRenderer::preprocess() } } - bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled()|| QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled()|| + QQuickProfiler::profilingSceneGraph(); if (profileFrames) preprocessTime = frameTimer.nsecsElapsed(); diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index faf2762acc..fb9fe00ee5 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -153,7 +153,8 @@ void QSGDistanceFieldGlyphCache::update() if (m_pendingGlyphs.isEmpty()) return; - bool profileFrames = QSG_LOG_TIME_GLYPH().isDebugEnabled() || QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_GLYPH().isDebugEnabled() || + QQuickProfiler::profilingSceneGraph(); if (profileFrames) qsg_render_timer.start(); diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index dc0939c023..4428918da5 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -362,7 +362,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) } QElapsedTimer renderTimer; qint64 renderTime = 0, syncTime = 0, polishTime = 0; - bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || + QQuickProfiler::profilingSceneGraph(); if (profileFrames) renderTimer.start(); diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 4e70c3f0a2..3866ed9a2b 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -521,7 +521,8 @@ void QSGRenderThread::sync(bool inExpose) void QSGRenderThread::syncAndRender() { - bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || + QQuickProfiler::profilingSceneGraph(); if (profileFrames) { sinceLastTime = threadTimer.nsecsElapsed(); threadTimer.start(); @@ -1087,7 +1088,8 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) qint64 polishTime = 0; qint64 waitTime = 0; qint64 syncTime = 0; - bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || + QQuickProfiler::profilingSceneGraph(); if (profileFrames) timer.start(); diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index f2731e347b..de1160064d 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -55,7 +55,7 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_ static QElapsedTimer qsg_render_timer; #define QSG_RENDER_TIMING_SAMPLE(sampleName) \ qint64 sampleName = 0; \ - if (QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::enabled) \ + if (QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::profilingSceneGraph()) \ sampleName = qsg_render_timer.nsecsElapsed() diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp index a9cbbe1dc3..5edcb5d67a 100644 --- a/src/quick/scenegraph/util/qsgatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgatlastexture.cpp @@ -377,7 +377,8 @@ void Atlas::bind(QSGTexture::Filtering filtering) // Upload all pending images.. for (int i=0; iclose(); } - Q_QUICK_PROFILE(pixmapStateChanged(job->url)); + PIXMAP_PROFILE(pixmapStateChanged(job->url)); // deleteLater, since not owned by this thread job->deleteLater(); } @@ -512,7 +514,7 @@ void QQuickPixmapReader::processJobs() runningJob->loading = true; QUrl url = runningJob->url; - Q_QUICK_PROFILE(pixmapStateChanged(url)); + PIXMAP_PROFILE(pixmapStateChanged(url)); QSize requestSize = runningJob->requestSize; locker.unlock(); @@ -660,7 +662,7 @@ void QQuickPixmapReader::cancel(QQuickPixmapReply *reply) // If loading was started (reply removed from jobs) but the reply was never processed // (otherwise it would have deleted itself) we need to profile an error. if (jobs.removeAll(reply) == 0) { - Q_QUICK_PROFILE(pixmapStateChanged(reply->url)); + PIXMAP_PROFILE(pixmapStateChanged(reply->url)); } delete reply; } @@ -894,12 +896,12 @@ bool QQuickPixmapReply::event(QEvent *event) if (data->pixmapStatus == QQuickPixmap::Ready) { data->textureFactory = de->textureFactory; data->implicitSize = de->implicitSize; - Q_QUICK_PROFILE(pixmapLoadingFinished(data->url, + PIXMAP_PROFILE(pixmapLoadingFinished(data->url, data->textureFactory != 0 && data->textureFactory->textureSize().isValid() ? data->textureFactory->textureSize() : (data->requestSize.isValid() ? data->requestSize : data->implicitSize))); } else { - Q_QUICK_PROFILE(pixmapStateChanged(data->url)); + PIXMAP_PROFILE(pixmapStateChanged(data->url)); data->errorString = de->errorString; data->removeFromCache(); // We don't continue to cache error'd pixmaps } @@ -907,7 +909,7 @@ bool QQuickPixmapReply::event(QEvent *event) data->reply = 0; emit finished(); } else { - Q_QUICK_PROFILE(pixmapStateChanged(url)); + PIXMAP_PROFILE(pixmapStateChanged(url)); } delete this; @@ -927,7 +929,7 @@ int QQuickPixmapData::cost() const void QQuickPixmapData::addref() { ++refCount; - Q_QUICK_PROFILE(pixmapCountChanged(url, refCount)); + PIXMAP_PROFILE(pixmapCountChanged(url, refCount)); if (prevUnreferencedPtr) pixmapStore()->referencePixmap(this); } @@ -936,7 +938,7 @@ void QQuickPixmapData::release() { Q_ASSERT(refCount > 0); --refCount; - Q_QUICK_PROFILE(pixmapCountChanged(url, refCount)); + PIXMAP_PROFILE(pixmapCountChanged(url, refCount)); if (refCount == 0) { if (reply) { QQuickPixmapReply *cancelReply = reply; @@ -967,7 +969,7 @@ void QQuickPixmapData::addToCache() QQuickPixmapKey key = { &url, &requestSize }; pixmapStore()->m_cache.insert(key, this); inCache = true; - Q_QUICK_PROFILE(pixmapCountChanged( + PIXMAP_PROFILE(pixmapCountChanged( url, pixmapStore()->m_cache.count())); } } @@ -978,7 +980,7 @@ void QQuickPixmapData::removeFromCache() QQuickPixmapKey key = { &url, &requestSize }; pixmapStore()->m_cache.remove(key); inCache = false; - Q_QUICK_PROFILE(pixmapCountChanged( + PIXMAP_PROFILE(pixmapCountChanged( url, pixmapStore()->m_cache.count())); } } @@ -1257,16 +1259,16 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques if (!(options & QQuickPixmap::Asynchronous)) { bool ok = false; - Q_QUICK_PROFILE(pixmapStateChanged(url)); + PIXMAP_PROFILE(pixmapStateChanged(url)); d = createPixmapDataSync(this, engine, url, requestSize, &ok); if (ok) { - Q_QUICK_PROFILE(pixmapLoadingFinished(url, QSize(width(), height()))); + PIXMAP_PROFILE(pixmapLoadingFinished(url, QSize(width(), height()))); if (options & QQuickPixmap::Cache) d->addToCache(); return; } if (d) { // loadable, but encountered error while loading - Q_QUICK_PROFILE(pixmapStateChanged(url)); + PIXMAP_PROFILE(pixmapStateChanged(url)); return; } } diff --git a/src/quick/util/qquickprofiler.cpp b/src/quick/util/qquickprofiler.cpp index 604d6e5cb1..3b34b7550b 100644 --- a/src/quick/util/qquickprofiler.cpp +++ b/src/quick/util/qquickprofiler.cpp @@ -40,7 +40,7 @@ QT_BEGIN_NAMESPACE // instance will be set, unset in constructor. Allows static methods to be inlined. QQuickProfiler *QQuickProfiler::s_instance = 0; -bool QQuickProfiler::enabled = false; +quint64 QQuickProfiler::featuresEnabled = 0; // convert to QByteArrays that can be sent to the debug client // use of QDataStream can skew results @@ -129,7 +129,7 @@ void QQuickProfiler::initialize() void animationTimerCallback(qint64 delta) { - Q_QUICK_PROFILE(animationFrame(delta, + Q_QUICK_PROFILE(QQuickProfiler::ProfileAnimations, animationFrame(delta, QThread::currentThread() == QCoreApplication::instance()->thread() ? QQuickProfiler::GuiThread : QQuickProfiler::RenderThread)); } @@ -158,10 +158,10 @@ QQuickProfiler::QQuickProfiler(QQmlProfilerService *service) : m_timer.start(); // We can always do DirectConnection here as all methods are protected by mutexes - connect(this, SIGNAL(profilingEnabled()), this, SLOT(startProfilingImpl()), - Qt::DirectConnection); - connect(this, SIGNAL(profilingEnabledWhileWaiting()), this, SLOT(startProfilingImpl()), + connect(this, SIGNAL(profilingEnabled(quint64)), this, SLOT(startProfilingImpl(quint64)), Qt::DirectConnection); + connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)), + this, SLOT(startProfilingImpl(quint64)), Qt::DirectConnection); connect(this, SIGNAL(referenceTimeKnown(QElapsedTimer)), this, SLOT(setTimer(QElapsedTimer)), Qt::DirectConnection); connect(this, SIGNAL(profilingDisabled()), this, SLOT(stopProfilingImpl()), @@ -179,23 +179,23 @@ QQuickProfiler::QQuickProfiler(QQmlProfilerService *service) : QQuickProfiler::~QQuickProfiler() { QMutexLocker lock(&m_dataMutex); - enabled = false; + featuresEnabled = 0; s_instance = 0; } -void QQuickProfiler::startProfilingImpl() +void QQuickProfiler::startProfilingImpl(quint64 features) { QMutexLocker lock(&m_dataMutex); next = 0; m_data.clear(); - enabled = true; + featuresEnabled = features; } void QQuickProfiler::stopProfilingImpl() { { QMutexLocker lock(&m_dataMutex); - enabled = false; + featuresEnabled = 0; next = 0; } service->dataReady(this); diff --git a/src/quick/util/qquickprofiler_p.h b/src/quick/util/qquickprofiler_p.h index 3aba3430e4..62e23cd393 100644 --- a/src/quick/util/qquickprofiler_p.h +++ b/src/quick/util/qquickprofiler_p.h @@ -54,18 +54,21 @@ QT_BEGIN_NAMESPACE -#define Q_QUICK_PROFILE_IF_ENABLED(Code)\ - if (QQuickProfiler::enabled) {\ +#define Q_QUICK_PROFILE_IF_ENABLED(feature, Code)\ + if (QQuickProfiler::featuresEnabled & (1 << feature)) {\ Code;\ } else\ (void)0 -#define Q_QUICK_PROFILE(Method)\ - Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::Method) +#define Q_QUICK_PROFILE(feature, Method)\ + Q_QUICK_PROFILE_IF_ENABLED(feature, QQuickProfiler::Method) #define Q_QUICK_SG_PROFILE(Type, Params)\ - Q_QUICK_PROFILE_IF_ENABLED((QQuickProfiler::sceneGraphFrame Params)) + Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileSceneGraph,\ + (QQuickProfiler::sceneGraphFrame Params)) +#define Q_QUICK_INPUT_PROFILE(Method)\ + Q_QUICK_PROFILE(QQuickProfiler::ProfileInputEvents, Method) // This struct is somewhat dangerous to use: // You can save values either with 32 or 64 bit precision. toByteArrays will @@ -196,7 +199,11 @@ public: qint64 sendMessages(qint64 until, QList &messages); - static bool enabled; + static quint64 featuresEnabled; + static bool profilingSceneGraph() + { + return featuresEnabled & (1 << QQuickProfiler::ProfileSceneGraph); + } static void initialize(); @@ -218,7 +225,7 @@ protected: } protected slots: - void startProfilingImpl(); + void startProfilingImpl(quint64 features); void stopProfilingImpl(); void reportDataImpl(); void setTimer(const QElapsedTimer &t); diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 8d93bf389b..707dc9b0a0 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -959,7 +959,7 @@ void QQuickWidget::resizeEvent(QResizeEvent *e) void QQuickWidget::keyPressEvent(QKeyEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QCoreApplication::sendEvent(d->offscreenWindow, e); } @@ -968,7 +968,7 @@ void QQuickWidget::keyPressEvent(QKeyEvent *e) void QQuickWidget::keyReleaseEvent(QKeyEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QCoreApplication::sendEvent(d->offscreenWindow, e); } @@ -977,7 +977,7 @@ void QQuickWidget::keyReleaseEvent(QKeyEvent *e) void QQuickWidget::mouseMoveEvent(QMouseEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); // Use the constructor taking localPos and screenPos. That puts localPos into the // event's localPos and windowPos, and screenPos into the event's screenPos. This way @@ -992,7 +992,7 @@ void QQuickWidget::mouseMoveEvent(QMouseEvent *e) void QQuickWidget::mouseDoubleClickEvent(QMouseEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); // As the second mouse press is suppressed in widget windows we emulate it here for QML. // See QTBUG-25831 @@ -1025,7 +1025,7 @@ void QQuickWidget::hideEvent(QHideEvent *) void QQuickWidget::mousePressEvent(QMouseEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QMouseEvent mappedEvent(e->type(), e->localPos(), e->screenPos(), e->button(), e->buttons(), e->modifiers()); QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent); @@ -1036,7 +1036,7 @@ void QQuickWidget::mousePressEvent(QMouseEvent *e) void QQuickWidget::mouseReleaseEvent(QMouseEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QMouseEvent mappedEvent(e->type(), e->localPos(), e->screenPos(), e->button(), e->buttons(), e->modifiers()); QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent); @@ -1048,7 +1048,7 @@ void QQuickWidget::mouseReleaseEvent(QMouseEvent *e) void QQuickWidget::wheelEvent(QWheelEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); // Wheel events only have local and global positions, no need to map. QCoreApplication::sendEvent(d->offscreenWindow, e); -- cgit v1.2.3 From 7ddb567f7cced8beed147c42b8c79fc017d260ee Mon Sep 17 00:00:00 2001 From: Venu Date: Tue, 2 Sep 2014 14:54:28 +0200 Subject: Doc: Added a bit more detail about the example Task-number: QTBUG-37203 Change-Id: I62664b5dd0041cf8ba210dc3f0375793f7c72a00 Reviewed-by: Nico Vertriest Reviewed-by: Martin Smith --- examples/quick/demos/stocqt/doc/src/stocqt.qdoc | 49 ++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/examples/quick/demos/stocqt/doc/src/stocqt.qdoc b/examples/quick/demos/stocqt/doc/src/stocqt.qdoc index 5f090e84f9..5e5ba3caf5 100644 --- a/examples/quick/demos/stocqt/doc/src/stocqt.qdoc +++ b/examples/quick/demos/stocqt/doc/src/stocqt.qdoc @@ -32,8 +32,53 @@ \brief A configurable stock chart for the NASDAQ-100. \image qtquick-demo-stocqt.png - \e{StocQt} demonstrates various QML and \l{Qt Quick} features such as - displaying custom components and downloading data from the internet. + The \e{StocQt} application presents a trend chart for the first stock in + the list of NASDAQ-100 stocks maintained by it. It allows the user to + choose another stock from the list, and fetches the required data for + the selected stock by sending an \c XMLHttpRequest to + http://finance.yahoo.com. + + The application uses several custom types such as Button, CheckBox, + StockChart, StockInfo, StockView, and so on. These types are used to + present the stock data in a readable form and also let the user customize + the trend chart. For example, the user can choose to view the yearly, + monthly, or daily trends in the stock price. + + The application uses the ObjectModel type to access the two visual data + models that it depends on. + + \quotefromfile demos/stocqt/stocqt.qml + \skipto ListView + \printuntil id + \dots 8 + \skipto model + \printuntil StockView + \printuntil } + \printuntil } + \printuntil } + + The StockListView model is a static data model listing the + NASDAQ-100 stocks with basic information such as stockId, name, value, + change, and so on. This data model is used by the application if the + user wants to choose another stock from the list. + + StockView is a complex data model that presents a trend chart for the + selected stock. It uses another custom type, StockChart, which presents + the graphical trend of the stock price using a Canvas. This data model + is used for most of the time during the lifetime of the application. + + \quotefromfile demos/stocqt/content/StockChart.qml + \skipto Rectangle + \printuntil height + \dots + \skipto Canvas + \printuntil id + \dots 8 + \skipto onPaint + \printuntil /^\}$/ + + To understand the application better, browse through its code using + Qt Creator. \include examples-run.qdocinc -- cgit v1.2.3 From e471398395508ce156bf9a287920393f838f2b22 Mon Sep 17 00:00:00 2001 From: Andy Nichols Date: Thu, 11 Sep 2014 12:23:37 +0200 Subject: Check for a current QOpenGLContext before use We can not assume that there will be a current OpenGL context to use in QQuickImageParticle so now there is a check before we make a call to the current context. Change-Id: I0c77895d0b0f1afdf4853c0486fba0ef9a7b883d Reviewed-by: Lars Knoll --- src/particles/qquickimageparticle.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp index 08d3142701..60a67d55a6 100644 --- a/src/particles/qquickimageparticle.cpp +++ b/src/particles/qquickimageparticle.cpp @@ -1223,6 +1223,9 @@ void QQuickImageParticle::buildParticleNodes(QSGNode** passThrough) void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node) { + if (!QOpenGLContext::currentContext()) + return; + if (QOpenGLContext::currentContext()->isOpenGLES() && m_count * 4 > 0xffff) { printf("ImageParticle: Too many particles - maximum 16,000 per ImageParticle.\n");//ES 2 vertex count limit is ushort return; -- cgit v1.2.3 From 56d9fb4881ec75ceccfe96babc2acb429d76b5ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Tue, 9 Sep 2014 14:37:59 +0200 Subject: Fix String leak by calling the correct destructor Task-number: QTBUG-41167 Change-Id: I696fbb7400215c7f1fb8cb2a1dbbc0780440a8c3 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4string.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index 63a8e93878..bd8a5ffccb 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -119,7 +119,7 @@ const ObjectVTable String::static_vtbl = void String::destroy(Managed *that) { - static_cast(that)->~String(); + static_cast(that)->d()->~Data(); } void String::markObjects(Managed *that, ExecutionEngine *e) -- cgit v1.2.3 From 50f100611620f9c2b0b1e01868d0de5f7b783de2 Mon Sep 17 00:00:00 2001 From: Andy Nichols Date: Thu, 11 Sep 2014 17:22:59 +0200 Subject: Check for valid QSGRenderContext instead of QOpenGLContext A QQuickWindow with a valid QSGRenderContext is what should be checked for in QQuickCanvasItem::itemChange. Change-Id: Ibb85c2bb79d85b2d91b5d68cfa8a4760106047ae Reviewed-by: Gunnar Sletta --- src/quick/items/context2d/qquickcanvasitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index f9e7bfd0ae..345af6faf4 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -667,7 +667,7 @@ void QQuickCanvasItem::itemChange(QQuickItem::ItemChange change, const QQuickIte return; d->window = value.window; - if (d->window->openglContext() != 0) // available context == initialized + if (QQuickWindowPrivate::get(d->window)->context != 0) // available context == initialized sceneGraphInitialized(); else connect(d->window, SIGNAL(sceneGraphInitialized()), SLOT(sceneGraphInitialized())); -- cgit v1.2.3 From 26aed3d930ef96ed214ccaf18a234ef3cb8730e4 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Thu, 11 Sep 2014 14:16:58 +0900 Subject: Fix a typo and a warning in qmltest::shadersource-from-other-window Change-Id: I60d0494ff8d619cb9be8d7a5db712c1316450b97 Reviewed-by: Gunnar Sletta --- tests/auto/qmltest/shadersource/tst_SourceInOtherWindow.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/auto/qmltest/shadersource/tst_SourceInOtherWindow.qml b/tests/auto/qmltest/shadersource/tst_SourceInOtherWindow.qml index 4ca687bdb6..b00cfbc5f8 100644 --- a/tests/auto/qmltest/shadersource/tst_SourceInOtherWindow.qml +++ b/tests/auto/qmltest/shadersource/tst_SourceInOtherWindow.qml @@ -37,6 +37,9 @@ import QtQuick.Window 2.0 import QtTest 1.0 Item { + width: 100 + height: 100 + Rectangle { id: box color: "red" @@ -65,7 +68,7 @@ Item { TestCase { name: "shadersource-from-other-window" - when: childWindow.isRendered + when: childWindow.rendered function test_endresult() { verify(true); // that we got here without problems... } -- cgit v1.2.3 From 97594aa3d82618c64f57e96116f39a59ab3bb029 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Thu, 11 Sep 2014 12:31:18 +0900 Subject: prevent crash when set ShaderEffectSource::sourceItem null Regression introduced in 81ba77d736f07efac37d284cd741d71f9dad4149 Task-number: QTBUG-41241 Change-Id: I9a65af6915325e1cbf9205c7da94273d5b91b310 Reviewed-by: Gunnar Sletta --- src/quick/items/qquickshadereffectsource.cpp | 32 ++++++------ tests/auto/qmltest/shadersource/tst_SourceItem.qml | 57 ++++++++++++++++++++++ 2 files changed, 73 insertions(+), 16 deletions(-) create mode 100644 tests/auto/qmltest/shadersource/tst_SourceItem.qml diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index 80be283443..120a8956eb 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -322,24 +322,24 @@ void QQuickShaderEffectSource::setSourceItem(QQuickItem *item) d->derefWindow(); } - if (window() == item->window()) { - m_sourceItem = item; - } else { - qWarning("ShaderEffectSource: sourceItem and ShaderEffectSource must both be children of the same window."); - m_sourceItem = 0; - } + m_sourceItem = item; if (m_sourceItem) { - QQuickItemPrivate *d = QQuickItemPrivate::get(item); - // 'item' needs a window to get a scene graph node. It usually gets one through its - // parent, but if the source item is "inline" rather than a reference -- i.e. - // "sourceItem: Item { }" instead of "sourceItem: foo" -- it will not get a parent. - // In those cases, 'item' should get the window from 'this'. - if (window()) - d->refWindow(window()); - d->refFromEffectItem(m_hideSource); - d->addItemChangeListener(this, QQuickItemPrivate::Geometry); - connect(m_sourceItem, SIGNAL(destroyed(QObject*)), this, SLOT(sourceItemDestroyed(QObject*))); + if (window() == m_sourceItem->window()) { + QQuickItemPrivate *d = QQuickItemPrivate::get(item); + // 'item' needs a window to get a scene graph node. It usually gets one through its + // parent, but if the source item is "inline" rather than a reference -- i.e. + // "sourceItem: Item { }" instead of "sourceItem: foo" -- it will not get a parent. + // In those cases, 'item' should get the window from 'this'. + if (window()) + d->refWindow(window()); + d->refFromEffectItem(m_hideSource); + d->addItemChangeListener(this, QQuickItemPrivate::Geometry); + connect(m_sourceItem, SIGNAL(destroyed(QObject*)), this, SLOT(sourceItemDestroyed(QObject*))); + } else { + qWarning("ShaderEffectSource: sourceItem and ShaderEffectSource must both be children of the same window."); + m_sourceItem = 0; + } } update(); emit sourceItemChanged(); diff --git a/tests/auto/qmltest/shadersource/tst_SourceItem.qml b/tests/auto/qmltest/shadersource/tst_SourceItem.qml new file mode 100644 index 0000000000..822b53d6fa --- /dev/null +++ b/tests/auto/qmltest/shadersource/tst_SourceItem.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtTest 1.0 + +Item { + id: root + + Rectangle { + id: box + color: "red" + } + + ShaderEffectSource { + id: theSource + } + + TestCase { + name: "shadersource-something-to-null" + function test_null() { + theSource.sourceItem = box + theSource.sourceItem = null + verify(true); // that we got here without problems... + } + } +} -- cgit v1.2.3 From 960e52776417ae599ffd62cc0b2c4b31a2e6bd62 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Fri, 12 Sep 2014 08:16:18 +0200 Subject: Link to Key Handling Priorities section more in Keys documentation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For those clicking directly on specific property links who might not know that the info they need about event order already exists. Change-Id: I18a9124697f542f5b3a2955ee10dfee538a93385 Reviewed-by: J-P Nurmi Reviewed-by: Topi Reiniö --- src/quick/items/qquickitem.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 1992398938..38ae0ed3c8 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -887,6 +887,8 @@ bool QQuickKeysAttached::isConnected(const char *signalName) handling. If the item accepts the key event it will not be handled by the Keys attached property handler. \endlist + + \sa {Key Handling Priorities} */ /*! @@ -914,6 +916,9 @@ bool QQuickKeysAttached::isConnected(const char *signalName) focus: true } \endqml + + To see the order in which events are received when using forwardTo, see + \l {Key Handling Priorities}. */ /*! -- cgit v1.2.3 From db44ad2be915fc00faba77bd9b1d19e3ec53b42c Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 11 Sep 2014 17:00:06 +0200 Subject: Fix stack size check on systems with less than 256kb stack We require at least 256 kbytes slack stack space, and if a system is configured with less (or equal), then the stack size checks fail early on and strange error message occur during engine startup and execution. This patch calls the stack check code early on and bails out with an error message that's more descriptive. Change-Id: I3263f2f93f62332d08003411e1bb5b3b1140d02b Task-number: QTBUG-41213 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4engine.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 88cd043d1e..ea075f9cbd 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -90,6 +90,8 @@ static ReturnedValue throwTypeError(CallContext *ctx) return ctx->throwTypeError(); } +const int MinimumStackSize = 256; // in kbytes + quintptr getStackLimit() { quintptr stackLimit; @@ -149,7 +151,7 @@ quintptr getStackLimit() #endif // 256k slack - return stackLimit + 256*1024; + return stackLimit + MinimumStackSize*1024; } @@ -203,6 +205,8 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) // set up stack limits jsStackLimit = jsStackBase + JSStackLimit/sizeof(Value); cStackLimit = getStackLimit(); + if (!recheckCStackLimits()) + qFatal("Fatal: Not enough stack space available for QML. Please increase the process stack size to more than %d KBytes.", MinimumStackSize); Scope scope(this); -- cgit v1.2.3 From 2153ca682a934ad969c8a4d49bfc857fa756ac9f Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 12 Sep 2014 17:34:34 +0200 Subject: Let QSGPlainTexture support shutting down without a GL context. Change-Id: Iae934e4d9e91f4ea21dd5bf27c4fafc5d481fb0a Task-number: QTBUG-41278 Reviewed-by: Laszlo Agocs --- src/quick/scenegraph/util/qsgtexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp index 4612e6b87d..fc5050014e 100644 --- a/src/quick/scenegraph/util/qsgtexture.cpp +++ b/src/quick/scenegraph/util/qsgtexture.cpp @@ -563,7 +563,7 @@ QSGPlainTexture::QSGPlainTexture() QSGPlainTexture::~QSGPlainTexture() { - if (m_texture_id && m_owns_texture) + if (m_texture_id && m_owns_texture && QOpenGLContext::currentContext()) QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id); } -- cgit v1.2.3 From 0265eec3ae023acc46cd66d6966ec966fd4bdbf8 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 15 Sep 2014 18:59:50 +0200 Subject: Wait longer for image to be loaded in canvas item test 200ms can be too short if the system is busy Change-Id: I4f9c6bcbec93d511b5b5e9d531450f3ffd22cb0c Reviewed-by: Simon Hausmann --- tests/auto/quick/qquickcanvasitem/data/tst_image.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml index ca95f2aec1..46a038a13c 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml @@ -11,7 +11,7 @@ CanvasTestCase { canvas.loadImage('rgrg-256x256.png'); canvas.loadImage('ggrr-256x256.png'); canvas.loadImage('broken.png'); - if (!canvas.isImageLoaded('green.png')) + while (!canvas.isImageLoaded('green.png')) wait(200); } -- cgit v1.2.3 From 2a6a33767f7068fc5c43bc03f66df6329fc3cea6 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 15 Sep 2014 16:57:35 +0200 Subject: Don't start QQmlThreads from their constructor In the case of derived classes (like the only user of QQmlThread) we cannot guarantee that the class is completely constructed when the thread starts. This includes the vtable which is necessary to decide which virtual functions to call. Change-Id: Ieaea67a72cc3b4f845b8621b34ca2928185917fb Reviewed-by: Simon Hausmann --- src/qml/qml/ftw/qqmlthread.cpp | 15 +++++++++------ src/qml/qml/ftw/qqmlthread_p.h | 2 ++ src/qml/qml/qqmltypeloader.cpp | 2 ++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp index 397b4851cf..18b257dc0e 100644 --- a/src/qml/qml/ftw/qqmlthread.cpp +++ b/src/qml/qml/ftw/qqmlthread.cpp @@ -207,12 +207,6 @@ void QQmlThreadPrivate::threadEvent() QQmlThread::QQmlThread() : d(new QQmlThreadPrivate(this)) { - d->lock(); - d->start(); - d->wait(); - d->unlock(); - d->moveToThread(d); - } QQmlThread::~QQmlThread() @@ -220,6 +214,15 @@ QQmlThread::~QQmlThread() delete d; } +void QQmlThread::startup() +{ + d->lock(); + d->start(); + d->wait(); + d->unlock(); + d->moveToThread(d); +} + void QQmlThread::shutdown() { d->lock(); diff --git a/src/qml/qml/ftw/qqmlthread_p.h b/src/qml/qml/ftw/qqmlthread_p.h index 995fcd4824..95d32d4fd2 100644 --- a/src/qml/qml/ftw/qqmlthread_p.h +++ b/src/qml/qml/ftw/qqmlthread_p.h @@ -60,6 +60,8 @@ class QQmlThread public: QQmlThread(); virtual ~QQmlThread(); + + void startup(); void shutdown(); bool isShutdown() const; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 0b7cc8e911..0e2d4d027a 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -728,6 +728,8 @@ void QQmlDataBlob::ThreadData::setProgress(quint8 v) QQmlDataLoaderThread::QQmlDataLoaderThread(QQmlDataLoader *loader) : m_loader(loader), m_networkAccessManager(0), m_networkReplyProxy(0) { + // Do that after initializing all the members. + startup(); } QNetworkAccessManager *QQmlDataLoaderThread::networkAccessManager() const -- cgit v1.2.3 From abff566ff85eb1fdee12e8a0fffddb7c1ff2dd7c Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 16 Sep 2014 12:18:01 +0200 Subject: Make Canvas test case independent of chosen font. 0/0 is not always a red pixel after rendering "Hello" in red. The chosen font has an influence on that. Looking for some red pixel in row 0 is pretty safe. Change-Id: I669548c3c9d8cd25d720998fd9ba31c1f480e4e3 Reviewed-by: Simon Hausmann --- tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml index 23fd5192f3..31413c23cd 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml @@ -368,7 +368,12 @@ CanvasTestCase { test: function(ctx) { ctx.font = "100px sans-serif"; ctx.fillText("Hello", -10, 10, extra); - comparePixel(ctx, 0, 0, 255, 0, 0, 255); + for (var x = 0; x < 100; ++x) { + var c = ctx.getImageData(x,0,1,1).data; + if (c[0] === 255 && c[1] === 0 && c[2] === 0 && c[3] === 255) + return; + } + qtest_fail("No red pixel found"); } }, { -- cgit v1.2.3 From 0e3f52de17e92fb83307dafe132363a57ce30941 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 16 Sep 2014 10:10:14 +0200 Subject: QQuickTextControl: update cursor rect when cursor changes position If the text cursor changes position by indirect manipulation of the document that backs a QQuickTextControl, we need to inform that the cursor rect changed as well. This will fix a bug with QQuickTextEdit that caused the platform input method to be out of sync since the cursor rect signal was never emitted from the the text control. Task-number: QTBUG-41042 Change-Id: Idcf35a2d51c8dffcb80ba21f8e59a61e04e5a879 Reviewed-by: Andrew den Exter --- src/quick/items/qquicktextcontrol.cpp | 6 +++--- src/quick/items/qquicktextcontrol_p.h | 2 +- src/quick/items/qquicktextcontrol_p_p.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp index a263a890b5..2585caefb5 100644 --- a/src/quick/items/qquicktextcontrol.cpp +++ b/src/quick/items/qquicktextcontrol.cpp @@ -435,12 +435,12 @@ void QQuickTextControlPrivate::setClipboardSelection() } #endif -void QQuickTextControlPrivate::_q_emitCursorPosChanged(const QTextCursor &someCursor) +void QQuickTextControlPrivate::_q_updateCursorPosChanged(const QTextCursor &someCursor) { Q_Q(QQuickTextControl); if (someCursor.isCopyOf(cursor)) { emit q->cursorPositionChanged(); - cursorRectangleChanged = true; + q->updateCursorRectangle(true); } } @@ -578,7 +578,7 @@ QQuickTextControl::QQuickTextControl(QTextDocument *doc, QObject *parent) qmlobject_connect(layout, QAbstractTextDocumentLayout, SIGNAL(updateBlock(QTextBlock)), this, QQuickTextControl, SIGNAL(updateRequest())); qmlobject_connect(doc, QTextDocument, SIGNAL(contentsChanged()), this, QQuickTextControl, SIGNAL(textChanged())); qmlobject_connect(doc, QTextDocument, SIGNAL(contentsChanged()), this, QQuickTextControl, SLOT(_q_updateCurrentCharFormatAndSelection())); - qmlobject_connect(doc, QTextDocument, SIGNAL(cursorPositionChanged(QTextCursor)), this, QQuickTextControl, SLOT(_q_emitCursorPosChanged(QTextCursor))); + qmlobject_connect(doc, QTextDocument, SIGNAL(cursorPositionChanged(QTextCursor)), this, QQuickTextControl, SLOT(_q_updateCursorPosChanged(QTextCursor))); connect(doc, &QTextDocument::contentsChange, this, &QQuickTextControl::contentsChange); layout->setProperty("cursorWidth", textCursorWidth); diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h index a47ab99112..d0af4a1cc9 100644 --- a/src/quick/items/qquicktextcontrol_p.h +++ b/src/quick/items/qquicktextcontrol_p.h @@ -169,7 +169,7 @@ protected: private: Q_DISABLE_COPY(QQuickTextControl) Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentCharFormatAndSelection()) - Q_PRIVATE_SLOT(d_func(), void _q_emitCursorPosChanged(const QTextCursor &)) + Q_PRIVATE_SLOT(d_func(), void _q_updateCursorPosChanged(const QTextCursor &)) }; diff --git a/src/quick/items/qquicktextcontrol_p_p.h b/src/quick/items/qquicktextcontrol_p_p.h index a3b7c7be99..bd07d86f9c 100644 --- a/src/quick/items/qquicktextcontrol_p_p.h +++ b/src/quick/items/qquicktextcontrol_p_p.h @@ -88,7 +88,7 @@ public: void setClipboardSelection(); #endif - void _q_emitCursorPosChanged(const QTextCursor &someCursor); + void _q_updateCursorPosChanged(const QTextCursor &someCursor); void setBlinkingCursorEnabled(bool enable); -- cgit v1.2.3 From cc8a76ce8ea76afe912902067e95ca2abf9e482f Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 16 Sep 2014 13:34:15 +0200 Subject: Fix crash when borders exceed item width/height in border image While we protected against the the borders exceeding the size of the source image when deciding whether to create a given patch, we did not protect against the case where the target rectangle is smaller than the borders. To fix this, we simply move the calculation of the target rectangle up to before we create the nodes, and check for isEmpty() before creating the nodes. In addition, we did not properly handle changing the borders dynamically. The subtree has to be rebuilt if the borders change so that the source or target rectangles change. Change-Id: Ia6a0df616ebbd0a32924de0b63fd48043027930a Task-number: QTBUG-41338 Reviewed-by: Gunnar Sletta --- src/quick/items/qquickborderimage.cpp | 211 ++++++++++++--------- src/quick/items/qquickimagebase_p_p.h | 2 + .../borderimage_borders_exceed_height.qml | 32 ++++ .../borderimage_borders_exceed_width.qml | 32 ++++ 4 files changed, 190 insertions(+), 87 deletions(-) create mode 100644 tests/manual/scenegraph_lancelot/data/borderimages/borderimage_borders_exceed_height.qml create mode 100644 tests/manual/scenegraph_lancelot/data/borderimages/borderimage_borders_exceed_width.qml diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp index 50a0a76267..127a5fa46b 100644 --- a/src/quick/items/qquickborderimage.cpp +++ b/src/quick/items/qquickborderimage.cpp @@ -563,6 +563,8 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat QRectF innerSourceRect(0, 0, 1, 1); QRectF innerTargetRect(0, 0, width(), height()); int borderLeft, borderTop, borderRight, borderBottom; + + bool updateNode = !oldNode; if (d->border) { const QQuickScaleGrid *border = d->getScaleGrid(); @@ -579,11 +581,17 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat borderTop, qMax(0, width() - border->right() - border->left()), qMax(0, height() - border->bottom() - border->top())); + + if (innerSourceRect != d->oldInnerSourceRect || innerTargetRect != d->oldInnerTargetRect) + updateNode = true; + d->oldInnerSourceRect = innerSourceRect; + d->oldInnerTargetRect = innerTargetRect; } bool updatePixmap = d->pixmapChanged; d->pixmapChanged = false; - if (!oldNode) { + if (updateNode) { + delete oldNode; oldNode = new QSGNode; updatePixmap = true; @@ -591,33 +599,130 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat d->regions[i].node = 0; if (innerSourceRect.left() > 0) { - if (innerSourceRect.top() > 0) - d->regions[0].node = d->sceneGraphContext()->createImageNode(); - if (innerSourceRect.bottom() < 1) - d->regions[6].node = d->sceneGraphContext()->createImageNode(); + if (innerSourceRect.top() > 0) { + QRectF rect(0, + 0, + innerTargetRect.left(), + innerTargetRect.top()); + + if (!rect.isEmpty()) { + d->regions[0].node = d->sceneGraphContext()->createImageNode(); + d->regions[0].node->setTargetRect(rect); + d->regions[0].node->setInnerTargetRect(rect); + d->regions[0].targetRect = rect; + } + } + + if (innerSourceRect.bottom() < 1) { + QRectF rect(0, + innerTargetRect.bottom(), + innerTargetRect.left(), + height() - innerTargetRect.height() - innerTargetRect.top()); + + if (!rect.isEmpty()) { + d->regions[6].node = d->sceneGraphContext()->createImageNode(); + d->regions[6].node->setTargetRect(rect); + d->regions[6].node->setInnerTargetRect(rect); + d->regions[6].targetRect = rect; + } + } - if (innerSourceRect.top() < innerSourceRect.bottom()) - d->regions[3].node = d->sceneGraphContext()->createImageNode(); + if (innerSourceRect.top() < innerSourceRect.bottom()) { + QRectF rect(0, + innerTargetRect.top(), + innerTargetRect.left(), + innerTargetRect.height()); + + if (!rect.isEmpty()) { + d->regions[3].node = d->sceneGraphContext()->createImageNode(); + d->regions[3].node->setTargetRect(rect); + d->regions[3].node->setInnerTargetRect(rect); + d->regions[3].targetRect = rect; + } + } } if (innerSourceRect.right() < 1) { - if (innerSourceRect.top() > 0) - d->regions[2].node = d->sceneGraphContext()->createImageNode(); - if (innerSourceRect.bottom() < 1) - d->regions[8].node = d->sceneGraphContext()->createImageNode(); + if (innerSourceRect.top() > 0) { + QRectF rect(innerTargetRect.right(), + 0, + width() - innerTargetRect.width() - innerTargetRect.left(), + innerTargetRect.top()); + + if (!rect.isEmpty()) { + d->regions[2].node = d->sceneGraphContext()->createImageNode(); + d->regions[2].node->setTargetRect(rect); + d->regions[2].node->setInnerTargetRect(rect); + d->regions[2].targetRect = rect; + } + } - if (innerSourceRect.top() < innerSourceRect.bottom()) - d->regions[5].node = d->sceneGraphContext()->createImageNode(); + if (innerSourceRect.bottom() < 1) { + QRectF rect(innerTargetRect.right(), + innerTargetRect.bottom(), + width() - innerTargetRect.width() - innerTargetRect.left(), + height() - innerTargetRect.height() - innerTargetRect.top()); + + if (!rect.isEmpty()) { + d->regions[8].node = d->sceneGraphContext()->createImageNode(); + d->regions[8].node->setTargetRect(rect); + d->regions[8].node->setInnerTargetRect(rect); + d->regions[8].targetRect = rect; + } + } + + if (innerSourceRect.top() < innerSourceRect.bottom()) { + QRectF rect(innerTargetRect.right(), + innerTargetRect.top(), + width() - innerTargetRect.width() - innerTargetRect.left(), + innerTargetRect.height()); + + if (!rect.isEmpty()) { + d->regions[5].node = d->sceneGraphContext()->createImageNode(); + d->regions[5].node->setTargetRect(rect); + d->regions[5].node->setInnerTargetRect(rect); + d->regions[5].targetRect = rect; + } + } } - if (innerSourceRect.top() > 0 && innerSourceRect.left() < innerSourceRect.right()) - d->regions[1].node = d->sceneGraphContext()->createImageNode(); + if (innerSourceRect.top() > 0 && innerSourceRect.left() < innerSourceRect.right()) { + QRectF rect(innerTargetRect.left(), + 0, + innerTargetRect.width(), + innerTargetRect.top()); + + if (!rect.isEmpty()) { + d->regions[1].node = d->sceneGraphContext()->createImageNode(); + d->regions[1].node->setTargetRect(rect); + d->regions[1].node->setInnerTargetRect(rect); + d->regions[1].targetRect = rect; + } + } - if (innerSourceRect.bottom() < 1 && innerSourceRect.left() < innerSourceRect.right()) - d->regions[7].node = d->sceneGraphContext()->createImageNode(); + if (innerSourceRect.bottom() < 1 && innerSourceRect.left() < innerSourceRect.right()) { + QRectF rect(innerTargetRect.left(), + innerTargetRect.bottom(), + innerTargetRect.width(), + height() - innerTargetRect.height() - innerTargetRect.top()); + + if (!rect.isEmpty()) { + d->regions[7].node = d->sceneGraphContext()->createImageNode(); + d->regions[7].node->setTargetRect(rect); + d->regions[7].node->setInnerTargetRect(rect); + d->regions[7].targetRect = rect; + } + } - if (innerSourceRect.left() < innerSourceRect.right() && innerSourceRect.top() < innerSourceRect.bottom()) - d->regions[4].node = d->sceneGraphContext()->createImageNode(); + if (innerSourceRect.left() < innerSourceRect.right() + && innerSourceRect.top() < innerSourceRect.bottom()) { + if (!innerTargetRect.isEmpty()) { + d->regions[4].node = d->sceneGraphContext()->createImageNode(); + d->regions[4].node->setInnerTargetRect(innerTargetRect); + d->regions[4].node->setTargetRect(innerTargetRect); + d->regions[4].targetRect = innerTargetRect; + } + } for (int i=0; i<9; ++i) { if (d->regions[i].node != 0) @@ -638,14 +743,6 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (d->regions[3].node == 0 && d->regions[6].node == 0) antialiasing |= QSGImageNode::AntialiasingBottom; d->regions[0].node->setAntialiasing(antialiasing); - - QRectF rect(0, - 0, - innerTargetRect.left(), - innerTargetRect.top()); - d->regions[0].node->setTargetRect(rect); - d->regions[0].node->setInnerTargetRect(rect); - d->regions[0].targetRect = rect; } if (d->regions[1].node != 0) { @@ -660,14 +757,6 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (d->regions[4].node == 0 && d->regions[7].node == 0) antialiasing |= QSGImageNode::AntialiasingBottom; d->regions[1].node->setAntialiasing(antialiasing); - - QRectF rect(innerTargetRect.left(), - 0, - innerTargetRect.width(), - innerTargetRect.top()); - d->regions[1].node->setTargetRect(rect); - d->regions[1].node->setInnerTargetRect(rect); - d->regions[1].targetRect = rect; } if (d->regions[2].node != 0) { @@ -680,14 +769,6 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (d->regions[5].node == 0 && d->regions[8].node == 0) antialiasing |= QSGImageNode::AntialiasingBottom; d->regions[2].node->setAntialiasing(antialiasing); - - QRectF rect(innerTargetRect.right(), - 0, - width() - innerTargetRect.width() - innerTargetRect.left(), - innerTargetRect.top()); - d->regions[2].node->setTargetRect(rect); - d->regions[2].node->setInnerTargetRect(rect); - d->regions[2].targetRect = rect; } if (d->regions[3].node != 0) { @@ -702,14 +783,6 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (d->regions[0].node == 0) antialiasing |= QSGImageNode::AntialiasingTop; d->regions[3].node->setAntialiasing(antialiasing); - - QRectF rect(0, - innerTargetRect.top(), - innerTargetRect.left(), - innerTargetRect.height()); - d->regions[3].node->setTargetRect(rect); - d->regions[3].node->setInnerTargetRect(rect); - d->regions[3].targetRect = rect; } if (d->regions[4].node != 0) { @@ -731,10 +804,6 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (d->regions[7].node == 0) antialiasing |= QSGImageNode::AntialiasingBottom; d->regions[4].node->setAntialiasing(antialiasing); - - d->regions[4].node->setInnerTargetRect(innerTargetRect); - d->regions[4].node->setTargetRect(innerTargetRect); - d->regions[4].targetRect = innerTargetRect; } if (d->regions[5].node != 0) { @@ -749,14 +818,6 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (d->regions[8].node == 0) antialiasing |= QSGImageNode::AntialiasingBottom; d->regions[5].node->setAntialiasing(antialiasing); - - QRectF rect(innerTargetRect.right(), - innerTargetRect.top(), - width() - innerTargetRect.width() - innerTargetRect.left(), - innerTargetRect.height()); - d->regions[5].node->setTargetRect(rect); - d->regions[5].node->setInnerTargetRect(rect); - d->regions[5].targetRect = rect; } if (d->regions[6].node != 0) { @@ -769,14 +830,6 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (d->regions[3].node == 0 && d->regions[0].node == 0) antialiasing |= QSGImageNode::AntialiasingTop; d->regions[6].node->setAntialiasing(antialiasing); - - QRectF rect(0, - innerTargetRect.bottom(), - innerTargetRect.left(), - height() - innerTargetRect.height() - innerTargetRect.top()); - d->regions[6].node->setTargetRect(rect); - d->regions[6].node->setInnerTargetRect(rect); - d->regions[6].targetRect = rect; } if (d->regions[7].node != 0) { @@ -791,14 +844,6 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (d->regions[4].node == 0 && d->regions[1].node == 0) antialiasing |= QSGImageNode::AntialiasingTop; d->regions[7].node->setAntialiasing(antialiasing); - - QRectF rect(innerTargetRect.left(), - innerTargetRect.bottom(), - innerTargetRect.width(), - height() - innerTargetRect.height() - innerTargetRect.top()); - d->regions[7].node->setTargetRect(rect); - d->regions[7].node->setInnerTargetRect(rect); - d->regions[7].targetRect = rect; } if (d->regions[8].node != 0) { @@ -811,14 +856,6 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (d->regions[5].node == 0 && d->regions[2].node == 0) antialiasing |= QSGImageNode::AntialiasingTop; d->regions[8].node->setAntialiasing(antialiasing); - - QRectF rect(innerTargetRect.right(), - innerTargetRect.bottom(), - width() - innerTargetRect.width() - innerTargetRect.left(), - height() - innerTargetRect.height() - innerTargetRect.top()); - d->regions[8].node->setTargetRect(rect); - d->regions[8].node->setInnerTargetRect(rect); - d->regions[8].targetRect = rect; } for (int i=0; i<9; ++i) { diff --git a/src/quick/items/qquickimagebase_p_p.h b/src/quick/items/qquickimagebase_p_p.h index f30eacb4ac..ec2f0bb73e 100644 --- a/src/quick/items/qquickimagebase_p_p.h +++ b/src/quick/items/qquickimagebase_p_p.h @@ -75,6 +75,8 @@ public: QSize sourcesize; QSize oldSourceSize; qreal devicePixelRatio; + QRectF oldInnerSourceRect; + QRectF oldInnerTargetRect; bool async : 1; bool cache : 1; bool mirror: 1; diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_borders_exceed_height.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_borders_exceed_height.qml new file mode 100644 index 0000000000..c4321d25bb --- /dev/null +++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_borders_exceed_height.qml @@ -0,0 +1,32 @@ +import QtQuick 2.2 + +Rectangle { + width: 320 + height: 480 + + color: "red" + + Item { + x: 80 + y: 80 + + BorderImage { + source: "../shared/world.png" + + width: 10 + height: 10 + + antialiasing: true + + horizontalTileMode: BorderImage.Repeat + verticalTileMode: BorderImage.Repeat + + smooth: false + + border.bottom: 5 + border.left: 0 + border.right: 0 + border.top: 5 + } + } +} diff --git a/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_borders_exceed_width.qml b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_borders_exceed_width.qml new file mode 100644 index 0000000000..328ff40008 --- /dev/null +++ b/tests/manual/scenegraph_lancelot/data/borderimages/borderimage_borders_exceed_width.qml @@ -0,0 +1,32 @@ +import QtQuick 2.2 + +Rectangle { + width: 320 + height: 480 + + color: "red" + + Item { + x: 80 + y: 80 + + BorderImage { + source: "../shared/world.png" + + width: 10 + height: 10 + + antialiasing: true + + horizontalTileMode: BorderImage.Repeat + verticalTileMode: BorderImage.Repeat + + smooth: false + + border.bottom: 0 + border.left: 5 + border.right: 5 + border.top: 0 + } + } +} -- cgit v1.2.3 From 3fee095bac4c2c777119c13e201777d3202ae084 Mon Sep 17 00:00:00 2001 From: Kavindra Palaraja Date: Tue, 16 Sep 2014 20:10:05 +0200 Subject: Fixed documentation for QQmlEngine::ObjectOwnership. The ObjectOwnership enum's documentation mentioned that QObjects returned from property access are indestructible, which they aren't. Task-number: QTBUG-35426 Change-Id: Ic936b33b736ff7a45482cf1b626977d34ac4ebb2 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index e54e23813d..7e66cce490 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1258,7 +1258,7 @@ void QQmlEngine::setContextForObject(QObject *object, QQmlContext *context) \value JavaScriptOwnership The object is owned by JavaScript. When the object is returned to QML as the return value of a method - call or property access, QML will track it, and delete the object + call, QML will track it, and delete the object if there are no remaining JavaScript references to it and it has no QObject::parent(). An object tracked by one QQmlEngine will be deleted during that QQmlEngine's destructor, and thus -- cgit v1.2.3 From cfe1a8152c948a4586ffa1fe79b47f9a0e88beb5 Mon Sep 17 00:00:00 2001 From: Kavindra Palaraja Date: Tue, 16 Sep 2014 20:36:19 +0200 Subject: Cleaned up the documentation for QQmlEngine::ObjectOwnership. The paragraphs needed a bit of polish. Change-Id: I5c6b41fad34f3f58a372aa1bf8be627769871cf8 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlengine.cpp | 64 ++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 7e66cce490..2b69661c4b 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1247,42 +1247,38 @@ void QQmlEngine::setContextForObject(QObject *object, QQmlContext *context) /*! \enum QQmlEngine::ObjectOwnership - Ownership controls whether or not QML automatically destroys the - QObject when the object is garbage collected by the JavaScript - engine. The two ownership options are: - - \value CppOwnership The object is owned by C++ code, and will - never be deleted by QML. The JavaScript destroy() method cannot be - used on objects with CppOwnership. This option is similar to - QScriptEngine::QtOwnership. - - \value JavaScriptOwnership The object is owned by JavaScript. - When the object is returned to QML as the return value of a method - call, QML will track it, and delete the object - if there are no remaining JavaScript references to it and it has no - QObject::parent(). An object tracked by one QQmlEngine - will be deleted during that QQmlEngine's destructor, and thus - JavaScript references between objects with JavaScriptOwnership from - two different engines will not be valid after the deletion of one of - those engines. This option is similar to QScriptEngine::ScriptOwnership. + ObjectOwnership controls whether or not QML automatically destroys the + QObject when the corresponding JavaScript object is garbage collected by the + engine. The two ownership options are: + + \value CppOwnership The object is owned by C++ code and QML will never delete + it. The JavaScript destroy() method cannot be used on these objects. This + option is similar to QScriptEngine::QtOwnership. + + \value JavaScriptOwnership The object is owned by JavaScript. When the object + is returned to QML as the return value of a method call, QML will track it + and delete it if there are no remaining JavaScript references to it and + it has no QObject::parent(). An object tracked by one QQmlEngine will be + deleted during that QQmlEngine's destructor. Thus, JavaScript references + between objects with JavaScriptOwnership from two different engines will + not be valid if one of these engines is deleted. This option is similar to + QScriptEngine::ScriptOwnership. Generally an application doesn't need to set an object's ownership - explicitly. QML uses a heuristic to set the default object - ownership. By default, an object that is created by QML has - JavaScriptOwnership. The exception to this are the root objects - created by calling QQmlComponent::create() or - QQmlComponent::beginCreate() which have CppOwnership by - default. The ownership of these root-level objects is considered to - have been transferred to the C++ caller. - - Objects not-created by QML have CppOwnership by default. The - exception to this is objects returned from C++ method calls; in these cases, - the ownership of the returned objects will be set to JavaScriptOwnerShip. - Note this applies only to explicit invocations of Q_INVOKABLE methods or slots, - and not to property getter invocations. - - Calling setObjectOwnership() overrides the default ownership - heuristic used by QML. + explicitly. QML uses a heuristic to set the default ownership. By default, an + object that is created by QML has JavaScriptOwnership. The exception to this + are the root objects created by calling QQmlComponent::create() or + QQmlComponent::beginCreate(), which have CppOwnership by default. The + ownership of these root-level objects is considered to have been transferred + to the C++ caller. + + Objects not-created by QML have CppOwnership by default. The exception to this + are objects returned from C++ method calls; their ownership will be set to + JavaScriptOwnership. This applies only to explicit invocations of Q_INVOKABLE + methods or slots, but not to property getter invocations. + + Calling setObjectOwnership() overrides the default ownership heuristic used by + QML. */ /*! -- cgit v1.2.3 From 3dbe05f6bf3fd51ce8097c35f6c7f12b39acb0f6 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 10 Sep 2014 17:13:10 +0200 Subject: Fix mapping of JS objects/arrays to C++ [ChangeLog][QtQml][Important Behavior Changes] When a JavaScript object/array is passed to C++ through a QVariant, the engine no longer immediately converts the object recursively into a QVariantMap or QVariantList but instead stores a QJSValue in the QVariant. This prevents a loss of data when the JS object contains non-primitive types such as function objects for example. Code that expects the variant type to be exactly QVariant::Map or QVariant::List may need to be adapted. Registered conversion functions however ensure that code that merely calls toMap() or toList() continues to work. Task-number: QTBUG-40431 Change-Id: I1dbc1d5f8e78ad28bb62db3681b9a0b34557e7f5 Reviewed-by: Lars Knoll --- src/qml/debugger/qqmlenginedebugservice.cpp | 8 +- src/qml/debugger/qqmlenginedebugservice_p.h | 2 +- src/qml/jsapi/qjsengine.cpp | 27 +- src/qml/jsapi/qjsvalue.cpp | 69 +++-- src/qml/jsapi/qjsvalue_p.h | 7 +- src/qml/jsruntime/qv4qobjectwrapper.cpp | 6 +- src/qml/jsruntime/qv4variantobject.cpp | 2 +- src/qml/qml/v8/qv8engine.cpp | 299 +++++++++------------ src/qml/qml/v8/qv8engine_p.h | 20 +- src/qml/types/qqmllistmodel.cpp | 11 + src/qml/util/qqmllistaccessor.cpp | 7 +- tests/auto/qml/qjsvalue/tst_qjsvalue.cpp | 50 +++- .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 20 +- tests/auto/qml/qqmllocale/tst_qqmllocale.cpp | 4 +- .../auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp | 12 +- .../qquickworkerscript/tst_qquickworkerscript.cpp | 5 +- 16 files changed, 296 insertions(+), 253 deletions(-) diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp index 399cc3e07d..cb533a0459 100644 --- a/src/qml/debugger/qqmlenginedebugservice.cpp +++ b/src/qml/debugger/qqmlenginedebugservice.cpp @@ -169,9 +169,13 @@ QQmlEngineDebugService::propertyData(QObject *obj, int propIdx) return rv; } -QVariant QQmlEngineDebugService::valueContents(const QVariant &value) const +QVariant QQmlEngineDebugService::valueContents(QVariant value) const { - int userType = value.userType(); + // We can't send JS objects across the wire, so transform them to variant + // maps for serialization. + if (value.userType() == qMetaTypeId()) + value = value.value().toVariant(); + const int userType = value.userType(); //QObject * is not streamable. //Convert all such instances to a String value diff --git a/src/qml/debugger/qqmlenginedebugservice_p.h b/src/qml/debugger/qqmlenginedebugservice_p.h index 1bab51d17b..940ca7d99c 100644 --- a/src/qml/debugger/qqmlenginedebugservice_p.h +++ b/src/qml/debugger/qqmlenginedebugservice_p.h @@ -111,7 +111,7 @@ private: void buildStatesList(bool cleanList, const QList > &instances); QQmlObjectData objectData(QObject *); QQmlObjectProperty propertyData(QObject *, int); - QVariant valueContents(const QVariant &defaultValue) const; + QVariant valueContents(QVariant defaultValue) const; bool setBinding(int objectId, const QString &propertyName, const QVariant &expression, bool isLiteralValue, QString filename = QString(), int line = -1, int column = 0); bool resetBinding(int objectId, const QString &propertyName); bool setMethodBody(int objectId, const QString &method, const QString &body); diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index 58251fac96..0d2b394cd6 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -420,17 +420,19 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr) QV4::ScopedValue v(scope, vp->getValue(engine->m_v4Engine)); return engine->metaTypeFromJS(v, type, ptr); } else if (vp->value.isEmpty()) { - // have a string based value without engine. Do conversion manually - if (type == QMetaType::Bool) { - *reinterpret_cast(ptr) = vp->string.length() != 0; - return true; - } - if (type == QMetaType::QString) { - *reinterpret_cast(ptr) = vp->string; - return true; - } - double d = QV4::RuntimeHelpers::stringToNumber(vp->string); - switch (type) { + if (vp->unboundData.userType() == QMetaType::QString) { + QString string = vp->unboundData.toString(); + // have a string based value without engine. Do conversion manually + if (type == QMetaType::Bool) { + *reinterpret_cast(ptr) = string.length() != 0; + return true; + } + if (type == QMetaType::QString) { + *reinterpret_cast(ptr) = string; + return true; + } + double d = QV4::RuntimeHelpers::stringToNumber(string); + switch (type) { case QMetaType::Int: *reinterpret_cast(ptr) = QV4::Primitive::toInt32(d); return true; @@ -466,6 +468,9 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr) return true; default: return false; + } + } else { + return QMetaType::convert(&vp->unboundData.data_ptr(), vp->unboundData.userType(), ptr, type); } } else { switch (type) { diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index 891f17762c..47a764e641 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -58,14 +58,14 @@ QV4::ReturnedValue QJSValuePrivate::getValue(QV4::ExecutionEngine *e) } if (value.isEmpty()) { - value = QV4::Encode(engine->newString(string)); + value = QV4::Encode(engine->v8Engine->fromVariant(unboundData)); PersistentValuePrivate **listRoot = &engine->memoryManager->m_persistentValues; prev = listRoot; next = *listRoot; *prev = this; if (next) next->prev = &this->next; - string = QString(); + unboundData.clear(); } return value.asReturnedValue(); } @@ -353,8 +353,21 @@ bool QJSValue::isVariant() const */ QString QJSValue::toString() const { - if (d->value.isEmpty()) - return d->string; + if (d->value.isEmpty()) { + if (d->unboundData.type() == QVariant::Map) + return QStringLiteral("[object Object]"); + else if (d->unboundData.type() == QVariant::List) { + const QVariantList list = d->unboundData.toList(); + QString result; + for (int i = 0; i < list.count(); ++i) { + if (i > 0) + result.append(QLatin1Char(',')); + result.append(list.at(i).toString()); + } + return result; + } + return d->unboundData.toString(); + } return d->value.toQStringNoThrow(); } @@ -372,8 +385,14 @@ QString QJSValue::toString() const */ double QJSValue::toNumber() const { - if (d->value.isEmpty()) - return RuntimeHelpers::stringToNumber(d->string); + if (d->value.isEmpty()) { + if (d->unboundData.type() == QVariant::String) + return RuntimeHelpers::stringToNumber(d->unboundData.toString()); + else if (d->unboundData.canConvert()) + return d->unboundData.value(); + else + return std::numeric_limits::quiet_NaN(); + } QV4::ExecutionContext *ctx = d->engine ? d->engine->currentContext() : 0; double dbl = d->value.toNumber(); @@ -398,8 +417,12 @@ double QJSValue::toNumber() const */ bool QJSValue::toBool() const { - if (d->value.isEmpty()) - return d->string.length() > 0; + if (d->value.isEmpty()) { + if (d->unboundData.userType() == QMetaType::QString) + return d->unboundData.toString().length() > 0; + else + return d->unboundData.toBool(); + } QV4::ExecutionContext *ctx = d->engine ? d->engine->currentContext() : 0; bool b = d->value.toBoolean(); @@ -424,8 +447,12 @@ bool QJSValue::toBool() const */ qint32 QJSValue::toInt() const { - if (d->value.isEmpty()) - return QV4::Primitive::toInt32(RuntimeHelpers::stringToNumber(d->string)); + if (d->value.isEmpty()) { + if (d->unboundData.userType() == QMetaType::QString) + return QV4::Primitive::toInt32(RuntimeHelpers::stringToNumber(d->unboundData.toString())); + else + return d->unboundData.toInt(); + } QV4::ExecutionContext *ctx = d->engine ? d->engine->currentContext() : 0; qint32 i = d->value.toInt32(); @@ -450,8 +477,12 @@ qint32 QJSValue::toInt() const */ quint32 QJSValue::toUInt() const { - if (d->value.isEmpty()) - return QV4::Primitive::toUInt32(RuntimeHelpers::stringToNumber(d->string)); + if (d->value.isEmpty()) { + if (d->unboundData.userType() == QMetaType::QString) + return QV4::Primitive::toUInt32(RuntimeHelpers::stringToNumber(d->unboundData.toString())); + else + return d->unboundData.toUInt(); + } QV4::ExecutionContext *ctx = d->engine ? d->engine->currentContext() : 0; quint32 u = d->value.toUInt32(); @@ -487,7 +518,7 @@ quint32 QJSValue::toUInt() const QVariant QJSValue::toVariant() const { if (d->value.isEmpty()) - return QVariant(d->string); + return d->unboundData; return QV4::VariantObject::toVariant(d->value); } @@ -775,8 +806,10 @@ bool QJSValue::equals(const QJSValue& other) const { if (d->value.isEmpty()) { if (other.d->value.isEmpty()) - return d->string == other.d->string; - return js_equal(d->string, QV4::ValueRef(other.d->value)); + return d->unboundData == other.d->unboundData; + if (d->unboundData.type() == QVariant::Map || d->unboundData.type() == QVariant::List) + return false; + return js_equal(d->unboundData.toString(), QV4::ValueRef(other.d->value)); } if (other.d->value.isEmpty()) return other.equals(*this); @@ -810,9 +843,11 @@ bool QJSValue::strictlyEquals(const QJSValue& other) const { if (d->value.isEmpty()) { if (other.d->value.isEmpty()) - return d->string == other.d->string; + return d->unboundData == other.d->unboundData; + if (d->unboundData.type() == QVariant::Map || d->unboundData.type() == QVariant::List) + return false; if (other.d->value.isString()) - return d->string == other.d->value.stringValue()->toQString(); + return d->unboundData.toString() == other.d->value.stringValue()->toQString(); return false; } if (other.d->value.isEmpty()) diff --git a/src/qml/jsapi/qjsvalue_p.h b/src/qml/jsapi/qjsvalue_p.h index e66c1bcde4..43a3a74e38 100644 --- a/src/qml/jsapi/qjsvalue_p.h +++ b/src/qml/jsapi/qjsvalue_p.h @@ -51,6 +51,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -72,8 +73,8 @@ public: Q_ASSERT(!value.isEmpty()); } QJSValuePrivate(const QString &s) - : PersistentValuePrivate(QV4::Primitive::emptyValue().asReturnedValue()) - , string(s) + : PersistentValuePrivate(QV4::Primitive::emptyValue().asReturnedValue()), + unboundData(s) { } @@ -81,7 +82,7 @@ public: static QJSValuePrivate *get(const QJSValue &v) { return v.d; } - QString string; + QVariant unboundData; }; QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index ff51ee6c6f..32379f7f1e 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -1665,17 +1665,13 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, const QV4::ValueRe type = -1; QQmlEnginePrivate *ep = engine->engine() ? QQmlEnginePrivate::get(engine->engine()) : 0; - QVariant v = engine->toVariant(value, -1); // why -1 instead of callType? + QVariant v = engine->toVariant(value, callType); if (v.userType() == callType) { *qvariantPtr = v; } else if (v.canConvert(callType)) { *qvariantPtr = v; qvariantPtr->convert(callType); - } else if (QV4::SequencePrototype::isSequenceType(callType) && v.userType() == qMetaTypeId()) { - // convert the JS array to a sequence of the correct type. - QVariant seqV = engine->toVariant(value, callType); - *qvariantPtr = seqV; } else { QQmlMetaObject mo = ep ? ep->rawMetaObjectForType(callType) : QQmlMetaObject(); if (!mo.isNull()) { diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp index 34657501e8..68b08fb3ca 100644 --- a/src/qml/jsruntime/qv4variantobject.cpp +++ b/src/qml/jsruntime/qv4variantobject.cpp @@ -59,7 +59,7 @@ VariantObject::Data::Data(ExecutionEngine *engine, const QVariant &value) QVariant VariantObject::toVariant(const QV4::ValueRef v) { if (v->asObject()) - return v->engine()->v8Engine->variantFromJS(v); + return v->engine()->v8Engine->toVariant(v, /*typeHint*/ -1, /*createJSValueForObjects*/ false); if (v->isString()) return QVariant(v->stringValue()->toQString()); diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index b56af2e7f6..993cf96104 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -79,6 +79,37 @@ Q_DECLARE_METATYPE(QList) // QQmlEngine is not available QT_BEGIN_NAMESPACE +template +ReturnType convertJSValueToVariantType(const QJSValue &value) +{ + return value.toVariant().value(); +} + +static void saveJSValue(QDataStream &stream, const void *data) +{ + const QJSValue *jsv = reinterpret_cast(data); + const quint32 isNullOrUndefined = jsv->isNull() | (jsv->isUndefined() << 1); + stream << isNullOrUndefined; + if (!isNullOrUndefined) + reinterpret_cast(data)->toVariant().save(stream); +} + +static void restoreJSValue(QDataStream &stream, void *data) +{ + QJSValue *jsv = reinterpret_cast(data); + QJSValuePrivate *d = QJSValuePrivate::get(*jsv); + + quint32 isNullOrUndefined; + stream >> isNullOrUndefined; + if (isNullOrUndefined & 0x1) { + d->value = QV4::Primitive::nullValue().asReturnedValue(); + } else if (isNullOrUndefined & 0x2) { + d->value = QV4::Primitive::undefinedValue().asReturnedValue(); + } else { + d->value = QV4::Primitive::emptyValue().asReturnedValue(); + d->unboundData.load(stream); + } +} QV8Engine::QV8Engine(QJSEngine* qq) : q(qq) @@ -96,6 +127,14 @@ QV8Engine::QV8Engine(QJSEngine* qq) qMetaTypeId(); qMetaTypeId >(); + if (!QMetaType::hasRegisteredConverterFunction()) + QMetaType::registerConverter(convertJSValueToVariantType); + if (!QMetaType::hasRegisteredConverterFunction()) + QMetaType::registerConverter(convertJSValueToVariantType); + if (!QMetaType::hasRegisteredConverterFunction()) + QMetaType::registerConverter(convertJSValueToVariantType); + QMetaType::registerStreamOperators(qMetaTypeId(), saveJSValue, restoreJSValue); + m_v4Engine = new QV4::ExecutionEngine; m_v4Engine->v8Engine = this; @@ -116,7 +155,7 @@ QV8Engine::~QV8Engine() delete m_v4Engine; } -QVariant QV8Engine::toVariant(const QV4::ValueRef value, int typeHint) +QVariant QV8Engine::toVariant(const QV4::ValueRef value, int typeHint, bool createJSValueForObjects, V8ObjectSet *visitedObjects) { Q_ASSERT (!value->isEmpty()); QV4::Scope scope(m_v4Engine); @@ -178,7 +217,88 @@ QVariant QV8Engine::toVariant(const QV4::ValueRef value, int typeHint) return retn; } - return toBasicVariant(value); + if (value->isUndefined()) + return QVariant(); + if (value->isNull()) + return QVariant(QMetaType::VoidStar, (void *)0); + if (value->isBoolean()) + return value->booleanValue(); + if (value->isInteger()) + return value->integerValue(); + if (value->isNumber()) + return value->asDouble(); + if (value->isString()) + return value->stringValue()->toQString(); + if (QQmlLocaleData *ld = value->as()) + return ld->d()->locale; + if (QV4::DateObject *d = value->asDateObject()) + return d->toQDateTime(); + // NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)! + + QV4::ScopedObject o(scope, value); + Q_ASSERT(o); + + if (QV4::RegExpObject *re = o->as()) + return re->toQRegExp(); + + if (createJSValueForObjects) + return QVariant::fromValue(QJSValue(new QJSValuePrivate(o->asReturnedValue()))); + + return objectToVariant(o, visitedObjects); +} + +QVariant QV8Engine::objectToVariant(QV4::Object *o, V8ObjectSet *visitedObjects) +{ + Q_ASSERT(o); + + V8ObjectSet recursionGuardSet; + if (!visitedObjects) { + visitedObjects = &recursionGuardSet; + } else if (visitedObjects->contains(o)) { + // Avoid recursion. + // For compatibility with QVariant{List,Map} conversion, we return an + // empty object (and no error is thrown). + if (o->asArrayObject()) + return QVariantList(); + return QVariantMap(); + } + visitedObjects->insert(o); + + QVariant result; + + if (o->asArrayObject()) { + QV4::Scope scope(m_v4Engine); + QV4::ScopedArrayObject a(scope, o->asReturnedValue()); + QV4::ScopedValue v(scope); + QVariantList list; + + int length = a->getLength(); + for (int ii = 0; ii < length; ++ii) { + v = a->getIndexed(ii); + list << toVariant(v, -1, /*createJSValueForObjects*/false, visitedObjects); + } + + result = list; + } else if (!o->asFunctionObject()) { + QVariantMap map; + QV4::Scope scope(m_v4Engine); + QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly); + QV4::ScopedValue name(scope); + QV4::ScopedValue val(scope); + while (1) { + name = it.nextPropertyNameAsString(val); + if (name->isNull()) + break; + + QString key = name->toQStringNoThrow(); + map.insert(key, toVariant(val, /*type hint*/-1, /*createJSValueForObjects*/false, visitedObjects)); + } + + result = map; + } + + visitedObjects->remove(o); + return result; } static QV4::ReturnedValue arrayFromStringList(QV8Engine *engine, const QStringList &list) @@ -370,61 +490,6 @@ QQmlContextData *QV8Engine::callingContext() return QV4::QmlContextWrapper::callingContext(m_v4Engine); } -// Converts a JS value to a QVariant. -// Null, Undefined -> QVariant() (invalid) -// Boolean -> QVariant(bool) -// Number -> QVariant(double) -// String -> QVariant(QString) -// Array -> QVariantList(...) -// Date -> QVariant(QDateTime) -// RegExp -> QVariant(QRegExp) -// [Any other object] -> QVariantMap(...) -QVariant QV8Engine::toBasicVariant(const QV4::ValueRef value) -{ - if (value->isUndefined()) - return QVariant(); - if (value->isNull()) - return QVariant(QMetaType::VoidStar, (void *)0); - if (value->isBoolean()) - return value->booleanValue(); - if (value->isInteger()) - return value->integerValue(); - if (value->isNumber()) - return value->asDouble(); - if (value->isString()) - return value->stringValue()->toQString(); - if (QQmlLocaleData *ld = value->as()) - return ld->d()->locale; - if (QV4::DateObject *d = value->asDateObject()) - return d->toQDateTime(); - // NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)! - - QV4::Scope scope(value->engine()); - QV4::ScopedObject o(scope, value); - Q_ASSERT(o); - - if (QV4::RegExpObject *re = o->as()) - return re->toQRegExp(); - if (o->asArrayObject()) { - QV4::ScopedArrayObject a(scope, o); - QV4::ScopedValue v(scope); - QVariantList rv; - - int length = a->getLength(); - for (int ii = 0; ii < length; ++ii) { - v = a->getIndexed(ii); - rv << toVariant(v, -1); - } - return rv; - } - if (!value->asFunctionObject()) - return variantMapFromJS(o); - - return QVariant(); -} - - - void QV8Engine::initializeGlobal() { QV4::Scope scope(m_v4Engine); @@ -547,36 +612,6 @@ QV4::ReturnedValue QV8Engine::variantListToJS(const QVariantList &lst) return a.asReturnedValue(); } -// Converts a JS Array object to a QVariantList. -// The result is a QVariantList with length equal to the length -// of the JS Array, and elements being the JS Array's elements -// converted to QVariants, recursively. -QVariantList QV8Engine::variantListFromJS(QV4::ArrayObject *a, V8ObjectSet &visitedObjects) -{ - QVariantList result; - if (!a) - return result; - - if (visitedObjects.contains(a)) - // Avoid recursion. - return result; - - visitedObjects.insert(a); - - QV4::Scope scope(a->engine()); - QV4::ScopedValue v(scope); - - quint32 length = a->getLength(); - for (quint32 i = 0; i < length; ++i) { - v = a->getIndexed(i); - result.append(variantFromJS(v, visitedObjects)); - } - - visitedObjects.remove(a); - - return result; -} - // Converts a QVariantMap to JS. // The result is a new Object object with property names being // the keys of the QVariantMap, and values being the values of @@ -600,43 +635,6 @@ QV4::ReturnedValue QV8Engine::variantMapToJS(const QVariantMap &vmap) return o.asReturnedValue(); } -// Converts a JS Object to a QVariantMap. -// The result is a QVariantMap with keys being the property names -// of the object, and values being the values of the JS object's -// properties converted to QVariants, recursively. -QVariantMap QV8Engine::variantMapFromJS(QV4::Object *o, V8ObjectSet &visitedObjects) -{ - QVariantMap result; - - if (!o || o->asFunctionObject()) - return result; - - if (visitedObjects.contains(o)) { - // Avoid recursion. - // For compatibility with QVariant{List,Map} conversion, we return an - // empty object (and no error is thrown). - return result; - } - QV4::Scope scope(o->engine()); - - visitedObjects.insert(o); - - QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly); - QV4::ScopedValue name(scope); - QV4::ScopedValue val(scope); - while (1) { - name = it.nextPropertyNameAsString(val); - if (name->isNull()) - break; - - QString key = name->toQStringNoThrow(); - result.insert(key, variantFromJS(val, visitedObjects)); - } - - visitedObjects.remove(o); - return result; -} - // Converts the meta-type defined by the given type and data to JS. // Returns the value if conversion succeeded, an empty handle otherwise. QV4::ReturnedValue QV8Engine::metaTypeToJS(int type, const void *data) @@ -811,7 +809,7 @@ bool QV8Engine::metaTypeFromJS(const QV4::ValueRef value, int type, void *data) case QMetaType::QVariantList: { QV4::ScopedArrayObject a(scope, value); if (a) { - *reinterpret_cast(data) = variantListFromJS(a); + *reinterpret_cast(data) = toVariant(a, /*typeHint*/-1, /*createJSValueForObjects*/false).toList(); return true; } break; @@ -825,7 +823,7 @@ bool QV8Engine::metaTypeFromJS(const QV4::ValueRef value, int type, void *data) break; } case QMetaType::QVariant: - *reinterpret_cast(data) = variantFromJS(value); + *reinterpret_cast(data) = toVariant(value, /*typeHint*/-1, /*createJSValueForObjects*/false); return true; case QMetaType::QJsonValue: *reinterpret_cast(data) = QV4::JsonObject::toJsonValue(value); @@ -921,55 +919,6 @@ QV4::ReturnedValue QV8Engine::variantToJS(const QVariant &value) return metaTypeToJS(value.userType(), value.constData()); } -// Converts a JS value to a QVariant. -// Undefined -> QVariant() (invalid) -// Null -> QVariant((void*)0) -// Boolean -> QVariant(bool) -// Number -> QVariant(double) -// String -> QVariant(QString) -// Array -> QVariantList(...) -// Date -> QVariant(QDateTime) -// RegExp -> QVariant(QRegExp) -// [Any other object] -> QVariantMap(...) -QVariant QV8Engine::variantFromJS(const QV4::ValueRef value, - V8ObjectSet &visitedObjects) -{ - Q_ASSERT(!value->isEmpty()); - if (value->isUndefined()) - return QVariant(); - if (value->isNull()) - return QVariant(QMetaType::VoidStar, 0); - if (value->isBoolean()) - return value->booleanValue(); - if (value->isInteger()) - return value->integerValue(); - if (value->isNumber()) - return value->asDouble(); - if (value->isString()) - return value->stringValue()->toQString(); - - Q_ASSERT(value->isObject()); - QV4::Scope scope(value->engine()); - - if (value->asArrayObject()) { - QV4::ScopedArrayObject a(scope, value); - return variantListFromJS(a, visitedObjects); - } - if (QV4::DateObject *d = value->asDateObject()) - return d->toQDateTime(); - if (QV4::RegExpObject *re = value->as()) - return re->toQRegExp(); - if (QV4::VariantObject *v = value->as()) - return v->d()->data; - if (value->as()) - return qVariantFromValue(qtObjectFromJS(value)); - if (QV4::QmlValueTypeWrapper *v = value->as()) - return v->toVariant(); - QV4::ScopedObject o(scope, value); - return variantMapFromJS(o, visitedObjects); -} - - bool QV8Engine::convertToNativeQObject(const QV4::ValueRef value, const QByteArray &targetType, void **result) { if (!targetType.endsWith('*')) diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index e2c96ffc87..51e857c8a2 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -197,9 +197,13 @@ public: void freezeObject(const QV4::ValueRef value); - QVariant toVariant(const QV4::ValueRef value, int typeHint); + QVariant toVariant(const QV4::ValueRef value, int typeHint, bool createJSValueForObjects = true, V8ObjectSet *visitedObjects = 0); + QVariant objectToVariant(QV4::Object *o, V8ObjectSet *visitedObjects = 0); QV4::ReturnedValue fromVariant(const QVariant &); + QVariantMap variantMapFromJS(QV4::Object *o) + { return objectToVariant(o).toMap(); } + // Return a JS string for the given QString \a string QV4::ReturnedValue toString(const QString &string); @@ -218,16 +222,8 @@ public: void setExtensionData(int, Deletable *); QV4::ReturnedValue variantListToJS(const QVariantList &lst); - inline QVariantList variantListFromJS(QV4::ArrayObject *array) - { V8ObjectSet visitedObjects; return variantListFromJS(array, visitedObjects); } - QV4::ReturnedValue variantMapToJS(const QVariantMap &vmap); - inline QVariantMap variantMapFromJS(QV4::Object *object) - { V8ObjectSet visitedObjects; return variantMapFromJS(object, visitedObjects); } - QV4::ReturnedValue variantToJS(const QVariant &value); - inline QVariant variantFromJS(const QV4::ValueRef value) - { V8ObjectSet visitedObjects; return variantFromJS(value, visitedObjects); } QV4::ReturnedValue metaTypeToJS(int type, const void *data); bool metaTypeFromJS(const QV4::ValueRef value, int type, void *data); @@ -265,15 +261,9 @@ protected: QHash m_consoleCount; - QVariant toBasicVariant(const QV4::ValueRef); - void initializeGlobal(); private: - QVariantList variantListFromJS(QV4::ArrayObject *array, V8ObjectSet &visitedObjects); - QVariantMap variantMapFromJS(QV4::Object *object, V8ObjectSet &visitedObjects); - QVariant variantFromJS(const QV4::ValueRef value, V8ObjectSet &visitedObjects); - Q_DISABLE_COPY(QV8Engine) }; diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index 25879972ca..142625d7ae 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -1330,6 +1330,11 @@ void DynamicRoleModelNode::updateValues(const QVariantMap &object, QVector QVariant value = object[key]; + // A JS array/object is translated into a (hierarchical) QQmlListModel, + // so translate to a variant map/list first with toVariant(). + if (value.userType() == qMetaTypeId()) + value = value.value().toVariant(); + if (value.type() == QVariant::List) { QQmlListModel *subModel = QQmlListModel::createWithOwner(m_owner); @@ -1392,6 +1397,12 @@ void DynamicRoleModelNodeMetaObject::propertyWritten(int index) QQmlListModel *parentModel = m_owner->m_owner; QVariant v = value(index); + + // A JS array/object is translated into a (hierarchical) QQmlListModel, + // so translate to a variant map/list first with toVariant(). + if (v.userType() == qMetaTypeId()) + v= v.value().toVariant(); + if (v.type() == QVariant::List) { QQmlListModel *subModel = QQmlListModel::createWithOwner(parentModel); diff --git a/src/qml/util/qqmllistaccessor.cpp b/src/qml/util/qqmllistaccessor.cpp index e434d6cef4..5a199abf44 100644 --- a/src/qml/util/qqmllistaccessor.cpp +++ b/src/qml/util/qqmllistaccessor.cpp @@ -61,6 +61,11 @@ void QQmlListAccessor::setList(const QVariant &v, QQmlEngine *engine) { d = v; + // An incoming JS array as model is treated as a variant list, so we need to + // convert it first with toVariant(). + if (d.userType() == qMetaTypeId()) + d = d.value().toVariant(); + QQmlEnginePrivate *enginePrivate = engine?QQmlEnginePrivate::get(engine):0; if (!d.isValid()) { @@ -73,7 +78,7 @@ void QQmlListAccessor::setList(const QVariant &v, QQmlEngine *engine) m_type = Integer; } else if ((!enginePrivate && QQmlMetaType::isQObject(d.userType())) || (enginePrivate && enginePrivate->isQObject(d.userType()))) { - QObject *data = enginePrivate?enginePrivate->toQObject(v):QQmlMetaType::toQObject(v); + QObject *data = enginePrivate?enginePrivate->toQObject(d):QQmlMetaType::toQObject(d); d = QVariant::fromValue(data); m_type = Instance; } else if (d.userType() == qMetaTypeId()) { diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp index 837403d391..9c615cfc15 100644 --- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp +++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp @@ -34,10 +34,6 @@ #include "tst_qjsvalue.h" #include -QT_BEGIN_NAMESPACE -extern bool qt_script_isJITEnabled(); -QT_END_NAMESPACE - tst_QJSValue::tst_QJSValue() : engine(0) { @@ -45,8 +41,7 @@ tst_QJSValue::tst_QJSValue() tst_QJSValue::~tst_QJSValue() { - if (engine) - delete engine; + delete engine; } void tst_QJSValue::ctor_invalid() @@ -308,6 +303,19 @@ void tst_QJSValue::ctor_copyAndAssign() QCOMPARE(v5.toNumber(), 1.0); } +static QJSValue createUnboundValue(const QJSValue &value) +{ + QVariant variant = QVariant::fromValue(value); + QBuffer buffer; + buffer.open(QIODevice::ReadWrite); + QDataStream stream(&buffer); + variant.save(stream); + buffer.seek(0); + QVariant resultVariant; + resultVariant.load(stream); + return resultVariant.value(); +} + void tst_QJSValue::toString() { QJSEngine eng; @@ -406,6 +414,28 @@ void tst_QJSValue::toString() variant = eng.toScriptValue(QUrl()); QVERIFY(variant.isVariant()); QVERIFY(variant.toString().isEmpty()); + + { + QJSValue o = eng.newObject(); + o.setProperty(QStringLiteral("test"), 42); + QCOMPARE(o.toString(), QStringLiteral("[object Object]")); + + o = createUnboundValue(o); + QVERIFY(!o.engine()); + QCOMPARE(o.toString(), QStringLiteral("[object Object]")); + } + + { + QJSValue o = eng.newArray(); + o.setProperty(0, 1); + o.setProperty(1, 2); + o.setProperty(2, 3); + QCOMPARE(o.toString(), QStringLiteral("1,2,3")); + + o = createUnboundValue(o); + QVERIFY(!o.engine()); + QCOMPARE(o.toString(), QStringLiteral("1,2,3")); + } } void tst_QJSValue::toNumber() @@ -419,35 +449,43 @@ void tst_QJSValue::toNumber() QJSValue null = eng.evaluate("null"); QCOMPARE(null.toNumber(), 0.0); QCOMPARE(qjsvalue_cast(null), 0.0); + QCOMPARE(createUnboundValue(null).toNumber(), 0.0); { QJSValue falskt = eng.toScriptValue(false); QCOMPARE(falskt.toNumber(), 0.0); + QCOMPARE(createUnboundValue(falskt).toNumber(), 0.0); QCOMPARE(qjsvalue_cast(falskt), 0.0); QJSValue sant = eng.toScriptValue(true); QCOMPARE(sant.toNumber(), 1.0); + QCOMPARE(createUnboundValue(sant).toNumber(), 1.0); QCOMPARE(qjsvalue_cast(sant), 1.0); QJSValue number = eng.toScriptValue(123.0); QCOMPARE(number.toNumber(), 123.0); QCOMPARE(qjsvalue_cast(number), 123.0); + QCOMPARE(createUnboundValue(number).toNumber(), 123.0); QJSValue str = eng.toScriptValue(QString("ciao")); QCOMPARE(qIsNaN(str.toNumber()), true); QCOMPARE(qIsNaN(qjsvalue_cast(str)), true); + QCOMPARE(qIsNaN(createUnboundValue(str).toNumber()), true); QJSValue str2 = eng.toScriptValue(QString("123")); QCOMPARE(str2.toNumber(), 123.0); QCOMPARE(qjsvalue_cast(str2), 123.0); + QCOMPARE(createUnboundValue(str2).toNumber(), 123.0); } QJSValue object = eng.newObject(); QCOMPARE(qIsNaN(object.toNumber()), true); + QCOMPARE(qIsNaN(createUnboundValue(object).toNumber()), true); QCOMPARE(qIsNaN(qjsvalue_cast(object)), true); QJSValue inv = QJSValue(); QVERIFY(qIsNaN(inv.toNumber())); + QCOMPARE(qIsNaN(createUnboundValue(inv).toNumber()), true); QVERIFY(qIsNaN(qjsvalue_cast(inv))); // V2 constructors diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index c246647325..196f6b96f9 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -746,13 +746,13 @@ void tst_qqmlecmascript::arrayExpressions() MyExpression expr(&context, "[a, b, c, 10]"); QVariant result = expr.evaluate(); - QCOMPARE(result.userType(), qMetaTypeId()); - QVariantList list = qvariant_cast(result); - QCOMPARE(list.count(), 4); - QCOMPARE(list.at(0).value(), &obj1); - QCOMPARE(list.at(1).value(), &obj2); - QCOMPARE(list.at(2).value(), &obj3); - QCOMPARE(list.at(3).value(), 10); + QCOMPARE(result.userType(), qMetaTypeId()); + QJSValue list = qvariant_cast(result); + QCOMPARE(list.property("length").toInt(), 4); + QCOMPARE(list.property(0).toQObject(), &obj1); + QCOMPARE(list.property(1).toQObject(), &obj2); + QCOMPARE(list.property(2).toQObject(), &obj3); + QCOMPARE(list.property(3).toInt(), 10); } // Tests that modifying a context property will reevaluate expressions @@ -4811,7 +4811,7 @@ void tst_qqmlecmascript::propertyVarCpp() QCOMPARE(object->property("varProperty2"), QVariant(QLatin1String("randomString"))); QCOMPARE(object->property("varProperty2").userType(), (int)QVariant::String); // now enforce behaviour when accessing JavaScript objects from cpp. - QCOMPARE(object->property("jsobject").userType(), (int)QVariant::Map); + QCOMPARE(object->property("jsobject").userType(), qMetaTypeId()); delete object; } @@ -5166,7 +5166,7 @@ void tst_qqmlecmascript::objectConversion() QVERIFY(object != 0); QVariant retn; QMetaObject::invokeMethod(object, "circularObject", Q_RETURN_ARG(QVariant, retn)); - QCOMPARE(retn.value().value("test"), QVariant(100)); + QCOMPARE(retn.value().property("test").toInt(), int(100)); delete object; } @@ -5434,7 +5434,7 @@ void tst_qqmlecmascript::sequenceConversionWrite() QVERIFY(seq != 0); // we haven't registered QList as a sequence type, so writing shouldn't work. - QString warningOne = qmlFile.toString() + QLatin1String(":16: Error: Cannot assign QVariantList to an unregistered type"); + QString warningOne = qmlFile.toString() + QLatin1String(":16: Error: Cannot assign QJSValue to an unregistered type"); QTest::ignoreMessage(QtWarningMsg, warningOne.toLatin1().constData()); QMetaObject::invokeMethod(object, "performTest"); diff --git a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp index 320333f889..4ee75f8df5 100644 --- a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp +++ b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp @@ -486,7 +486,7 @@ void tst_qqmllocale::weekDays() Q_ARG(QVariant, QVariant(locale))); QVariant val = obj->property("weekDays"); - QVERIFY(val.type() == QVariant::List); + QVERIFY(val.userType() == qMetaTypeId()); QList qmlDays = val.toList(); QList days = QLocale(locale).weekdays(); @@ -528,7 +528,7 @@ void tst_qqmllocale::uiLanguages() Q_ARG(QVariant, QVariant(locale))); QVariant val = obj->property("uiLanguages"); - QVERIFY(val.type() == QVariant::List); + QVERIFY(val.userType() == qMetaTypeId()); QList qmlLangs = val.toList(); QStringList langs = QLocale(locale).uiLanguages(); diff --git a/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp b/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp index 510a76cc06..b6e7a43c46 100644 --- a/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp +++ b/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp @@ -249,16 +249,22 @@ void tst_QQmlMetaObject::property() QSignalSpy changedSpy(object, SIGNAL(testChanged())); QObject::connect(object, SIGNAL(testChanged()), object, SLOT(deleteLater())); + QVariant value = prop.read(object); + if (value.userType() == qMetaTypeId()) + value = value.value().toVariant(); if (expectedValue.isValid()) - QCOMPARE(prop.read(object), expectedValue); + QCOMPARE(value, expectedValue); else - QVERIFY(prop.read(object).isValid()); + QVERIFY(value.isValid()); QCOMPARE(changedSpy.count(), 0); if (isWritable) { QVERIFY(prop.write(object, newValue)); QCOMPARE(changedSpy.count(), 1); - QCOMPARE(prop.read(object), newValue); + QVariant value = prop.read(object); + if (value.userType() == qMetaTypeId()) + value = value.value().toVariant(); + QCOMPARE(value, newValue); } else { QVERIFY(!prop.write(object, prop.read(object))); QCOMPARE(changedSpy.count(), 0); diff --git a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp index 66ddb392f9..801707f2ec 100644 --- a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp +++ b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp @@ -115,7 +115,10 @@ void tst_QQuickWorkerScript::messaging() waitForEchoMessage(worker); const QMetaObject *mo = worker->metaObject(); - QCOMPARE(mo->property(mo->indexOfProperty("response")).read(worker).value(), value); + QVariant response = mo->property(mo->indexOfProperty("response")).read(worker).value(); + if (response.userType() == qMetaTypeId()) + response = response.value().toVariant(); + QCOMPARE(response, value); qApp->processEvents(); delete worker; -- cgit v1.2.3 From c137c6f07bde37f113268581b2c7394dfee22f0d Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 15 Sep 2014 14:36:23 +0200 Subject: Add a note about winId() to QQuickWidget This unfortunate function causes the creation of a native window which is very wrong. Task-number: QTBUG-40765 Change-Id: Ia08138cf35c240c883c63a66a54f949b86ccc2d2 Reviewed-by: Paul Olav Tvete --- src/quickwidgets/qquickwidget.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 707dc9b0a0..7df529c9d9 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -294,6 +294,11 @@ QImage QQuickWidgetPrivate::grabFramebuffer() some of the benefits of threaded rendering, for example \l Animator classes and vsync driven animations, will not be available. + \note Avoid calling winId() on a QQuickWidget. This function triggers the creation of + a native window, resulting in reduced performance and possibly rendering glitches. The + entire purpose of QQuickWidget is to render Quick scenes without a separate native + window, hence making it a native widget should always be avoided. + \section1 Limitations Putting other widgets underneath and making the QQuickWidget transparent will not lead -- cgit v1.2.3 From acd0f6244904213f581a55bd416483c5d56ccfb4 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 17 Sep 2014 10:49:20 +0200 Subject: Protect QQuickWindow::openglContext against not having a context. Change-Id: I3d5087d9c322ee5ee3325858ee717161fd7801a3 Reviewed-by: Ulf Hermann --- src/quick/items/qquickwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 1cb88fdc49..e1ee368f96 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -2922,7 +2922,7 @@ void QQuickWindow::setTransientParent_helper(QQuickWindow *window) QOpenGLContext *QQuickWindow::openglContext() const { Q_D(const QQuickWindow); - return d->context->openglContext(); + return d->context ? d->context->openglContext() : 0; } /*! -- cgit v1.2.3 From e3c21ca0e7681d75a27f825587b1700ead79a864 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 16 Sep 2014 16:01:40 +0200 Subject: Don't assume a QSGRenderContext is valid just because it's not 0 Task-number: QTBUG-41353 Change-Id: I2a8c500ed974b3e5f45f3a1eb1f66c7a24b17d56 Reviewed-by: Andy Nichols Reviewed-by: Gunnar Sletta --- src/quick/items/context2d/qquickcanvasitem.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 345af6faf4..587ba6591d 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -667,7 +667,10 @@ void QQuickCanvasItem::itemChange(QQuickItem::ItemChange change, const QQuickIte return; d->window = value.window; - if (QQuickWindowPrivate::get(d->window)->context != 0) // available context == initialized + QSGRenderContext *context = QQuickWindowPrivate::get(d->window)->context; + + // Rendering to FramebufferObject needs a valid OpenGL context. + if (context != 0 && (d->renderTarget != FramebufferObject || context->isValid())) sceneGraphInitialized(); else connect(d->window, SIGNAL(sceneGraphInitialized()), SLOT(sceneGraphInitialized())); -- cgit v1.2.3 From 401c4e2e5eb97c221bc7d8ca36cf45aea0f8255a Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 17 Sep 2014 08:06:31 +0000 Subject: QQuickWindow::setColor() should use update() rather than dirtyItem() dirtyItem() will trigger maybeUpdate in the renderloop which may decide to skip the render pass if nothing changed in the scene graph. Use update() instead which forces the rendering to go through regardless. Change-Id: I4730bb0cd79d58fa21970a847cc1720060cb14a8 Reviewed-by: Laszlo Agocs --- src/quick/items/qquickwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index e1ee368f96..c522eff0a1 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -3521,7 +3521,7 @@ void QQuickWindow::setColor(const QColor &color) } d->clearColor = color; emit colorChanged(color); - d->dirtyItem(contentItem()); + update(); } QColor QQuickWindow::color() const -- cgit v1.2.3 From 428b676d84c5576cbbaf549381f47b73e2c9b6aa Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 17 Sep 2014 10:08:09 +0200 Subject: Sync QQuickWindow::update() up with polishAndSync(). When calling QQuickWindow::update() on the GUI thread, we would immediately flag the render thread that a repaint was needed and then schedule a polishAndSync. If the render thread completed the current frame before the GUI thread got to polishAndSync, it would repaint right away without syncing with GUI first. Instead of sending the repaint right away, register the need for a full repaint in the window and set it as part of the next sync phase. Change-Id: Ia731fb46724cc79f5391422213b069de9362d002 Reviewed-by: Giulio Camuffo Reviewed-by: Laszlo Agocs --- src/quick/scenegraph/qsgthreadedrenderloop.cpp | 20 +++++++++++++++++--- src/quick/scenegraph/qsgthreadedrenderloop_p.h | 1 + 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 3866ed9a2b..7cce4593ab 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -189,9 +189,15 @@ public: class WMSyncEvent : public WMWindowEvent { public: - WMSyncEvent(QQuickWindow *c, bool inExpose) : WMWindowEvent(c, WM_RequestSync), size(c->size()), syncInExpose(inExpose) { } + WMSyncEvent(QQuickWindow *c, bool inExpose, bool force) + : WMWindowEvent(c, WM_RequestSync) + , size(c->size()) + , syncInExpose(inExpose) + , forceRenderPass(force) + {} QSize size; bool syncInExpose; + bool forceRenderPass; }; @@ -368,6 +374,10 @@ bool QSGRenderThread::event(QEvent *e) qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- triggered from expose"; pendingUpdate |= ExposeRequest; } + if (se->forceRenderPass) { + qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- repaint regardless"; + pendingUpdate |= RepaintRequest; + } return true; } case WM_TryRelease: { @@ -855,6 +865,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window) win.thread = new QSGRenderThread(this, QQuickWindowPrivate::get(window)->context); win.timerId = 0; win.updateDuringSync = false; + win.forceRenderPass = true; // also covered by polishAndSync(inExpose=true), but doesn't hurt m_windows << win; w = &m_windows.last(); } @@ -998,7 +1009,9 @@ void QSGThreadedRenderLoop::update(QQuickWindow *window) } qCDebug(QSG_LOG_RENDERLOOP) << "update on window" << w->window; - w->thread->postEvent(new QEvent(WM_RequestRepaint)); + // We set forceRenderPass because we want to make sure the QQuickWindow + // actually does a full render pass after the next sync. + w->forceRenderPass = true; maybeUpdate(w); } @@ -1106,7 +1119,8 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) qCDebug(QSG_LOG_RENDERLOOP) << "- lock for sync"; w->thread->mutex.lock(); m_lockedForSync = true; - w->thread->postEvent(new WMSyncEvent(window, inExpose)); + w->thread->postEvent(new WMSyncEvent(window, inExpose, w->forceRenderPass)); + w->forceRenderPass = false; qCDebug(QSG_LOG_RENDERLOOP) << "- wait for sync"; if (profileFrames) diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h index 0e4da27fc6..82f314a6af 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h +++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h @@ -82,6 +82,7 @@ private: QSurfaceFormat actualWindowFormat; int timerId; uint updateDuringSync : 1; + uint forceRenderPass : 1; }; friend class QSGRenderThread; -- cgit v1.2.3 From 67777986284410cbe307f58250ee8e557b7ebaad Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Tue, 16 Sep 2014 13:31:20 +0200 Subject: Fix QQuickText::lineLaidOutRelayout autotest on OS X QTextLine::height() can be different that QTextLine::rect().height() Task-number: QTBUG-37829 Change-Id: I7fa93d50e29397237220ba111baa3bd1a56b88f2 Reviewed-by: Eskil Abrahamsen Blomfeldt --- tests/auto/quick/qquicktext/tst_qquicktext.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index 143c10435d..b7335ccc4a 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -2675,14 +2675,15 @@ void tst_qquicktext::lineLaidOutRelayout() qreal maxH = 0; for (int i = 0; i < textPrivate->layout.lineCount(); ++i) { - QRectF r = textPrivate->layout.lineAt(i).rect(); - + QTextLine line = textPrivate->layout.lineAt(i); + const QRectF r = line.rect(); + const qreal h = line.height(); if (r.x() == 0) { - QCOMPARE(r.y(), i * r.height()); - maxH = qMax(maxH, r.y() + r.height()); + QCOMPARE(r.y(), i * h); + maxH = qMax(maxH, r.y() + h); } else { QCOMPARE(r.x(), myText->width() / 2); - QCOMPARE(r.y(), (i * r.height()) - maxH); + QCOMPARE(r.y(), i * h - maxH); } } -- cgit v1.2.3 From 0129887195c7255f41515f72ceb213a38b98f72d Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 12 Sep 2014 11:21:36 +0200 Subject: Finally: A default animation driver which doesn't use walltime. I've wanted this for a long time, but the animation system didn't support it when mixed with timers/pauses. However, because of dfc8f8b5d4a02f33c7f9063c2a28450902a9d863 and 0db3ea4048fe572a256deb343ea5e64a55d98de9 to qtbase, it is now possible. Change-Id: Ic70c181ce49eae90276bd4f22a2d299061f96087 Reviewed-by: Michael Brasser --- src/quick/scenegraph/qsgcontext.cpp | 135 ++++++++++++++++++++++++- src/quick/scenegraph/qsgrenderloop.cpp | 18 ---- src/quick/scenegraph/qsgrenderloop_p.h | 2 - src/quick/scenegraph/qsgthreadedrenderloop.cpp | 1 - 4 files changed, 134 insertions(+), 22 deletions(-) diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index fdf27085b9..83b221a8cc 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -50,6 +50,7 @@ #include #include +#include #include #include #include @@ -58,6 +59,7 @@ #include #include +#include #include #include @@ -134,6 +136,135 @@ public: bool distanceFieldAntialiasingDecided; }; +static bool qsg_useConsistentTiming() +{ + static int use = -1; + if (use < 0) { + QByteArray fixed = qgetenv("QSG_FIXED_ANIMATION_STEP"); + use = !(fixed.isEmpty() || fixed == "no"); + qCDebug(QSG_LOG_INFO, "Using %s", bool(use) ? "fixed animation steps" : "sg animation driver"); + } + return bool(use); +} + +class QSGAnimationDriver : public QAnimationDriver +{ + Q_OBJECT +public: + enum Mode { + VSyncMode, + TimerMode + }; + + QSGAnimationDriver(QObject *parent) + : QAnimationDriver(parent) + , m_time(0) + , m_vsync(0) + , m_mode(VSyncMode) + , m_bad(0) + , m_reallyBad(0) + , m_good(0) + { + QScreen *screen = QGuiApplication::primaryScreen(); + if (screen && !qsg_useConsistentTiming()) { + m_vsync = 1000.0 / screen->refreshRate(); + if (m_vsync <= 0) + m_mode = TimerMode; + } else { + m_mode = TimerMode; + if (qsg_useConsistentTiming()) + QUnifiedTimer::instance(true)->setConsistentTiming(true); + } + if (m_mode == VSyncMode) + qCDebug(QSG_LOG_INFO, "Animation Driver: using vsync: %.2f ms", m_vsync); + else + qCDebug(QSG_LOG_INFO, "Animation Driver: using walltime"); + } + + void start() Q_DECL_OVERRIDE + { + m_time = 0; + m_timer.start(); + QAnimationDriver::start(); + } + + qint64 elapsed() const Q_DECL_OVERRIDE + { + return m_mode == VSyncMode + ? qint64(m_time) + : QAnimationDriver::elapsed(); + } + + void advance() Q_DECL_OVERRIDE + { + qint64 delta = m_timer.restart(); + + if (m_mode == VSyncMode) { + // If a frame is skipped, either because rendering was slow or because + // the QML was slow, we accept it and continue advancing with a single + // vsync tick. The reason for this is that by the time we notice this + // on the GUI thread, the temporal distortion has already gone to screen + // and by catching up, we will introduce a second distortion which will + // worse. We accept that the animation time falls behind wall time because + // it comes out looking better. + // Only when multiple bad frames are hit in a row, do we consider + // switching. A few really bad frames and we switch right away. For frames + // just above the vsync delta, we tolerate a bit more since a buffered + // driver can have vsync deltas on the form: 4, 21, 21, 2, 23, 16, and + // still manage to put the frames to screen at 16 ms intervals. In addition + // to that, we tolerate a 25% margin of error on the value of m_vsync + // reported from the system as this value is often not precise. + + m_time += m_vsync; + + if (delta > m_vsync * 5) { + ++m_reallyBad; + ++m_bad; + } else if (delta > m_vsync * 1.25) { + ++m_bad; + } else { + // reset counters on a good frame. + m_reallyBad = 0; + m_bad = 0; + } + + // rational for the 3 and 50. If we have several really bad frames + // in a row, that would indicate a huge performance problem and we should + // switch right away. For the case of m_bad, we're a bit more tolerant. + if (m_reallyBad > 3 || m_bad > 50) { + m_mode = TimerMode; + qCDebug(QSG_LOG_INFO, "animation driver switched to timer mode"); + } + + } else { + if (delta < 1.25 * m_vsync) { + ++m_good; + } else { + m_good = 0; + } + + // We've been solid for a while, switch back to vsync mode. Tolerance + // for switching back is lower than switching to timer mode, as we + // want to stay in vsync mode as much as possible. + if (m_good > 10 && !qsg_useConsistentTiming()) { + m_time = elapsed(); + m_mode = VSyncMode; + qCDebug(QSG_LOG_INFO, "animation driver switched to vsync mode"); + } + } + + advanceAnimation(); + } + + float m_time; + float m_vsync; + Mode m_mode; + QElapsedTimer m_timer; + int m_bad; + int m_reallyBad; + int m_good; +}; + class QSGTextureCleanupEvent : public QEvent { public: @@ -385,7 +516,7 @@ bool QSGContext::isDistanceFieldEnabled() const QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent) { - return new QAnimationDriver(parent); + return new QSGAnimationDriver(parent); } QSGRenderContext::QSGRenderContext(QSGContext *context) @@ -726,4 +857,6 @@ void QSGRenderContext::initialize(QSGMaterialShader *shader) shader->initialize(); } +#include "qsgcontext.moc" + QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 4428918da5..720d9a6fd1 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -147,19 +147,6 @@ public: bool eventPending; }; -bool QSGRenderLoop::useConsistentTiming() -{ - bool bufferQueuing = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::BufferQueueingOpenGL); - // Enable fixed animation steps... - QByteArray fixed = qgetenv("QSG_FIXED_ANIMATION_STEP"); - bool fixedAnimationSteps = bufferQueuing; - if (fixed == "no") - fixedAnimationSteps = false; - else if (fixed.length()) - fixedAnimationSteps = true; - return fixedAnimationSteps; -} - QSGRenderLoop *QSGRenderLoop::instance() { if (!s_instance) { @@ -170,11 +157,6 @@ QSGRenderLoop *QSGRenderLoop::instance() s_instance = QSGContext::createWindowManager(); - if (useConsistentTiming()) { - QUnifiedTimer::instance(true)->setConsistentTiming(true); - qCDebug(QSG_LOG_INFO, "using fixed animation steps"); - } - if (!s_instance) { enum RenderLoopType { diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h index daba3bc69d..e9b58c60ba 100644 --- a/src/quick/scenegraph/qsgrenderloop_p.h +++ b/src/quick/scenegraph/qsgrenderloop_p.h @@ -82,8 +82,6 @@ public: static QSGRenderLoop *instance(); static void setInstance(QSGRenderLoop *instance); - static bool useConsistentTiming(); - virtual bool interleaveIncubation() const { return false; } static void cleanup(); diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 7cce4593ab..ff32ccb358 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -651,7 +651,6 @@ void QSGRenderThread::run() qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "run()"; animatorDriver = sgrc->sceneGraphContext()->createAnimationDriver(0); animatorDriver->install(); - QUnifiedTimer::instance(true)->setConsistentTiming(QSGRenderLoop::useConsistentTiming()); if (QQmlDebugService::isDebuggingEnabled()) QQuickProfiler::registerAnimationCallback(); -- cgit v1.2.3 From 72eef1da9e34aace7b0e2bc601d88f6b5363c075 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 17 Sep 2014 16:18:00 +0200 Subject: Avoid crashing the rendercontrol example on exit Task-number: QTBUG-41278 Change-Id: I456467698e66fb28f1bf6a05d85771ac25f454d0 Reviewed-by: Gunnar Sletta --- examples/quick/rendercontrol/window.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/quick/rendercontrol/window.cpp b/examples/quick/rendercontrol/window.cpp index 396e9f8afa..4813936538 100644 --- a/examples/quick/rendercontrol/window.cpp +++ b/examples/quick/rendercontrol/window.cpp @@ -111,8 +111,11 @@ Window::Window() Window::~Window() { - // Make sure the context is current while doing cleanup. - m_context->makeCurrent(this); + // Make sure the context is current while doing cleanup. Note that we use the + // offscreen surface here because passing 'this' at this point is not safe: the + // underlying platform window may already be destroyed. To avoid all the trouble, use + // another surface that is valid for sure. + m_context->makeCurrent(m_offscreenSurface); // Delete the render control first since it will free the scenegraph resources. // Destroy the QQuickWindow only afterwards. -- cgit v1.2.3 From f99573677aa0242f398bb9b0f79c35a8d0e16422 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 17 Sep 2014 13:41:33 +0200 Subject: Remove tst_dialogs - moved to qtquickcontrols QtQuick.Dialogs were moved from qtdeclarative to qtquickcontrols already in Qt 5.3, but the auto test was forgotten. Change-Id: I5c74e45b9ee2302f1d20fb476af6a93879913a28 Reviewed-by: Frederik Gladhorn --- .../auto/quick/dialogs/data/RectWithFileDialog.qml | 33 ----- tests/auto/quick/dialogs/dialogs.pro | 20 --- tests/auto/quick/dialogs/tst_dialogs.cpp | 152 --------------------- tests/auto/quick/quick.pro | 3 +- 4 files changed, 1 insertion(+), 207 deletions(-) delete mode 100644 tests/auto/quick/dialogs/data/RectWithFileDialog.qml delete mode 100644 tests/auto/quick/dialogs/dialogs.pro delete mode 100644 tests/auto/quick/dialogs/tst_dialogs.cpp diff --git a/tests/auto/quick/dialogs/data/RectWithFileDialog.qml b/tests/auto/quick/dialogs/data/RectWithFileDialog.qml deleted file mode 100644 index ca7ecc948a..0000000000 --- a/tests/auto/quick/dialogs/data/RectWithFileDialog.qml +++ /dev/null @@ -1,33 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Dialogs 1.0 - -Rectangle { - width: 1024 - height: 320 - property alias fileDialog: fileDialog - property alias label: label - property alias mouseArea: mouseArea - - FileDialog { - id: fileDialog - title: "Choose some files" - selectMultiple: true - nameFilters: [ "QML files (*.qml)", "All files (*)" ] - selectedNameFilter: "QML files (*.qml)" - onAccepted: label.text = fileDialog.filePaths - } - - MouseArea { - id: mouseArea - anchors.fill: parent - onClicked: fileDialog.visible = !fileDialog.visible - } - - Text { - id: label - text: "Click to open a file dialog" - wrapMode: Text.Wrap - anchors.fill: parent - anchors.margins: 10 - } -} diff --git a/tests/auto/quick/dialogs/dialogs.pro b/tests/auto/quick/dialogs/dialogs.pro deleted file mode 100644 index 4069ad4c68..0000000000 --- a/tests/auto/quick/dialogs/dialogs.pro +++ /dev/null @@ -1,20 +0,0 @@ -CONFIG += testcase -TARGET = tst_dialogs -SOURCES += tst_dialogs.cpp - -include (../../shared/util.pri) - -macx:CONFIG -= app_bundle -macx:CONFIG+=insignificant_test # QTBUG-30513 - test is unstable -linux-*:CONFIG+=insignificant_test # QTBUG-30513 - test is unstable -win32:CONFIG+=insignificant_test # QTBUG-30513 - test is unstable - -CONFIG += parallel_test -QT += core-private gui-private qml-private quick-private testlib - -TESTDATA = data/* - -OTHER_FILES += \ - data/FileDialog.qml \ - -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/dialogs/tst_dialogs.cpp b/tests/auto/quick/dialogs/tst_dialogs.cpp deleted file mode 100644 index 01fe6c3722..0000000000 --- a/tests/auto/quick/dialogs/tst_dialogs.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "../../shared/util.h" -#include -#include -#include - -class tst_dialogs : public QQmlDataTest -{ - Q_OBJECT -public: - -private slots: - void initTestCase() - { - QQmlDataTest::initTestCase(); - } - - // FileDialog - void fileDialogDefaultModality(); - void fileDialogNonModal(); - void fileDialogNameFilters(); - -private: -}; - -void tst_dialogs::fileDialogDefaultModality() -{ - QQuickView *window = new QQuickView; - QScopedPointer cleanup(window); - - window->setSource(testFileUrl("RectWithFileDialog.qml")); - window->setGeometry(240,240,1024,320); - window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window)); - QVERIFY(window->rootObject()); - - // Click to show - QObject *dlg = qvariant_cast(window->rootObject()->property("fileDialog")); - QSignalSpy spyVisibilityChanged(dlg, SIGNAL(visibilityChanged())); - QTest::mouseClick(window, Qt::LeftButton, 0, QPoint(1000, 100)); // show - QTRY_VERIFY(spyVisibilityChanged.count() > 0); - int visibilityChangedCount = spyVisibilityChanged.count(); - // Can't hide by clicking the main window, because dialog is modal. - QTest::mouseClick(window, Qt::LeftButton, 0, QPoint(1000, 100)); - /* - On the Mac, if you send an event directly to a window, the modal dialog - doesn't block the event, so the window will process it normally. This - is a different code path compared to having a user click the mouse and - generate a native event; in that case the OS does the filtering itself, - and Qt will not even see the event. But simulating real events in the - test framework is generally unstable. So there isn't a good way to test - modality on the mac. - This test sometimes fails on other platforms too. Maybe it's not reliable - to try to click the main window in a location which is outside the - dialog, without checking or guaranteeing it somehow. - */ - QSKIP("Modality test is flaky in general and doesn't work at all on MacOS"); - // So we expect no change in visibility. - QCOMPARE(spyVisibilityChanged.count(), visibilityChangedCount); - - QCOMPARE(dlg->property("visible").toBool(), true); - QMetaObject::invokeMethod(dlg, "close"); - QTRY_VERIFY(spyVisibilityChanged.count() > visibilityChangedCount); - visibilityChangedCount = spyVisibilityChanged.count(); - QCOMPARE(dlg->property("visible").toBool(), false); - QMetaObject::invokeMethod(dlg, "open"); - QTRY_VERIFY(spyVisibilityChanged.count() > visibilityChangedCount); - QCOMPARE(dlg->property("visible").toBool(), true); - QCOMPARE(dlg->property("modality").toInt(), (int)Qt::WindowModal); -} - -void tst_dialogs::fileDialogNonModal() -{ - QQuickView *window = new QQuickView; - QScopedPointer cleanup(window); - - window->setSource(testFileUrl("RectWithFileDialog.qml")); - window->setGeometry(240,240,1024,320); - window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window)); - QVERIFY(window->rootObject()); - - // Click to toggle visibility - QObject *dlg = qvariant_cast(window->rootObject()->property("fileDialog")); - dlg->setProperty("modality", QVariant((int)Qt::NonModal)); - QSignalSpy spyVisibilityChanged(dlg, SIGNAL(visibilityChanged())); - QTest::mouseClick(window, Qt::LeftButton, 0, QPoint(1000, 100)); // show - QTRY_VERIFY(spyVisibilityChanged.count() > 0); - int visibilityChangedCount = spyVisibilityChanged.count(); - QCOMPARE(dlg->property("visible").toBool(), true); - QTest::mouseClick(window, Qt::LeftButton, 0, QPoint(1000, 100)); // hide - QTRY_VERIFY(spyVisibilityChanged.count() > visibilityChangedCount); - QCOMPARE(dlg->property("visible").toBool(), false); - QCOMPARE(dlg->property("modality").toInt(), (int)Qt::NonModal); -} - -void tst_dialogs::fileDialogNameFilters() -{ - QQuickView *window = new QQuickView; - QScopedPointer cleanup(window); - - window->setSource(testFileUrl("RectWithFileDialog.qml")); - window->setGeometry(240,240,1024,320); - window->show(); - QVERIFY(QTest::qWaitForWindowExposed(window)); - QVERIFY(window->rootObject()); - - QObject *dlg = qvariant_cast(window->rootObject()->property("fileDialog")); - QStringList filters; - filters << "QML files (*.qml)"; - filters << "Image files (*.jpg, *.png, *.gif)"; - filters << "All files (*)"; - dlg->setProperty("nameFilters", QVariant(filters)); - QCOMPARE(dlg->property("selectedNameFilter").toString(), filters.first()); -} - -QTEST_MAIN(tst_dialogs) - -#include "tst_dialogs.moc" diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro index 0a887534bd..e400556b67 100644 --- a/tests/auto/quick/quick.pro +++ b/tests/auto/quick/quick.pro @@ -73,8 +73,7 @@ QUICKTESTS = \ qquickview \ qquickcanvasitem \ qquickscreen \ - touchmouse \ - dialogs \ + touchmouse SUBDIRS += $$PUBLICTESTS -- cgit v1.2.3 From 941eff6c1c3a2b188565e4449cf4671d87fd7645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Korpipa=CC=88a=CC=88?= Date: Thu, 18 Sep 2014 07:41:11 +0300 Subject: Fixed frame focusing on touch devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also fixed the \quotefromfile commands in the doc to display the changed code correctly. Task-number: QTBUG-38779 Change-Id: I37d37139459cb9cdee7ec9beaffeab26a1cb4aaf Reviewed-by: Leena Miettinen Reviewed-by: Topi Reiniö --- .../quick/demos/photosurface/doc/src/photosurface.qdoc | 18 +++++------------- examples/quick/demos/photosurface/photosurface.qml | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/examples/quick/demos/photosurface/doc/src/photosurface.qdoc b/examples/quick/demos/photosurface/doc/src/photosurface.qdoc index b66143368e..49f864b4d9 100644 --- a/examples/quick/demos/photosurface/doc/src/photosurface.qdoc +++ b/examples/quick/demos/photosurface/doc/src/photosurface.qdoc @@ -53,7 +53,7 @@ \quotefromfile demos/photosurface/photosurface.qml \skipto Window { - \printuntil defaultSize + \printuntil currentFrame To use the \l{Window} type, we must import it: @@ -123,9 +123,7 @@ We use a PinchArea that contains a MouseArea in the photo frames to handle dragging, rotation and pinch zooming of the frame: - \quotefromfile demos/photosurface/photosurface.qml - \skipto PinchArea - \printuntil onPinchFinished + \printuntil onPinchStarted We use the \c pinch group property to control how the photo frames react to pinch gestures. The \c pinch.target sets \c photoFrame as the item to @@ -136,18 +134,14 @@ In the MouseArea's \c onPressed signal handler, we raise the selected photo frame to the top by increasing the value of its \c z property. The root item stores the z value of the top-most frame. The border color of the photo - frame is controlled in the \c onEntered and \c onExited signal handlers to - highlight the selected image. + frame is controlled in the \c onEntered signal handler to highlight the + selected image: - \quotefromfile demos/photosurface/photosurface.qml - \skipto MouseArea - \printuntil onExited + \printuntil onEntered To enable you to test the example on the desktop, we use the MouseArea's \c onWheel signal handler to simulate pinch gestures by using a mouse: - \quotefromfile demos/photosurface/photosurface.qml - \skipto onWheel \printuntil photoFrame.y \printuntil } \printuntil } @@ -157,7 +151,5 @@ Use the vertical wheel to zoom and Ctrl and the vertical wheel to rotate frames. If the mouse has a horizontal wheel, use it to rotate frames. - \section1 List of Files - \sa {QML Applications} */ diff --git a/examples/quick/demos/photosurface/photosurface.qml b/examples/quick/demos/photosurface/photosurface.qml index 9d081de1e3..c269018426 100644 --- a/examples/quick/demos/photosurface/photosurface.qml +++ b/examples/quick/demos/photosurface/photosurface.qml @@ -49,6 +49,7 @@ Window { color: "black" property int highestZ: 0 property real defaultSize: 200 + property var currentFrame: undefined FileDialog { id: fileDialog @@ -90,15 +91,17 @@ Window { pinch.maximumRotation: 360 pinch.minimumScale: 0.1 pinch.maximumScale: 10 - onPinchFinished: photoFrame.border.color = "black"; + onPinchStarted: setFrameColor(); MouseArea { id: dragArea hoverEnabled: true anchors.fill: parent drag.target: photoFrame - onPressed: photoFrame.z = ++root.highestZ; - onEntered: photoFrame.border.color = "red"; - onExited: photoFrame.border.color = "black"; + onPressed: { + photoFrame.z = ++root.highestZ; + parent.setFrameColor(); + } + onEntered: parent.setFrameColor(); onWheel: { if (wheel.modifiers & Qt.ControlModifier) { photoFrame.rotation += wheel.angleDelta.y / 120 * 5; @@ -115,6 +118,12 @@ Window { } } } + function setFrameColor() { + if (currentFrame) + currentFrame.border.color = "black"; + currentFrame = photoFrame; + currentFrame.border.color = "red"; + } } } } -- cgit v1.2.3 From 5701b73e8215115fa47c373e0b846f28744dd4f1 Mon Sep 17 00:00:00 2001 From: Bjoern Breitmeyer Date: Thu, 4 Sep 2014 11:26:04 +0200 Subject: Replace vsnprintf with qvsnprintf. Windows CE does not have vsnprintf, so use qvsnprintf instead. Change-Id: I30ddbf2469424ec174903f0cce2b482c652b5d22 Reviewed-by: Simon Hausmann --- src/qml/jit/qv4isel_masm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 753626c811..5cf00f6d60 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -86,7 +86,7 @@ public: void vprintf(const char* format, va_list argList) WTF_ATTRIBUTE_PRINTF(2, 0) { - const int written = vsnprintf(buf.data(), buf.size(), format, argList); + const int written = qvsnprintf(buf.data(), buf.size(), format, argList); if (written > 0) dest->write(buf.constData(), written); memset(buf.data(), 0, qMin(written, buf.size())); -- cgit v1.2.3 From 605777e6cf557dbaf2835c63562bf3fe1620ee45 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 18 Sep 2014 17:03:44 +0200 Subject: Revert mapping of var signal parameters to QJSValue This reverts commit 70004585f89f325f398c556d101bfa1833d87b53, which is superseded by commit 3dbe05f6bf3fd51ce8097c35f6c7f12b39acb0f6, which is a much better solution. [ChangeLog][QtQml][Important Behavior Changes] Qt 5.3 changed the mapping of "var" parameters in QML declared signals to QJSValue. This was reverted to the behavior of earlier Qt versions to use QVariant. The original issue of not being able to pass function objects through var parameters of QML declared signals is solved by wrapping a QJSValue inside the QVariant. Task-number: QTBUG-39971 Change-Id: I44de2ef2660c64c68e6a3b2a1ae251ad563d6b3c Reviewed-by: Taylor Braun-Jones Reviewed-by: Lars Knoll --- src/qml/compiler/qqmltypecompiler.cpp | 2 +- tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 90f775f781..13367efc3d 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -571,7 +571,7 @@ bool QQmlPropertyCacheCreator::createMetaObject(int objectIndex, const QmlIR::Ob QV4::CompiledData::Property::Type dtype; int metaType; } builtinTypes[] = { - { QV4::CompiledData::Property::Var, qMetaTypeId() }, + { QV4::CompiledData::Property::Var, QMetaType::QVariant }, { QV4::CompiledData::Property::Variant, QMetaType::QVariant }, { QV4::CompiledData::Property::Int, QMetaType::Int }, { QV4::CompiledData::Property::Bool, QMetaType::Bool }, diff --git a/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp b/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp index b6e7a43c46..ffaab792a7 100644 --- a/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp +++ b/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp @@ -327,11 +327,11 @@ void tst_QQmlMetaObject::method_data() << (QList() << "int" << "bool" << "double") << (QList() << "foo" << "bar" << "baz"); QTest::newRow("testSignal(variant foo, var bar)") << "signal.4.qml" - << "testSignal(QVariant,QJSValue)" + << "testSignal(QVariant,QVariant)" << QMetaMethod::Signal << int(QMetaType::Void) << "void" - << (QList() << QMetaType::QVariant << qMetaTypeId()) - << (QList() << "QVariant" << "QJSValue") + << (QList() << QMetaType::QVariant << QMetaType::QVariant) + << (QList() << "QVariant" << "QVariant") << (QList() << "foo" << "bar"); QTest::newRow("testSignal(color foo, date bar, url baz)") << "signal.5.qml" << "testSignal(QColor,QDateTime,QUrl)" -- cgit v1.2.3 From e5bed0995603294274500f764df027f7fb35cd87 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 17 Sep 2014 10:51:05 +0200 Subject: Remove qtdemo from gitignore QtDemo was removed with a commit in qtdoc. Change-Id: I75228b748a2307a713f0c86ecf144dae3b3569a3 Reviewed-by: Alessandro Portale --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index c14d237ee3..3995091983 100644 --- a/.gitignore +++ b/.gitignore @@ -55,7 +55,6 @@ bin/pixeltool* bin/qmake* bin/qdoc3* bin/qt3to4* -bin/qtdemo* bin/qttracereplay* bin/rcc* bin/uic* -- cgit v1.2.3 From 95778d80a6053fcaf66f7c37b1d58c140a4fa48d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 19 Sep 2014 09:23:22 +0200 Subject: Fix compiler warnings in qv8engine.cpp. qml\v8\qv8engine.cpp(91) : warning C4805: '|' : unsafe mix of type 'bool' and type 'int' in operation Task-number: QTBUG-40431 Change-Id: Ibdc96907aaab132956c87dd6aec2eab2f3bf0e9f Reviewed-by: Simon Hausmann --- src/qml/qml/v8/qv8engine.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 993cf96104..39b816f97c 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -88,7 +88,11 @@ ReturnType convertJSValueToVariantType(const QJSValue &value) static void saveJSValue(QDataStream &stream, const void *data) { const QJSValue *jsv = reinterpret_cast(data); - const quint32 isNullOrUndefined = jsv->isNull() | (jsv->isUndefined() << 1); + quint32 isNullOrUndefined = 0; + if (jsv->isNull()) + isNullOrUndefined |= 0x1; + if (jsv->isUndefined()) + isNullOrUndefined |= 0x2; stream << isNullOrUndefined; if (!isNullOrUndefined) reinterpret_cast(data)->toVariant().save(stream); -- cgit v1.2.3 From 2ef09acbf47f97fd5811081421e3e00fc61a2fd8 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 11 Sep 2014 17:15:37 +0200 Subject: Doc: add documentation for Photo Viewer example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iffedd9361bd0475a53c1a8b9567c9cbf5e5d4867 Reviewed-by: Topi Reiniö --- .../demos/photoviewer/doc/src/photoviewer.qdoc | 291 ++++++++++++++++++++- src/quick/doc/qtquick.qdocconf | 2 + 2 files changed, 290 insertions(+), 3 deletions(-) diff --git a/examples/quick/demos/photoviewer/doc/src/photoviewer.qdoc b/examples/quick/demos/photoviewer/doc/src/photoviewer.qdoc index 29c432be3c..ac56cb2b7a 100644 --- a/examples/quick/demos/photoviewer/doc/src/photoviewer.qdoc +++ b/examples/quick/demos/photoviewer/doc/src/photoviewer.qdoc @@ -29,13 +29,298 @@ \title Qt Quick Demo - Photo Viewer \ingroup qtquickdemos \example demos/photoviewer - \brief A photo viewer that displays Flickr feeds. + \brief A QML photo viewer that that uses XmlListModel and XmlRole to + download Flickr feeds, and Package to display the photos in different views. + \image qtquick-demo-photoviewer-small.png - \e{Photo Viewer} demonstrates various QML and \l{Qt Quick} features such as - displaying custom components. + \e{Photo Viewer} demonstrates the following \l{Qt Quick} features: + + \list + \li Using custom types to create screens and screen controls. + \li Using Qt Quick Controls to create an application window. + \li Using the \l Package type with a \l DelegateModel to provide + delegates with a shared context to multiple views. + \li Using XML list models to download Flickr feeds. + \li Using the \l Flipable type to create labels with different text on + the front and back. + \li Using the PathView, \l Path, PathAttribute, and PathLine types to + lay out photos on a path. + \li Providing feedback to users while data is loading. + \li Localizing applications. + \endlist \include examples-run.qdocinc + \section1 Using Custom Types + + In the Photo Viewer app, we use the following custom types that are each + defined in a separate .qml file: + + \list + \li \c AlbumDelegate.qml + \li \c BusyIndicator.qml + \li \c Button.qml + \li \c EditableButton.qml + \li \c PhotoDelegate.qml + \li \c ProgressBar.qml + \li \c RssModel.qml + \li \c Tag.qml + \endlist + + To use the custom types, we add an import statement to the main QML file, + main.qml, that imports the folder called \c PhotoViewerCore where the types + are located: + + \quotefromfile demos/photoviewer/main.qml + \skipto PhotoViewerCore + \printuntil " + + \section1 Creating the Main Window + + In main.qml, we use the ApplicationWindow Qt Quick Control to create the app + main window: + + \printuntil visible + + We use a ListModel type with \l ListElement types to display photo albums: + + \skipto ListModel + \printuntil Prague + \printuntil } + + List elements are defined like other QML types except that they contain a + collection of \e role definitions instead of properties. Roles both define + how the data is accessed and include the data itself. For each list element, + we use the \c tag role to specify the photos to download. + + A DelegateModel type is used together with the \l Package type to provide + delegates to multiple views. The \c model property holds the model providing + data for the delegate model and the \c delegate property specifies the + template defining each item instantiated by a view: + + \printuntil DelegateModel + + We use a GridView type to lay out the albums as a grid: + + \printuntil } + + The \c model property references the package name \c album that we specify + in AlbumDelegate.qml. We use the \l Package type to allow the photos to move + between different views. The \l Package contains the named items \c browser, + \c fullscreen, and \c album: + + \quotefromfile demos/photoviewer/PhotoViewerCore/AlbumDelegate.qml + \skipto Package + \printuntil albumWrapper + + The named items are used as the delegates by the views that reference the + special DelegateModel::parts property to select the model that provides + the chosen delegate. + + We use a ListView type to lay out albums in other views: + + \quotefromfile demos/photoviewer/main.qml + \skipto ListView + \printuntil } + \skipto ListView + \printuntil } + + \section1 Displaying Photos + + We use the PhotoDelegate custom type that is specified in PhotoDelegate.qml + to display photos. We use a \l Package type to lay out the photos either in + a stack, list, or a grid: + + \quotefromfile demos/photoviewer/PhotoViewerCore/PhotoDelegate.qml + \skipto Package + \printuntil gridItem + + The photos are rotated at random angles by using the \c Math.random() + JavaScript method: + + \printuntil stackItem + + We use a BorderImage type to create borders for the images: + + \printuntil border.left + \printuntil } + + \section1 Downloading Flickr Feeds + + In AlbumDelegate.qml, we use the DelegateModel to provide the + PhotoDelegate delegate to the RssModel model: + + \quotefromfile demos/photoviewer/PhotoViewerCore/AlbumDelegate.qml + \skipto DelegateModel + \printuntil RssModel + \printuntil } + + In RssModel.qml, we use an XmlListModel type as a data source for + \l Package objects to download photos from the selected feeds: + + \quotefromfile demos/photoviewer/PhotoViewerCore/RssModel.qml + \skipto XmlListModel + \printuntil encodeTags + + We use the \c tags custom property to specify which photos to download. The + \c encodeTags custom function uses the \c encodeURIComponent JavaScript + method to ensure that the requests to the server are correctly formatted. + + We use the \c source property to fetch photos that have the specified tags + attached from public Flickr feeds: + + \printuntil namespaceDeclarations + + The \c query property specifies that the XmlListModel generates a model item + for each feed entry. + + The \c namespaceDeclarations property specifies that the requested document + uses the namespace \c{http://www.w3.org/2005/Atom}, which is declared as the + default namespace. + + We use the XmlRole type to specify the model item attributes. Each model + item has the \c title, \c content, and \c hq attributes that match the + values of the corresponding feed entry: + + \printuntil hq + + \section1 Creating Flipable Labels + + When users select the \b Edit button, the album labels are flipped from + their front side to their back side and the text on them changes from album + name to \b Remove. + + In AlbumDelegate.qml, we use the Tag custom type to specify the text to + display on the front and back sides of album labels: + + \quotefromfile demos/photoviewer/PhotoViewerCore/AlbumDelegate.qml + \skipto Tag + \printuntil onBackClicked + \printuntil } + + The \c onTagChanged signal handler is used to change the tag based on + which the model is populated. The \c onBackClicked signal handler is used to + remove the album. + + In Tag.qml, we use a \l Flipable type with custom properties and signals to + create the labels: + + \quotefromfile demos/photoviewer/PhotoViewerCore/Tag.qml + \skipto Flipable + \printuntil tagChanged + + The \c front property holds the EditableButton custom type that enables + users to edit the label text: + + \printuntil onLabelChanged + \printuntil } + + The \c back property holds the \c Button custom type that is used to remove + the album: + + \printuntil onClicked + \printuntil } + + \section1 Laying out Photos on a Path + + In AlbumDelegate.qml, we use a PathView type to lay out the photos provided + by the \c visualModel.parts.stack model on a path that has the form of a + stack: + + \quotefromfile demos/photoviewer/PhotoViewerCore/AlbumDelegate.qml + \skipto PathView + \printuntil 0.0 + \printuntil } + \printuntil } + + The \c path property holds the \l Path type that defines the path used by + the PathView. The PathAttribute types are used to set a range of + \c 0 to \c 9999 for the \c z attribute. This way, the path creates a stack + of album photos. Because each PhotoDelegate is slightly rotated at a random + angle, this results in a realistic-looking stack of photos. + + \section1 Providing Feedback to Users + + We use a busy indicator and a progress bar to indicate activity while + Flickr feeds and photos are being loaded. + + In AlbumDelegate.qml, we use the \c BusyIndicator custom type and the + \c on custom property to display a rotating image while the Flickr feed is + being loaded: + + \quotefromfile demos/photoviewer/PhotoViewerCore/AlbumDelegate.qml + \skipto BusyIndicator + \printuntil rssModel + \printuntil } + + In PhotoDelegate.qml, we use them to indicate activity while a photo is + being loaded: + + \quotefromfile demos/photoviewer/PhotoViewerCore/PhotoDelegate.qml + \skipto BusyIndicator + \printuntil } + + We define the \c BusyIndicator type in \c BusyIndicator.qml. We use an + \l Image type to display an image and apply a NumberAnimation to its + \c rotation property to rotate the image in an infinite loop: + + \quotefromfile demos/photoviewer/PhotoViewerCore/BusyIndicator.qml + \skipto Image + \printuntil } + \printuntil } + + In your apps, you can also use the BusyIndicator type from the + \l {Qt Quick Controls} module. + + In main.qml, we use the \c ProgressBar custom type to indicate progress + while a high quality version of a photo is being opened on full screen: + + \quotefromfile demos/photoviewer/main.qml + \skipto ProgressBar + \printuntil } + + We define the \c ProgressBar type in \c ProgressBar.qml. We use a + \l Rectangle type to create the progress bar and apply a NumberAnimation to + its \c opacity property to change the color of the bar from black to white + as data loading proceeds: + + \quotefromfile demos/photoviewer/PhotoViewerCore/ProgressBar.qml + \skipto Item + \printuntil /^\}/ + + In your apps, you can also use the ProgressBar type from the + \l {Qt Quick Controls} module. + + \section1 Localizing Applications + + The example application is translated into German and French. The translated + strings are loaded at runtime according to the current locale. + + We use a \l Column type in main.qml to position buttons for adding and + editing albums and exiting the application: + + \quotefromfile demos/photoviewer/main.qml + \skipto Column + \printuntil quit() + \printuntil } + \printuntil } + + We use the \l qsTr() command to mark the button labels translatable. + + We use the \l lupdate tool to generate the translation source files and + the \l lrelease tool to convert the translated strings to the QM files used + by the application at runtime. These files are stored in the \c i18n + directory. + + To make the application aware of the translations, we add code to the + \c main() function in the main.cpp file. The code creates a \l QTranslator + object, loads a translation according to the current locale at runtime, and + installs the translator object into the application: + + \quotefromfile demos/photoviewer/main.cpp + \skipto main + \printuntil app.installTranslator + \sa {QML Applications} */ diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf index 5b8388f977..b0d1f1e0de 100644 --- a/src/quick/doc/qtquick.qdocconf +++ b/src/quick/doc/qtquick.qdocconf @@ -66,6 +66,8 @@ excludedirs += ../../imports/dialogs \ ../../imports/models \ ../../../examples/quick/dialogs +examples.fileextensions += "*.qm" + manifestmeta.thumbnail.names += "QtQuick/Threaded ListModel Example" navigation.landingpage = "Qt Quick" -- cgit v1.2.3 From ca9668694b5430ab73dfd2b090760a7235ece3e3 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 17 Sep 2014 14:56:54 +0200 Subject: Make tst_qquickanimations more reliable As we usually don't get realtime guarantees we cannot rely on exact sleep times. This change relaxes our expactations in that regard. Task-number: QTBUG-29062 Change-Id: I54dfb7a28d6bb46479aedb9f943f5ff4db2df701 Reviewed-by: J-P Nurmi --- .../qquickanimations/tst_qquickanimations.cpp | 67 ++++++++++++---------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp index c908e8c9bf..f86c8fb36a 100644 --- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp +++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp @@ -569,12 +569,26 @@ void tst_qquickanimations::alwaysRunToEnd() animation.setAlwaysRunToEnd(true); QVERIFY(animation.loops() == -1); QVERIFY(animation.alwaysRunToEnd() == true); + + QElapsedTimer timer; + timer.start(); animation.start(); - QTest::qWait(1500); + + // Make sure the animation has started but is not finished, yet. + QTRY_VERIFY(rect.x() > qreal(0) && rect.x() != qreal(200)); + animation.stop(); - QVERIFY(rect.x() != qreal(200)); - QTest::qWait(500); - QTIMED_COMPARE(rect.x(), qreal(200)); + + // Make sure it didn't just jump to the end and also didn't revert to the start. + QVERIFY(rect.x() > qreal(0) && rect.x() != qreal(200)); + + // Make sure it eventually reaches the end. + QTRY_COMPARE(rect.x(), qreal(200)); + + // This should have taken at least 1s but less than 2s + // (otherwise it has run the animation twice). + qint64 elapsed = timer.elapsed(); + QVERIFY(elapsed >= 1000 && elapsed < 2000); } void tst_qquickanimations::complete() @@ -592,8 +606,7 @@ void tst_qquickanimations::complete() animation.stop(); QVERIFY(rect.x() != qreal(200)); animation.start(); - QTest::qWait(50); - QVERIFY(animation.isRunning()); + QTRY_VERIFY(animation.isRunning()); animation.complete(); QCOMPARE(rect.x(), qreal(200)); } @@ -718,10 +731,10 @@ void tst_qquickanimations::badTypes() QVERIFY(rect); QQuickItemPrivate::get(rect)->setState("state1"); - QTest::qWait(1000 + 50); - QQuickRectangle *myRect = rect->findChild("MyRect"); - QVERIFY(myRect); - QCOMPARE(myRect->x(),qreal(200)); + + QQuickRectangle *myRect = 0; + QTRY_VERIFY(myRect = rect->findChild("MyRect")); + QTRY_COMPARE(myRect->x(),qreal(200)); } } @@ -764,7 +777,7 @@ void tst_qquickanimations::mixedTypes() QQuickRectangle *myRect = rect->findChild("MyRect"); QVERIFY(myRect); - //rather inexact -- is there a better way? + // We cannot get that more exact than that without dependable real-time behavior. QVERIFY(myRect->x() > 100 && myRect->x() < 200); QVERIFY(myRect->border()->width() > 1 && myRect->border()->width() < 10); } @@ -780,7 +793,7 @@ void tst_qquickanimations::mixedTypes() QQuickRectangle *myRect = rect->findChild("MyRect"); QVERIFY(myRect); - //rather inexact -- is there a better way? + // We cannot get that more exact than that without dependable real-time behavior. QVERIFY(myRect->x() > 100 && myRect->x() < 200); QVERIFY(myRect->color() != QColor("red") && myRect->color() != QColor("blue")); } @@ -1215,42 +1228,33 @@ void tst_qquickanimations::startStopSignals() QCOMPARE(root->property("startedCount").toInt(), 1); QCOMPARE(root->property("stoppedCount").toInt(), 1); + QElapsedTimer timer; + timer.start(); QMetaObject::invokeMethod(root, "start"); QCOMPARE(root->property("startedCount").toInt(), 2); QCOMPARE(root->property("stoppedCount").toInt(), 1); - QTest::qWait(100); - - QCOMPARE(root->property("startedCount").toInt(), 2); - QCOMPARE(root->property("stoppedCount").toInt(), 1); - - QTest::qWait(100); - QTRY_COMPARE(root->property("stoppedCount").toInt(), 2); QCOMPARE(root->property("startedCount").toInt(), 2); + QVERIFY(timer.elapsed() >= 200); root->setProperty("alwaysRunToEnd", true); + timer.restart(); QMetaObject::invokeMethod(root, "start"); QCOMPARE(root->property("startedCount").toInt(), 3); QCOMPARE(root->property("stoppedCount").toInt(), 2); - QTest::qWait(100); - - QCOMPARE(root->property("startedCount").toInt(), 3); - QCOMPARE(root->property("stoppedCount").toInt(), 2); - QMetaObject::invokeMethod(root, "stop"); QCOMPARE(root->property("startedCount").toInt(), 3); QCOMPARE(root->property("stoppedCount").toInt(), 2); - QTest::qWait(100); - QTRY_COMPARE(root->property("stoppedCount").toInt(), 3); QCOMPARE(root->property("startedCount").toInt(), 3); + QVERIFY(timer.elapsed() >= 200); } void tst_qquickanimations::runningTrueBug() @@ -1352,10 +1356,13 @@ void tst_qquickanimations::alwaysRunToEndRestartBug() animation.stop(); animation.start(); animation.stop(); - QTest::qWait(500); - QVERIFY(rect.x() != qreal(200)); - QTest::qWait(800); - QTIMED_COMPARE(rect.x(), qreal(200)); + + // Waiting for a fixed time here would be dangerous as the starting and stopping itself takes + // time and clocks are unreliable. The only thing we do know is that the animation should + // eventually start and eventually stop. As its duration is 1000ms we can be pretty sure to hit + // an in between state with the 50ms iterations QTRY_VERIFY does. + QTRY_VERIFY(rect.x() != qreal(200)); + QTRY_COMPARE(rect.x(), qreal(200)); QCOMPARE(static_cast(&animation)->qtAnimation()->state(), QAbstractAnimationJob::Stopped); } -- cgit v1.2.3 From 3f1156ee5f6c49e4f8d7881e73760b936975e1b2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 19 Sep 2014 11:59:42 +0200 Subject: qmlplugindump: Use _CrtSetReportMode() for MSVC only. Fix warnings when using MinGW: main.cpp: In function 'int main(int, char**)': main.cpp:734:55: warning: statement has no effect [-Wunused-value] _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); ^ main.cpp:735:53: warning: statement has no effect [-Wunused-value] _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG); ^ main.cpp:736:54: warning: statement has no effect [-Wunused-value] _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); where _CrtSetReportMode() is an empty macro. Change-Id: I644bc207b5a3df62d6390811f53b2c0948979d58 Reviewed-by: Fawzi Mohamed --- tools/qmlplugindump/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 3f38a66da4..b387e4ff6e 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -728,13 +728,13 @@ void printDebugMessage(QtMsgType, const QMessageLogContext &, const QString &msg int main(int argc, char *argv[]) { -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_CC_MINGW) // we do not want windows popping up if the module loaded triggers an assert SetErrorMode(SEM_NOGPFAULTERRORBOX); _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); -#endif +#endif // Q_OS_WIN && !Q_CC_MINGW // The default message handler might not print to console on some systems. Enforce this. qInstallMessageHandler(printDebugMessage); #ifdef Q_OS_UNIX -- cgit v1.2.3 From d0c58e6ad2fa188c96788575b13fede151ab98bd Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 17 Sep 2014 14:57:02 +0200 Subject: Cleanup remaining QtQuick.Dialogs leftovers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QtQuick.Dialogs was moved to the qtquickcontrols module in Qt 5.3 Change-Id: I16d03dc1c342d396963c5bec3125b3d11d0d9bed Reviewed-by: Topi Reiniö --- .gitignore | 1 - src/quick/doc/qtquick.qdocconf | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 3995091983..b0854aab2a 100644 --- a/.gitignore +++ b/.gitignore @@ -105,7 +105,6 @@ tools/activeqt/testcon/testcon.tlb translations/*.qm translations/*_untranslated.ts qrc_*.cpp -src/imports/dialogs/dialogs.qrc # Test generated files QObject.log diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf index b0d1f1e0de..d54e5feecb 100644 --- a/src/quick/doc/qtquick.qdocconf +++ b/src/quick/doc/qtquick.qdocconf @@ -62,9 +62,7 @@ headerdirs += ../../plugins sourcedirs += ../../plugins #exclude certain directories -excludedirs += ../../imports/dialogs \ - ../../imports/models \ - ../../../examples/quick/dialogs +excludedirs += ../../imports/models examples.fileextensions += "*.qm" -- cgit v1.2.3 From 0c17d92cdabda92d345b1c1c968a2a7bbe88aed2 Mon Sep 17 00:00:00 2001 From: Tarja Sundqvist Date: Wed, 17 Sep 2014 15:14:14 +0300 Subject: Update used colors on basis of the recommended color palette. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qtdeclarative/examples/quick/animation uses some colors which are not mentioned on the recommended color palette. They are replaced with recommended colors. Task-number: QTBUG-41368 Change-Id: I6f07340735333c5da319fdc59ecf8aa7388ad2a5 Reviewed-by: Topi Reiniö --- examples/quick/animation/basics/animators.qml | 8 ++++---- examples/quick/animation/basics/color-animation.qml | 14 +++++++------- examples/quick/animation/basics/property-animation.qml | 8 ++++---- examples/quick/animation/behaviors/tvtennis.qml | 18 +++++++++--------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/examples/quick/animation/basics/animators.qml b/examples/quick/animation/basics/animators.qml index 3454eca13c..df1bd55be7 100644 --- a/examples/quick/animation/basics/animators.qml +++ b/examples/quick/animation/basics/animators.qml @@ -48,10 +48,10 @@ Item { Rectangle { anchors.fill: parent gradient: Gradient { - GradientStop { position: 0.0; color: "DeepSkyBlue" } - GradientStop { position: 0.499; color: "LightSkyBlue" } - GradientStop { position: 0.5; color: "ForestGreen" } - GradientStop { position: 1.0; color: "DarkGreen" } + GradientStop { position: 0.0; color: "#14148c" } + GradientStop { position: 0.499; color: "#14aaff" } + GradientStop { position: 0.5; color: "#80c342" } + GradientStop { position: 1.0; color: "#006325" } } } diff --git a/examples/quick/animation/basics/color-animation.qml b/examples/quick/animation/basics/color-animation.qml index 0de4177a9f..a4a149df5c 100644 --- a/examples/quick/animation/basics/color-animation.qml +++ b/examples/quick/animation/basics/color-animation.qml @@ -54,16 +54,16 @@ Item { position: 0.0 SequentialAnimation on color { loops: Animation.Infinite - ColorAnimation { from: "DeepSkyBlue"; to: "#0E1533"; duration: 5000 } - ColorAnimation { from: "#0E1533"; to: "DeepSkyBlue"; duration: 5000 } + ColorAnimation { from: "#14148c"; to: "#0E1533"; duration: 5000 } + ColorAnimation { from: "#0E1533"; to: "#14148c"; duration: 5000 } } } GradientStop { position: 1.0 SequentialAnimation on color { loops: Animation.Infinite - ColorAnimation { from: "SkyBlue"; to: "#437284"; duration: 5000 } - ColorAnimation { from: "#437284"; to: "SkyBlue"; duration: 5000 } + ColorAnimation { from: "#14aaff"; to: "#437284"; duration: 5000 } + ColorAnimation { from: "#437284"; to: "#14aaff"; duration: 5000 } } } } @@ -113,11 +113,11 @@ Item { position: 0.0 SequentialAnimation on color { loops: Animation.Infinite - ColorAnimation { from: "ForestGreen"; to: "#001600"; duration: 5000 } - ColorAnimation { from: "#001600"; to: "ForestGreen"; duration: 5000 } + ColorAnimation { from: "#80c342"; to: "#001600"; duration: 5000 } + ColorAnimation { from: "#001600"; to: "#80c342"; duration: 5000 } } } - GradientStop { position: 1.0; color: "DarkGreen" } + GradientStop { position: 1.0; color: "#006325" } } } } diff --git a/examples/quick/animation/basics/property-animation.qml b/examples/quick/animation/basics/property-animation.qml index ae808ba2fe..d237bb1f87 100644 --- a/examples/quick/animation/basics/property-animation.qml +++ b/examples/quick/animation/basics/property-animation.qml @@ -48,8 +48,8 @@ Item { Rectangle { anchors { left: parent.left; top: parent.top; right: parent.right; bottom: parent.verticalCenter } gradient: Gradient { - GradientStop { position: 0.0; color: "DeepSkyBlue" } - GradientStop { position: 1.0; color: "LightSkyBlue" } + GradientStop { position: 0.0; color: "#14148c" } + GradientStop { position: 1.0; color: "#14aaff" } } } @@ -57,8 +57,8 @@ Item { Rectangle { anchors { left: parent.left; top: parent.verticalCenter; right: parent.right; bottom: parent.bottom } gradient: Gradient { - GradientStop { position: 0.0; color: "ForestGreen" } - GradientStop { position: 1.0; color: "DarkGreen" } + GradientStop { position: 0.0; color: "#80c342" } + GradientStop { position: 1.0; color: "#006325" } } } diff --git a/examples/quick/animation/behaviors/tvtennis.qml b/examples/quick/animation/behaviors/tvtennis.qml index b5ad2e8667..46dd861fc8 100644 --- a/examples/quick/animation/behaviors/tvtennis.qml +++ b/examples/quick/animation/behaviors/tvtennis.qml @@ -43,7 +43,7 @@ import QtQuick 2.0 Rectangle { id: page width: 320; height: 480; - color: "Black" + color: "#1e1b18" // Make a ball to bounce Rectangle { @@ -53,7 +53,7 @@ Rectangle { property variant direction : "right" x: 20; width: 20; height: 20; z: 1 - color: "Lime" + color: "#80c342" // Move the ball to the right and back to the left repeatedly SequentialAnimation on x { @@ -84,7 +84,7 @@ Rectangle { // coordinates of the ball. Rectangle { id: leftBat - color: "Lime" + color: "#328930" x: 2; width: 20; height: 90 // ![0] y: ball.direction == 'left' ? ball.y - 45 : page.height/2 -45; @@ -93,19 +93,19 @@ Rectangle { } Rectangle { id: rightBat - color: "Lime" + color: "#328930" x: page.width - 22; width: 20; height: 90 y: ball.direction == 'right' ? ball.y - 45 : page.height/2 -45; Behavior on y { SpringAnimation{ velocity: 300 } } } // The rest, to make it look realistic, if neither ever scores... - Rectangle { color: "Lime"; x: page.width/2-80; y: 0; width: 40; height: 60 } - Rectangle { color: "Black"; x: page.width/2-70; y: 10; width: 20; height: 40 } - Rectangle { color: "Lime"; x: page.width/2+40; y: 0; width: 40; height: 60 } - Rectangle { color: "Black"; x: page.width/2+50; y: 10; width: 20; height: 40 } + Rectangle { color: "#328930"; x: page.width/2-80; y: 0; width: 40; height: 60 } + Rectangle { color: "#1e1b18"; x: page.width/2-70; y: 10; width: 20; height: 40 } + Rectangle { color: "#328930"; x: page.width/2+40; y: 0; width: 40; height: 60 } + Rectangle { color: "#1e1b18"; x: page.width/2+50; y: 10; width: 20; height: 40 } Repeater { model: page.height / 20 - Rectangle { color: "Lime"; x: page.width/2-5; y: index * 20; width: 10; height: 10 } + Rectangle { color: "#328930"; x: page.width/2-5; y: index * 20; width: 10; height: 10 } } } -- cgit v1.2.3 From a5cb3ca5c058903bcf68fb24d3fdcf1eecb1e5a8 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 16 Sep 2014 12:51:24 +0200 Subject: StocQt example: Display trading volume scale for stock charts Similar to how the example already shows scale of the stock price on the right-hand side margin, this change adds a scale for the trading volume. Large volume values are shortened to a more readable format, using symbols for units of thousand/million/billion etc. Task-number: QTBUG-38254 Change-Id: I068bba1622d2a586a5dd14dddd4b832c8b112d2d Reviewed-by: Venugopal Shivashankar Reviewed-by: Diana de Sousa Reviewed-by: J-P Nurmi --- examples/quick/demos/stocqt/content/StockChart.qml | 24 +++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/examples/quick/demos/stocqt/content/StockChart.qml b/examples/quick/demos/stocqt/content/StockChart.qml index 2b97863f76..625a91e6f9 100644 --- a/examples/quick/demos/stocqt/content/StockChart.qml +++ b/examples/quick/demos/stocqt/content/StockChart.qml @@ -168,7 +168,7 @@ Rectangle { property int pixelSkip: 1 property int numPoints: 1 - property int tickMargin: 32 + property int tickMargin: 34 property real xGridStep: (width - tickMargin) / numPoints property real yGridOffset: height / 26 @@ -214,6 +214,21 @@ Rectangle { ctx.restore(); } + // Returns a shortened, readable version of the potentially + // large volume number. + function volumeToString(value) { + if (value < 1000) + return value; + var exponent = parseInt(Math.log(value) / Math.log(1000)); + var shortVal = parseFloat(parseFloat(value) / Math.pow(1000, exponent)).toFixed(1); + + // Drop the decimal point on 3-digit values to make it fit + if (shortVal >= 100.0) { + shortVal = parseFloat(shortVal).toFixed(0); + } + return shortVal + "KMBTG".charAt(exponent - 1); + } + function drawScales(ctx, high, low, vol) { ctx.save(); @@ -229,8 +244,11 @@ Rectangle { ctx.text(price, x, canvas.yGridOffset + i * yGridStep - 2); } - // highest volume - ctx.text(vol, 0, canvas.yGridOffset + 9 * yGridStep + 12); + // volume scale + for (i = 0; i < 3; i++) { + var volume = volumeToString(vol - (i * (vol/3))); + ctx.text(volume, x, canvas.yGridOffset + (i + 9) * yGridStep + 10); + } ctx.closePath(); ctx.stroke(); -- cgit v1.2.3 From 51a2bd8dfa15f52e2b45b3a0cc0135603a374200 Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Sun, 21 Sep 2014 12:30:24 -0700 Subject: Fix deadlock with QQuickView embedded via QWidget::createWindowContainer A QQuickView embedded in a widget application will be deleted in the QApplication destructor. At that point, events are not being posted, so the QQmlThread cannot properly shut down, and will deadlock waiting for an event. Task-number: QTBUG-36115 Change-Id: I4595f03e0afcf9463cfbc2ba95146d4777d19c56 Reviewed-by: Simon Hausmann --- src/qml/qml/ftw/qqmlthread.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp index 18b257dc0e..b3d7bddff7 100644 --- a/src/qml/qml/ftw/qqmlthread.cpp +++ b/src/qml/qml/ftw/qqmlthread.cpp @@ -139,6 +139,7 @@ void QQmlThreadPrivate::run() q->startupThread(); exec(); + q->shutdownThread(); } void QQmlThreadPrivate::mainEvent() @@ -177,7 +178,6 @@ void QQmlThreadPrivate::threadEvent() quit(); wakeOne(); unlock(); - q->shutdownThread(); return; } else if (!threadList.isEmpty()) { @@ -229,7 +229,14 @@ void QQmlThread::shutdown() Q_ASSERT(!d->m_shutdown); d->m_shutdown = true; if (d->threadList.isEmpty() && d->m_threadProcessing == false) { - d->triggerThreadEvent(); + if (QCoreApplication::closingDown()) { + d->quit(); + d->unlock(); + d->QThread::wait(); + return; + } else { + d->triggerThreadEvent(); + } } else if (d->mainSync) { d->wakeOne(); } -- cgit v1.2.3 From 106900b2058036681a9f6efabc4ea6f76c3f5990 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 22 Sep 2014 16:04:19 +0200 Subject: Window example: setOrientationUpdateMask to allow all orientations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The purpose of showing both orientation and primaryOrientation is to see how they both change when the screen is rotated. Change-Id: I54e51c834c568b1dbd895584b9f80e4b00c8d506 Reviewed-by: Tor Arne Vestbø --- examples/quick/window/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/quick/window/main.cpp b/examples/quick/window/main.cpp index 7872c7183c..953b87e047 100644 --- a/examples/quick/window/main.cpp +++ b/examples/quick/window/main.cpp @@ -39,6 +39,7 @@ ****************************************************************************/ #include +#include #include #include #include @@ -48,6 +49,9 @@ int main(int argc, char* argv[]) { QGuiApplication app(argc, argv); + foreach (QScreen * screen, QGuiApplication::screens()) + screen->setOrientationUpdateMask(Qt::LandscapeOrientation | Qt::PortraitOrientation | + Qt::InvertedLandscapeOrientation | Qt::InvertedPortraitOrientation); QQmlEngine engine; QQmlComponent component(&engine); QQuickWindow::setDefaultAlphaBuffer(true); -- cgit v1.2.3 From 22792559f5bf7a3b4c39481d152acdf414bf5488 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 16 Sep 2014 15:20:53 -0700 Subject: Don't do qgetenv on library load Bad for two reasons: first, it increases the load time of the application and second, it makes it impossible to to setenv/putenv from main(). The latter is useful if you need to work on an embedded device that doesn't allow setting environment variables. Change-Id: Id543f77336d7ac2e4ea820b51f55ce5a40a33b4e Reviewed-by: Gunnar Sletta --- src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 74 ++++++++++++----------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 0a39188b24..ce331cc883 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -63,15 +63,19 @@ extern QByteArray qsgShaderRewriter_insertZAttributes(const char *input, QSurfac namespace QSGBatchRenderer { -const bool debug_render = qgetenv("QSG_RENDERER_DEBUG").contains("render"); -const bool debug_build = qgetenv("QSG_RENDERER_DEBUG").contains("build"); -const bool debug_change = qgetenv("QSG_RENDERER_DEBUG").contains("change"); -const bool debug_upload = qgetenv("QSG_RENDERER_DEBUG").contains("upload"); -const bool debug_roots = qgetenv("QSG_RENDERER_DEBUG").contains("roots"); -const bool debug_dump = qgetenv("QSG_RENDERER_DEBUG").contains("dump"); -const bool debug_noalpha = qgetenv("QSG_RENDERER_DEBUG").contains("noalpha"); -const bool debug_noopaque = qgetenv("QSG_RENDERER_DEBUG").contains("noopaque"); -const bool debug_noclip = qgetenv("QSG_RENDERER_DEBUG").contains("noclip"); +#define DECLARE_DEBUG_VAR(variable) \ + static bool debug_ ## variable() \ + { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; } +DECLARE_DEBUG_VAR(render) +DECLARE_DEBUG_VAR(build) +DECLARE_DEBUG_VAR(change) +DECLARE_DEBUG_VAR(upload) +DECLARE_DEBUG_VAR(roots) +DECLARE_DEBUG_VAR(dump) +DECLARE_DEBUG_VAR(noalpha) +DECLARE_DEBUG_VAR(noopaque) +DECLARE_DEBUG_VAR(noclip) +#undef DECLARE_DEBUG_VAR static QElapsedTimer qsg_renderer_timer; @@ -268,10 +272,10 @@ void Updater::updateStates(QSGNode *n) Node *sn = renderer->m_nodes.value(n, 0); Q_ASSERT(sn); - if (Q_UNLIKELY(debug_roots)) + if (Q_UNLIKELY(debug_roots())) qsg_dumpShadowRoots(sn); - if (Q_UNLIKELY(debug_build)) { + if (Q_UNLIKELY(debug_build())) { qDebug() << "Updater::updateStates()"; if (sn->dirtyState & (QSGNode::DirtyNodeAdded << 16)) qDebug() << " - nodes have been added"; @@ -785,7 +789,7 @@ Renderer::Renderer(QSGRenderContext *ctx) if (ok) m_batchVertexThreshold = threshold; } - if (Q_UNLIKELY(debug_build || debug_render)) { + if (Q_UNLIKELY(debug_build() || debug_render())) { qDebug() << "Batch thresholds: nodes:" << m_batchNodeThreshold << " vertices:" << m_batchVertexThreshold; qDebug() << "Using buffer strategy:" << (m_bufferStrategy == GL_STATIC_DRAW ? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream")); } @@ -1048,7 +1052,7 @@ void Renderer::nodeWasRemoved(Node *node) void Renderer::turnNodeIntoBatchRoot(Node *node) { - if (Q_UNLIKELY(debug_change)) qDebug() << " - new batch root"; + if (Q_UNLIKELY(debug_change())) qDebug() << " - new batch root"; m_rebuild |= FullRebuild; node->isBatchRoot = true; node->becameBatchRoot = true; @@ -1069,7 +1073,7 @@ void Renderer::turnNodeIntoBatchRoot(Node *node) void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state) { - if (Q_UNLIKELY(debug_change)) { + if (Q_UNLIKELY(debug_change())) { QDebug debug = qDebug(); debug << "dirty:"; if (state & QSGNode::DirtyGeometry) @@ -1616,7 +1620,7 @@ void Renderer::prepareAlphaBatches() void Renderer::uploadMergedElement(Element *e, int vaOffset, char **vertexData, char **zData, char **indexData, quint16 *iBase, int *indexCount) { - if (Q_UNLIKELY(debug_upload)) qDebug() << " - uploading element:" << e << e->node << (void *) *vertexData << (qintptr) (*zData - *vertexData) << (qintptr) (*indexData - *vertexData); + if (Q_UNLIKELY(debug_upload())) qDebug() << " - uploading element:" << e << e->node << (void *) *vertexData << (qintptr) (*zData - *vertexData) << (qintptr) (*indexData - *vertexData); QSGGeometry *g = e->node->geometry(); const QMatrix4x4 &localx = *e->node->matrix(); @@ -1689,17 +1693,17 @@ void Renderer::uploadBatch(Batch *b) { // Early out if nothing has changed in this batch.. if (!b->needsUpload) { - if (Q_UNLIKELY(debug_upload)) qDebug() << " Batch:" << b << "already uploaded..."; + if (Q_UNLIKELY(debug_upload())) qDebug() << " Batch:" << b << "already uploaded..."; return; } if (!b->first) { - if (Q_UNLIKELY(debug_upload)) qDebug() << " Batch:" << b << "is invalid..."; + if (Q_UNLIKELY(debug_upload())) qDebug() << " Batch:" << b << "is invalid..."; return; } if (b->isRenderNode) { - if (Q_UNLIKELY(debug_upload)) qDebug() << " Batch: " << b << "is a render node..."; + if (Q_UNLIKELY(debug_upload())) qDebug() << " Batch: " << b << "is a render node..."; return; } @@ -1778,7 +1782,7 @@ void Renderer::uploadBatch(Batch *b) #endif map(&b->vbo, bufferSize); - if (Q_UNLIKELY(debug_upload)) qDebug() << " - batch" << b << " first:" << b->first << " root:" + if (Q_UNLIKELY(debug_upload())) qDebug() << " - batch" << b << " first:" << b->first << " root:" << b->root << " merged:" << b->merged << " positionAttribute" << b->positionAttribute << " vbo:" << b->vbo.id << ":" << b->vbo.size; @@ -1844,7 +1848,7 @@ void Renderer::uploadBatch(Batch *b) } } - if (Q_UNLIKELY(debug_upload)) { + if (Q_UNLIKELY(debug_upload())) { const char *vd = b->vbo.data; qDebug() << " -- Vertex Data, count:" << b->vertexCount << " - " << g->sizeOfVertex() << "bytes/vertex"; for (int i=0; ivertexCount; ++i) { @@ -1902,11 +1906,11 @@ void Renderer::uploadBatch(Batch *b) unmap(&b->ibo, true); #endif - if (Q_UNLIKELY(debug_upload)) qDebug() << " --- vertex/index buffers unmapped, batch upload completed..."; + if (Q_UNLIKELY(debug_upload())) qDebug() << " --- vertex/index buffers unmapped, batch upload completed..."; b->needsUpload = false; - if (Q_UNLIKELY(debug_render)) + if (Q_UNLIKELY(debug_render())) b->uploadedThisFrame = true; } @@ -2038,7 +2042,7 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip) void Renderer::updateClip(const QSGClipNode *clipList, const Batch *batch) { - if (clipList != m_currentClip && Q_LIKELY(!debug_noclip)) { + if (clipList != m_currentClip && Q_LIKELY(!debug_noclip())) { m_currentClip = clipList; // updateClip sets another program, so force-reactivate our own if (m_currentShader) @@ -2117,7 +2121,7 @@ void Renderer::renderMergedBatch(const Batch *batch) Element *e = batch->first; Q_ASSERT(e); - if (Q_UNLIKELY(debug_render)) { + if (Q_UNLIKELY(debug_render())) { QDebug debug = qDebug(); debug << " -" << batch @@ -2226,7 +2230,7 @@ void Renderer::renderUnmergedBatch(const Batch *batch) Element *e = batch->first; Q_ASSERT(e); - if (Q_UNLIKELY(debug_render)) { + if (Q_UNLIKELY(debug_render())) { qDebug() << " -" << batch << (batch->uploadedThisFrame ? "[ upload]" : "[retained]") @@ -2356,7 +2360,7 @@ void Renderer::renderUnmergedBatch(const Batch *batch) void Renderer::renderBatches() { - if (Q_UNLIKELY(debug_render)) { + if (Q_UNLIKELY(debug_render())) { qDebug().nospace() << "Rendering:" << endl << " -> Opaque: " << qsg_countNodesInBatches(m_opaqueBatches) << " nodes in " << m_opaqueBatches.size() << " batches..." << endl << " -> Alpha: " << qsg_countNodesInBatches(m_alphaBatches) << " nodes in " << m_alphaBatches.size() << " batches..."; @@ -2389,8 +2393,8 @@ void Renderer::renderBatches() m_currentProgram = 0; m_currentClip = 0; - bool renderOpaque = !debug_noopaque; - bool renderAlpha = !debug_noalpha; + bool renderOpaque = !debug_noopaque(); + bool renderAlpha = !debug_noalpha(); if (Q_LIKELY(renderOpaque)) { for (int i=0; ifirst->isRenderNode); -- cgit v1.2.3 From 38d37b13a3aae54ef0480150247d96ac9da0247a Mon Sep 17 00:00:00 2001 From: Matt Fischer Date: Wed, 10 Sep 2014 13:34:51 -0500 Subject: Fix clip state tracking in Context2D A recent change (f45fe58ad2aa741c90b756643da75f1a6bc2fdf6) introduced the concept of clipping being disabled for a context, so that it can start with no clip path set. However, this state is not properly tracked, so an attempt to restore a context state which has no clip path does not work properly. This change adds this information to the Clip command, so that it can be properly restored. This patch also re-enables a test case which was supposed to check this behavior, but had been disabled. Task-number: QTBUG-40312 Change-Id: I3fd5626ecfcc1298a81931828cbb590290098a92 Reviewed-by: Ulf Hermann Reviewed-by: Gunnar Sletta --- src/quick/items/context2d/qquickcontext2d.cpp | 6 +++--- src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp | 7 +++++-- src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h | 3 ++- tests/auto/quick/qquickcanvasitem/data/tst_state.qml | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 28c84facb5..d9ac3abdc3 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -3548,7 +3548,7 @@ void QQuickContext2D::clip() state.clip = true; state.clipPath = clipPath; } - buffer()->clip(state.clipPath); + buffer()->clip(state.clip, state.clipPath); } void QQuickContext2D::stroke() @@ -4283,8 +4283,8 @@ void QQuickContext2D::popState() if (newState.miterLimit != state.miterLimit) buffer()->setMiterLimit(newState.miterLimit); - if (newState.clip && (!state.clip || newState.clipPath != state.clipPath)) - buffer()->clip(newState.clipPath); + if (newState.clip != state.clip || newState.clipPath != state.clipPath) + buffer()->clip(newState.clip, newState.clipPath); if (newState.shadowBlur != state.shadowBlur) buffer()->setShadowBlur(newState.shadowBlur); diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp index 9e0a924462..a52f1c8cd2 100644 --- a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp +++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp @@ -207,6 +207,7 @@ void QQuickContext2DCommandBuffer::setPainterState(QPainter* p, const QQuickCont if (state.globalCompositeOperation != p->compositionMode()) p->setCompositionMode(state.globalCompositeOperation); + p->setClipping(state.clip); if (state.clip) p->setClipPath(state.clipPath); } @@ -383,9 +384,11 @@ void QQuickContext2DCommandBuffer::replay(QPainter* p, QQuickContext2D::State& s } case QQuickContext2D::Clip: { + state.clip = takeBool(); state.clipPath = takePath(); - p->setClipping(true); - p->setClipPath(state.clipPath); + p->setClipping(state.clip); + if (state.clip) + p->setClipPath(state.clipPath); break; } case QQuickContext2D::GlobalAlpha: diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h b/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h index 9b2fde33d8..4e6232ac7f 100644 --- a/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h +++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer_p.h @@ -145,9 +145,10 @@ public: pathes << path; } - inline void clip(const QPainterPath& path) + inline void clip(bool enabled, const QPainterPath& path) { commands << QQuickContext2D::Clip; + bools << enabled; pathes << path; } diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_state.qml b/tests/auto/quick/qquickcanvasitem/data/tst_state.qml index 1ceb17b31b..18464def7c 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_state.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_state.qml @@ -30,7 +30,7 @@ CanvasTestCase { ctx.restore(); ctx.fillStyle = '#0f0'; ctx.fillRect(0, 0, 100, 50); - //comparePixel(ctx, 50,25, 0,255,0,255); + comparePixel(ctx, 50,25, 0,255,0,255); canvas.destroy() } function test_fillStyle(row) { -- cgit v1.2.3 From a76985eb05fcb7ecf9b22e5472d439585d4f2075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Fri, 19 Sep 2014 14:31:19 +0100 Subject: Add missing import to documentation code snippet Change-Id: I358b306fb286ffb00d2edd51bc3d97f1884fe34e Reviewed-by: Alan Alpert (Personal) <416365416c@gmail.com> --- src/qml/types/qqmlobjectmodel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp index cdc8f2393f..d2f47c41b2 100644 --- a/src/qml/types/qqmlobjectmodel.cpp +++ b/src/qml/types/qqmlobjectmodel.cpp @@ -138,6 +138,7 @@ public: The example below places three colored rectangles in a ListView. \code import QtQuick 2.0 + import QtQml.Models 2.1 Rectangle { ObjectModel { -- cgit v1.2.3 From edb6976120be9b8ad76b48ecd929f916dcdf216a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 11 Sep 2014 13:04:49 +0200 Subject: Recreate the fbo on screen change in QQuickWidget when needed Move the rendering code out into a separate function since it is now called from three places. Like in QOpenGLWidget, the FBO may need to be recreated with a different size in case the window is moved onto a screen with a different device pixel ratio. Change-Id: Iaaa42a06dab9e02710b0a7dafb0ea8c018b69ec2 Reviewed-by: Gunnar Sletta --- src/quickwidgets/qquickwidget.cpp | 62 +++++++++++++++++++++------------------ src/quickwidgets/qquickwidget_p.h | 1 + 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 7df529c9d9..ef6c174b88 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -200,6 +200,26 @@ void QQuickWidgetPrivate::itemGeometryChanged(QQuickItem *resizeItem, const QRec QQuickItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry); } +void QQuickWidgetPrivate::render(bool needsSync) +{ + context->makeCurrent(offscreenSurface); + + if (needsSync) { + renderControl->polishItems(); + renderControl->sync(); + } + + renderControl->render(); + context->functions()->glFlush(); + + if (resolvedFbo) { + QRect rect(QPoint(0, 0), fbo->size()); + QOpenGLFramebufferObject::blitFramebuffer(resolvedFbo, rect, fbo, rect); + } + + context->doneCurrent(); +} + void QQuickWidgetPrivate::renderSceneGraph() { Q_Q(QQuickWidget); @@ -215,19 +235,8 @@ void QQuickWidgetPrivate::renderSceneGraph() } Q_ASSERT(offscreenSurface); - context->makeCurrent(offscreenSurface); - renderControl->polishItems(); - renderControl->sync(); - renderControl->render(); - context->functions()->glFlush(); - - if (resolvedFbo) { - QRect rect(QPoint(0, 0), fbo->size()); - QOpenGLFramebufferObject::blitFramebuffer(resolvedFbo, rect, fbo, rect); - } - - context->doneCurrent(); - q->update(); + render(true); + q->update(); // schedule composition } QImage QQuickWidgetPrivate::grabFramebuffer() @@ -942,22 +951,7 @@ void QQuickWidget::resizeEvent(QResizeEvent *e) return; } - context->makeCurrent(d->offscreenSurface); - - if (needsSync) { - d->renderControl->polishItems(); - d->renderControl->sync(); - } - - d->renderControl->render(); - context->functions()->glFlush(); - - if (d->resolvedFbo) { - QRect rect(QPoint(0, 0), d->fbo->size()); - QOpenGLFramebufferObject::blitFramebuffer(d->resolvedFbo, rect, d->fbo, rect); - } - - context->doneCurrent(); + d->render(needsSync); } /*! \reimp */ @@ -1104,6 +1098,16 @@ bool QQuickWidget::event(QEvent *e) case QEvent::WindowChangeInternal: d->handleWindowChange(); break; + + case QEvent::ScreenChangeInternal: + if (d->fbo) { + // This will check the size taking the devicePixelRatio into account + // and recreate if needed. + createFramebufferObject(); + d->render(true); + } + break; + default: break; } diff --git a/src/quickwidgets/qquickwidget_p.h b/src/quickwidgets/qquickwidget_p.h index 2289b18d72..2ff9601f77 100644 --- a/src/quickwidgets/qquickwidget_p.h +++ b/src/quickwidgets/qquickwidget_p.h @@ -75,6 +75,7 @@ public: void updateSize(); void updateFrambufferObjectSize(); void setRootObject(QObject *); + void render(bool needsSync); void renderSceneGraph(); void createContext(); void destroyContext(); -- cgit v1.2.3 From d0138bbd479019e0ac402c87144995554950970c Mon Sep 17 00:00:00 2001 From: Venu Date: Mon, 15 Sep 2014 17:02:43 +0200 Subject: Updated the example to accept input on Android MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Android inputMethod doesn't commit the text until a word is chosen from the suggestions list. This makes the URL for XMLHTTPRequest invalid. To avoid the invalid URL, we should either not use predictive text or explicitly commit the text. I choose to go with the earlier option. Task-number: QTBUT-41335 Change-Id: Id03c4dc8cfbd1b32cc2868fe8b78cd039994ff71 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Topi Reiniö --- examples/quick/demos/tweetsearch/content/SearchDelegate.qml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/quick/demos/tweetsearch/content/SearchDelegate.qml b/examples/quick/demos/tweetsearch/content/SearchDelegate.qml index cb0e190fe8..669021a582 100644 --- a/examples/quick/demos/tweetsearch/content/SearchDelegate.qml +++ b/examples/quick/demos/tweetsearch/content/SearchDelegate.qml @@ -113,7 +113,11 @@ FlipBar { hint: flipBar.placeHolder focus: flipBar.opened anchors { fill: parent; margins: 6 } - onAccepted: flipBar.ok() + onAccepted: { + if (Qt.inputMethod.visible) + Qt.inputMethod.hide() + flipBar.ok() + } } } } -- cgit v1.2.3 From cce0e1f9c27683292741310a730e21e36f123ae0 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Fri, 12 Sep 2014 11:01:33 +0200 Subject: Doc: apply title case to all section1 titles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-41250 Change-Id: I303d989992c9685f73baae50c64accf71b43549f Reviewed-by: Topi Reiniö --- examples/qml/doc/src/qml-extending.qdoc | 14 +++++++------- examples/qml/xmlhttprequest/doc/src/xmlhttprequest.qdoc | 2 +- examples/quick/canvas/doc/src/canvas.qdoc | 8 ++++---- .../painteditem/textballoons/doc/src/textballoons.qdoc | 2 +- examples/quick/text/doc/src/text.qdoc | 2 +- src/qml/doc/src/cppintegration/definetypes.qdoc | 2 +- src/qml/doc/src/cppintegration/exposecppattributes.qdoc | 2 +- src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc | 2 +- src/qml/qml/qqmlextensionplugin.cpp | 2 +- src/qml/types/qqmlbind.cpp | 2 +- src/quick/doc/src/concepts/input/focus.qdoc | 2 +- src/quick/doc/src/concepts/positioning/righttoleft.qdoc | 8 ++++---- src/quick/items/context2d/qquickcanvasitem.cpp | 2 +- src/quick/items/qquickgridview.cpp | 2 +- src/quick/items/qquicklistview.cpp | 2 +- 15 files changed, 27 insertions(+), 27 deletions(-) diff --git a/examples/qml/doc/src/qml-extending.qdoc b/examples/qml/doc/src/qml-extending.qdoc index 7dbd147cc1..8f44e4f506 100644 --- a/examples/qml/doc/src/qml-extending.qdoc +++ b/examples/qml/doc/src/qml-extending.qdoc @@ -36,7 +36,7 @@ The \c Person type can be used from QML like this: \snippet referenceexamples/adding/example.qml 0 -\section1 Declare the Person class +\section1 Declare the Person Class All QML types map to C++ types. Here we declare a basic C++ Person class with the two properties we want accessible on the QML type - name and shoeSize. @@ -45,7 +45,7 @@ type, the C++ class can be named differently, or appear in a namespace. \snippet referenceexamples/adding/person.h 0 -\section1 Define the Person class +\section1 Define the Person Class \snippet referenceexamples/adding/person.cpp 0 @@ -56,7 +56,7 @@ The \c main.cpp file also calls the \c qmlRegisterType() function to register the \c Person type with QML as a type in the People library version 1.0, and defines the mapping between the C++ and QML class names. -\section1 Running the example +\section1 Running the Example The main.cpp file in the example includes a simple shell application that loads and runs the QML snippet shown at the beginning of this page. @@ -106,7 +106,7 @@ The implementation of BirthdayParty property accessors is straight forward. \snippet referenceexamples/properties/birthdayparty.cpp 0 -\section1 Running the example +\section1 Running the Example The main.cpp file in the example includes a simple shell application that loads and runs the QML snippet shown at the beginning of this page. @@ -162,7 +162,7 @@ The implementation of Boy and Girl are trivial. All that is necessary is to implement the constructor, and to register the types and their QML name with the QML engine. -\section1 Running the example +\section1 Running the Example The BirthdayParty type has not changed since the previous example. The celebrant and guests property still use the People type. @@ -196,7 +196,7 @@ specification of a BirthdayParty through the use of a default property. \snippet referenceexamples/default/example.qml 0 -\section1 Declaring the BirthdayParty class +\section1 Declaring the BirthdayParty Class The only difference between this example and the last, is the addition of the \c DefaultProperty class info annotation. @@ -209,7 +209,7 @@ property. It is purely a syntactic simplification, the behavior is identical to specifying the property by name, but it can add a more natural feel in many situations. The default property must be either an object or list property. -\section1 Running the example +\section1 Running the Example The main.cpp file in the example includes a simple shell application that loads and runs the QML snippet shown at the beginning of this page. diff --git a/examples/qml/xmlhttprequest/doc/src/xmlhttprequest.qdoc b/examples/qml/xmlhttprequest/doc/src/xmlhttprequest.qdoc index 579cc5f80f..8619c528a9 100644 --- a/examples/qml/xmlhttprequest/doc/src/xmlhttprequest.qdoc +++ b/examples/qml/xmlhttprequest/doc/src/xmlhttprequest.qdoc @@ -36,7 +36,7 @@ \include examples-run.qdocinc - \section1 Get data + \section1 Get Data \e{Get data} uses the XMLHttpRequest API to fetch an XML document from a server. It displays the header of the HTTP response and the body of the XML diff --git a/examples/quick/canvas/doc/src/canvas.qdoc b/examples/quick/canvas/doc/src/canvas.qdoc index 2c4bd1f752..e5138e3f35 100644 --- a/examples/quick/canvas/doc/src/canvas.qdoc +++ b/examples/quick/canvas/doc/src/canvas.qdoc @@ -38,12 +38,12 @@ \include examples-run.qdocinc - \section1 Red heart + \section1 Red Heart \e{Red heart} uses the bezier curve API to stroke and fill a red heart. \snippet canvas/bezierCurve/bezierCurve.qml 0 - \section1 Talk bubble + \section1 Talk Bubble \e{Talk bubble} uses the quadraticCurveTo() API to stroke and fill a customized talk bubble: @@ -57,12 +57,12 @@ \e Squircle uses a collection of simple moveTo() and lineTo() path APIs to draw a smooth squircle. - \section1 Rounded rectangle + \section1 Rounded Rectangle \e{Rounded rectangle} uses a collection of lineTo() and arcTo() path APIs to draw a rounded rectangle. - \section1 Smile face + \section1 Smile Face \e{Smile face} uses several paths to draw and fill a smiling face. diff --git a/examples/quick/painteditem/textballoons/doc/src/textballoons.qdoc b/examples/quick/painteditem/textballoons/doc/src/textballoons.qdoc index cdf4cadf82..d823074b37 100644 --- a/examples/quick/painteditem/textballoons/doc/src/textballoons.qdoc +++ b/examples/quick/painteditem/textballoons/doc/src/textballoons.qdoc @@ -83,7 +83,7 @@ returned by the \l {QQuickPaintedItem::}{contentsBoundingRect()} function is the size of the item as defined in the QML file. - \section1 textballoons.qml file + \section1 Textballoons.qml File The Interface consists of two main parts. The scrollable area with the textballoons and the controls button to add new balloons. diff --git a/examples/quick/text/doc/src/text.qdoc b/examples/quick/text/doc/src/text.qdoc index 8ef79ab9d9..e882ba3535 100644 --- a/examples/quick/text/doc/src/text.qdoc +++ b/examples/quick/text/doc/src/text.qdoc @@ -73,7 +73,7 @@ \e Banner is a simple example showing how to create a banner using a row of text types and a \l NumberAnimation. - \section1 Img tag + \section1 Img Tag \e{Img tag} shows different ways of displaying images in text objects using the \c{} tag. diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc index 6aed2f1339..03607df2e5 100644 --- a/src/qml/doc/src/cppintegration/definetypes.qdoc +++ b/src/qml/doc/src/cppintegration/definetypes.qdoc @@ -47,7 +47,7 @@ features such as \e{attached properties} and \e{default properties} in C++. demonstrated in the \l{Writing QML Extensions with C++} tutorial.) -\section1 Registering C++ types with the QML type system +\section1 Registering C++ Types with the QML Type System A QObject-derived class can be registered with the QML type system to enable the type to be used as a data type from within QML code. diff --git a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc index 8f6836558a..9527229204 100644 --- a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc +++ b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc @@ -359,7 +359,7 @@ implementation, whereas an object-type property can be freely created and destroyed through QML code. -\section1 Exposing Methods (including Qt Slots) +\section1 Exposing Methods (Including Qt Slots) Any method of a QObject-derived type is accessible from QML code if it is: diff --git a/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc index 16e36f6f6d..1a154e5d5a 100644 --- a/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc +++ b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc @@ -646,7 +646,7 @@ property is only invoked when the property is reassigned to a different object v This basic type is provided by the QML language. Some enumeration values are provided by the QtQuick import. - \section1 Using the enumeration type in QML + \section1 Using the enumeration Type in QML The \c enumeration type is a representation of a C++ \c enum type. It is not possible to refer to the \c enumeration type in QML itself; instead, the diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp index d84a7804f4..e48224333c 100644 --- a/src/qml/qml/qqmlextensionplugin.cpp +++ b/src/qml/qml/qqmlextensionplugin.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE or other issues in the library user's code. - \section1 An example + \section1 An Example Suppose there is a new \c TimeModel C++ class that should be made available as a new QML element. It provides the current time through \c hour and \c minute diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp index 602e5cf14e..9ba610b9ba 100644 --- a/src/qml/types/qqmlbind.cpp +++ b/src/qml/types/qqmlbind.cpp @@ -72,7 +72,7 @@ public: \ingroup qtquick-interceptors \brief Enables the arbitrary creation of property bindings - \section1 Binding to an inaccessible property + \section1 Binding to an Inaccessible Property Sometimes it is necessary to bind to a property of an object that wasn't directly instantiated by QML - generally a property of a class exported diff --git a/src/quick/doc/src/concepts/input/focus.qdoc b/src/quick/doc/src/concepts/input/focus.qdoc index 065651c826..748c8eb53c 100644 --- a/src/quick/doc/src/concepts/input/focus.qdoc +++ b/src/quick/doc/src/concepts/input/focus.qdoc @@ -172,7 +172,7 @@ See \l{Qt Quick Examples - Key Interaction} for a demonstration of moving keyboard focus between multiple areas using FocusScope types. -\section1 Advanced uses of Focus Scopes +\section1 Advanced Uses of Focus Scopes Focus scopes allow focus to allocation to be easily partitioned. Several QML items use it to this effect. diff --git a/src/quick/doc/src/concepts/positioning/righttoleft.qdoc b/src/quick/doc/src/concepts/positioning/righttoleft.qdoc index 8f55cc8dd7..d6b1753ee3 100644 --- a/src/quick/doc/src/concepts/positioning/righttoleft.qdoc +++ b/src/quick/doc/src/concepts/positioning/righttoleft.qdoc @@ -69,7 +69,7 @@ the effective alignment of the text element that takes the mirroring into accoun \snippet qml/righttoleft.qml 0 -\section1 Layout direction of positioners and views +\section1 Layout Direction of Positioners and Views (This applies to the \l Row, \l Grid, \l Flow, \l ListView and \l GridView types.) @@ -85,7 +85,7 @@ views that takes the mirroring into account can be read from the \c effectiveLay \snippet qml/righttoleft.qml 1 -\section1 Layout mirroring +\section1 Layout Mirroring The attached property \l LayoutMirroring is provided as a convenience for easily implementing right-to-left support for existing left-to-right Qt Quick applications. It mirrors the behavior of \l {anchor-layout} @@ -127,7 +127,7 @@ the animations and transitions continue to work as expected. If you do not have right-to-left support for your application, it may be better to just keep the application layouts left aligned and just make sure that text is translated and aligned properly. -\section1 Mirroring icons +\section1 Mirroring Icons (This applies to \l Image, \l BorderImage and \l AnimatedImage types.) @@ -136,7 +136,7 @@ The painting of these icons can be mirrored with a dedicated \c mirror property \snippet qml/righttoleft.qml 5 -\section1 Default layout direction +\section1 Default Layout Direction The \l {QtQml::Qt::application}{Qt.application.layoutDirection} property can be used to query the active layout direction of the application. It is based on QGuiApplication::layoutDirection(), which most commonly determines the layout diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 587ba6591d..77a405907e 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -275,7 +275,7 @@ QQuickCanvasItemPrivate::~QQuickCanvasItemPrivate() \l{http://en.wikipedia.org/wiki/Screen_tearing}{screen tearing}) which will further impact pixel operations with \c Canvas.FrambufferObject render target. - \section1 Tips for Porting Existing HTML5 Canvas applications + \section1 Tips for Porting Existing HTML5 Canvas Applications Although the Canvas item is provides a HTML5 like API, HTML5 canvas applications need to be modified to run in the Canvas item: diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index 502c3edfe2..72edce4339 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -1173,7 +1173,7 @@ bool QQuickGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte fully outside the view. - \section1 GridView layouts + \section1 GridView Layouts The layout of the items in a GridView can be controlled by these properties: diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 9a56d47221..d381fe2030 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -1742,7 +1742,7 @@ bool QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte nicely. - \section1 ListView layouts + \section1 ListView Layouts The layout of the items in a ListView can be controlled by these properties: -- cgit v1.2.3 From d2d0bfe830330f30913973a79c080d3cc5b00a21 Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Fri, 19 Sep 2014 11:46:44 +0200 Subject: Fix disappearing slider during size/orientation change Now the slider remains at a position that is equivalent to the old position based on the previous percentage. This change is most commonly triggered during orientation changes on mobile device. That is the reason why the app was converted to a proper Qt project. This way it was possible to test this behavior on Android. Task-number: QTBUG-18423 Change-Id: If05e6a1e42249f90a821c4882021d28cf212fc52 Reviewed-by: Simon Hausmann --- .../quick/customitems/dialcontrol/dialcontrol.pro | 11 ++++++ .../quick/customitems/dialcontrol/dialcontrol.qml | 19 ++++++++-- .../quick/customitems/dialcontrol/dialcontrol.qrc | 12 +++++++ examples/quick/customitems/dialcontrol/main.cpp | 41 ++++++++++++++++++++++ 4 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 examples/quick/customitems/dialcontrol/dialcontrol.pro create mode 100644 examples/quick/customitems/dialcontrol/dialcontrol.qrc create mode 100644 examples/quick/customitems/dialcontrol/main.cpp diff --git a/examples/quick/customitems/dialcontrol/dialcontrol.pro b/examples/quick/customitems/dialcontrol/dialcontrol.pro new file mode 100644 index 0000000000..ceb8e239dc --- /dev/null +++ b/examples/quick/customitems/dialcontrol/dialcontrol.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = dialcontrol + +QT += quick qml + +SOURCES += main.cpp + +RESOURCES += dialcontrol.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/quick/customitems/dialcontrol +INSTALLS += target diff --git a/examples/quick/customitems/dialcontrol/dialcontrol.qml b/examples/quick/customitems/dialcontrol/dialcontrol.qml index f545877655..0bf6d7e68c 100644 --- a/examples/quick/customitems/dialcontrol/dialcontrol.qml +++ b/examples/quick/customitems/dialcontrol/dialcontrol.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the examples of the Qt Toolkit. @@ -39,7 +39,8 @@ ****************************************************************************/ //! [imports] -import QtQuick 2.0 +import QtQuick 2.2 +import QtQuick.Window 2.1 import "content" //! [imports] @@ -53,12 +54,13 @@ Rectangle { Dial { id: dial anchors.centerIn: parent - value: slider.x * 100 / (container.width - 34) + value: slider.x * 100 / (container.width - 32) } //! [the dial in use] Rectangle { id: container + property int oldWidth: 0 anchors { bottom: parent.bottom; left: parent.left right: parent.right; leftMargin: 20; rightMargin: 20 bottomMargin: 10 @@ -73,6 +75,17 @@ Rectangle { GradientStop { position: 1.0; color: "white" } } + onWidthChanged: { + if (oldWidth === 0) { + oldWidth = width; + return + } + + var desiredPercent = slider.x * 100 / (oldWidth - 32) + slider.x = desiredPercent * (width - 32) / 100 + oldWidth = width + } + Rectangle { id: slider x: 1; y: 1; width: 30; height: 14 diff --git a/examples/quick/customitems/dialcontrol/dialcontrol.qrc b/examples/quick/customitems/dialcontrol/dialcontrol.qrc new file mode 100644 index 0000000000..6433d68bb8 --- /dev/null +++ b/examples/quick/customitems/dialcontrol/dialcontrol.qrc @@ -0,0 +1,12 @@ + + + dialcontrol.qml + content/background.png + content/Dial.qml + content/needle_shadow.png + content/needle.png + content/overlay.png + content/quit.png + content/QuitButton.qml + + diff --git a/examples/quick/customitems/dialcontrol/main.cpp b/examples/quick/customitems/dialcontrol/main.cpp new file mode 100644 index 0000000000..c72251cde7 --- /dev/null +++ b/examples/quick/customitems/dialcontrol/main.cpp @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "../../shared/shared.h" +DECLARATIVE_EXAMPLE_MAIN(dialcontrol) -- cgit v1.2.3 From ef8e2cd85d380ee9f19cb6642c11e9f7c9fc3a7d Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 22 Sep 2014 14:09:41 +0200 Subject: Allow multiple cached qml unit registration functions Only few will be necessary, but this allows for greater flexibility at run-time. Change-Id: Ia03abeb6296a5dee97544209c578dc2974af7cbc Reviewed-by: Lars Knoll --- src/qml/qml/qqmlmetatype.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index c09ab69424..d20fe72d09 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -98,7 +98,7 @@ struct QQmlMetaTypeData QBitArray lists; QList parentFunctions; - QQmlPrivate::QmlUnitCacheLookupFunction lookupCachedQmlUnit; + QVector lookupCachedQmlUnit; QSet protectedNamespaces; @@ -135,7 +135,6 @@ static uint qHash(const QQmlMetaTypeData::VersionedUri &v) } QQmlMetaTypeData::QQmlMetaTypeData() - : lookupCachedQmlUnit(0) { } @@ -1347,7 +1346,7 @@ int registerQmlUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &hookRe qFatal("qmlRegisterType(): Cannot mix incompatible QML versions."); QWriteLocker lock(metaTypeDataLock()); QQmlMetaTypeData *data = metaTypeData(); - data->lookupCachedQmlUnit = hookRegistration.lookupCachedQmlUnit; + data->lookupCachedQmlUnit << hookRegistration.lookupCachedQmlUnit; return 0; } @@ -1877,8 +1876,11 @@ const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(const { QReadLocker lock(metaTypeDataLock()); QQmlMetaTypeData *data = metaTypeData(); - if (data->lookupCachedQmlUnit) - return data->lookupCachedQmlUnit(uri); + for (QVector::ConstIterator it = data->lookupCachedQmlUnit.constBegin(), end = data->lookupCachedQmlUnit.constEnd(); + it != end; ++it) { + if (const QQmlPrivate::CachedQmlUnit *unit = (*it)(uri)) + return unit; + } return 0; } -- cgit v1.2.3 From 37c52cf6453a91127bcf54f1506fe7eaffd563ad Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 24 Sep 2014 12:27:21 +0200 Subject: Cleanup: Simplify CompiledData::Unit structure to always include the string table at the end Change-Id: Iae86b8f4dc0dc67c14974472f627e28d6795369f Reviewed-by: Lars Knoll --- src/qml/compiler/qqmlirbuilder.cpp | 6 +++++- src/qml/compiler/qv4compileddata.cpp | 2 +- src/qml/compiler/qv4compiler.cpp | 25 +++++++++++++++---------- src/qml/compiler/qv4compiler_p.h | 9 +++++++-- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index d22116fc83..a96fafac9b 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1523,7 +1523,7 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output) objectsSize += signalTableSize; } - const int totalSize = unitSize + importSize + objectOffsetTableSize + objectsSize; + const int totalSize = unitSize + importSize + objectOffsetTableSize + objectsSize + output.jsGenerator.stringTable.sizeOfTableAndData(); char *data = (char*)malloc(totalSize); memcpy(data, jsUnit, unitSize); if (jsUnit != compilationUnit->data) @@ -1539,6 +1539,8 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output) qmlUnit->offsetToObjects = unitSize + importSize; qmlUnit->nObjects = output.objects.count(); qmlUnit->indexOfRootObject = output.indexOfRootObject; + qmlUnit->offsetToStringTable = totalSize - output.jsGenerator.stringTable.sizeOfTableAndData(); + qmlUnit->stringTableSize = output.jsGenerator.stringTable.stringCount(); // write imports char *importPtr = data + qmlUnit->offsetToImports; @@ -1630,6 +1632,8 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output) } } + output.jsGenerator.stringTable.serialize(qmlUnit); + return qmlUnit; } diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index a5530e167d..d242fb7b3a 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -181,7 +181,7 @@ void CompilationUnit::markObjects(QV4::ExecutionEngine *e) Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument) { - return irDocument->jsGenerator.generateUnit(); + return irDocument->jsGenerator.generateUnit(QV4::Compiler::JSUnitGenerator::GenerateWithoutStringTable); } QString Binding::valueAsString(const Unit *unit) const diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index d6f0bc8335..22107c4bd1 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -66,8 +66,11 @@ void QV4::Compiler::StringTableGenerator::clear() stringDataSize = 0; } -void QV4::Compiler::StringTableGenerator::serialize(uint *stringTable, char *dataStart, char *stringData) +void QV4::Compiler::StringTableGenerator::serialize(CompiledData::Unit *unit) { + char *dataStart = reinterpret_cast(unit); + uint *stringTable = reinterpret_cast(dataStart + unit->offsetToStringTable); + char *stringData = dataStart + unit->offsetToStringTable + unit->stringTableSize * sizeof(uint); for (int i = 0; i < strings.size(); ++i) { stringTable[i] = stringData - dataStart; const QString &qstr = strings.at(i); @@ -190,7 +193,7 @@ int QV4::Compiler::JSUnitGenerator::registerJSClass(int count, IR::ExprList *arg return jsClasses.size() - 1; } -QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit() +QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorOption option) { registerString(irModule->fileName); foreach (QV4::IR::Function *f, irModule->functions) { @@ -214,7 +217,7 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit() functionDataSize += QV4::CompiledData::Function::calculateSize(f->formals.size(), f->locals.size(), f->nestedFunctions.size(), qmlIdDepsCount, qmlPropertyDepsCount); } - const int totalSize = unitSize + functionDataSize + jsClassDataSize + stringTable.sizeOfTableAndData(); + const int totalSize = unitSize + functionDataSize + jsClassDataSize + (option == GenerateWithStringTable ? stringTable.sizeOfTableAndData() : 0); char *data = (char *)malloc(totalSize); memset(data, 0, totalSize); QV4::CompiledData::Unit *unit = (QV4::CompiledData::Unit*)data; @@ -234,8 +237,13 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit() unit->offsetToConstantTable = unit->offsetToRegexpTable + unit->regexpTableSize * CompiledData::RegExp::calculateSize(); unit->jsClassTableSize = jsClasses.count(); unit->offsetToJSClassTable = unit->offsetToConstantTable + unit->constantTableSize * sizeof(ReturnedValue); - unit->stringTableSize = stringTable.stringCount(); - unit->offsetToStringTable = unitSize + functionDataSize + jsClassDataSize; + if (option == GenerateWithStringTable) { + unit->stringTableSize = stringTable.stringCount(); + unit->offsetToStringTable = unitSize + functionDataSize + jsClassDataSize; + } else { + unit->stringTableSize = 0; + unit->offsetToStringTable = 0; + } unit->indexOfRootFunction = -1; unit->sourceFileIndex = getStringId(irModule->fileName); unit->nImports = 0; @@ -287,11 +295,8 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit() } // write strings and string table - { - uint *stringTablePtr = (uint *)(data + unit->offsetToStringTable); - char *string = data + unit->offsetToStringTable + unit->stringTableSize * sizeof(uint); - stringTable.serialize(stringTablePtr, data, string); - } + if (option == GenerateWithStringTable) + stringTable.serialize(unit); return unit; } diff --git a/src/qml/compiler/qv4compiler_p.h b/src/qml/compiler/qv4compiler_p.h index 109998dc33..7b349caaf8 100644 --- a/src/qml/compiler/qv4compiler_p.h +++ b/src/qml/compiler/qv4compiler_p.h @@ -63,7 +63,7 @@ struct Q_QML_PRIVATE_EXPORT StringTableGenerator { void clear(); - void serialize(uint *stringTable, char *dataStart, char *stringData); + void serialize(CompiledData::Unit *unit); private: QHash stringToId; @@ -90,7 +90,12 @@ struct Q_QML_PRIVATE_EXPORT JSUnitGenerator { int registerJSClass(int count, IR::ExprList *args); - QV4::CompiledData::Unit *generateUnit(); + enum GeneratorOption { + GenerateWithStringTable, + GenerateWithoutStringTable + }; + + QV4::CompiledData::Unit *generateUnit(GeneratorOption option = GenerateWithStringTable); // Returns bytes written int writeFunction(char *f, int index, IR::Function *irFunction); -- cgit v1.2.3 From c2706491906c053f5d38ddc0558a993bbf7cfd3e Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 19 Sep 2014 09:52:25 +0200 Subject: Fix cleanup of non-threaded render loops. They would unconditionally call cleanupNodesOnShutdown on hide(), but QQuickWindow::sceneGraphInvalidated would only be emitted if this was the last window being hidden, leading to an inconsistent state in the application. Since the non-threaded render loops do not support releasing resources (there is one OpenGL context and one QSGRenderContext shared between all windows) we delay cleanup until the window is destroyed. This change also make the render loops track the windows until they are destroyed, similar to what the threaded one does. The purpose of this is to, in the case of dangling windows, only trigger invalidation of the scene graph when the last QQuickWindow is destroyed through QSGRenderLoop::cleanup(). Task-number: QTBUG-41210 Change-Id: I7e12a4f726ebb3e7935c822b6046abb3590c583a Reviewed-by: Ulf Hermann Reviewed-by: Laszlo Agocs --- src/quick/scenegraph/qsgrenderloop.cpp | 25 +++-------- src/quick/scenegraph/qsgwindowsrenderloop.cpp | 48 ++++++++-------------- tests/auto/quick/qquickwindow/tst_qquickwindow.cpp | 30 +++++++++----- 3 files changed, 42 insertions(+), 61 deletions(-) diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 720d9a6fd1..cd92d12d43 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -265,37 +265,24 @@ void QSGGuiThreadRenderLoop::show(QQuickWindow *window) void QSGGuiThreadRenderLoop::hide(QQuickWindow *window) { - if (!m_windows.contains(window)) - return; - - m_windows.remove(window); QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window); - if (gl) - gl->makeCurrent(window); cd->fireAboutToStop(); - cd->cleanupNodesOnShutdown(); - - if (m_windows.size() == 0) { - if (!cd->persistentSceneGraph) { - rc->invalidate(); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - if (!cd->persistentGLContext) { - delete gl; - gl = 0; - } - } - } } void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window) { + m_windows.remove(window); hide(window); + QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); + if (gl) + gl->makeCurrent(window); + d->cleanupNodesOnShutdown(); if (m_windows.size() == 0) { rc->invalidate(); QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); delete gl; gl = 0; - } else if (window == gl->surface()) { + } else if (gl && window == gl->surface()) { gl->doneCurrent(); } } diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index de1160064d..10eba74607 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -185,14 +185,6 @@ void QSGWindowsRenderLoop::show(QQuickWindow *window) void QSGWindowsRenderLoop::hide(QQuickWindow *window) { RLDEBUG("hide"); - - for (int i=0; iisExposed()) handleObscurity(); - if (!m_gl) return; - - QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window); - m_gl->makeCurrent(window); - cd->fireAboutToStop(); - cd->cleanupNodesOnShutdown(); - - // If this is the last tracked window, check for persistent SG and GL and - // potentially clean up. - if (m_windows.size() == 0) { - if (!cd->persistentSceneGraph) { - QQuickWindowPrivate::get(window)->context->invalidate(); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - if (!cd->persistentGLContext) { - delete m_gl; - m_gl = 0; - } - } - } + QQuickWindowPrivate::get(window)->fireAboutToStop(); } void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window) { RLDEBUG("windowDestroyed"); + for (int i=0; imakeCurrent(window); + d->cleanupNodesOnShutdown(); if (m_windows.size() == 0) { - QQuickWindowPrivate::get(window)->context->invalidate(); + d->context->invalidate(); QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); delete m_gl; m_gl = 0; + } else if (m_gl) { + m_gl->doneCurrent(); } } bool QSGWindowsRenderLoop::anyoneShowing() const { foreach (const WindowData &wd, m_windows) - if (wd.window->isExposed() && wd.window->size().isValid()) + if (wd.window->isVisible() && wd.window->isExposed() && wd.window->size().isValid()) return true; return false; } @@ -251,7 +237,7 @@ void QSGWindowsRenderLoop::exposureChanged(QQuickWindow *window) if (windowData(window) == 0) return; - if (window->isExposed()) { + if (window->isExposed() && window->isVisible()) { // Stop non-visual animation timer as we now have a window rendering if (m_animationTimer && anyoneShowing()) { diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index aecd28f44b..dfb1ac5bfe 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -1188,6 +1188,7 @@ void tst_qquickwindow::headless() QVERIFY(QTest::qWaitForWindowExposed(window)); QVERIFY(window->isVisible()); + bool threaded = window->openglContext()->thread() != QThread::currentThread(); QSignalSpy initialized(window, SIGNAL(sceneGraphInitialized())); QSignalSpy invalidated(window, SIGNAL(sceneGraphInvalidated())); @@ -1202,8 +1203,10 @@ void tst_qquickwindow::headless() window->hide(); window->releaseResources(); - QTRY_COMPARE(invalidated.size(), 1); - QVERIFY(window->openglContext() == 0); + if (threaded) { + QTRY_COMPARE(invalidated.size(), 1); + QVERIFY(window->openglContext() == 0); + } // Destroy the native windowing system buffers window->destroy(); @@ -1213,7 +1216,8 @@ void tst_qquickwindow::headless() window->show(); QVERIFY(QTest::qWaitForWindowExposed(window)); - QTRY_COMPARE(initialized.size(), 1); + if (threaded) + QTRY_COMPARE(initialized.size(), 1); QVERIFY(window->openglContext() != 0); // Verify that the visual output is the same @@ -1536,6 +1540,7 @@ void tst_qquickwindow::hideThenDelete() QSignalSpy *openglDestroyed = 0; QSignalSpy *sgInvalidated = 0; + bool threaded = false; { QQuickWindow window; @@ -1548,6 +1553,7 @@ void tst_qquickwindow::hideThenDelete() window.show(); QTest::qWaitForWindowExposed(&window); + threaded = window.openglContext()->thread() != QThread::currentThread(); openglDestroyed = new QSignalSpy(window.openglContext(), SIGNAL(aboutToBeDestroyed())); sgInvalidated = new QSignalSpy(&window, SIGNAL(sceneGraphInvalidated())); @@ -1556,15 +1562,17 @@ void tst_qquickwindow::hideThenDelete() QTRY_VERIFY(!window.isExposed()); - if (!persistentSG) { - QVERIFY(sgInvalidated->size() > 0); - if (!persistentGL) - QVERIFY(openglDestroyed->size() > 0); - else + if (threaded) { + if (!persistentSG) { + QVERIFY(sgInvalidated->size() > 0); + if (!persistentGL) + QVERIFY(openglDestroyed->size() > 0); + else + QVERIFY(openglDestroyed->size() == 0); + } else { + QVERIFY(sgInvalidated->size() == 0); QVERIFY(openglDestroyed->size() == 0); - } else { - QVERIFY(sgInvalidated->size() == 0); - QVERIFY(openglDestroyed->size() == 0); + } } } -- cgit v1.2.3 From 5b21f8529ebc8e3e66ec6d057734f90b10bb7657 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 10 Sep 2014 15:27:58 +0200 Subject: move QQuickWindowAttached to QQuickWindowQmlImpl It causes problems to do qmlRegisterType on QQuickWindow if the attached property also refers to QQuickWindow. Task-number: QTBUG-40816 Task-number: QTBUG-41047 Change-Id: I7a6f75af52f65e2be022b97128702982bec7cbe8 Reviewed-by: J-P Nurmi --- src/quick/items/qquickwindow.cpp | 5 ----- src/quick/items/qquickwindow.h | 3 --- src/quick/items/qquickwindowmodule.cpp | 11 +++++++---- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index c522eff0a1..24b8e042df 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -3905,11 +3905,6 @@ void QQuickWindow::scheduleRenderJob(QRunnable *job, RenderStage stage) d->renderJobMutex.unlock(); } -QQuickWindowAttached *QQuickWindow::qmlAttachedProperties(QObject *object) -{ - return new QQuickWindowAttached(object); -} - void QQuickWindowPrivate::runAndClearJobs(QList *jobs) { renderJobMutex.lock(); diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index 7547d76ae9..b52d6b807e 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -142,8 +142,6 @@ public: void scheduleRenderJob(QRunnable *job, RenderStage schedule); - static QQuickWindowAttached *qmlAttachedProperties(QObject *object); - Q_SIGNALS: void frameSwapped(); Q_REVISION(2) void openglContextCreated(QOpenGLContext *context); @@ -208,7 +206,6 @@ private: QT_END_NAMESPACE Q_DECLARE_METATYPE(QQuickWindow *) -QML_DECLARE_TYPEINFO(QQuickWindow, QML_HAS_ATTACHED_PROPERTIES) #endif // QQUICKWINDOW_H diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index b0c99782f2..371abd163b 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -79,6 +79,11 @@ public: QQuickWindow::setVisibility(visibility); } + static QQuickWindowAttached *qmlAttachedProperties(QObject *object) + { + return new QQuickWindowAttached(object); + } + Q_SIGNALS: void visibleChanged(bool arg); void visibilityChanged(QWindow::Visibility visibility); @@ -166,16 +171,13 @@ void QQuickWindowModule::defineModule() { const char uri[] = "QtQuick.Window"; - // Since Window is both an attached property and a createable type, - // the attached property declaration must come first so that it can - // be overridden below. - qmlRegisterUncreatableType(uri, 2, 2, "Window", QQuickWindow::tr("Window is available via attached properties")); qmlRegisterType(uri, 2, 0, "Window"); qmlRegisterRevision(uri, 2, 1); qmlRegisterRevision(uri, 2, 2); qmlRegisterRevision(uri, 2, 1);//Type moved to a subclass, but also has new members qmlRegisterRevision(uri, 2, 2); qmlRegisterType(uri, 2, 1, "Window"); + qmlRegisterType(uri, 2, 2, "Window"); qmlRegisterUncreatableType(uri, 2, 0, "Screen", QStringLiteral("Screen can only be used via the attached property.")); } @@ -183,3 +185,4 @@ void QQuickWindowModule::defineModule() QT_END_NAMESPACE +QML_DECLARE_TYPEINFO(QQuickWindowQmlImpl, QML_HAS_ATTACHED_PROPERTIES) -- cgit v1.2.3 From 40f76f99469e75d7a6818306891964e5966d0fad Mon Sep 17 00:00:00 2001 From: Sebastian Sauer Date: Thu, 18 Sep 2014 00:10:40 +0700 Subject: QDSM: Nested statemachines are supported * Remove wrongly printed info that nested statemachines are not supported. * Added autotest for nested statemachines. * Re-enable commented out testcase in the nestedInitalStates autotest. The reason why the test was disabled was fixed a while ago. Change-Id: I921483fa49d751d14c877f8f63335fa88cf2ce7b Reviewed-by: Brett Stottlemyer Reviewed-by: Simon Hausmann --- src/imports/statemachine/childrenprivate.h | 6 -- .../statemachine/tst_nestedinitialstates.qml | 3 +- .../statemachine/tst_nestedstatemachine.qml | 71 ++++++++++++++++++++++ 3 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 tests/auto/qmltest/statemachine/tst_nestedstatemachine.qml diff --git a/src/imports/statemachine/childrenprivate.h b/src/imports/statemachine/childrenprivate.h index 5e2d60e299..d66454ca1c 100644 --- a/src/imports/statemachine/childrenprivate.h +++ b/src/imports/statemachine/childrenprivate.h @@ -51,9 +51,6 @@ public: { QAbstractState *state = qobject_cast(item); if (state) { - if (qobject_cast(item)) - qmlInfo(static_cast(prop->object)) << "StateMachines should not be nested."; - item->setParent(prop->object); } else { QAbstractTransition *trans = qobject_cast(item); @@ -68,9 +65,6 @@ public: { QAbstractState *state = qobject_cast(item); if (state) { - if (qobject_cast(item)) - qmlInfo(static_cast(prop->object)) << "StateMachines should not be nested."; - item->setParent(prop->object); } static_cast*>(prop->data)->children.append(item); diff --git a/tests/auto/qmltest/statemachine/tst_nestedinitialstates.qml b/tests/auto/qmltest/statemachine/tst_nestedinitialstates.qml index dc13481bf9..2906de2986 100644 --- a/tests/auto/qmltest/statemachine/tst_nestedinitialstates.qml +++ b/tests/auto/qmltest/statemachine/tst_nestedinitialstates.qml @@ -52,8 +52,7 @@ TestCase { name: "nestedInitalStates" function test_nestedInitalStates() { - // uncomment me after vm problems are fixed. - // compare(myStateMachine.running, false); + compare(myStateMachine.running, false); compare(parentState.active, false); compare(childState1.active, false); compare(childState2.active, false); diff --git a/tests/auto/qmltest/statemachine/tst_nestedstatemachine.qml b/tests/auto/qmltest/statemachine/tst_nestedstatemachine.qml new file mode 100644 index 0000000000..41a2c2a852 --- /dev/null +++ b/tests/auto/qmltest/statemachine/tst_nestedstatemachine.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Ford Motor Company +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQml.StateMachine 1.0 +import QtTest 1.0 + +TestCase { + StateMachine { + id: myStateMachine + initialState: parentState + StateBase { + id: parentState + initialState: childStateMachine + StateMachine { + id: childStateMachine + initialState: childState2 + StateBase { + id: childState1 + } + StateBase { + id: childState2 + } + } + } + } + name: "nestedStateMachine" + + function test_nestedStateMachine() { + compare(myStateMachine.running, false); + compare(parentState.active, false); + compare(childStateMachine.running, false); + compare(childState1.active, false); + compare(childState2.active, false); + myStateMachine.start(); + tryCompare(myStateMachine, "running", true); + tryCompare(parentState, "active", true); + tryCompare(childStateMachine, "running", true); + tryCompare(childState1, "active", false); + tryCompare(childState2, "active", true); + } +} -- cgit v1.2.3 From b160c9906d7b31e5de446c9db17ebc2baa7c4ea2 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 25 Sep 2014 09:02:13 +0200 Subject: Reset 'invalidatePending' after the FBO has been recreated. If not, we will always request a new FBO during updatePaintNode, even when the fbo is not following the items size. Task-number: QTBUG-41565 Change-Id: I20b4b3a8e3630ff963a876320808869bba62fb8a Reviewed-by: Laszlo Agocs --- src/quick/items/qquickframebufferobject.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp index da1709f055..dc4668be3f 100644 --- a/src/quick/items/qquickframebufferobject.cpp +++ b/src/quick/items/qquickframebufferobject.cpp @@ -254,6 +254,7 @@ QSGNode *QQuickFramebufferObject::updatePaintNode(QSGNode *node, UpdatePaintNode n->fbo = 0; delete n->msDisplayFbo; n->msDisplayFbo = 0; + n->invalidatePending = false; } } -- cgit v1.2.3 From 6641214214213f079176b81e9a98d63cf21bfd3c Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 19 Sep 2014 15:00:11 +0200 Subject: Doc: Add docs for Clocks example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I626376ae2a169f7d892e86309754633e9ed6a6e9 Reviewed-by: Topi Reiniö --- examples/quick/demos/clocks/doc/src/clocks.qdoc | 92 ++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/examples/quick/demos/clocks/doc/src/clocks.qdoc b/examples/quick/demos/clocks/doc/src/clocks.qdoc index b57894c5d3..1118984a7d 100644 --- a/examples/quick/demos/clocks/doc/src/clocks.qdoc +++ b/examples/quick/demos/clocks/doc/src/clocks.qdoc @@ -29,13 +29,99 @@ \title Qt Quick Demo - Clocks \ingroup qtquickdemos \example demos/clocks - \brief A QML application that shows the current time in different cities. + \brief A QML clock application that demonstrates using a ListView type to + display data generated by a ListModel and a SpringAnimation type to animate + images. \image qtquick-demo-clocks-small.png - \e Clocks demonstrates various QML and \l{Qt Quick} features such as - displaying custom components. + \e Clocks demonstrates using a ListView type to display data generated by a + ListModel. The delegate used by the model is specified as a custom QML type + that is specified in the Clock.qml file. + + JavaScript methods are used to fetch the current time in several cities in + different time zones and QML types are used to display the time on a clock + face with animated clock hands. \include examples-run.qdocinc + \section1 Displaying Data Generated by List Models + + In the clocks.qml file, we use a \l Rectangle type to create the application + main window: + + \quotefromfile demos/clocks/clocks.qml + \skipto Rectangle + \printuntil color + + We use a ListView type to display a list of the items provided by a + ListModel type: + + \printuntil Los Angeles + \printuntil } + \printuntil } + + List elements are defined like other QML types except that they contain a + collection of \e role definitions instead of properties. Roles both define + how the data is accessed and include the data itself. + + For each list element, we use the \c cityName role to specify the name of a + city and the \c timeShift role to specify a time zone as a positive or + negative offset from UTC (coordinated universal time). + + The Clock custom type is used as the ListView's \c delegate, defining the + visual appearance of list items. To use the Clock type, we add an import + statement that imports the folder called \c content where the type is + located: + + \quotefromfile demos/clocks/clocks.qml + \skipto content + \printuntil " + + We use an \l Image type to display arrows that indicate whether users can + flick the view to see more clocks on the left or right: + + \quotefromfile demos/clocks/clocks.qml + \skipto Image + \printuntil /^\}/ + + We use the \c opacity property to hide the arrows when the list view is + located at the beginning or end of the x axis. + + In Clock.qml, we define a \c timeChanged() function in which we use + methods from the JavaScript \c Date object to fetch the current time in + UTC and to adjust it to the correct time zone: + + \quotefromfile demos/clocks/content/Clock.qml + \skipto timeChanged + \printuntil } + + We use a \l Timer type to update the time at intervals of 100 milliseconds: + + \printuntil } + + We use \l Image types within an \l Item type to display the time on an + analog clock face. Different images are used for daytime and nighttime + hours: + + \printuntil clock-night.png + + A \l Rotation transform applied to \l Image types provides a way to rotate + the clock hands. The \c origin property holds the point that stays fixed + relative to the parent as the rest of the item rotates. The \c angle + property determines the angle to rotate the hands in degrees clockwise. + + \printuntil center.png + \printuntil } + + We use a \l Behavior type on the \c angle property to apply a + SpringAnimation when the time changes. The \c spring and \c damping + properties enable the spring-like motion of the clock hands, and a + \c modulus of \c 360 makes the animation target values wrap around at a + full circle. + + We use a \l Text type to display the city name below the clock: + + \printuntil } + \sa {QML Applications} */ -- cgit v1.2.3 From da217ce941e1f4bde594cf97221f953b106cb15a Mon Sep 17 00:00:00 2001 From: Johanna Aijala Date: Tue, 16 Sep 2014 15:14:16 +0300 Subject: Updated calqlatr demo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes and finetuning of calqlatr demo: - fixed text overlapping, changed max length of a number from 14 to 9 - fixed app "freeze" after entering number of maximum length - implemented +/- operator functionality - fixed listview scrolling, after multiple operations listview was scrolling only when entering '=' leaving the active line hidden when the numbers and operator were typed - added support for entering numbers and certain operators from keyboard - removed commented code Task-number: QTBUG-38818 Change-Id: Ic0ecd2dff68a89007421e95a5bdc3ab7ca2e401d Reviewed-by: Topi Reiniö --- examples/quick/demos/calqlatr/calqlatr.qml | 37 ++++++++++++++++++++++ examples/quick/demos/calqlatr/content/Button.qml | 7 ---- examples/quick/demos/calqlatr/content/Display.qml | 2 ++ .../quick/demos/calqlatr/content/calculator.js | 23 +++++++++----- 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/examples/quick/demos/calqlatr/calqlatr.qml b/examples/quick/demos/calqlatr/calqlatr.qml index 5f0ebe85a8..02c5b13399 100644 --- a/examples/quick/demos/calqlatr/calqlatr.qml +++ b/examples/quick/demos/calqlatr/calqlatr.qml @@ -75,6 +75,43 @@ Rectangle { } } + Keys.onPressed: { + if (event.key == Qt.Key_0) + digitPressed("0") + else if (event.key == Qt.Key_1) + digitPressed("1") + else if (event.key == Qt.Key_2) + digitPressed("2") + else if (event.key == Qt.Key_3) + digitPressed("3") + else if (event.key == Qt.Key_4) + digitPressed("4") + else if (event.key == Qt.Key_5) + digitPressed("5") + else if (event.key == Qt.Key_6) + digitPressed("6") + else if (event.key == Qt.Key_7) + digitPressed("7") + else if (event.key == Qt.Key_8) + digitPressed("8") + else if (event.key == Qt.Key_9) + digitPressed("9") + else if (event.key == Qt.Key_Plus) + operatorPressed("+") + else if (event.key == Qt.Key_Minus) + operatorPressed("−") + else if (event.key == Qt.Key_Asterisk) + operatorPressed("×") + else if (event.key == Qt.Key_Slash) + operatorPressed("÷") + else if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) + operatorPressed("=") + else if (event.key == Qt.Key_Comma || event.key == Qt.Key_Period) + digitPressed(".") + else if (event.key == Qt.Key_Backspace) + operatorPressed("backspace") + } + Display { id: display x: -16 diff --git a/examples/quick/demos/calqlatr/content/Button.qml b/examples/quick/demos/calqlatr/content/Button.qml index 3f28e6f3c0..fc6234414f 100644 --- a/examples/quick/demos/calqlatr/content/Button.qml +++ b/examples/quick/demos/calqlatr/content/Button.qml @@ -59,18 +59,11 @@ Item { color: "white" } -// Rectangle { -// color: "red" -// opacity: 0.2 -// anchors.fill: mouse -// } - MouseArea { id: mouse anchors.fill: parent anchors.margins: -5 onClicked: { - //parent.clicked() if (operator) window.operatorPressed(parent.text) else diff --git a/examples/quick/demos/calqlatr/content/Display.qml b/examples/quick/demos/calqlatr/content/Display.qml index ec8edfea66..97eed1e57e 100644 --- a/examples/quick/demos/calqlatr/content/Display.qml +++ b/examples/quick/demos/calqlatr/content/Display.qml @@ -48,6 +48,7 @@ Item { { listView.model.append({ "operator": operator, "operand": "" }) enteringDigits = true + listView.positionViewAtEnd() } function newLine(operator, operand) @@ -64,6 +65,7 @@ Item { var i = listView.model.count - 1; listView.model.get(i).operand = listView.model.get(i).operand + digit; enteringDigits = true + listView.positionViewAtEnd() } function clear() diff --git a/examples/quick/demos/calqlatr/content/calculator.js b/examples/quick/demos/calqlatr/content/calculator.js index da8e940b16..906cb9d3b7 100644 --- a/examples/quick/demos/calqlatr/content/calculator.js +++ b/examples/quick/demos/calqlatr/content/calculator.js @@ -59,7 +59,7 @@ function digitPressed(op) { if (disabled(op)) return - if (digits.toString().length >= 14) + if (digits.toString().length >= 8) return if (lastOp.toString().length == 1 && ((lastOp >= "0" && lastOp <= "9") || lastOp == ".") ) { digits = digits + op.toString() @@ -80,7 +80,7 @@ function operatorPressed(op) if (previousOperator == "+") { digits = Number(digits.valueOf()) + Number(curVal.valueOf()) } else if (previousOperator == "−") { - digits = Number(curVal) - Number(digits.valueOf()) + digits = Number(curVal.valueOf()) - Number(digits.valueOf()) } else if (previousOperator == "×") { digits = Number(curVal) * Number(digits.valueOf()) } else if (previousOperator == "÷") { @@ -91,11 +91,15 @@ function operatorPressed(op) if (op == "+" || op == "−" || op == "×" || op == "÷") { previousOperator = op curVal = digits.valueOf() + digits = "" display.displayOperator(previousOperator) return } if (op == "=") { + if (digits.toString().length >= 9) + digits = digits.toExponential(2) + display.newLine("=", digits.toString()) } @@ -112,6 +116,8 @@ function operatorPressed(op) digits = (Math.floor(digits.valueOf())).toString() } else if (op == "±") { digits = (digits.valueOf() * -1).toString() + display.clear() + display.appendDigit(digits) } else if (op == "√") { digits = (Math.sqrt(digits.valueOf())).toString() } else if (op == "mc") { @@ -122,22 +128,23 @@ function operatorPressed(op) digits = memory.toString() } else if (op == "m-") { memory = digits.valueOf() - } else if (op == window.leftArrow) { + } else if (op == "backspace") { digits = digits.toString().slice(0, -1) - if (digits.length == 0) { - digits = "0" - } + display.clear() + display.appendDigit(digits) } else if (op == "Off") { Qt.quit(); } else if (op == "C") { display.clear() + curVal = 0 + memory = 0 + lastOp = "" + digits ="0" } else if (op == "AC") { curVal = 0 memory = 0 lastOp = "" digits ="0" } - - } -- cgit v1.2.3 From be22466c8b54645adda216c55438d16b54321a1a Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Mon, 15 Sep 2014 13:36:12 +0200 Subject: Doc: Replace VisualDataModel with DelegateModel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-37725 Change-Id: Iad3b31470af8ea965d19b3d0901822b901407d40 Reviewed-by: Venugopal Shivashankar Reviewed-by: Topi Reiniö --- .../doc/src/concepts/modelviewsdata/cppmodels.qdoc | 8 ++--- src/quick/doc/src/dynamicview-tutorial.qdoc | 34 +++++++++++----------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc b/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc index 49e4998ee1..dcc7a592e6 100644 --- a/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc +++ b/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc @@ -146,14 +146,14 @@ within the Qt install directory. QAbstractItemModel presents a hierarchy of tables, but the views currently provided by QML can only display list data. In order to display the child lists of a hierarchical model, -use the VisualDataModel type, which provides the following properties and functions to be used +use the DelegateModel QML type, which provides the following properties and functions to be used with list models of QAbstractItemModel type: \list \li \e hasModelChildren role property to determine whether a node has child nodes. -\li \l VisualDataModel::rootIndex allows the root node to be specified -\li \l VisualDataModel::modelIndex() returns a QModelIndex which can be assigned to VisualDataModel::rootIndex -\li \l VisualDataModel::parentModelIndex() returns a QModelIndex which can be assigned to VisualDataModel::rootIndex +\li \l DelegateModel::rootIndex allows the root node to be specified +\li \l DelegateModel::modelIndex() returns a QModelIndex which can be assigned to DelegateModel::rootIndex +\li \l DelegateModel::parentModelIndex() returns a QModelIndex which can be assigned to DelegateModel::rootIndex \endlist \section2 Exposing C++ Data Models to QML diff --git a/src/quick/doc/src/dynamicview-tutorial.qdoc b/src/quick/doc/src/dynamicview-tutorial.qdoc index cf1115cf4a..619f0abd4b 100644 --- a/src/quick/doc/src/dynamicview-tutorial.qdoc +++ b/src/quick/doc/src/dynamicview-tutorial.qdoc @@ -136,7 +136,7 @@ so that is above other items in the stacking order and isn't obscured as it is d The next step in our application to move items within the list as they're dragged so that we can re-order the list. To achieve this we introduce three new types to our application; -VisualDataModel, \l Drag and DropArea. +DelegateModel, \l Drag and DropArea. \snippet tutorials/dynamicview/dynamicview3/dynamicview.qml 0 \snippet tutorials/dynamicview/dynamicview3/dynamicview.qml 1 @@ -162,17 +162,17 @@ to the index of the item it was dragged over. \snippet tutorials/dynamicview/dynamicview3/dynamicview.qml 3 -To move the items within the view we use a VisualDataModel. The VisualDataModel type is used by +To move the items within the view we use a DelegateModel. The DelegateModel type is used by the view types to instantiate delegate items from model data and when constructed explicitly can be used to filter and re-order the model items provided to ListView. The -\l {QtQuick::VisualDataModel::items}{items} property of VisualDataModel provides access to the +\l {QtQuick::DelegateModel::items}{items} property of DelegateModel provides access to the view's items and allows us to change the visible order without modifying the source model. To -determine the current visible index of the items we use \l {QtQuick::VisualDataModel::itemsIndex} -{itemsIndex} property on the VisualDataModel attached property of the delegate item. +determine the current visible index of the items we use \l {QtQuick::DelegateModel::itemsIndex} +{itemsIndex} property on the DelegateModel attached property of the delegate item. -To utilize a VisualDataModel with a ListView we bind it to the \l {QtQuick::ListView::model}{model} -property of the view and bind the \l {QtQuick::VisualDataModel::model}{model} and -\l {QtQuick::VisualDataModel::delegate}{delegate} to the VisualDataModel. +To utilize a DelegateModel with a ListView we bind it to the \l {QtQuick::ListView::model}{model} +property of the view and bind the \l {QtQuick::DelegateModel::model}{model} and +\l {QtQuick::DelegateModel::delegate}{delegate} to the DelegateModel. \snippet tutorials/dynamicview/dynamicview3/dynamicview.qml 4 @@ -185,16 +185,16 @@ property of the view and bind the \l {QtQuick::VisualDataModel::model}{model} an \example tutorials/dynamicview/dynamicview4 -Drag and drop isn't the only way items in a view can be re-ordered, using a VisualDataModel it is -also possible to sort items based on model data. To do that we extend our VisualDataModel instance +Drag and drop isn't the only way items in a view can be re-ordered, using a DelegateModel it is +also possible to sort items based on model data. To do that we extend our DelegateModel instance like this: \snippet tutorials/dynamicview/dynamicview4/dynamicview.qml 0 \section2 Walkthrough -Items in a VisualDataModel are filtered into groups represented by the VisualDataGroup type, -normally all items in the model belong to a default \l {QtQuick::VisualDataModel::items}{items} +Items in a DelegateModel are filtered into groups represented by the DelegateModelGroup type, +normally all items in the model belong to a default \l {QtQuick::DelegateModel::items}{items} group but this default can be changed with the includeByDefault property. To implement our sorting we want items to first be added to an unsorted group from where we can transfer them to a sorted position in the items group. To do that we clear includeByDefault on the items group and set it on @@ -208,7 +208,7 @@ item and then transfer the item to the items group before moving it to the pre-d repeat until the unsorted group is empty. To find the insert position for an item we request a handle for the item from the unsorted group -with the \l {QtQuick::VisualDataModel::get} {get} function. Through the model property on this +with the \l {QtQuick::DelegateModel::get} {get} function. Through the model property on this handle we can access the same model data that is available in a delegate instance of that item and compare against other items to determine relative position. @@ -219,8 +219,8 @@ of the list. In this example it can be one of the following: \snippet tutorials/dynamicview/dynamicview4/dynamicview.qml 4 -A sort is triggered whenever new items are added to the unsorted VisualDataGroup which we are -notified of by the \l {QtQuick::VisualDataGroup::onChanged}{onChanged} handler. If no sort +A sort is triggered whenever new items are added to the unsorted DelegateModel which we are +notified of by the \l {QtQuick::DelegateModelGroup::onChanged}{onChanged} handler. If no sort function is currently selected we simply transfer all items from the unsorted group to the items group, otherwise we call sort with the selected sort function. @@ -228,8 +228,8 @@ group, otherwise we call sort with the selected sort function. Finally when the selected sort order changes we can trigger a full re-sort of the list by moving all items from the items group to the unsorted group, which will trigger the -\l {QtQuick::VisualDataGroup::onChanged}{onChanged} handler and transfer the items back to the -items group in correct order. Note that the \l {QtQuick::VisualDataGroup::onChanged}{onChanged} +\l {QtQuick::DelegateModelGroup::onChanged}{onChanged} handler and transfer the items back to the +items group in correct order. Note that the \l {QtQuick::DelegateModelGroup::onChanged}{onChanged} handler will not be invoked recursively so there's no issue with it being invoked during a sort. \snippet tutorials/dynamicview/dynamicview4/dynamicview.qml 6 -- cgit v1.2.3 From 26387cf498843ce10dd4411d538e1e44a823b8a8 Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Thu, 18 Sep 2014 22:40:09 +0200 Subject: qmlimportscanner: allow a qmlFile to come from stdin Change-Id: I22b0e45a8aa25d232791cdbeca15b5bc7400ae7d Reviewed-by: Thomas Hartmann --- tools/qmlimportscanner/main.cpp | 42 +++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp index ac4f6ae437..102b5ada6e 100644 --- a/tools/qmlimportscanner/main.cpp +++ b/tools/qmlimportscanner/main.cpp @@ -194,16 +194,8 @@ QVariantList findPathsForModuleImports(const QVariantList &imports) } // Scan a single qml file for import statements -QVariantList findQmlImportsInQmlFile(const QString &filePath) +static QVariantList findQmlImportsInQmlCode(const QString &filePath, const QString &code) { - QFile file(filePath); - if (!file.open(QIODevice::ReadOnly)) { - std::cerr << "Cannot open input file " << QDir::toNativeSeparators(file.fileName()).toStdString() - << ':' << file.errorString().toStdString() << std::endl; - return QVariantList(); - } - QString code = QString::fromUtf8(file.readAll()); - QQmlJS::Engine engine; QQmlJS::Lexer lexer(&engine); lexer.setCode(code, /*line = */ 1); @@ -212,12 +204,25 @@ QVariantList findQmlImportsInQmlFile(const QString &filePath) if (!parser.parse() || !parser.diagnosticMessages().isEmpty()) { // Extract errors from the parser foreach (const QQmlJS::DiagnosticMessage &m, parser.diagnosticMessages()) { - std::cerr << QDir::toNativeSeparators(file.fileName()).toStdString() << ':' + std::cerr << QDir::toNativeSeparators(filePath).toStdString() << ':' << m.loc.startLine << ':' << m.message.toStdString() << std::endl; } return QVariantList(); } - return findImportsInAst(parser.ast()->headers, code, file.fileName()); + return findImportsInAst(parser.ast()->headers, code, filePath); +} + +// Scan a single qml file for import statements +static QVariantList findQmlImportsInQmlFile(const QString &filePath) +{ + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) { + std::cerr << "Cannot open input file " << QDir::toNativeSeparators(file.fileName()).toStdString() + << ':' << file.errorString().toStdString() << std::endl; + return QVariantList(); + } + QString code = QString::fromUtf8(file.readAll()); + return findQmlImportsInQmlCode(filePath, code); } // Scan a single javascrupt file for import statements @@ -272,10 +277,15 @@ QVariantList findQmlImportsInJavascriptFile(const QString &filePath) QVariantList findQmlImportsInFile(const QString &filePath) { QVariantList imports; - if (filePath.endsWith(QStringLiteral(".qml"))) - imports = findQmlImportsInQmlFile(filePath); - else if (filePath.endsWith(QStringLiteral(".js"))) + if (filePath == QLatin1String("-")) { + QFile f; + if (f.open(stdin, QIODevice::ReadOnly)) + imports = findQmlImportsInQmlCode(QLatin1String(""), QString::fromUtf8(f.readAll())); + } else if (filePath.endsWith(QStringLiteral(".qml"))) { + imports = findQmlImportsInQmlFile(filePath); + } else if (filePath.endsWith(QStringLiteral(".js"))) { imports = findQmlImportsInJavascriptFile(filePath); + } return findPathsForModuleImports(imports); } @@ -390,7 +400,7 @@ int main(int argc, char *argv[]) const QString &arg = args.at(i); ++i; QStringList *argReceiver = 0; - if (!arg.startsWith(QLatin1Char('-'))) { + if (!arg.startsWith(QLatin1Char('-')) || arg == QLatin1String("-")) { qmlRootPaths += arg; } else if (arg == QLatin1String("-rootPath")) { if (i >= args.count()) @@ -415,7 +425,7 @@ int main(int argc, char *argv[]) while (i < args.count()) { const QString arg = args.at(i); - if (arg.startsWith(QLatin1Char('-'))) + if (arg.startsWith(QLatin1Char('-')) && arg != QLatin1String("-")) break; ++i; *argReceiver += arg; -- cgit v1.2.3 From 2bd7438d77c8544d263c51be432206970eae5ccf Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Sun, 28 Sep 2014 12:26:55 +0200 Subject: Give Item::layer documentation some much needed love. Change-Id: I31e038d961d3aa09a36db0c091c4e4910e395c2e Reviewed-by: Laszlo Agocs --- src/quick/doc/images/qml-blending-layered.png | Bin 0 -> 7582 bytes src/quick/doc/images/qml-blending-nonlayered.png | Bin 0 -> 7707 bytes .../doc/images/qml-shadereffect-layereffect.png | Bin 0 -> 22264 bytes .../doc/images/qml-shadereffect-nolayereffect.png | Bin 0 -> 26718 bytes .../doc/images/qml-shadereffect-opacitymask.png | Bin 0 -> 15661 bytes src/quick/doc/snippets/qml/layerblending.qml | 111 ++++++++++++++++++++ src/quick/doc/snippets/qml/layerwitheffect.qml | 111 ++++++++++++++++++++ src/quick/doc/snippets/qml/opacitymask.qml | 114 +++++++++++++++++++++ src/quick/items/qquickitem.cpp | 102 +++++++++++++++++- src/quick/items/qquickshadereffect.cpp | 24 +++++ 10 files changed, 460 insertions(+), 2 deletions(-) create mode 100644 src/quick/doc/images/qml-blending-layered.png create mode 100644 src/quick/doc/images/qml-blending-nonlayered.png create mode 100644 src/quick/doc/images/qml-shadereffect-layereffect.png create mode 100644 src/quick/doc/images/qml-shadereffect-nolayereffect.png create mode 100644 src/quick/doc/images/qml-shadereffect-opacitymask.png create mode 100644 src/quick/doc/snippets/qml/layerblending.qml create mode 100644 src/quick/doc/snippets/qml/layerwitheffect.qml create mode 100644 src/quick/doc/snippets/qml/opacitymask.qml diff --git a/src/quick/doc/images/qml-blending-layered.png b/src/quick/doc/images/qml-blending-layered.png new file mode 100644 index 0000000000..fa1c24a98e Binary files /dev/null and b/src/quick/doc/images/qml-blending-layered.png differ diff --git a/src/quick/doc/images/qml-blending-nonlayered.png b/src/quick/doc/images/qml-blending-nonlayered.png new file mode 100644 index 0000000000..265abf6530 Binary files /dev/null and b/src/quick/doc/images/qml-blending-nonlayered.png differ diff --git a/src/quick/doc/images/qml-shadereffect-layereffect.png b/src/quick/doc/images/qml-shadereffect-layereffect.png new file mode 100644 index 0000000000..44b05a9949 Binary files /dev/null and b/src/quick/doc/images/qml-shadereffect-layereffect.png differ diff --git a/src/quick/doc/images/qml-shadereffect-nolayereffect.png b/src/quick/doc/images/qml-shadereffect-nolayereffect.png new file mode 100644 index 0000000000..f21e3f0c4e Binary files /dev/null and b/src/quick/doc/images/qml-shadereffect-nolayereffect.png differ diff --git a/src/quick/doc/images/qml-shadereffect-opacitymask.png b/src/quick/doc/images/qml-shadereffect-opacitymask.png new file mode 100644 index 0000000000..e056aa763b Binary files /dev/null and b/src/quick/doc/images/qml-shadereffect-opacitymask.png differ diff --git a/src/quick/doc/snippets/qml/layerblending.qml b/src/quick/doc/snippets/qml/layerblending.qml new file mode 100644 index 0000000000..0ef23465a5 --- /dev/null +++ b/src/quick/doc/snippets/qml/layerblending.qml @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Gunnar Sletta +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + width: 300 + height: 200 + + // The checkers background + ShaderEffect { + id: tileBackground + anchors.fill: parent + + property real tileSize: 10 + property color color1: Qt.rgba(0.9, 0.9, 0.9, 1); + property color color2: Qt.rgba(0.85, 0.85, 0.85, 1); + + property size pixelSize: Qt.size(width / tileSize, height / tileSize); + + fragmentShader: + " + uniform lowp vec4 color1; + uniform lowp vec4 color2; + uniform highp vec2 pixelSize; + varying highp vec2 qt_TexCoord0; + void main() { + highp vec2 tc = sign(sin(3.14152 * qt_TexCoord0 * pixelSize)); + if (tc.x != tc.y) + gl_FragColor = color1; + else + gl_FragColor = color2; + } + " + } + + + Row { + height: 100 + anchors.centerIn: parent + spacing: 50 + +//! [non-layered] +Item { + id: nonLayered + + opacity: 0.5 + + width: 100 + height: 100 + + Rectangle { width: 80; height: 80; border.width: 1 } + Rectangle { x: 20; y: 20; width: 80; height: 80; border.width: 1 } +} +//! [non-layered] + +//! [layered] +Item { + id: layered + + opacity: 0.5 + + layer.enabled: true + + width: 100 + height: 100 + + Rectangle { width: 80; height: 80; border.width: 1 } + Rectangle { x: 20; y: 20; width: 80; height: 80; border.width: 1 } +} +//! [layered] + + } +} diff --git a/src/quick/doc/snippets/qml/layerwitheffect.qml b/src/quick/doc/snippets/qml/layerwitheffect.qml new file mode 100644 index 0000000000..8cfac0bb19 --- /dev/null +++ b/src/quick/doc/snippets/qml/layerwitheffect.qml @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Gunnar Sletta +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 + +Rectangle { + id: root + width: 320 + height: 320 + + gradient: Gradient { + GradientStop { position: 0; color: "steelblue" } + GradientStop { position: 1; color: "black" } + } + + property real cx: width / 2; + property real cy: height / 2; + property real boxSize: root.width * 0.2; + property real radius: width / 4; + + +//! [1] +Item { + id: layerRoot + layer.enabled: true + layer.effect: ShaderEffect { + fragmentShader: " + uniform lowp sampler2D source; // this item + uniform lowp float qt_Opacity; // inherited opacity of this item + varying highp vec2 qt_TexCoord0; + void main() { + lowp vec4 p = texture2D(source, qt_TexCoord0); + lowp float g = dot(p.xyz, vec3(0.344, 0.5, 0.156)); + gl_FragColor = vec4(g, g, g, p.a) * qt_Opacity; + }" + } +//! [1] + + anchors.fill: parent + + + Repeater { + id: repeater + model: 200 + + Rectangle { + id: box + + property real t: index / (repeater.model - 1); + + width: 0 + height: 0 + x: root.cx - Math.sin(Math.PI * 2 * t) * root.radius; + y: root.cy - Math.cos(Math.PI * 2 * t) * root.radius; + + Rectangle { + width: root.boxSize + height: root.boxSize + anchors.centerIn: parent + color: Qt.hsla(box.t, 0.5, 0.5); + border.color: "white" + antialiasing: true; + rotation: box.t * 360; +// RotationAnimator on rotation { +// from: box.t * 360; +// to: box.t * 360 + 360; +// duration: 7592; +// loops: Animation.Infinite +// } + } + } + } + } +} diff --git a/src/quick/doc/snippets/qml/opacitymask.qml b/src/quick/doc/snippets/qml/opacitymask.qml new file mode 100644 index 0000000000..e458f810ea --- /dev/null +++ b/src/quick/doc/snippets/qml/opacitymask.qml @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Gunnar Sletta +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: root + width: 480 + height: 320 + + // The checkers background + ShaderEffect { + id: tileBackground + anchors.fill: parent + + property real tileSize: 20 + property color color1: Qt.hsla(0, 0, 0.1); + property color color2: Qt.hsla(0, 0, 0.2); + + property size pixelSize: Qt.size(width / tileSize, height / tileSize); + + fragmentShader: + " + uniform lowp vec4 color1; + uniform lowp vec4 color2; + uniform highp vec2 pixelSize; + varying highp vec2 qt_TexCoord0; + void main() { + highp vec2 tc = sign(sin(3.14152 * qt_TexCoord0 * pixelSize)); + if (tc.x != tc.y) + gl_FragColor = color1; + else + gl_FragColor = color2; + } + " + } + +//! [1] + Rectangle { + id: gradientRect; + width: 10 + height: 10 + gradient: Gradient { + GradientStop { position: 0; color: "white" } + GradientStop { position: 1; color: "steelblue" } + } + visible: false; // should not be visible on screen. + layer.enabled: true; + layer.smooth: true + } + + Text { + id: textItem + font.pixelSize: 48 + text: "Gradient Text" + anchors.centerIn: parent + layer.enabled: true + // This item should be used as the 'mask' + layer.samplerName: "maskSource" + layer.effect: ShaderEffect { + property var colorSource: gradientRect; + fragmentShader: " + uniform lowp sampler2D colorSource; + uniform lowp sampler2D maskSource; + uniform lowp float qt_Opacity; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = + texture2D(colorSource, qt_TexCoord0) + * texture2D(maskSource, qt_TexCoord0).a + * qt_Opacity; + } + " + } + } +//! [1] +} diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 38ae0ed3c8..b8362c9dac 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -1838,6 +1838,101 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus) their layouts. See LayoutMirroring for more details. + + \section1 Item Layers + + An Item will normally be rendered directly into the window it + belongs to. However, by setting \l layer.enabled, it is possible + to delegate the item and its entire subtree into an offscreen + surface. Only the offscreen surface, a texture, will be then drawn + into the window. + + If it is desired to have a texture size different from that of the + item, this is possible using \l layer.textureSize. To render only + a section of the item into the texture, use \l + layer.sourceRect. It is also possible to specify \l + layer.sourceRect so it extends beyond the bounds of the item. In + this case, the exterior will be padded with transparent pixels. + + The item will use linear interpolation for scaling if + \l layer.smooth is set to \c true and will use mipmap for + downsampling if \l layer.mipmap is set to \c true. Mipmapping may + improve visual quality of downscaled items. For mipmapping of + single Image items, prefer Image::mipmap. + + \section2 Layer Opacity vs Item Opacity + + When applying \l opacity to an item hierarchy the opacity is + applied to each item individually. This can lead to undesired + visual results when the opacity is applied to a subtree. Consider + the following example: + + \table + \row + \li \inlineimage qml-blending-nonlayered.png + \li \b {Non-layered Opacity} \snippet qml/layerblending.qml non-layered + \endtable + + A layer is rendered with the root item's opacity being 1, and then + the root item's opacity is applied to the texture when it is + drawn. This means that fading in a large item hierarchy from + transparent to opaque, or vice versa, can be done without the + overlap artifacts that the normal item by item alpha blending + has. Here is the same example with layer enabled: + + \table + \row + \li \image qml-blending-layered.png + \li \b {Layered Opacity} \snippet qml/layerblending.qml layered + \endtable + + \section2 Combined with ShaderEffects + + Setting \l layer.enabled to true will turn the item into a \l + {QQuickItem::isTextureProvider}{texture provider}, making it + possible to use the item directly as a texture, for instance + in combination with the ShaderEffect type. + + It is possible to apply an effect on a layer at runtime using + layer.effect: + + \snippet qml/layerwitheffect.qml 1 + + In this example, we implement the shader effect manually. The \l + {Qt Graphical Effects} module contains a suite of ready-made + effects for use with Qt Quick. + + See ShaderEffect for more information about using effects. + + \note \l layer.enabled is actually just a more convenient way of using + ShaderEffectSource. + + + \section2 Memory and Performance + + When an item's layer is enabled, the scene graph will allocate memory + in the GPU equal to \c {width x height x 4}. In memory constrained + configurations, large layers should be used with care. + + In the QPainter / QWidget world, it is some times favorable to + cache complex content in a pixmap, image or texture. In Qt Quick, + because of the techniques already applied by the \l {Qt Quick + Scene Graph Renderer} {scene graph renderer}, this will in most + cases not be the case. Excessive draw calls are already reduced + because of batching and a cache will in most cases end up blending + more pixels than the original content. The overhead of rendering + to an offscreen and the blending involved with drawing the + resulting texture is therefore often more costly than simply + letting the item and its children be drawn normally. + + Also, an item using a layer can not be \l {Batching} {batched} during + rendering. This means that a scene with many layered items may + have performance problems. + + Layering can be convenient and useful for visual effects, but + should in most cases be enabled for the duration of the effect and + disabled afterwards. + */ /*! @@ -7486,12 +7581,15 @@ void QQuickItemLayer::setMipmap(bool mipmap) allow you to save some texture memory. \list - \li ShaderEffectSource.Alpha - GL_ALPHA + \li ShaderEffectSource.Alpha - GL_ALPHA; \li ShaderEffectSource.RGB - GL_RGB \li ShaderEffectSource.RGBA - GL_RGBA \endlist - \note Some OpenGL implementations do not support the GL_ALPHA format. + \note ShaderEffectSource.RGB and ShaderEffectSource.Alpha should + be used with caution, as support for these formats in the underlying + hardare and driver is often not present. + */ void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f) diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp index fb5dac1080..0358495a3b 100644 --- a/src/quick/items/qquickshadereffect.cpp +++ b/src/quick/items/qquickshadereffect.cpp @@ -641,10 +641,34 @@ void QQuickShaderEffectCommon::propertyChanged(QQuickItem *item, int mappedId, corner. For non-linear vertex transformations, like page curl, you can specify a fine grid of vertices by specifying a \l mesh resolution. + \section1 ShaderEffect and Item Layers + + The ShaderEffect type can be combined with \l {Item Layers} {layered items}. + + \table + \row + \li \b {Layer with effect disabled} \inlineimage qml-shadereffect-nolayereffect.png + \li \b {Layer with effect enabled} \inlineimage qml-shadereffect-layereffect.png + \li \snippet qml/layerwitheffect.qml 1 + \endtable + + It is also possible to combine multiple layered items: + + \table + \row + \li \inlineimage qml-shadereffect-opacitymask.png + \li \snippet qml/opacitymask.qml 1 + \endtable + + The \l {Qt Graphical Effects} module contains several ready-made effects + for using with Qt Quick applications. + \note Scene Graph textures have origin in the top-left corner rather than bottom-left which is common in OpenGL. For information about the GLSL version being used, see \l QtQuick::OpenGLInfo. + + \sa {Item Layers} */ QQuickShaderEffect::QQuickShaderEffect(QQuickItem *parent) -- cgit v1.2.3 From 29b77e5e0759472ab1f7da1dd756b857d3b2ddd7 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 23 Sep 2014 10:36:22 +0200 Subject: Also search for visual children in TestCase::findChild(). It previously used QObject::findChild(), which won't work in all cases, because items like ListView don't seem to make their delegate items QObject children, while simple nested Items do. Change-Id: I1a8ed1fb55493212cb25abf595d016437812a80f Reviewed-by: Simon Hausmann --- src/imports/testlib/TestCase.qml | 32 ++++++++++++++++++++-- tests/auto/qmltest/selftests/tst_findChild.qml | 37 +++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml index 8d9f6822f4..700c9112eb 100644 --- a/src/imports/testlib/TestCase.qml +++ b/src/imports/testlib/TestCase.qml @@ -633,17 +633,45 @@ Item { \since 5.4 \qmlmethod QtObject TestCase::findChild(parent, objectName) - Returns the first child of \a parent with \a objectName, - or \c null if no such item exists. Children are searched recursively. + Returns the first child of \a parent with \a objectName, or \c null if + no such item exists. Both visual and non-visual children are searched + recursively, with visual children being searched first. \code compare(findChild(item, "childObject"), expectedChildObject); \endcode */ function findChild(parent, objectName) { + // First, search the visual item hierarchy. + var child = qtest_findVisualChild(parent, objectName); + if (child) + return child; + + // If it's not a visual child, it might be a QObject child. return qtest_results.findChild(parent, objectName); } + /*! \internal */ + function qtest_findVisualChild(parent, objectName) { + if (!parent || parent.children === undefined) + return null; + + for (var i = 0; i < parent.children.length; ++i) { + // Is this direct child of ours the child we're after? + var child = parent.children[i]; + if (child.objectName === objectName) + return child; + } + + for (i = 0; i < parent.children.length; ++i) { + // Try the direct child's children. + child = qtest_findVisualChild(parent.children[i], objectName); + if (child) + return child; + } + return null; + } + /*! \qmlmethod TestCase::tryCompare(obj, property, expected, timeout = 5000, message = "") diff --git a/tests/auto/qmltest/selftests/tst_findChild.qml b/tests/auto/qmltest/selftests/tst_findChild.qml index 1ed4c94423..69bcb390e9 100644 --- a/tests/auto/qmltest/selftests/tst_findChild.qml +++ b/tests/auto/qmltest/selftests/tst_findChild.qml @@ -82,6 +82,33 @@ TestCase { objectName: "nestedChildItem2" } + Loader { + id: loader + + sourceComponent: Item { + id: loaderItem + objectName: "loaderItem" + + Item { + objectName: "nestedLoaderItem" + } + + Repeater { + model: 5 + delegate: Item { + objectName: "repeaterItem" + index + } + } + + ListView { + model: 5 + delegate: Item { + objectName: "listViewItem" + index + } + } + } + } + function test_findChild() { compare(findChild(null, ""), null); compare(findChild(undefined, ""), null); @@ -99,6 +126,14 @@ TestCase { var mostDirectChild = duplicateNestedChildItem2Component.createObject(nestedChildItem0); compare(nestedChildItem0.children.length, 2); - compare(findChild(nestedChildrenItem, "nestedChildItem2"), mostDirectChild); + compare(findChild(nestedChildrenItem, "nestedChildItem2"), mostDirectChild, + "Dynamically created nested child items are found"); + + compare(findChild(loader, "loaderItem"), loader.item); + verify(findChild(loader, "nestedLoaderItem")); + + // These don't make their delegate items QObject children, only visual. + verify(findChild(loader, "repeaterItem0")); + verify(findChild(loader, "listViewItem0")); } } -- cgit v1.2.3 From c8f1ed8e514ad25474125343a7f98f6ca60a886c Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 29 Sep 2014 13:21:09 +0200 Subject: Fix example in scope documentation The example tried to demonstrate the use of direct access to properties of the root component object, but unfortunately it also defined an id property that clashed with it. Therefore the provided example did not work as intended and produced a "stringified" object reference instead of the text of the "title" property. This patch changes the id to avoid a clash. Change-Id: Ib9abcf48482773a0dcdf5e2375d1445d87ccf4ef Reviewed-by: Michael Brasser --- src/qml/doc/src/qmllanguageref/documents/scope.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qml/doc/src/qmllanguageref/documents/scope.qdoc b/src/qml/doc/src/qmllanguageref/documents/scope.qdoc index af59afe1fb..67ae881908 100644 --- a/src/qml/doc/src/qmllanguageref/documents/scope.qdoc +++ b/src/qml/doc/src/qmllanguageref/documents/scope.qdoc @@ -163,14 +163,14 @@ Item { property string title Text { - id: title + id: titletype text: "" + title + "" font.pixelSize: 22 anchors.top: parent.top } Text { - text: title.text + text: titletype.text font.pixelSize: 18 anchors.bottom: parent.bottom } -- cgit v1.2.3 From da15a19b3f23cc29a5cc513f283e04c8cf51bd09 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Wed, 24 Sep 2014 12:09:50 +0300 Subject: Partially revert "Disable tests on failing ANGLE config" This partially reverts commit fa29df24bd2792f5eb64e4ff21a116b2c5f5384c. The sprite sequence test now passes in CI under MSVC2010. Change-Id: Ie8f7abdd2ff00db377b1ef3f221c5048c430c067 Reviewed-by: Friedemann Kleint --- tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp b/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp index afc4787cdb..6cfdc90364 100644 --- a/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp +++ b/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp @@ -109,9 +109,6 @@ void tst_qquickspritesequence::test_framerateAdvance() void tst_qquickspritesequence::test_jumpToCrash() { -#if defined(QT_OPENGL_ES_2_ANGLE) && _MSC_VER==1600 - QSKIP("QTBUG-40658"); -#endif QQuickView *window = new QQuickView(0); window->setSource(testFileUrl("crashonstart.qml")); -- cgit v1.2.3 From d5b10eda96e2b00a11a2346cb2374af053a5c5af Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Wed, 24 Sep 2014 10:29:39 +0300 Subject: Revert "Temporarily mark grab()/item.layer tests insignificant under ANGLE" This reverts commit 6b31418a1b5d9be47df5ed61747e8a5fb225acfa. These tests now pass with the latest ANGLE. Change-Id: If812d430e69f0d39a970e9119ebc1f2e5b4886dc Reviewed-by: Friedemann Kleint --- tests/auto/quick/qquickitem2/tst_qquickitem.cpp | 3 -- .../quick/qquickitemlayer/tst_qquickitemlayer.cpp | 33 ---------------------- 2 files changed, 36 deletions(-) diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index a6011a252f..68a8260827 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -2806,9 +2806,6 @@ void tst_QQuickItem::childAt() void tst_QQuickItem::grab() { -#if defined(Q_OS_WIN32) && defined(QT_OPENGL_ES_2_ANGLE) - QSKIP("QTBUG-40649"); -#endif QQuickView view; view.setSource(testFileUrl("grabToImage.qml")); view.show(); diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp index 9f69dcb83e..eb720e5109 100644 --- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp +++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp @@ -130,9 +130,6 @@ tst_QQuickItemLayer::tst_QQuickItemLayer() void tst_QQuickItemLayer::layerSmooth() { -#if defined(Q_OS_WIN32) && defined(QT_OPENGL_ES_2_ANGLE) - QSKIP("QTBUG-40649"); -#endif if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); QImage fb = runTest("Smooth.qml"); @@ -152,9 +149,6 @@ void tst_QQuickItemLayer::layerSmooth() void tst_QQuickItemLayer::layerEnabled() { -#if defined(Q_OS_WIN32) && defined(QT_OPENGL_ES_2_ANGLE) - QSKIP("QTBUG-40649"); -#endif if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); QImage fb = runTest("Enabled.qml"); @@ -171,9 +165,6 @@ void tst_QQuickItemLayer::layerEnabled() void tst_QQuickItemLayer::layerMipmap() { -#if defined(Q_OS_WIN32) && defined(QT_OPENGL_ES_2_ANGLE) - QSKIP("QTBUG-40649"); -#endif if (m_isMesaSoftwareRasterizer) QSKIP("Mipmapping does not work with the Mesa Software Rasterizer."); QImage fb = runTest("Mipmap.qml"); @@ -188,9 +179,6 @@ void tst_QQuickItemLayer::layerMipmap() void tst_QQuickItemLayer::layerEffect() { -#if defined(Q_OS_WIN32) && defined(QT_OPENGL_ES_2_ANGLE) - QSKIP("QTBUG-40649"); -#endif if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); QImage fb = runTest("Effect.qml"); @@ -205,9 +193,6 @@ void tst_QQuickItemLayer::layerEffect() // a shader that pads transparent to blue. Everything else is red. void tst_QQuickItemLayer::layerSourceRect() { -#if defined(Q_OS_WIN32) && defined(QT_OPENGL_ES_2_ANGLE) - QSKIP("QTBUG-40649"); -#endif if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); @@ -229,9 +214,6 @@ void tst_QQuickItemLayer::layerSourceRect() // directly in a stand alone ShaderEffect void tst_QQuickItemLayer::layerIsTextureProvider() { -#if defined(Q_OS_WIN32) && defined(QT_OPENGL_ES_2_ANGLE) - QSKIP("QTBUG-40649"); -#endif if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); QImage fb = runTest("TextureProvider.qml"); @@ -264,9 +246,6 @@ void tst_QQuickItemLayer::layerVisibility_data() void tst_QQuickItemLayer::layerVisibility() { -#if defined(Q_OS_WIN32) && defined(QT_OPENGL_ES_2_ANGLE) - QSKIP("QTBUG-40649"); -#endif if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); @@ -315,9 +294,6 @@ void tst_QQuickItemLayer::layerZOrder_data() void tst_QQuickItemLayer::layerZOrder() { -#if defined(Q_OS_WIN32) && defined(QT_OPENGL_ES_2_ANGLE) - QSKIP("QTBUG-40649"); -#endif if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); @@ -352,9 +328,6 @@ void tst_QQuickItemLayer::changeZOrder_data() void tst_QQuickItemLayer::changeZOrder() { -#if defined(Q_OS_WIN32) && defined(QT_OPENGL_ES_2_ANGLE) - QSKIP("QTBUG-40649"); -#endif if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); @@ -423,9 +396,6 @@ void tst_QQuickItemLayer::disableLayer() void tst_QQuickItemLayer::changeSamplerName() { -#if defined(Q_OS_WIN32) && defined(QT_OPENGL_ES_2_ANGLE) - QSKIP("QTBUG-40649"); -#endif if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); QImage fb = runTest("SamplerNameChange.qml"); @@ -434,9 +404,6 @@ void tst_QQuickItemLayer::changeSamplerName() void tst_QQuickItemLayer::itemEffect() { -#if defined(Q_OS_WIN32) && defined(QT_OPENGL_ES_2_ANGLE) - QSKIP("QTBUG-40649"); -#endif if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); QImage fb = runTest("ItemEffect.qml"); -- cgit v1.2.3 From 536ead429648f40b874f8d6927bb8f98e8f47a37 Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Wed, 24 Sep 2014 12:08:10 +0200 Subject: Add orientationUpdateMask to QQuickScreen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-38699 Change-Id: I173b7e53c27dba336351572859f7c9aeafe07ef9 Reviewed-by: Tor Arne Vestbø --- src/quick/items/qquickscreen.cpp | 34 ++++++++++++++++++++++ src/quick/items/qquickscreen_p.h | 10 ++++++- tests/auto/quick/qquickscreen/data/screen.qml | 3 ++ tests/auto/quick/qquickscreen/tst_qquickscreen.cpp | 1 + 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp index 0d9226d77f..926ac7b4ee 100644 --- a/src/quick/items/qquickscreen.cpp +++ b/src/quick/items/qquickscreen.cpp @@ -171,6 +171,9 @@ QT_BEGIN_NAMESPACE change, then probably you are using a device which does not rotate its own display. In that case you may need to use \l {Item::rotation}{Item.rotation} or \l {Item::transform}{Item.transform} to rotate your content. + + \note This property does not update unless a Screen::orientationUpdateMask + is set to a value other than \c 0. */ /*! \qmlattachedmethod int Screen::angleBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b) @@ -178,10 +181,21 @@ QT_BEGIN_NAMESPACE Returns the rotation angle, in degrees, between the two specified angles. */ +/*! + \qmlattachedproperty Qt::ScreenOrientations Screen::orientationUpdateMask + \since 5.4 + + This contains the update mask for the orientation. Screen::orientation + only emits changes for the screen orientations matching this mask. + + The default, \c 0, means Screen::orientation never updates. +*/ + QQuickScreenAttached::QQuickScreenAttached(QObject* attachee) : QObject(attachee) , m_screen(NULL) , m_window(NULL) + , m_updateMask(0) { m_attachee = qobject_cast(attachee); @@ -260,6 +274,24 @@ Qt::ScreenOrientation QQuickScreenAttached::orientation() const return m_screen->orientation(); } +Qt::ScreenOrientations QQuickScreenAttached::orientationUpdateMask() const +{ + return m_updateMask; +} + +void QQuickScreenAttached::setOrientationUpdateMask(Qt::ScreenOrientations mask) +{ + if (m_updateMask == mask) + return; + + m_updateMask = mask; + + if (m_screen) + m_screen->setOrientationUpdateMask(m_updateMask); + + emit orientationUpdateMaskChanged(); +} + int QQuickScreenAttached::angleBetween(int a, int b) { if (!m_screen) @@ -290,6 +322,8 @@ void QQuickScreenAttached::screenChanged(QScreen *screen) if (!screen) return; //Don't bother emitting signals, because the new values are garbage anyways + screen->setOrientationUpdateMask(m_updateMask); + if (!oldScreen || screen->size() != oldScreen->size()) { emit widthChanged(); emit heightChanged(); diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h index 884995a67e..d661cc6f56 100644 --- a/src/quick/items/qquickscreen_p.h +++ b/src/quick/items/qquickscreen_p.h @@ -50,15 +50,19 @@ class Q_AUTOTEST_EXPORT QQuickScreenAttached : public QObject { Q_OBJECT - Q_PROPERTY(QString name READ name NOTIFY nameChanged); + Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(int width READ width NOTIFY widthChanged) Q_PROPERTY(int height READ height NOTIFY heightChanged) Q_PROPERTY(int desktopAvailableWidth READ desktopAvailableWidth NOTIFY desktopGeometryChanged) Q_PROPERTY(int desktopAvailableHeight READ desktopAvailableHeight NOTIFY desktopGeometryChanged) Q_PROPERTY(qreal logicalPixelDensity READ logicalPixelDensity NOTIFY logicalPixelDensityChanged) Q_PROPERTY(qreal pixelDensity READ pixelDensity NOTIFY pixelDensityChanged) + // TODO Qt 6 Rename primaryOrientation to orientation Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ primaryOrientation NOTIFY primaryOrientationChanged) + // TODO Qt 6 Remove this orientation -> incomplete device orientation -> better use OrientationSensor Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged) + Q_PROPERTY(Qt::ScreenOrientations orientationUpdateMask READ orientationUpdateMask + WRITE setOrientationUpdateMask NOTIFY orientationUpdateMaskChanged) public: QQuickScreenAttached(QObject* attachee); @@ -72,6 +76,8 @@ public: qreal pixelDensity() const; Qt::ScreenOrientation primaryOrientation() const; Qt::ScreenOrientation orientation() const; + Qt::ScreenOrientations orientationUpdateMask() const; + void setOrientationUpdateMask(Qt::ScreenOrientations mask); //Treats int as Qt::ScreenOrientation, due to QTBUG-20639 Q_INVOKABLE int angleBetween(int a, int b); @@ -87,6 +93,7 @@ Q_SIGNALS: void pixelDensityChanged(); void primaryOrientationChanged(); void orientationChanged(); + void orientationUpdateMaskChanged(); protected Q_SLOTS: void screenChanged(QScreen*); @@ -95,6 +102,7 @@ private: QScreen* m_screen; QQuickWindow* m_window; QQuickItem* m_attachee; + Qt::ScreenOrientations m_updateMask; }; class Q_AUTOTEST_EXPORT QQuickScreen : public QObject diff --git a/tests/auto/quick/qquickscreen/data/screen.qml b/tests/auto/quick/qquickscreen/data/screen.qml index 780b22f23d..dc3803f4e3 100644 --- a/tests/auto/quick/qquickscreen/data/screen.qml +++ b/tests/auto/quick/qquickscreen/data/screen.qml @@ -8,4 +8,7 @@ Item { property int h: Window.Screen.height property int curOrientation: Window.Screen.orientation property int priOrientation: Window.Screen.primaryOrientation + property int updateMask: Window.Screen.orientationUpdateMask + + Window.Screen.orientationUpdateMask: Qt.LandscapeOrientation | Qt.InvertedLandscapeOrientation } diff --git a/tests/auto/quick/qquickscreen/tst_qquickscreen.cpp b/tests/auto/quick/qquickscreen/tst_qquickscreen.cpp index dc6fe061c3..be543e8022 100644 --- a/tests/auto/quick/qquickscreen/tst_qquickscreen.cpp +++ b/tests/auto/quick/qquickscreen/tst_qquickscreen.cpp @@ -62,6 +62,7 @@ void tst_qquickscreen::basicProperties() QCOMPARE(screen->size().height(), root->property("h").toInt()); QCOMPARE(int(screen->orientation()), root->property("curOrientation").toInt()); QCOMPARE(int(screen->primaryOrientation()), root->property("priOrientation").toInt()); + QCOMPARE(int(screen->orientationUpdateMask()), root->property("updateMask").toInt()); } QTEST_MAIN(tst_qquickscreen) -- cgit v1.2.3 From c2c710e5a8d66fa696276aa69c2e3b00436eefe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Thu, 25 Sep 2014 21:02:04 +0100 Subject: Fix build when using -Werror "'borderBottom' may be used uninitialized in this function [-Werror=maybe-uninitialized]" Observed when compiling for android. Change-Id: Ifcb26e28440f08528a192ea2fe88d6343e33710b Reviewed-by: BogDan Vatra --- src/quick/items/qquickborderimage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp index 127a5fa46b..8d8e4b6a02 100644 --- a/src/quick/items/qquickborderimage.cpp +++ b/src/quick/items/qquickborderimage.cpp @@ -562,7 +562,7 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat // Don't implicitly create the scalegrid in the rendering thread... QRectF innerSourceRect(0, 0, 1, 1); QRectF innerTargetRect(0, 0, width(), height()); - int borderLeft, borderTop, borderRight, borderBottom; + int borderLeft = 0, borderTop = 0, borderRight = 0, borderBottom = 0; bool updateNode = !oldNode; if (d->border) { -- cgit v1.2.3 From fccf0e29120f64a8b9b2a15b33971a648ab190e7 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Fri, 26 Sep 2014 15:00:14 +0200 Subject: Doc: Combine the extending QML tutorial chapters into a single example Combine the six examples associated with each tutorial chapter into a single, top-level example project 'extending-qml', with subprojects for each of the tutorial chapters. Clean up the docs, add links, and a note about a warning that the user may see when running the code in the first chapter. Task-number: QTBUG-32947 Change-Id: Idba4e2153817ab29f1afaf1947d1f2e25964e7b3 Reviewed-by: Leena Miettinen --- .../extending-qml/chapter1-basics/app.qml | 60 +++++++ .../chapter1-basics/chapter1-basics.pro | 15 ++ .../chapter1-basics/chapter1-basics.qrc | 5 + .../extending-qml/chapter1-basics/main.cpp | 57 +++++++ .../extending-qml/chapter1-basics/piechart.cpp | 79 +++++++++ .../extending-qml/chapter1-basics/piechart.h | 71 ++++++++ .../extending-qml/chapter2-methods/app.qml | 66 ++++++++ .../chapter2-methods/chapter2-methods.pro | 15 ++ .../chapter2-methods/chapter2-methods.qrc | 5 + .../extending-qml/chapter2-methods/main.cpp | 57 +++++++ .../extending-qml/chapter2-methods/piechart.cpp | 84 +++++++++ .../extending-qml/chapter2-methods/piechart.h | 84 +++++++++ .../extending-qml/chapter3-bindings/app.qml | 74 ++++++++ .../chapter3-bindings/chapter3-binding.qrc | 5 + .../chapter3-bindings/chapter3-bindings.pro | 15 ++ .../extending-qml/chapter3-bindings/main.cpp | 57 +++++++ .../extending-qml/chapter3-bindings/piechart.cpp | 86 ++++++++++ .../extending-qml/chapter3-bindings/piechart.h | 84 +++++++++ .../chapter4-customPropertyTypes/app.qml | 60 +++++++ .../chapter4-customPropertyTypes.pro | 17 ++ .../chapter4-customPropertyTypes.qrc | 5 + .../chapter4-customPropertyTypes/main.cpp | 66 ++++++++ .../chapter4-customPropertyTypes/piechart.cpp | 70 ++++++++ .../chapter4-customPropertyTypes/piechart.h | 78 +++++++++ .../chapter4-customPropertyTypes/pieslice.cpp | 66 ++++++++ .../chapter4-customPropertyTypes/pieslice.h | 66 ++++++++ .../extending-qml/chapter5-listproperties/app.qml | 70 ++++++++ .../chapter5-listproperties.pro | 17 ++ .../chapter5-listproperties.qrc | 5 + .../extending-qml/chapter5-listproperties/main.cpp | 58 +++++++ .../chapter5-listproperties/piechart.cpp | 72 ++++++++ .../chapter5-listproperties/piechart.h | 75 ++++++++ .../chapter5-listproperties/pieslice.cpp | 86 ++++++++++ .../chapter5-listproperties/pieslice.h | 76 +++++++++ .../extending-qml/chapter6-plugins/app.pro | 10 ++ .../extending-qml/chapter6-plugins/app.qml | 69 ++++++++ .../extending-qml/chapter6-plugins/app.qrc | 5 + .../chapter6-plugins/chapter6-plugins.pro | 5 + .../chapter6-plugins/import/chartsplugin.cpp | 53 ++++++ .../chapter6-plugins/import/chartsplugin.h | 57 +++++++ .../chapter6-plugins/import/import.pro | 26 +++ .../chapter6-plugins/import/piechart.cpp | 70 ++++++++ .../chapter6-plugins/import/piechart.h | 69 ++++++++ .../chapter6-plugins/import/pieslice.cpp | 86 ++++++++++ .../chapter6-plugins/import/pieslice.h | 74 ++++++++ .../extending-qml/chapter6-plugins/import/qmldir | 2 + .../extending-qml/chapter6-plugins/main.cpp | 53 ++++++ .../qml/tutorials/extending-qml/extending-qml.pro | 10 ++ .../tutorials/extending/chapter1-basics/app.qml | 60 ------- .../extending/chapter1-basics/chapter1-basics.pro | 15 -- .../extending/chapter1-basics/chapter1-basics.qrc | 5 - .../tutorials/extending/chapter1-basics/main.cpp | 57 ------- .../extending/chapter1-basics/piechart.cpp | 79 --------- .../tutorials/extending/chapter1-basics/piechart.h | 71 -------- .../tutorials/extending/chapter2-methods/app.qml | 66 -------- .../chapter2-methods/chapter2-methods.pro | 15 -- .../chapter2-methods/chapter2-methods.qrc | 5 - .../tutorials/extending/chapter2-methods/main.cpp | 57 ------- .../extending/chapter2-methods/piechart.cpp | 84 --------- .../extending/chapter2-methods/piechart.h | 84 --------- .../tutorials/extending/chapter3-bindings/app.qml | 74 -------- .../chapter3-bindings/chapter3-binding.qrc | 5 - .../chapter3-bindings/chapter3-bindings.pro | 15 -- .../tutorials/extending/chapter3-bindings/main.cpp | 57 ------- .../extending/chapter3-bindings/piechart.cpp | 86 ---------- .../extending/chapter3-bindings/piechart.h | 84 --------- .../extending/chapter4-customPropertyTypes/app.qml | 60 ------- .../chapter4-customPropertyTypes.pro | 17 -- .../chapter4-customPropertyTypes.qrc | 5 - .../chapter4-customPropertyTypes/main.cpp | 66 -------- .../chapter4-customPropertyTypes/piechart.cpp | 70 -------- .../chapter4-customPropertyTypes/piechart.h | 78 --------- .../chapter4-customPropertyTypes/pieslice.cpp | 66 -------- .../chapter4-customPropertyTypes/pieslice.h | 66 -------- .../extending/chapter5-listproperties/app.qml | 70 -------- .../chapter5-listproperties.pro | 17 -- .../chapter5-listproperties.qrc | 5 - .../extending/chapter5-listproperties/main.cpp | 58 ------- .../extending/chapter5-listproperties/piechart.cpp | 72 -------- .../extending/chapter5-listproperties/piechart.h | 75 -------- .../extending/chapter5-listproperties/pieslice.cpp | 86 ---------- .../extending/chapter5-listproperties/pieslice.h | 76 --------- .../tutorials/extending/chapter6-plugins/app.pro | 10 -- .../tutorials/extending/chapter6-plugins/app.qml | 69 -------- .../tutorials/extending/chapter6-plugins/app.qrc | 5 - .../chapter6-plugins/chapter6-plugins.pro | 5 - .../chapter6-plugins/import/chartsplugin.cpp | 53 ------ .../chapter6-plugins/import/chartsplugin.h | 57 ------- .../extending/chapter6-plugins/import/import.pro | 26 --- .../extending/chapter6-plugins/import/piechart.cpp | 70 -------- .../extending/chapter6-plugins/import/piechart.h | 69 -------- .../extending/chapter6-plugins/import/pieslice.cpp | 86 ---------- .../extending/chapter6-plugins/import/pieslice.h | 74 -------- .../extending/chapter6-plugins/import/qmldir | 2 - .../tutorials/extending/chapter6-plugins/main.cpp | 53 ------ examples/qml/tutorials/extending/extending.pro | 10 -- .../doc/src/cppintegration/extending-tutorial.qdoc | 188 ++++++++------------- 97 files changed, 2470 insertions(+), 2508 deletions(-) create mode 100644 examples/qml/tutorials/extending-qml/chapter1-basics/app.qml create mode 100644 examples/qml/tutorials/extending-qml/chapter1-basics/chapter1-basics.pro create mode 100644 examples/qml/tutorials/extending-qml/chapter1-basics/chapter1-basics.qrc create mode 100644 examples/qml/tutorials/extending-qml/chapter1-basics/main.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter1-basics/piechart.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter1-basics/piechart.h create mode 100644 examples/qml/tutorials/extending-qml/chapter2-methods/app.qml create mode 100644 examples/qml/tutorials/extending-qml/chapter2-methods/chapter2-methods.pro create mode 100644 examples/qml/tutorials/extending-qml/chapter2-methods/chapter2-methods.qrc create mode 100644 examples/qml/tutorials/extending-qml/chapter2-methods/main.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter2-methods/piechart.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter2-methods/piechart.h create mode 100644 examples/qml/tutorials/extending-qml/chapter3-bindings/app.qml create mode 100644 examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-binding.qrc create mode 100644 examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-bindings.pro create mode 100644 examples/qml/tutorials/extending-qml/chapter3-bindings/main.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter3-bindings/piechart.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter3-bindings/piechart.h create mode 100644 examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/app.qml create mode 100644 examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pro create mode 100644 examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/chapter4-customPropertyTypes.qrc create mode 100644 examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/main.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/piechart.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/piechart.h create mode 100644 examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.h create mode 100644 examples/qml/tutorials/extending-qml/chapter5-listproperties/app.qml create mode 100644 examples/qml/tutorials/extending-qml/chapter5-listproperties/chapter5-listproperties.pro create mode 100644 examples/qml/tutorials/extending-qml/chapter5-listproperties/chapter5-listproperties.qrc create mode 100644 examples/qml/tutorials/extending-qml/chapter5-listproperties/main.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.h create mode 100644 examples/qml/tutorials/extending-qml/chapter5-listproperties/pieslice.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter5-listproperties/pieslice.h create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/app.pro create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/app.qml create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/app.qrc create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/chapter6-plugins.pro create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/import/chartsplugin.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/import/chartsplugin.h create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/import/import.pro create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.h create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.cpp create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.h create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/import/qmldir create mode 100644 examples/qml/tutorials/extending-qml/chapter6-plugins/main.cpp create mode 100644 examples/qml/tutorials/extending-qml/extending-qml.pro delete mode 100644 examples/qml/tutorials/extending/chapter1-basics/app.qml delete mode 100644 examples/qml/tutorials/extending/chapter1-basics/chapter1-basics.pro delete mode 100644 examples/qml/tutorials/extending/chapter1-basics/chapter1-basics.qrc delete mode 100644 examples/qml/tutorials/extending/chapter1-basics/main.cpp delete mode 100644 examples/qml/tutorials/extending/chapter1-basics/piechart.cpp delete mode 100644 examples/qml/tutorials/extending/chapter1-basics/piechart.h delete mode 100644 examples/qml/tutorials/extending/chapter2-methods/app.qml delete mode 100644 examples/qml/tutorials/extending/chapter2-methods/chapter2-methods.pro delete mode 100644 examples/qml/tutorials/extending/chapter2-methods/chapter2-methods.qrc delete mode 100644 examples/qml/tutorials/extending/chapter2-methods/main.cpp delete mode 100644 examples/qml/tutorials/extending/chapter2-methods/piechart.cpp delete mode 100644 examples/qml/tutorials/extending/chapter2-methods/piechart.h delete mode 100644 examples/qml/tutorials/extending/chapter3-bindings/app.qml delete mode 100644 examples/qml/tutorials/extending/chapter3-bindings/chapter3-binding.qrc delete mode 100644 examples/qml/tutorials/extending/chapter3-bindings/chapter3-bindings.pro delete mode 100644 examples/qml/tutorials/extending/chapter3-bindings/main.cpp delete mode 100644 examples/qml/tutorials/extending/chapter3-bindings/piechart.cpp delete mode 100644 examples/qml/tutorials/extending/chapter3-bindings/piechart.h delete mode 100644 examples/qml/tutorials/extending/chapter4-customPropertyTypes/app.qml delete mode 100644 examples/qml/tutorials/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pro delete mode 100644 examples/qml/tutorials/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.qrc delete mode 100644 examples/qml/tutorials/extending/chapter4-customPropertyTypes/main.cpp delete mode 100644 examples/qml/tutorials/extending/chapter4-customPropertyTypes/piechart.cpp delete mode 100644 examples/qml/tutorials/extending/chapter4-customPropertyTypes/piechart.h delete mode 100644 examples/qml/tutorials/extending/chapter4-customPropertyTypes/pieslice.cpp delete mode 100644 examples/qml/tutorials/extending/chapter4-customPropertyTypes/pieslice.h delete mode 100644 examples/qml/tutorials/extending/chapter5-listproperties/app.qml delete mode 100644 examples/qml/tutorials/extending/chapter5-listproperties/chapter5-listproperties.pro delete mode 100644 examples/qml/tutorials/extending/chapter5-listproperties/chapter5-listproperties.qrc delete mode 100644 examples/qml/tutorials/extending/chapter5-listproperties/main.cpp delete mode 100644 examples/qml/tutorials/extending/chapter5-listproperties/piechart.cpp delete mode 100644 examples/qml/tutorials/extending/chapter5-listproperties/piechart.h delete mode 100644 examples/qml/tutorials/extending/chapter5-listproperties/pieslice.cpp delete mode 100644 examples/qml/tutorials/extending/chapter5-listproperties/pieslice.h delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/app.pro delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/app.qml delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/app.qrc delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/chapter6-plugins.pro delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/import/chartsplugin.cpp delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/import/chartsplugin.h delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/import/import.pro delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/import/piechart.cpp delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/import/piechart.h delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/import/pieslice.cpp delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/import/pieslice.h delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/import/qmldir delete mode 100644 examples/qml/tutorials/extending/chapter6-plugins/main.cpp delete mode 100644 examples/qml/tutorials/extending/extending.pro diff --git a/examples/qml/tutorials/extending-qml/chapter1-basics/app.qml b/examples/qml/tutorials/extending-qml/chapter1-basics/app.qml new file mode 100644 index 0000000000..d2f03daf83 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter1-basics/app.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import Charts 1.0 +import QtQuick 2.0 + +Item { + width: 300; height: 200 + + PieChart { + id: aPieChart + anchors.centerIn: parent + width: 100; height: 100 + name: "A simple pie chart" + color: "red" + } + + Text { + anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 } + text: aPieChart.name + } +} +//![0] diff --git a/examples/qml/tutorials/extending-qml/chapter1-basics/chapter1-basics.pro b/examples/qml/tutorials/extending-qml/chapter1-basics/chapter1-basics.pro new file mode 100644 index 0000000000..9911e02484 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter1-basics/chapter1-basics.pro @@ -0,0 +1,15 @@ +QT += qml quick + +HEADERS += piechart.h +SOURCES += piechart.cpp \ + main.cpp + +RESOURCES += chapter1-basics.qrc + +DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter1-basics +target.path = $$DESTPATH + +qml.files = *.qml +qml.path = $$DESTPATH + +INSTALLS += target qml diff --git a/examples/qml/tutorials/extending-qml/chapter1-basics/chapter1-basics.qrc b/examples/qml/tutorials/extending-qml/chapter1-basics/chapter1-basics.qrc new file mode 100644 index 0000000000..f1168aef3b --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter1-basics/chapter1-basics.qrc @@ -0,0 +1,5 @@ + + + app.qml + + diff --git a/examples/qml/tutorials/extending-qml/chapter1-basics/main.cpp b/examples/qml/tutorials/extending-qml/chapter1-basics/main.cpp new file mode 100644 index 0000000000..4e719d2722 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter1-basics/main.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +#include "piechart.h" +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType("Charts", 1, 0, "PieChart"); + + QQuickView view; + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setSource(QUrl("qrc:///app.qml")); + view.show(); + return app.exec(); +} +//![0] diff --git a/examples/qml/tutorials/extending-qml/chapter1-basics/piechart.cpp b/examples/qml/tutorials/extending-qml/chapter1-basics/piechart.cpp new file mode 100644 index 0000000000..fa005781d8 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter1-basics/piechart.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "piechart.h" +#include + +//![0] +PieChart::PieChart(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ +} +//![0] + +QString PieChart::name() const +{ + return m_name; +} + +void PieChart::setName(const QString &name) +{ + m_name = name; +} + +QColor PieChart::color() const +{ + return m_color; +} + +void PieChart::setColor(const QColor &color) +{ + m_color = color; +} + +//![1] +void PieChart::paint(QPainter *painter) +{ + QPen pen(m_color, 2); + painter->setPen(pen); + painter->setRenderHints(QPainter::Antialiasing, true); + painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16); +} +//![1] + diff --git a/examples/qml/tutorials/extending-qml/chapter1-basics/piechart.h b/examples/qml/tutorials/extending-qml/chapter1-basics/piechart.h new file mode 100644 index 0000000000..a6272453ce --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter1-basics/piechart.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef PIECHART_H +#define PIECHART_H + +//![0] +#include +#include + +class PieChart : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QColor color READ color WRITE setColor) + +public: + PieChart(QQuickItem *parent = 0); + + QString name() const; + void setName(const QString &name); + + QColor color() const; + void setColor(const QColor &color); + + void paint(QPainter *painter); + +private: + QString m_name; + QColor m_color; +}; +//![0] + +#endif + diff --git a/examples/qml/tutorials/extending-qml/chapter2-methods/app.qml b/examples/qml/tutorials/extending-qml/chapter2-methods/app.qml new file mode 100644 index 0000000000..06ecb3a09d --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter2-methods/app.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import Charts 1.0 +import QtQuick 2.0 + +Item { + width: 300; height: 200 + + PieChart { + id: aPieChart + anchors.centerIn: parent + width: 100; height: 100 + color: "red" + + onChartCleared: console.log("The chart has been cleared") + } + + MouseArea { + anchors.fill: parent + onClicked: aPieChart.clearChart() + } + + Text { + anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 } + text: "Click anywhere to clear the chart" + } +} +//![0] diff --git a/examples/qml/tutorials/extending-qml/chapter2-methods/chapter2-methods.pro b/examples/qml/tutorials/extending-qml/chapter2-methods/chapter2-methods.pro new file mode 100644 index 0000000000..7fd850ce36 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter2-methods/chapter2-methods.pro @@ -0,0 +1,15 @@ +QT += qml quick + +HEADERS += piechart.h +SOURCES += piechart.cpp \ + main.cpp + +RESOURCES += chapter2-methods.qrc + +DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter2-methods +target.path = $$DESTPATH + +qml.files = *.qml +qml.path = $$DESTPATH + +INSTALLS += target qml diff --git a/examples/qml/tutorials/extending-qml/chapter2-methods/chapter2-methods.qrc b/examples/qml/tutorials/extending-qml/chapter2-methods/chapter2-methods.qrc new file mode 100644 index 0000000000..f1168aef3b --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter2-methods/chapter2-methods.qrc @@ -0,0 +1,5 @@ + + + app.qml + + diff --git a/examples/qml/tutorials/extending-qml/chapter2-methods/main.cpp b/examples/qml/tutorials/extending-qml/chapter2-methods/main.cpp new file mode 100644 index 0000000000..4e719d2722 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter2-methods/main.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +#include "piechart.h" +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType("Charts", 1, 0, "PieChart"); + + QQuickView view; + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setSource(QUrl("qrc:///app.qml")); + view.show(); + return app.exec(); +} +//![0] diff --git a/examples/qml/tutorials/extending-qml/chapter2-methods/piechart.cpp b/examples/qml/tutorials/extending-qml/chapter2-methods/piechart.cpp new file mode 100644 index 0000000000..ddcb1b3efd --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter2-methods/piechart.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "piechart.h" +#include + +PieChart::PieChart(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ +} + +QString PieChart::name() const +{ + return m_name; +} + +void PieChart::setName(const QString &name) +{ + m_name = name; +} + +QColor PieChart::color() const +{ + return m_color; +} + +void PieChart::setColor(const QColor &color) +{ + m_color = color; +} + +void PieChart::paint(QPainter *painter) +{ + QPen pen(m_color, 2); + painter->setPen(pen); + painter->setRenderHints(QPainter::Antialiasing, true); + painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16); +} + +//![0] +void PieChart::clearChart() +{ + setColor(QColor(Qt::transparent)); + update(); + + emit chartCleared(); +} +//![0] diff --git a/examples/qml/tutorials/extending-qml/chapter2-methods/piechart.h b/examples/qml/tutorials/extending-qml/chapter2-methods/piechart.h new file mode 100644 index 0000000000..86750197d2 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter2-methods/piechart.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef PIECHART_H +#define PIECHART_H + +#include +#include + +//![0] +class PieChart : public QQuickPaintedItem +{ +//![0] + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QColor color READ color WRITE setColor) + +//![1] +public: +//![1] + + PieChart(QQuickItem *parent = 0); + + QString name() const; + void setName(const QString &name); + + QColor color() const; + void setColor(const QColor &color); + + void paint(QPainter *painter); + +//![2] + Q_INVOKABLE void clearChart(); + +signals: + void chartCleared(); +//![2] + +private: + QString m_name; + QColor m_color; + +//![3] +}; +//![3] + +#endif + diff --git a/examples/qml/tutorials/extending-qml/chapter3-bindings/app.qml b/examples/qml/tutorials/extending-qml/chapter3-bindings/app.qml new file mode 100644 index 0000000000..afb9e25c51 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter3-bindings/app.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import Charts 1.0 +import QtQuick 2.0 + +Item { + width: 300; height: 200 + + Row { + anchors.centerIn: parent + spacing: 20 + + PieChart { + id: chartA + width: 100; height: 100 + color: "red" + } + + PieChart { + id: chartB + width: 100; height: 100 + color: chartA.color + } + } + + MouseArea { + anchors.fill: parent + onClicked: { chartA.color = "blue" } + } + + Text { + anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 } + text: "Click anywhere to change the chart color" + } +} +//![0] diff --git a/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-binding.qrc b/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-binding.qrc new file mode 100644 index 0000000000..f1168aef3b --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-binding.qrc @@ -0,0 +1,5 @@ + + + app.qml + + diff --git a/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-bindings.pro b/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-bindings.pro new file mode 100644 index 0000000000..0c31592eeb --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-bindings.pro @@ -0,0 +1,15 @@ +QT += qml quick + +HEADERS += piechart.h +SOURCES += piechart.cpp \ + main.cpp + +RESOURCES += chapter3-binding.qrc + +DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter3-binding +target.path = $$DESTPATH + +qml.files = *.qml +qml.path = $$DESTPATH + +INSTALLS += target qml diff --git a/examples/qml/tutorials/extending-qml/chapter3-bindings/main.cpp b/examples/qml/tutorials/extending-qml/chapter3-bindings/main.cpp new file mode 100644 index 0000000000..4e719d2722 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter3-bindings/main.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +#include "piechart.h" +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType("Charts", 1, 0, "PieChart"); + + QQuickView view; + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setSource(QUrl("qrc:///app.qml")); + view.show(); + return app.exec(); +} +//![0] diff --git a/examples/qml/tutorials/extending-qml/chapter3-bindings/piechart.cpp b/examples/qml/tutorials/extending-qml/chapter3-bindings/piechart.cpp new file mode 100644 index 0000000000..a63035033f --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter3-bindings/piechart.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "piechart.h" +#include + +PieChart::PieChart(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ +} + +QString PieChart::name() const +{ + return m_name; +} + +void PieChart::setName(const QString &name) +{ + m_name = name; +} + +QColor PieChart::color() const +{ + return m_color; +} + +//![0] +void PieChart::setColor(const QColor &color) +{ + if (color != m_color) { + m_color = color; + update(); // repaint with the new color + emit colorChanged(); + } +} +//![0] + +void PieChart::paint(QPainter *painter) +{ + QPen pen(m_color, 2); + painter->setPen(pen); + painter->setRenderHints(QPainter::Antialiasing, true); + painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16); +} + +void PieChart::clearChart() +{ + setColor(QColor(Qt::transparent)); + update(); +} diff --git a/examples/qml/tutorials/extending-qml/chapter3-bindings/piechart.h b/examples/qml/tutorials/extending-qml/chapter3-bindings/piechart.h new file mode 100644 index 0000000000..25e82d66cc --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter3-bindings/piechart.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef PIECHART_H +#define PIECHART_H + +#include +#include + +//![0] +class PieChart : public QQuickPaintedItem +{ +//![0] + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName) + +//![1] + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) +public: +//![1] + + PieChart(QQuickItem *parent = 0); + + QString name() const; + void setName(const QString &name); + + QColor color() const; + void setColor(const QColor &color); + + void paint(QPainter *painter); + + Q_INVOKABLE void clearChart(); + +//![2] +signals: + void colorChanged(); +//![2] + +private: + QString m_name; + QColor m_color; + +//![3] +}; +//![3] + +#endif + diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/app.qml b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/app.qml new file mode 100644 index 0000000000..c757fdaedd --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/app.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import Charts 1.0 +import QtQuick 2.0 + +Item { + width: 300; height: 200 + + PieChart { + id: chart + anchors.centerIn: parent + width: 100; height: 100 + + pieSlice: PieSlice { + anchors.fill: parent + color: "red" + } + } + + Component.onCompleted: console.log("The pie is colored " + chart.pieSlice.color) +} +//![0] diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pro b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pro new file mode 100644 index 0000000000..12dfbd6280 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pro @@ -0,0 +1,17 @@ +QT += qml quick + +HEADERS += piechart.h \ + pieslice.h +SOURCES += piechart.cpp \ + pieslice.cpp \ + main.cpp + +RESOURCES += chapter4-customPropertyTypes.qrc + +DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter4-customPropertyTypes +target.path = $$DESTPATH + +qml.files = *.qml +qml.path = $$DESTPATH + +INSTALLS += target qml diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/chapter4-customPropertyTypes.qrc b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/chapter4-customPropertyTypes.qrc new file mode 100644 index 0000000000..f1168aef3b --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/chapter4-customPropertyTypes.qrc @@ -0,0 +1,5 @@ + + + app.qml + + diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/main.cpp b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/main.cpp new file mode 100644 index 0000000000..fc59a11987 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/main.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "piechart.h" +#include "pieslice.h" + +#include +#include + +//![0] +int main(int argc, char *argv[]) +{ +//![0] + QGuiApplication app(argc, argv); + + qmlRegisterType("Charts", 1, 0, "PieChart"); + +//![1] + qmlRegisterType("Charts", 1, 0, "PieSlice"); +//![1] + + QQuickView view; + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setSource(QUrl("qrc:///app.qml")); + view.show(); + return app.exec(); + +//![2] +} +//![2] diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/piechart.cpp b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/piechart.cpp new file mode 100644 index 0000000000..c1e2996e83 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/piechart.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "piechart.h" +#include "pieslice.h" + +PieChart::PieChart(QQuickItem *parent) + : QQuickItem(parent) +{ +} + +QString PieChart::name() const +{ + return m_name; +} + +void PieChart::setName(const QString &name) +{ + m_name = name; +} + +PieSlice *PieChart::pieSlice() const +{ + return m_pieSlice; +} + +//![0] +void PieChart::setPieSlice(PieSlice *pieSlice) +{ + m_pieSlice = pieSlice; + pieSlice->setParentItem(this); +} +//![0] + diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/piechart.h b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/piechart.h new file mode 100644 index 0000000000..9f0ea47eb9 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/piechart.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef PIECHART_H +#define PIECHART_H + +#include + +class PieSlice; + +//![0] +class PieChart : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(PieSlice* pieSlice READ pieSlice WRITE setPieSlice) +//![0] + Q_PROPERTY(QString name READ name WRITE setName) + +//![1] +public: +//![1] + + PieChart(QQuickItem *parent = 0); + + QString name() const; + void setName(const QString &name); + +//![2] + PieSlice *pieSlice() const; + void setPieSlice(PieSlice *pieSlice); +//![2] + +private: + QString m_name; + PieSlice *m_pieSlice; + +//![3] +}; +//![3] + +#endif + diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.cpp b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.cpp new file mode 100644 index 0000000000..2afe82048f --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "pieslice.h" + +#include + +PieSlice::PieSlice(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ +} + +QColor PieSlice::color() const +{ + return m_color; +} + +void PieSlice::setColor(const QColor &color) +{ + m_color = color; +} + +void PieSlice::paint(QPainter *painter) +{ + QPen pen(m_color, 2); + painter->setPen(pen); + painter->setRenderHints(QPainter::Antialiasing, true); + painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16); +} + diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.h b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.h new file mode 100644 index 0000000000..4eef9bb6d1 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef PIESLICE_H +#define PIESLICE_H + +#include +#include + +//![0] +class PieSlice : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor) + +public: + PieSlice(QQuickItem *parent = 0); + + QColor color() const; + void setColor(const QColor &color); + + void paint(QPainter *painter); + +private: + QColor m_color; +}; +//![0] + +#endif + diff --git a/examples/qml/tutorials/extending-qml/chapter5-listproperties/app.qml b/examples/qml/tutorials/extending-qml/chapter5-listproperties/app.qml new file mode 100644 index 0000000000..68aa6e0c1d --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter5-listproperties/app.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import Charts 1.0 +import QtQuick 2.0 + +Item { + width: 300; height: 200 + + PieChart { + anchors.centerIn: parent + width: 100; height: 100 + + slices: [ + PieSlice { + anchors.fill: parent + color: "red" + fromAngle: 0; angleSpan: 110 + }, + PieSlice { + anchors.fill: parent + color: "black" + fromAngle: 110; angleSpan: 50 + }, + PieSlice { + anchors.fill: parent + color: "blue" + fromAngle: 160; angleSpan: 100 + } + ] + } +} +//![0] diff --git a/examples/qml/tutorials/extending-qml/chapter5-listproperties/chapter5-listproperties.pro b/examples/qml/tutorials/extending-qml/chapter5-listproperties/chapter5-listproperties.pro new file mode 100644 index 0000000000..67d1cd35c3 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter5-listproperties/chapter5-listproperties.pro @@ -0,0 +1,17 @@ +QT += qml quick + +HEADERS += piechart.h \ + pieslice.h +SOURCES += piechart.cpp \ + pieslice.cpp \ + main.cpp + +RESOURCES += chapter5-listproperties.qrc + +DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter5-listproperties +target.path = $$DESTPATH + +qml.files = *.qml +qml.path = $$DESTPATH + +INSTALLS += target qml diff --git a/examples/qml/tutorials/extending-qml/chapter5-listproperties/chapter5-listproperties.qrc b/examples/qml/tutorials/extending-qml/chapter5-listproperties/chapter5-listproperties.qrc new file mode 100644 index 0000000000..f1168aef3b --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter5-listproperties/chapter5-listproperties.qrc @@ -0,0 +1,5 @@ + + + app.qml + + diff --git a/examples/qml/tutorials/extending-qml/chapter5-listproperties/main.cpp b/examples/qml/tutorials/extending-qml/chapter5-listproperties/main.cpp new file mode 100644 index 0000000000..8a4afcf96d --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter5-listproperties/main.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "piechart.h" +#include "pieslice.h" + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType("Charts", 1, 0, "PieChart"); + qmlRegisterType("Charts", 1, 0, "PieSlice"); + + QQuickView view; + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setSource(QUrl("qrc:///app.qml")); + view.show(); + return app.exec(); +} diff --git a/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.cpp b/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.cpp new file mode 100644 index 0000000000..9fb61d9cd8 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "piechart.h" +#include "pieslice.h" + +PieChart::PieChart(QQuickItem *parent) + : QQuickItem(parent) +{ +} + +QString PieChart::name() const +{ + return m_name; +} + +void PieChart::setName(const QString &name) +{ + m_name = name; +} + +//![0] +QQmlListProperty PieChart::slices() +{ + return QQmlListProperty(this, 0, &PieChart::append_slice, 0, 0, 0); +} + +void PieChart::append_slice(QQmlListProperty *list, PieSlice *slice) +{ + PieChart *chart = qobject_cast(list->object); + if (chart) { + slice->setParentItem(chart); + chart->m_slices.append(slice); + } +} +//![0] diff --git a/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.h b/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.h new file mode 100644 index 0000000000..55488f4900 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter5-listproperties/piechart.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef PIECHART_H +#define PIECHART_H + +#include + +class PieSlice; + +//![0] +class PieChart : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty slices READ slices) +//![0] + Q_PROPERTY(QString name READ name WRITE setName) + +//![1] +public: +//![1] + PieChart(QQuickItem *parent = 0); + + QString name() const; + void setName(const QString &name); + +//![2] + QQmlListProperty slices(); + +private: + static void append_slice(QQmlListProperty *list, PieSlice *slice); + + QString m_name; + QList m_slices; +}; +//![2] + +#endif + diff --git a/examples/qml/tutorials/extending-qml/chapter5-listproperties/pieslice.cpp b/examples/qml/tutorials/extending-qml/chapter5-listproperties/pieslice.cpp new file mode 100644 index 0000000000..52b409aa22 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter5-listproperties/pieslice.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "pieslice.h" + +#include + +PieSlice::PieSlice(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ +} + +QColor PieSlice::color() const +{ + return m_color; +} + +void PieSlice::setColor(const QColor &color) +{ + m_color = color; +} + +int PieSlice::fromAngle() const +{ + return m_fromAngle; +} + +void PieSlice::setFromAngle(int angle) +{ + m_fromAngle = angle; +} + +int PieSlice::angleSpan() const +{ + return m_angleSpan; +} + +void PieSlice::setAngleSpan(int angle) +{ + m_angleSpan = angle; +} + +void PieSlice::paint(QPainter *painter) +{ + QPen pen(m_color, 2); + painter->setPen(pen); + painter->setRenderHints(QPainter::Antialiasing, true); + painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), m_fromAngle * 16, m_angleSpan * 16); +} + diff --git a/examples/qml/tutorials/extending-qml/chapter5-listproperties/pieslice.h b/examples/qml/tutorials/extending-qml/chapter5-listproperties/pieslice.h new file mode 100644 index 0000000000..f324179481 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter5-listproperties/pieslice.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef PIESLICE_H +#define PIESLICE_H + +#include +#include + +//![0] +class PieSlice : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(int fromAngle READ fromAngle WRITE setFromAngle) + Q_PROPERTY(int angleSpan READ angleSpan WRITE setAngleSpan) +//![0] + +public: + PieSlice(QQuickItem *parent = 0); + + QColor color() const; + void setColor(const QColor &color); + + int fromAngle() const; + void setFromAngle(int angle); + + int angleSpan() const; + void setAngleSpan(int span); + + void paint(QPainter *painter); + +private: + QColor m_color; + int m_fromAngle; + int m_angleSpan; +}; + +#endif + diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/app.pro b/examples/qml/tutorials/extending-qml/chapter6-plugins/app.pro new file mode 100644 index 0000000000..c55db00d27 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/app.pro @@ -0,0 +1,10 @@ +TARGET = chapter6-plugins +QT += qml quick + +# Avoid going to debug/release subdirectory +# so that our application will see the +# import path for the Charts module. +win32: DESTDIR = ./ + +SOURCES += main.cpp +RESOURCES += app.qrc diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/app.qml b/examples/qml/tutorials/extending-qml/chapter6-plugins/app.qml new file mode 100644 index 0000000000..d5a474b8d3 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/app.qml @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.0 +import Charts 1.0 + +Item { + width: 300; height: 200 + + PieChart { + anchors.centerIn: parent + width: 100; height: 100 + + slices: [ + PieSlice { + anchors.fill: parent + color: "red" + fromAngle: 0; angleSpan: 110 + }, + PieSlice { + anchors.fill: parent + color: "black" + fromAngle: 110; angleSpan: 50 + }, + PieSlice { + anchors.fill: parent + color: "blue" + fromAngle: 160; angleSpan: 100 + } + ] + } +} + diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/app.qrc b/examples/qml/tutorials/extending-qml/chapter6-plugins/app.qrc new file mode 100644 index 0000000000..f1168aef3b --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/app.qrc @@ -0,0 +1,5 @@ + + + app.qml + + diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/chapter6-plugins.pro b/examples/qml/tutorials/extending-qml/chapter6-plugins/chapter6-plugins.pro new file mode 100644 index 0000000000..f858c80876 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/chapter6-plugins.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs +CONFIG += ordered +SUBDIRS = \ + import \ + app.pro diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/chartsplugin.cpp b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/chartsplugin.cpp new file mode 100644 index 0000000000..fea4c1aa85 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/chartsplugin.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "chartsplugin.h" +//![0] +#include "piechart.h" +#include "pieslice.h" +#include + +void ChartsPlugin::registerTypes(const char *uri) +{ + qmlRegisterType(uri, 1, 0, "PieChart"); + qmlRegisterType(uri, 1, 0, "PieSlice"); +} + +//![0] + diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/chartsplugin.h b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/chartsplugin.h new file mode 100644 index 0000000000..d768306967 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/chartsplugin.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef CHARTSPLUGIN_H +#define CHARTSPLUGIN_H + +//![0] +#include + +class ChartsPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") + +public: + void registerTypes(const char *uri); +}; +//![0] + +#endif + diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/import.pro b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/import.pro new file mode 100644 index 0000000000..cefcf3b477 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/import.pro @@ -0,0 +1,26 @@ +TEMPLATE = lib +CONFIG += plugin +QT += qml quick + +DESTDIR = ../Charts +TARGET = $$qtLibraryTarget(chartsplugin) + +HEADERS += piechart.h \ + pieslice.h \ + chartsplugin.h + +SOURCES += piechart.cpp \ + pieslice.cpp \ + chartsplugin.cpp + +DESTPATH=$$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter6-plugins/Charts + +target.path=$$DESTPATH +qmldir.files=$$PWD/qmldir +qmldir.path=$$DESTPATH +INSTALLS += target qmldir + +OTHER_FILES += qmldir + +# Copy the qmldir file to the same folder as the plugin binary +QMAKE_POST_LINK += $$QMAKE_COPY $$replace($$list($$quote($$PWD/qmldir) $$DESTDIR), /, $$QMAKE_DIR_SEP) diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.cpp b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.cpp new file mode 100644 index 0000000000..295bb8961d --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "piechart.h" +#include "pieslice.h" + +PieChart::PieChart(QQuickItem *parent) + : QQuickItem(parent) +{ +} + +QString PieChart::name() const +{ + return m_name; +} + +void PieChart::setName(const QString &name) +{ + m_name = name; +} + +QQmlListProperty PieChart::slices() +{ + return QQmlListProperty(this, 0, &PieChart::append_slice, 0, 0, 0); +} + +void PieChart::append_slice(QQmlListProperty *list, PieSlice *slice) +{ + PieChart *chart = qobject_cast(list->object); + if (chart) { + slice->setParentItem(chart); + chart->m_slices.append(slice); + } +} diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.h b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.h new file mode 100644 index 0000000000..b37bcdd411 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/piechart.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef PIECHART_H +#define PIECHART_H + +#include + +class PieSlice; + +class PieChart : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty slices READ slices) + Q_PROPERTY(QString name READ name WRITE setName) + +public: + PieChart(QQuickItem *parent = 0); + + QString name() const; + void setName(const QString &name); + + QQmlListProperty slices(); + +private: + static void append_slice(QQmlListProperty *list, PieSlice *slice); + + QString m_name; + QList m_slices; +}; + +#endif + diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.cpp b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.cpp new file mode 100644 index 0000000000..52b409aa22 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "pieslice.h" + +#include + +PieSlice::PieSlice(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ +} + +QColor PieSlice::color() const +{ + return m_color; +} + +void PieSlice::setColor(const QColor &color) +{ + m_color = color; +} + +int PieSlice::fromAngle() const +{ + return m_fromAngle; +} + +void PieSlice::setFromAngle(int angle) +{ + m_fromAngle = angle; +} + +int PieSlice::angleSpan() const +{ + return m_angleSpan; +} + +void PieSlice::setAngleSpan(int angle) +{ + m_angleSpan = angle; +} + +void PieSlice::paint(QPainter *painter) +{ + QPen pen(m_color, 2); + painter->setPen(pen); + painter->setRenderHints(QPainter::Antialiasing, true); + painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), m_fromAngle * 16, m_angleSpan * 16); +} + diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.h b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.h new file mode 100644 index 0000000000..0b488b4835 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/pieslice.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef PIESLICE_H +#define PIESLICE_H + +#include +#include + +class PieSlice : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(int fromAngle READ fromAngle WRITE setFromAngle) + Q_PROPERTY(int angleSpan READ angleSpan WRITE setAngleSpan) + +public: + PieSlice(QQuickItem *parent = 0); + + QColor color() const; + void setColor(const QColor &color); + + int fromAngle() const; + void setFromAngle(int angle); + + int angleSpan() const; + void setAngleSpan(int span); + + void paint(QPainter *painter); + +private: + QColor m_color; + int m_fromAngle; + int m_angleSpan; +}; + +#endif + diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/qmldir b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/qmldir new file mode 100644 index 0000000000..d9e8471b3c --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/qmldir @@ -0,0 +1,2 @@ +module Charts +plugin chartsplugin diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/main.cpp b/examples/qml/tutorials/extending-qml/chapter6-plugins/main.cpp new file mode 100644 index 0000000000..60d8c6cd7a --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + QQuickView view; + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setSource(QUrl("qrc:///app.qml")); + view.show(); + return app.exec(); +} +//![0] diff --git a/examples/qml/tutorials/extending-qml/extending-qml.pro b/examples/qml/tutorials/extending-qml/extending-qml.pro new file mode 100644 index 0000000000..a665975382 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/extending-qml.pro @@ -0,0 +1,10 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + chapter1-basics \ + chapter2-methods \ + chapter3-bindings \ + chapter4-customPropertyTypes \ + chapter5-listproperties \ + chapter6-plugins + diff --git a/examples/qml/tutorials/extending/chapter1-basics/app.qml b/examples/qml/tutorials/extending/chapter1-basics/app.qml deleted file mode 100644 index d2f03daf83..0000000000 --- a/examples/qml/tutorials/extending/chapter1-basics/app.qml +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//![0] -import Charts 1.0 -import QtQuick 2.0 - -Item { - width: 300; height: 200 - - PieChart { - id: aPieChart - anchors.centerIn: parent - width: 100; height: 100 - name: "A simple pie chart" - color: "red" - } - - Text { - anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 } - text: aPieChart.name - } -} -//![0] diff --git a/examples/qml/tutorials/extending/chapter1-basics/chapter1-basics.pro b/examples/qml/tutorials/extending/chapter1-basics/chapter1-basics.pro deleted file mode 100644 index c28664ea51..0000000000 --- a/examples/qml/tutorials/extending/chapter1-basics/chapter1-basics.pro +++ /dev/null @@ -1,15 +0,0 @@ -QT += qml quick - -HEADERS += piechart.h -SOURCES += piechart.cpp \ - main.cpp - -RESOURCES += chapter1-basics.qrc - -DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending/chapter1-basics -target.path = $$DESTPATH - -qml.files = *.qml -qml.path = $$DESTPATH - -INSTALLS += target qml diff --git a/examples/qml/tutorials/extending/chapter1-basics/chapter1-basics.qrc b/examples/qml/tutorials/extending/chapter1-basics/chapter1-basics.qrc deleted file mode 100644 index f1168aef3b..0000000000 --- a/examples/qml/tutorials/extending/chapter1-basics/chapter1-basics.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - app.qml - - diff --git a/examples/qml/tutorials/extending/chapter1-basics/main.cpp b/examples/qml/tutorials/extending/chapter1-basics/main.cpp deleted file mode 100644 index 4e719d2722..0000000000 --- a/examples/qml/tutorials/extending/chapter1-basics/main.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//![0] -#include "piechart.h" -#include -#include - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - - qmlRegisterType("Charts", 1, 0, "PieChart"); - - QQuickView view; - view.setResizeMode(QQuickView::SizeRootObjectToView); - view.setSource(QUrl("qrc:///app.qml")); - view.show(); - return app.exec(); -} -//![0] diff --git a/examples/qml/tutorials/extending/chapter1-basics/piechart.cpp b/examples/qml/tutorials/extending/chapter1-basics/piechart.cpp deleted file mode 100644 index fa005781d8..0000000000 --- a/examples/qml/tutorials/extending/chapter1-basics/piechart.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "piechart.h" -#include - -//![0] -PieChart::PieChart(QQuickItem *parent) - : QQuickPaintedItem(parent) -{ -} -//![0] - -QString PieChart::name() const -{ - return m_name; -} - -void PieChart::setName(const QString &name) -{ - m_name = name; -} - -QColor PieChart::color() const -{ - return m_color; -} - -void PieChart::setColor(const QColor &color) -{ - m_color = color; -} - -//![1] -void PieChart::paint(QPainter *painter) -{ - QPen pen(m_color, 2); - painter->setPen(pen); - painter->setRenderHints(QPainter::Antialiasing, true); - painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16); -} -//![1] - diff --git a/examples/qml/tutorials/extending/chapter1-basics/piechart.h b/examples/qml/tutorials/extending/chapter1-basics/piechart.h deleted file mode 100644 index a6272453ce..0000000000 --- a/examples/qml/tutorials/extending/chapter1-basics/piechart.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef PIECHART_H -#define PIECHART_H - -//![0] -#include -#include - -class PieChart : public QQuickPaintedItem -{ - Q_OBJECT - Q_PROPERTY(QString name READ name WRITE setName) - Q_PROPERTY(QColor color READ color WRITE setColor) - -public: - PieChart(QQuickItem *parent = 0); - - QString name() const; - void setName(const QString &name); - - QColor color() const; - void setColor(const QColor &color); - - void paint(QPainter *painter); - -private: - QString m_name; - QColor m_color; -}; -//![0] - -#endif - diff --git a/examples/qml/tutorials/extending/chapter2-methods/app.qml b/examples/qml/tutorials/extending/chapter2-methods/app.qml deleted file mode 100644 index 06ecb3a09d..0000000000 --- a/examples/qml/tutorials/extending/chapter2-methods/app.qml +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//![0] -import Charts 1.0 -import QtQuick 2.0 - -Item { - width: 300; height: 200 - - PieChart { - id: aPieChart - anchors.centerIn: parent - width: 100; height: 100 - color: "red" - - onChartCleared: console.log("The chart has been cleared") - } - - MouseArea { - anchors.fill: parent - onClicked: aPieChart.clearChart() - } - - Text { - anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 } - text: "Click anywhere to clear the chart" - } -} -//![0] diff --git a/examples/qml/tutorials/extending/chapter2-methods/chapter2-methods.pro b/examples/qml/tutorials/extending/chapter2-methods/chapter2-methods.pro deleted file mode 100644 index a451c775cf..0000000000 --- a/examples/qml/tutorials/extending/chapter2-methods/chapter2-methods.pro +++ /dev/null @@ -1,15 +0,0 @@ -QT += qml quick - -HEADERS += piechart.h -SOURCES += piechart.cpp \ - main.cpp - -RESOURCES += chapter2-methods.qrc - -DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending/chapter2-methods -target.path = $$DESTPATH - -qml.files = *.qml -qml.path = $$DESTPATH - -INSTALLS += target qml diff --git a/examples/qml/tutorials/extending/chapter2-methods/chapter2-methods.qrc b/examples/qml/tutorials/extending/chapter2-methods/chapter2-methods.qrc deleted file mode 100644 index f1168aef3b..0000000000 --- a/examples/qml/tutorials/extending/chapter2-methods/chapter2-methods.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - app.qml - - diff --git a/examples/qml/tutorials/extending/chapter2-methods/main.cpp b/examples/qml/tutorials/extending/chapter2-methods/main.cpp deleted file mode 100644 index 4e719d2722..0000000000 --- a/examples/qml/tutorials/extending/chapter2-methods/main.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//![0] -#include "piechart.h" -#include -#include - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - - qmlRegisterType("Charts", 1, 0, "PieChart"); - - QQuickView view; - view.setResizeMode(QQuickView::SizeRootObjectToView); - view.setSource(QUrl("qrc:///app.qml")); - view.show(); - return app.exec(); -} -//![0] diff --git a/examples/qml/tutorials/extending/chapter2-methods/piechart.cpp b/examples/qml/tutorials/extending/chapter2-methods/piechart.cpp deleted file mode 100644 index ddcb1b3efd..0000000000 --- a/examples/qml/tutorials/extending/chapter2-methods/piechart.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "piechart.h" -#include - -PieChart::PieChart(QQuickItem *parent) - : QQuickPaintedItem(parent) -{ -} - -QString PieChart::name() const -{ - return m_name; -} - -void PieChart::setName(const QString &name) -{ - m_name = name; -} - -QColor PieChart::color() const -{ - return m_color; -} - -void PieChart::setColor(const QColor &color) -{ - m_color = color; -} - -void PieChart::paint(QPainter *painter) -{ - QPen pen(m_color, 2); - painter->setPen(pen); - painter->setRenderHints(QPainter::Antialiasing, true); - painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16); -} - -//![0] -void PieChart::clearChart() -{ - setColor(QColor(Qt::transparent)); - update(); - - emit chartCleared(); -} -//![0] diff --git a/examples/qml/tutorials/extending/chapter2-methods/piechart.h b/examples/qml/tutorials/extending/chapter2-methods/piechart.h deleted file mode 100644 index 86750197d2..0000000000 --- a/examples/qml/tutorials/extending/chapter2-methods/piechart.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef PIECHART_H -#define PIECHART_H - -#include -#include - -//![0] -class PieChart : public QQuickPaintedItem -{ -//![0] - Q_OBJECT - Q_PROPERTY(QString name READ name WRITE setName) - Q_PROPERTY(QColor color READ color WRITE setColor) - -//![1] -public: -//![1] - - PieChart(QQuickItem *parent = 0); - - QString name() const; - void setName(const QString &name); - - QColor color() const; - void setColor(const QColor &color); - - void paint(QPainter *painter); - -//![2] - Q_INVOKABLE void clearChart(); - -signals: - void chartCleared(); -//![2] - -private: - QString m_name; - QColor m_color; - -//![3] -}; -//![3] - -#endif - diff --git a/examples/qml/tutorials/extending/chapter3-bindings/app.qml b/examples/qml/tutorials/extending/chapter3-bindings/app.qml deleted file mode 100644 index afb9e25c51..0000000000 --- a/examples/qml/tutorials/extending/chapter3-bindings/app.qml +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//![0] -import Charts 1.0 -import QtQuick 2.0 - -Item { - width: 300; height: 200 - - Row { - anchors.centerIn: parent - spacing: 20 - - PieChart { - id: chartA - width: 100; height: 100 - color: "red" - } - - PieChart { - id: chartB - width: 100; height: 100 - color: chartA.color - } - } - - MouseArea { - anchors.fill: parent - onClicked: { chartA.color = "blue" } - } - - Text { - anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 } - text: "Click anywhere to change the chart color" - } -} -//![0] diff --git a/examples/qml/tutorials/extending/chapter3-bindings/chapter3-binding.qrc b/examples/qml/tutorials/extending/chapter3-bindings/chapter3-binding.qrc deleted file mode 100644 index f1168aef3b..0000000000 --- a/examples/qml/tutorials/extending/chapter3-bindings/chapter3-binding.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - app.qml - - diff --git a/examples/qml/tutorials/extending/chapter3-bindings/chapter3-bindings.pro b/examples/qml/tutorials/extending/chapter3-bindings/chapter3-bindings.pro deleted file mode 100644 index 6193f466c1..0000000000 --- a/examples/qml/tutorials/extending/chapter3-bindings/chapter3-bindings.pro +++ /dev/null @@ -1,15 +0,0 @@ -QT += qml quick - -HEADERS += piechart.h -SOURCES += piechart.cpp \ - main.cpp - -RESOURCES += chapter3-binding.qrc - -DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending/chapter3-binding -target.path = $$DESTPATH - -qml.files = *.qml -qml.path = $$DESTPATH - -INSTALLS += target qml diff --git a/examples/qml/tutorials/extending/chapter3-bindings/main.cpp b/examples/qml/tutorials/extending/chapter3-bindings/main.cpp deleted file mode 100644 index 4e719d2722..0000000000 --- a/examples/qml/tutorials/extending/chapter3-bindings/main.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//![0] -#include "piechart.h" -#include -#include - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - - qmlRegisterType("Charts", 1, 0, "PieChart"); - - QQuickView view; - view.setResizeMode(QQuickView::SizeRootObjectToView); - view.setSource(QUrl("qrc:///app.qml")); - view.show(); - return app.exec(); -} -//![0] diff --git a/examples/qml/tutorials/extending/chapter3-bindings/piechart.cpp b/examples/qml/tutorials/extending/chapter3-bindings/piechart.cpp deleted file mode 100644 index a63035033f..0000000000 --- a/examples/qml/tutorials/extending/chapter3-bindings/piechart.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "piechart.h" -#include - -PieChart::PieChart(QQuickItem *parent) - : QQuickPaintedItem(parent) -{ -} - -QString PieChart::name() const -{ - return m_name; -} - -void PieChart::setName(const QString &name) -{ - m_name = name; -} - -QColor PieChart::color() const -{ - return m_color; -} - -//![0] -void PieChart::setColor(const QColor &color) -{ - if (color != m_color) { - m_color = color; - update(); // repaint with the new color - emit colorChanged(); - } -} -//![0] - -void PieChart::paint(QPainter *painter) -{ - QPen pen(m_color, 2); - painter->setPen(pen); - painter->setRenderHints(QPainter::Antialiasing, true); - painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16); -} - -void PieChart::clearChart() -{ - setColor(QColor(Qt::transparent)); - update(); -} diff --git a/examples/qml/tutorials/extending/chapter3-bindings/piechart.h b/examples/qml/tutorials/extending/chapter3-bindings/piechart.h deleted file mode 100644 index 25e82d66cc..0000000000 --- a/examples/qml/tutorials/extending/chapter3-bindings/piechart.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef PIECHART_H -#define PIECHART_H - -#include -#include - -//![0] -class PieChart : public QQuickPaintedItem -{ -//![0] - Q_OBJECT - Q_PROPERTY(QString name READ name WRITE setName) - -//![1] - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) -public: -//![1] - - PieChart(QQuickItem *parent = 0); - - QString name() const; - void setName(const QString &name); - - QColor color() const; - void setColor(const QColor &color); - - void paint(QPainter *painter); - - Q_INVOKABLE void clearChart(); - -//![2] -signals: - void colorChanged(); -//![2] - -private: - QString m_name; - QColor m_color; - -//![3] -}; -//![3] - -#endif - diff --git a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/app.qml b/examples/qml/tutorials/extending/chapter4-customPropertyTypes/app.qml deleted file mode 100644 index c757fdaedd..0000000000 --- a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/app.qml +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//![0] -import Charts 1.0 -import QtQuick 2.0 - -Item { - width: 300; height: 200 - - PieChart { - id: chart - anchors.centerIn: parent - width: 100; height: 100 - - pieSlice: PieSlice { - anchors.fill: parent - color: "red" - } - } - - Component.onCompleted: console.log("The pie is colored " + chart.pieSlice.color) -} -//![0] diff --git a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pro b/examples/qml/tutorials/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pro deleted file mode 100644 index 1742334107..0000000000 --- a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pro +++ /dev/null @@ -1,17 +0,0 @@ -QT += qml quick - -HEADERS += piechart.h \ - pieslice.h -SOURCES += piechart.cpp \ - pieslice.cpp \ - main.cpp - -RESOURCES += chapter4-customPropertyTypes.qrc - -DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending/chapter4-customPropertyTypes -target.path = $$DESTPATH - -qml.files = *.qml -qml.path = $$DESTPATH - -INSTALLS += target qml diff --git a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.qrc b/examples/qml/tutorials/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.qrc deleted file mode 100644 index f1168aef3b..0000000000 --- a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - app.qml - - diff --git a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/main.cpp b/examples/qml/tutorials/extending/chapter4-customPropertyTypes/main.cpp deleted file mode 100644 index fc59a11987..0000000000 --- a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/main.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "piechart.h" -#include "pieslice.h" - -#include -#include - -//![0] -int main(int argc, char *argv[]) -{ -//![0] - QGuiApplication app(argc, argv); - - qmlRegisterType("Charts", 1, 0, "PieChart"); - -//![1] - qmlRegisterType("Charts", 1, 0, "PieSlice"); -//![1] - - QQuickView view; - view.setResizeMode(QQuickView::SizeRootObjectToView); - view.setSource(QUrl("qrc:///app.qml")); - view.show(); - return app.exec(); - -//![2] -} -//![2] diff --git a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/piechart.cpp b/examples/qml/tutorials/extending/chapter4-customPropertyTypes/piechart.cpp deleted file mode 100644 index c1e2996e83..0000000000 --- a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/piechart.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "piechart.h" -#include "pieslice.h" - -PieChart::PieChart(QQuickItem *parent) - : QQuickItem(parent) -{ -} - -QString PieChart::name() const -{ - return m_name; -} - -void PieChart::setName(const QString &name) -{ - m_name = name; -} - -PieSlice *PieChart::pieSlice() const -{ - return m_pieSlice; -} - -//![0] -void PieChart::setPieSlice(PieSlice *pieSlice) -{ - m_pieSlice = pieSlice; - pieSlice->setParentItem(this); -} -//![0] - diff --git a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/piechart.h b/examples/qml/tutorials/extending/chapter4-customPropertyTypes/piechart.h deleted file mode 100644 index 9f0ea47eb9..0000000000 --- a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/piechart.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef PIECHART_H -#define PIECHART_H - -#include - -class PieSlice; - -//![0] -class PieChart : public QQuickItem -{ - Q_OBJECT - Q_PROPERTY(PieSlice* pieSlice READ pieSlice WRITE setPieSlice) -//![0] - Q_PROPERTY(QString name READ name WRITE setName) - -//![1] -public: -//![1] - - PieChart(QQuickItem *parent = 0); - - QString name() const; - void setName(const QString &name); - -//![2] - PieSlice *pieSlice() const; - void setPieSlice(PieSlice *pieSlice); -//![2] - -private: - QString m_name; - PieSlice *m_pieSlice; - -//![3] -}; -//![3] - -#endif - diff --git a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/pieslice.cpp b/examples/qml/tutorials/extending/chapter4-customPropertyTypes/pieslice.cpp deleted file mode 100644 index 2afe82048f..0000000000 --- a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/pieslice.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "pieslice.h" - -#include - -PieSlice::PieSlice(QQuickItem *parent) - : QQuickPaintedItem(parent) -{ -} - -QColor PieSlice::color() const -{ - return m_color; -} - -void PieSlice::setColor(const QColor &color) -{ - m_color = color; -} - -void PieSlice::paint(QPainter *painter) -{ - QPen pen(m_color, 2); - painter->setPen(pen); - painter->setRenderHints(QPainter::Antialiasing, true); - painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16); -} - diff --git a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/pieslice.h b/examples/qml/tutorials/extending/chapter4-customPropertyTypes/pieslice.h deleted file mode 100644 index 4eef9bb6d1..0000000000 --- a/examples/qml/tutorials/extending/chapter4-customPropertyTypes/pieslice.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef PIESLICE_H -#define PIESLICE_H - -#include -#include - -//![0] -class PieSlice : public QQuickPaintedItem -{ - Q_OBJECT - Q_PROPERTY(QColor color READ color WRITE setColor) - -public: - PieSlice(QQuickItem *parent = 0); - - QColor color() const; - void setColor(const QColor &color); - - void paint(QPainter *painter); - -private: - QColor m_color; -}; -//![0] - -#endif - diff --git a/examples/qml/tutorials/extending/chapter5-listproperties/app.qml b/examples/qml/tutorials/extending/chapter5-listproperties/app.qml deleted file mode 100644 index 68aa6e0c1d..0000000000 --- a/examples/qml/tutorials/extending/chapter5-listproperties/app.qml +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//![0] -import Charts 1.0 -import QtQuick 2.0 - -Item { - width: 300; height: 200 - - PieChart { - anchors.centerIn: parent - width: 100; height: 100 - - slices: [ - PieSlice { - anchors.fill: parent - color: "red" - fromAngle: 0; angleSpan: 110 - }, - PieSlice { - anchors.fill: parent - color: "black" - fromAngle: 110; angleSpan: 50 - }, - PieSlice { - anchors.fill: parent - color: "blue" - fromAngle: 160; angleSpan: 100 - } - ] - } -} -//![0] diff --git a/examples/qml/tutorials/extending/chapter5-listproperties/chapter5-listproperties.pro b/examples/qml/tutorials/extending/chapter5-listproperties/chapter5-listproperties.pro deleted file mode 100644 index ba51dd9093..0000000000 --- a/examples/qml/tutorials/extending/chapter5-listproperties/chapter5-listproperties.pro +++ /dev/null @@ -1,17 +0,0 @@ -QT += qml quick - -HEADERS += piechart.h \ - pieslice.h -SOURCES += piechart.cpp \ - pieslice.cpp \ - main.cpp - -RESOURCES += chapter5-listproperties.qrc - -DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending/chapter5-listproperties -target.path = $$DESTPATH - -qml.files = *.qml -qml.path = $$DESTPATH - -INSTALLS += target qml diff --git a/examples/qml/tutorials/extending/chapter5-listproperties/chapter5-listproperties.qrc b/examples/qml/tutorials/extending/chapter5-listproperties/chapter5-listproperties.qrc deleted file mode 100644 index f1168aef3b..0000000000 --- a/examples/qml/tutorials/extending/chapter5-listproperties/chapter5-listproperties.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - app.qml - - diff --git a/examples/qml/tutorials/extending/chapter5-listproperties/main.cpp b/examples/qml/tutorials/extending/chapter5-listproperties/main.cpp deleted file mode 100644 index 8a4afcf96d..0000000000 --- a/examples/qml/tutorials/extending/chapter5-listproperties/main.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "piechart.h" -#include "pieslice.h" - -#include -#include - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - - qmlRegisterType("Charts", 1, 0, "PieChart"); - qmlRegisterType("Charts", 1, 0, "PieSlice"); - - QQuickView view; - view.setResizeMode(QQuickView::SizeRootObjectToView); - view.setSource(QUrl("qrc:///app.qml")); - view.show(); - return app.exec(); -} diff --git a/examples/qml/tutorials/extending/chapter5-listproperties/piechart.cpp b/examples/qml/tutorials/extending/chapter5-listproperties/piechart.cpp deleted file mode 100644 index 9fb61d9cd8..0000000000 --- a/examples/qml/tutorials/extending/chapter5-listproperties/piechart.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "piechart.h" -#include "pieslice.h" - -PieChart::PieChart(QQuickItem *parent) - : QQuickItem(parent) -{ -} - -QString PieChart::name() const -{ - return m_name; -} - -void PieChart::setName(const QString &name) -{ - m_name = name; -} - -//![0] -QQmlListProperty PieChart::slices() -{ - return QQmlListProperty(this, 0, &PieChart::append_slice, 0, 0, 0); -} - -void PieChart::append_slice(QQmlListProperty *list, PieSlice *slice) -{ - PieChart *chart = qobject_cast(list->object); - if (chart) { - slice->setParentItem(chart); - chart->m_slices.append(slice); - } -} -//![0] diff --git a/examples/qml/tutorials/extending/chapter5-listproperties/piechart.h b/examples/qml/tutorials/extending/chapter5-listproperties/piechart.h deleted file mode 100644 index 55488f4900..0000000000 --- a/examples/qml/tutorials/extending/chapter5-listproperties/piechart.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef PIECHART_H -#define PIECHART_H - -#include - -class PieSlice; - -//![0] -class PieChart : public QQuickItem -{ - Q_OBJECT - Q_PROPERTY(QQmlListProperty slices READ slices) -//![0] - Q_PROPERTY(QString name READ name WRITE setName) - -//![1] -public: -//![1] - PieChart(QQuickItem *parent = 0); - - QString name() const; - void setName(const QString &name); - -//![2] - QQmlListProperty slices(); - -private: - static void append_slice(QQmlListProperty *list, PieSlice *slice); - - QString m_name; - QList m_slices; -}; -//![2] - -#endif - diff --git a/examples/qml/tutorials/extending/chapter5-listproperties/pieslice.cpp b/examples/qml/tutorials/extending/chapter5-listproperties/pieslice.cpp deleted file mode 100644 index 52b409aa22..0000000000 --- a/examples/qml/tutorials/extending/chapter5-listproperties/pieslice.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "pieslice.h" - -#include - -PieSlice::PieSlice(QQuickItem *parent) - : QQuickPaintedItem(parent) -{ -} - -QColor PieSlice::color() const -{ - return m_color; -} - -void PieSlice::setColor(const QColor &color) -{ - m_color = color; -} - -int PieSlice::fromAngle() const -{ - return m_fromAngle; -} - -void PieSlice::setFromAngle(int angle) -{ - m_fromAngle = angle; -} - -int PieSlice::angleSpan() const -{ - return m_angleSpan; -} - -void PieSlice::setAngleSpan(int angle) -{ - m_angleSpan = angle; -} - -void PieSlice::paint(QPainter *painter) -{ - QPen pen(m_color, 2); - painter->setPen(pen); - painter->setRenderHints(QPainter::Antialiasing, true); - painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), m_fromAngle * 16, m_angleSpan * 16); -} - diff --git a/examples/qml/tutorials/extending/chapter5-listproperties/pieslice.h b/examples/qml/tutorials/extending/chapter5-listproperties/pieslice.h deleted file mode 100644 index f324179481..0000000000 --- a/examples/qml/tutorials/extending/chapter5-listproperties/pieslice.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef PIESLICE_H -#define PIESLICE_H - -#include -#include - -//![0] -class PieSlice : public QQuickPaintedItem -{ - Q_OBJECT - Q_PROPERTY(QColor color READ color WRITE setColor) - Q_PROPERTY(int fromAngle READ fromAngle WRITE setFromAngle) - Q_PROPERTY(int angleSpan READ angleSpan WRITE setAngleSpan) -//![0] - -public: - PieSlice(QQuickItem *parent = 0); - - QColor color() const; - void setColor(const QColor &color); - - int fromAngle() const; - void setFromAngle(int angle); - - int angleSpan() const; - void setAngleSpan(int span); - - void paint(QPainter *painter); - -private: - QColor m_color; - int m_fromAngle; - int m_angleSpan; -}; - -#endif - diff --git a/examples/qml/tutorials/extending/chapter6-plugins/app.pro b/examples/qml/tutorials/extending/chapter6-plugins/app.pro deleted file mode 100644 index c55db00d27..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/app.pro +++ /dev/null @@ -1,10 +0,0 @@ -TARGET = chapter6-plugins -QT += qml quick - -# Avoid going to debug/release subdirectory -# so that our application will see the -# import path for the Charts module. -win32: DESTDIR = ./ - -SOURCES += main.cpp -RESOURCES += app.qrc diff --git a/examples/qml/tutorials/extending/chapter6-plugins/app.qml b/examples/qml/tutorials/extending/chapter6-plugins/app.qml deleted file mode 100644 index d5a474b8d3..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/app.qml +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -import QtQuick 2.0 -import Charts 1.0 - -Item { - width: 300; height: 200 - - PieChart { - anchors.centerIn: parent - width: 100; height: 100 - - slices: [ - PieSlice { - anchors.fill: parent - color: "red" - fromAngle: 0; angleSpan: 110 - }, - PieSlice { - anchors.fill: parent - color: "black" - fromAngle: 110; angleSpan: 50 - }, - PieSlice { - anchors.fill: parent - color: "blue" - fromAngle: 160; angleSpan: 100 - } - ] - } -} - diff --git a/examples/qml/tutorials/extending/chapter6-plugins/app.qrc b/examples/qml/tutorials/extending/chapter6-plugins/app.qrc deleted file mode 100644 index f1168aef3b..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/app.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - app.qml - - diff --git a/examples/qml/tutorials/extending/chapter6-plugins/chapter6-plugins.pro b/examples/qml/tutorials/extending/chapter6-plugins/chapter6-plugins.pro deleted file mode 100644 index f858c80876..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/chapter6-plugins.pro +++ /dev/null @@ -1,5 +0,0 @@ -TEMPLATE = subdirs -CONFIG += ordered -SUBDIRS = \ - import \ - app.pro diff --git a/examples/qml/tutorials/extending/chapter6-plugins/import/chartsplugin.cpp b/examples/qml/tutorials/extending/chapter6-plugins/import/chartsplugin.cpp deleted file mode 100644 index fea4c1aa85..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/import/chartsplugin.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "chartsplugin.h" -//![0] -#include "piechart.h" -#include "pieslice.h" -#include - -void ChartsPlugin::registerTypes(const char *uri) -{ - qmlRegisterType(uri, 1, 0, "PieChart"); - qmlRegisterType(uri, 1, 0, "PieSlice"); -} - -//![0] - diff --git a/examples/qml/tutorials/extending/chapter6-plugins/import/chartsplugin.h b/examples/qml/tutorials/extending/chapter6-plugins/import/chartsplugin.h deleted file mode 100644 index d768306967..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/import/chartsplugin.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef CHARTSPLUGIN_H -#define CHARTSPLUGIN_H - -//![0] -#include - -class ChartsPlugin : public QQmlExtensionPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") - -public: - void registerTypes(const char *uri); -}; -//![0] - -#endif - diff --git a/examples/qml/tutorials/extending/chapter6-plugins/import/import.pro b/examples/qml/tutorials/extending/chapter6-plugins/import/import.pro deleted file mode 100644 index 83cfb96ab5..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/import/import.pro +++ /dev/null @@ -1,26 +0,0 @@ -TEMPLATE = lib -CONFIG += plugin -QT += qml quick - -DESTDIR = ../Charts -TARGET = $$qtLibraryTarget(chartsplugin) - -HEADERS += piechart.h \ - pieslice.h \ - chartsplugin.h - -SOURCES += piechart.cpp \ - pieslice.cpp \ - chartsplugin.cpp - -DESTPATH=$$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending/chapter6-plugins/Charts - -target.path=$$DESTPATH -qmldir.files=$$PWD/qmldir -qmldir.path=$$DESTPATH -INSTALLS += target qmldir - -OTHER_FILES += qmldir - -# Copy the qmldir file to the same folder as the plugin binary -QMAKE_POST_LINK += $$QMAKE_COPY $$replace($$list($$quote($$PWD/qmldir) $$DESTDIR), /, $$QMAKE_DIR_SEP) diff --git a/examples/qml/tutorials/extending/chapter6-plugins/import/piechart.cpp b/examples/qml/tutorials/extending/chapter6-plugins/import/piechart.cpp deleted file mode 100644 index 295bb8961d..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/import/piechart.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "piechart.h" -#include "pieslice.h" - -PieChart::PieChart(QQuickItem *parent) - : QQuickItem(parent) -{ -} - -QString PieChart::name() const -{ - return m_name; -} - -void PieChart::setName(const QString &name) -{ - m_name = name; -} - -QQmlListProperty PieChart::slices() -{ - return QQmlListProperty(this, 0, &PieChart::append_slice, 0, 0, 0); -} - -void PieChart::append_slice(QQmlListProperty *list, PieSlice *slice) -{ - PieChart *chart = qobject_cast(list->object); - if (chart) { - slice->setParentItem(chart); - chart->m_slices.append(slice); - } -} diff --git a/examples/qml/tutorials/extending/chapter6-plugins/import/piechart.h b/examples/qml/tutorials/extending/chapter6-plugins/import/piechart.h deleted file mode 100644 index b37bcdd411..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/import/piechart.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef PIECHART_H -#define PIECHART_H - -#include - -class PieSlice; - -class PieChart : public QQuickItem -{ - Q_OBJECT - Q_PROPERTY(QQmlListProperty slices READ slices) - Q_PROPERTY(QString name READ name WRITE setName) - -public: - PieChart(QQuickItem *parent = 0); - - QString name() const; - void setName(const QString &name); - - QQmlListProperty slices(); - -private: - static void append_slice(QQmlListProperty *list, PieSlice *slice); - - QString m_name; - QList m_slices; -}; - -#endif - diff --git a/examples/qml/tutorials/extending/chapter6-plugins/import/pieslice.cpp b/examples/qml/tutorials/extending/chapter6-plugins/import/pieslice.cpp deleted file mode 100644 index 52b409aa22..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/import/pieslice.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "pieslice.h" - -#include - -PieSlice::PieSlice(QQuickItem *parent) - : QQuickPaintedItem(parent) -{ -} - -QColor PieSlice::color() const -{ - return m_color; -} - -void PieSlice::setColor(const QColor &color) -{ - m_color = color; -} - -int PieSlice::fromAngle() const -{ - return m_fromAngle; -} - -void PieSlice::setFromAngle(int angle) -{ - m_fromAngle = angle; -} - -int PieSlice::angleSpan() const -{ - return m_angleSpan; -} - -void PieSlice::setAngleSpan(int angle) -{ - m_angleSpan = angle; -} - -void PieSlice::paint(QPainter *painter) -{ - QPen pen(m_color, 2); - painter->setPen(pen); - painter->setRenderHints(QPainter::Antialiasing, true); - painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), m_fromAngle * 16, m_angleSpan * 16); -} - diff --git a/examples/qml/tutorials/extending/chapter6-plugins/import/pieslice.h b/examples/qml/tutorials/extending/chapter6-plugins/import/pieslice.h deleted file mode 100644 index 0b488b4835..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/import/pieslice.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef PIESLICE_H -#define PIESLICE_H - -#include -#include - -class PieSlice : public QQuickPaintedItem -{ - Q_OBJECT - Q_PROPERTY(QColor color READ color WRITE setColor) - Q_PROPERTY(int fromAngle READ fromAngle WRITE setFromAngle) - Q_PROPERTY(int angleSpan READ angleSpan WRITE setAngleSpan) - -public: - PieSlice(QQuickItem *parent = 0); - - QColor color() const; - void setColor(const QColor &color); - - int fromAngle() const; - void setFromAngle(int angle); - - int angleSpan() const; - void setAngleSpan(int span); - - void paint(QPainter *painter); - -private: - QColor m_color; - int m_fromAngle; - int m_angleSpan; -}; - -#endif - diff --git a/examples/qml/tutorials/extending/chapter6-plugins/import/qmldir b/examples/qml/tutorials/extending/chapter6-plugins/import/qmldir deleted file mode 100644 index d9e8471b3c..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/import/qmldir +++ /dev/null @@ -1,2 +0,0 @@ -module Charts -plugin chartsplugin diff --git a/examples/qml/tutorials/extending/chapter6-plugins/main.cpp b/examples/qml/tutorials/extending/chapter6-plugins/main.cpp deleted file mode 100644 index 60d8c6cd7a..0000000000 --- a/examples/qml/tutorials/extending/chapter6-plugins/main.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -//![0] -#include -#include - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - QQuickView view; - view.setResizeMode(QQuickView::SizeRootObjectToView); - view.setSource(QUrl("qrc:///app.qml")); - view.show(); - return app.exec(); -} -//![0] diff --git a/examples/qml/tutorials/extending/extending.pro b/examples/qml/tutorials/extending/extending.pro deleted file mode 100644 index a665975382..0000000000 --- a/examples/qml/tutorials/extending/extending.pro +++ /dev/null @@ -1,10 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS += \ - chapter1-basics \ - chapter2-methods \ - chapter3-bindings \ - chapter4-customPropertyTypes \ - chapter5-listproperties \ - chapter6-plugins - diff --git a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc index aab729656b..b593753d33 100644 --- a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc +++ b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc @@ -26,9 +26,9 @@ ****************************************************************************/ /*! -\page qml-extending-tutorial-index.html tutorial +\example tutorials/extending-qml \title Writing QML Extensions with C++ -\brief tutorial about extending QML with Qt C++ +\brief Tutorial about extending QML with Qt C++. The \l {Qt QML} module provides a set of APIs for extending QML through C++ extensions. You can write extensions to add your own QML types, extend existing @@ -38,33 +38,22 @@ This tutorial shows how to write a QML extension using C++ that includes core QML features, including properties, signals and bindings. It also shows how extensions can be deployed through plugins. -You can find the source code for this tutorial in \c Qt's -examples/qml/tutorials/extending directory. - -Tutorial chapters: - -\list 1 -\li \l{tutorials/extending/chapter1-basics}{Creating a New Type} -\li \l{tutorials/extending/chapter2-methods}{Connecting to C++ Methods and Signals} -\li \l{tutorials/extending/chapter3-bindings}{Property Binding} -\li \l{tutorials/extending/chapter4-customPropertyTypes}{Using Custom Property Types} -\li \l{tutorials/extending/chapter5-listproperties}{Using List Property Types} -\li \l{tutorials/extending/chapter6-plugins}{Writing an Extension Plugin} -\li \l{qml-extending-tutorial7.html}{In Summary} -\endlist - Many of the topics covered in this tutorial are documented in further detail in \l {qtqml-cppintegration-topic.html}{Integrating QML and C++} and its documentation sub-topics. In particular, you may be interested in the sub-topics \l{qtqml-cppintegration-exposecppattributes.html}{Exposing Attributes of C++ Classes to QML} and \l {qtqml-cppintegration-definetypes.html}{Defining QML Types from C++}. -*/ +\section1 Running the Tutorial Examples -/*! -\title Chapter 1: Creating a New Type +The code in this tutorial is available as an example project with subprojects +associated with each tutorial chapter. In \l{Qt Creator Manual}{Qt Creator}, open +the \uicontrol Welcome mode and select the tutorial from \uicontrol Examples. In +\uicontrol Edit mode, expand the \e extending-qml project, right-click on the +subproject (chapter) you want to run and select \uicontrol Run. -\example tutorials/extending/chapter1-basics +\section1 Chapter 1: Creating a New Type +\c extending-qml/chapter1-basics A common task when extending QML is to provide a new QML type that supports some custom functionality beyond what is provided by the built-in \l {Qt Quick QML Types}{Qt Quick types}. @@ -83,7 +72,7 @@ a version of 1.0. We want this \c PieChart type to be usable from QML like this: -\code +\badcode import Charts 1.0 PieChart { @@ -104,7 +93,7 @@ this new class must: Here is our \c PieChart class, defined in \c piechart.h: -\snippet tutorials/extending/chapter1-basics/piechart.h 0 +\snippet tutorials/extending-qml/chapter1-basics/piechart.h 0 The class inherits from QQuickPaintedItem because we want to override QQuickPaintedItem::paint() in perform drawing operations with the QPainter API. @@ -120,15 +109,15 @@ simply sets and returns the \c m_name and \c m_color values as appropriate, and implements \c paint() to draw a simple pie chart. It also turns off the QGraphicsItem::ItemHasNoContents flag to enable painting: -\snippet tutorials/extending/chapter1-basics/piechart.cpp 0 +\snippet tutorials/extending-qml/chapter1-basics/piechart.cpp 0 \dots 0 -\snippet tutorials/extending/chapter1-basics/piechart.cpp 1 +\snippet tutorials/extending-qml/chapter1-basics/piechart.cpp 1 Now that we have defined the \c PieChart type, we will use it from QML. The \c app.qml file creates a \c PieChart item and display the pie chart's details using a standard QML \l Text item: -\snippet tutorials/extending/chapter1-basics/app.qml 0 +\snippet tutorials/extending-qml/chapter1-basics/app.qml 0 Notice that although the color is specified as a string in QML, it is automatically converted to a QColor object for the PieChart \c color property. Automatic conversions are @@ -142,46 +131,46 @@ you don't register the type, \c app.qml won't be able to create a \c PieChart. Here is the application \c main.cpp: -\snippet tutorials/extending/chapter1-basics/main.cpp 0 +\snippet tutorials/extending-qml/chapter1-basics/main.cpp 0 This call to qmlRegisterType() registers the \c PieChart type as a type called "PieChart", in a type namespace called "Charts", with a version of 1.0. Lastly, we write a \c .pro project file that includes the files and the \c declarative library: -\quotefile tutorials/extending/chapter1-basics/chapter1-basics.pro +\quotefile tutorials/extending-qml/chapter1-basics/chapter1-basics.pro Now we can build and run the application: \image extending-tutorial-chapter1.png -Try it yourself with the code in Qt's \c examples/qml/tutorials/extending/chapter1-basics directory. -*/ - - -/*! -\title Chapter 2: Connecting to C++ Methods and Signals +\note You may see a warning \e {Expression ... depends on non-NOTIFYable properties: + PieChart::name}. This happens because we add a binding to the writable \c name + property, but haven't yet defined a notify signal for it. The QML engine therefore + cannot update the binding if the \c name value changes. This is addressed in + the following chapters. -\example tutorials/extending/chapter2-methods +\section1 Chapter 2: Connecting to C++ Methods and Signals +\c extending-qml/chapter2-methods Suppose we want \c PieChart to have a "clearChart()" method that erases the chart and then emits a "chartCleared" signal. Our \c app.qml would be able to call \c clearChart() and receive \c chartCleared() signals like this: -\snippet tutorials/extending/chapter2-methods/app.qml 0 +\snippet tutorials/extending-qml/chapter2-methods/app.qml 0 \image extending-tutorial-chapter2.png To do this, we add a \c clearChart() method and a \c chartCleared() signal to our C++ class: -\snippet tutorials/extending/chapter2-methods/piechart.h 0 +\snippet tutorials/extending-qml/chapter2-methods/piechart.h 0 \dots -\snippet tutorials/extending/chapter2-methods/piechart.h 1 +\snippet tutorials/extending-qml/chapter2-methods/piechart.h 1 \dots -\snippet tutorials/extending/chapter2-methods/piechart.h 2 +\snippet tutorials/extending-qml/chapter2-methods/piechart.h 2 \dots -\snippet tutorials/extending/chapter2-methods/piechart.h 3 +\snippet tutorials/extending-qml/chapter2-methods/piechart.h 3 The use of Q_INVOKABLE makes the \c clearChart() method available to the Qt Meta-Object system, and in turn, to QML. Note that it could have @@ -191,23 +180,17 @@ slots are also callable from QML. Both of these approaches are valid. The \c clearChart() method simply changes the color to Qt::transparent, repaints the chart, then emits the \c chartCleared() signal: -\snippet tutorials/extending/chapter2-methods/piechart.cpp 0 +\snippet tutorials/extending-qml/chapter2-methods/piechart.cpp 0 Now when we run the application and click the window, the pie chart disappears, and the application outputs: -\code - The chart has been cleared +\badcode + qml: The chart has been cleared \endcode -Try out the example yourself with the updated code in Qt's \c examples/qml/tutorials/extending/chapter2-methods directory. - -*/ - -/*! -\title Chapter 3: Adding Property Bindings - -\example tutorials/extending/chapter3-bindings +\section1 Chapter 3: Adding Property Bindings +\c extending-qml/chapter3-bindings Property binding is a powerful feature of QML that allows values of different types to be synchronized automatically. It uses signals to notify and update @@ -216,7 +199,7 @@ other types' values when property values are changed. Let's enable property bindings for the \c color property. That means if we have code like this: -\snippet tutorials/extending/chapter3-bindings/app.qml 0 +\snippet tutorials/extending-qml/chapter3-bindings/app.qml 0 \image extending-tutorial-chapter3.png @@ -231,17 +214,17 @@ It's easy to enable property binding for the \c color property. We add a \l{Qt's Property System}{NOTIFY} feature to its Q_PROPERTY() declaration to indicate that a "colorChanged" signal is emitted whenever the value changes. -\snippet tutorials/extending/chapter3-bindings/piechart.h 0 +\snippet tutorials/extending-qml/chapter3-bindings/piechart.h 0 \dots -\snippet tutorials/extending/chapter3-bindings/piechart.h 1 +\snippet tutorials/extending-qml/chapter3-bindings/piechart.h 1 \dots -\snippet tutorials/extending/chapter3-bindings/piechart.h 2 +\snippet tutorials/extending-qml/chapter3-bindings/piechart.h 2 \dots -\snippet tutorials/extending/chapter3-bindings/piechart.h 3 +\snippet tutorials/extending-qml/chapter3-bindings/piechart.h 3 Then, we emit this signal in \c setPieSlice(): -\snippet tutorials/extending/chapter3-bindings/piechart.cpp 0 +\snippet tutorials/extending-qml/chapter3-bindings/piechart.cpp 0 It's important for \c setColor() to check that the color value has actually changed before emitting \c colorChanged(). This ensures the signal is not emitted unnecessarily and @@ -254,12 +237,9 @@ automatically updated and cannot be used as flexibly in QML. Also, since bindings are invoked so often and relied upon in QML usage, users of your custom QML types may see unexpected behavior if bindings are not implemented. -*/ - -/*! -\title Chapter 4: Using Custom Property Types +\section1 Chapter 4: Using Custom Property Types -\example tutorials/extending/chapter4-customPropertyTypes +\c extending-qml/chapter4-customPropertyTypes The \c PieChart type currently has a string-type property and a color-type property. It could have many other types of properties. For example, it could have an @@ -299,57 +279,49 @@ For example, let's replace the use of the \c property with a type called "PieSlice" that has a \c color property. Instead of assigning a color, we assign an \c PieSlice value which itself contains a \c color: -\snippet tutorials/extending/chapter4-customPropertyTypes/app.qml 0 +\snippet tutorials/extending-qml/chapter4-customPropertyTypes/app.qml 0 Like \c PieChart, this new \c PieSlice type inherits from QQuickPaintedItem and declares its properties with Q_PROPERTY(): -\snippet tutorials/extending/chapter4-customPropertyTypes/pieslice.h 0 +\snippet tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.h 0 To use it in \c PieChart, we modify the \c color property declaration and associated method signatures: -\snippet tutorials/extending/chapter4-customPropertyTypes/piechart.h 0 +\snippet tutorials/extending-qml/chapter4-customPropertyTypes/piechart.h 0 \dots -\snippet tutorials/extending/chapter4-customPropertyTypes/piechart.h 1 +\snippet tutorials/extending-qml/chapter4-customPropertyTypes/piechart.h 1 \dots -\snippet tutorials/extending/chapter4-customPropertyTypes/piechart.h 2 +\snippet tutorials/extending-qml/chapter4-customPropertyTypes/piechart.h 2 \dots -\snippet tutorials/extending/chapter4-customPropertyTypes/piechart.h 3 +\snippet tutorials/extending-qml/chapter4-customPropertyTypes/piechart.h 3 There is one thing to be aware of when implementing \c setPieSlice(). The \c PieSlice is a visual item, so it must be set as a child of the \c PieChart using QQuickItem::setParentItem() so that the \c PieChart knows to paint this child item when its contents are drawn: -\snippet tutorials/extending/chapter4-customPropertyTypes/piechart.cpp 0 - +\snippet tutorials/extending-qml/chapter4-customPropertyTypes/piechart.cpp 0 Like the \c PieChart type, the \c PieSlice type has to be registered using qmlRegisterType() to be used from QML. As with \c PieChart, we'll add the type to the "Charts" type namespace, version 1.0: -\snippet tutorials/extending/chapter4-customPropertyTypes/main.cpp 0 +\snippet tutorials/extending-qml/chapter4-customPropertyTypes/main.cpp 0 \dots -\snippet tutorials/extending/chapter4-customPropertyTypes/main.cpp 1 +\snippet tutorials/extending-qml/chapter4-customPropertyTypes/main.cpp 1 \dots -\snippet tutorials/extending/chapter4-customPropertyTypes/main.cpp 2 - -Try it out with the code in Qt's \c examples/qml/tutorials/extending/chapter4-customPropertyTypes directory. - -*/ - +\snippet tutorials/extending-qml/chapter4-customPropertyTypes/main.cpp 2 -/*! -\title Chapter 5: Using List Property Types - -\example tutorials/extending/chapter5-listproperties +\section1 Chapter 5: Using List Property Types +\c extending-qml/chapter5-listproperties Right now, a \c PieChart can only have one \c PieSlice. Ideally a chart would have multiple slices, with different colors and sizes. To do this, we could have a \c slices property that accepts a list of \c PieSlice items: -\snippet tutorials/extending/chapter5-listproperties/app.qml 0 +\snippet tutorials/extending-qml/chapter5-listproperties/app.qml 0 \image extending-tutorial-chapter5.png @@ -360,11 +332,11 @@ function with a \c slices() function that returns a list of slices, and add an internal \c append_slice() function (discussed below). We also use a QList to store the internal list of slices as \c m_slices: -\snippet tutorials/extending/chapter5-listproperties/piechart.h 0 +\snippet tutorials/extending-qml/chapter5-listproperties/piechart.h 0 \dots -\snippet tutorials/extending/chapter5-listproperties/piechart.h 1 +\snippet tutorials/extending-qml/chapter5-listproperties/piechart.h 1 \dots -\snippet tutorials/extending/chapter5-listproperties/piechart.h 2 +\snippet tutorials/extending-qml/chapter5-listproperties/piechart.h 2 Although the \c slices property does not have an associated \c WRITE function, it is still modifiable because of the way QQmlListProperty works. @@ -373,7 +345,7 @@ return a QQmlListProperty value and indicate that the internal \c PieChart::append_slice() function is to be called whenever a request is made from QML to add items to the list: -\snippet tutorials/extending/chapter5-listproperties/piechart.cpp 0 +\snippet tutorials/extending-qml/chapter5-listproperties/piechart.cpp 0 The \c append_slice() function simply sets the parent item as before, and adds the new item to the \c m_slices list. As you can see, the append function for a @@ -384,15 +356,9 @@ The \c PieSlice class has also been modified to include \c fromAngle and \c angl properties and to draw the slice according to these values. This is a straightforward modification if you have read the previous pages in this tutorial, so the code is not shown here. -The complete code can be seen in the updated \c examples/qml/tutorials/extending/chapter5-listproperties directory. - -*/ - +\section1 Chapter 6: Writing an Extension Plugin -/*! -\title Chapter 6: Writing an Extension Plugin - -\example tutorials/extending/chapter6-plugins +\c extending-qml/chapter6-plugins Currently the \c PieChart and \c PieSlice types are used by \c app.qml, which is displayed using a QQuickView in a C++ application. An alternative @@ -408,17 +374,17 @@ and registers our QML types in the inherited \l{QQmlExtensionPlugin::}{registerT Here is the \c ChartsPlugin definition in \c chartsplugin.h: -\snippet tutorials/extending/chapter6-plugins/import/chartsplugin.h 0 +\snippet tutorials/extending-qml/chapter6-plugins/import/chartsplugin.h 0 And its implementation in \c chartsplugin.cpp: -\snippet tutorials/extending/chapter6-plugins/import/chartsplugin.cpp 0 +\snippet tutorials/extending-qml/chapter6-plugins/import/chartsplugin.cpp 0 Then, we write a \c .pro project file that defines the project as a plugin library and specifies with DESTDIR that library files should be built into a \c {../Charts} directory. -\quotefile tutorials/extending/chapter6-plugins/import/import.pro +\quotefile tutorials/extending-qml/chapter6-plugins/import/import.pro In this example, the \c Charts directory is located at the same level as the application that uses our new import module. This way, the QML engine will find our module @@ -434,7 +400,7 @@ to the same location as the plugin binary. The \c qmldir file declares the module name and the plugin that is made available by the module: -\quotefile tutorials/extending/chapter6-plugins/import/qmldir +\quotefile tutorials/extending-qml/chapter6-plugins/import/qmldir Now we have a QML module that can be imported to any application, provided that the QML engine knows where to find it. The example contains an executable that loads @@ -448,31 +414,29 @@ import path to the current directory so that it finds the \c qmldir file: The module "Charts" will be loaded by the QML engine, and the types provided by that module will be available for use in any QML document which imports it. -*/ - -/*! -\page qml-extending-tutorial7.html -\title Chapter 7: In Summary +\section1 Chapter 7: Summary In this tutorial, we've shown the basic steps for creating a QML extension: \list -\li Define new QML types by subclassing QObject and registering them with qmlRegisterType() -\li Add callable methods using Q_INVOKABLE or Qt slots, and connect to Qt signals with an \c onSignal syntax +\li Define new QML types by subclassing QObject and registering them with + qmlRegisterType() +\li Add callable methods using \l Q_INVOKABLE or Qt slots, and connect to Qt signals + with an \c onSignal syntax \li Add property bindings by defining \l{Qt's Property System}{NOTIFY} signals \li Define custom property types if the built-in types are not sufficient \li Define list property types using QQmlListProperty -\li Create a plugin library by defining a Qt plugin and writing a \c qmldir file +\li Create a plugin library by defining a Qt plugin and writing a + \l {Module Definition qmldir Files}{qmldir} file \endlist - The \l{Integrating QML and C++} documentation shows other useful features that can be added to QML extensions. For example, we could use \l{Default Properties}{default properties} to allow slices to be added without using the \c slices property: -\code +\badcode PieChart { PieSlice { ... } PieSlice { ... } @@ -482,13 +446,11 @@ slices to be added without using the \c slices property: Or randomly add and remove slices from time to time using \l{Property Value Sources}{property value sources}: -\code +\badcode PieChart { PieSliceRandomizer on slices {} } \endcode - -See the \l{Integrating QML and C++} documentation for more information. - +\sa {Integrating QML and C++} */ -- cgit v1.2.3 From f83d12e0c27ad76d98d66a663140a09698b11d37 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 24 Sep 2014 14:37:46 +0200 Subject: Update the Calqltr demo visuals and engine logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add logic for displaying the calculation result in the best available precision, determined by the display width - Display 'ERROR' when the result cannot be displayed - Animate the number pad button colors to react to presses and visually disable them when pressing the button has no effect - Fix issues in calculator.js logic - Update documentation accordingly Task-number: QTBUG-41253 Change-Id: Ibed7b8218ea4cd074b8f9b90d9bb4e3ea6b25ba2 Reviewed-by: Johanna Äijälä Reviewed-by: Leena Miettinen Reviewed-by: Venugopal Shivashankar --- examples/quick/demos/calqlatr/calqlatr.qml | 15 ++++- examples/quick/demos/calqlatr/content/Button.qml | 29 ++++++++-- examples/quick/demos/calqlatr/content/Display.qml | 61 ++++++++++++++++++-- .../quick/demos/calqlatr/content/NumberPad.qml | 18 +++--- .../quick/demos/calqlatr/content/calculator.js | 43 +++++++------- .../quick/demos/calqlatr/doc/src/calqlatr.qdoc | 67 ++++++++++++++++++---- 6 files changed, 181 insertions(+), 52 deletions(-) diff --git a/examples/quick/demos/calqlatr/calqlatr.qml b/examples/quick/demos/calqlatr/calqlatr.qml index 02c5b13399..8bda2c521e 100644 --- a/examples/quick/demos/calqlatr/calqlatr.qml +++ b/examples/quick/demos/calqlatr/calqlatr.qml @@ -53,13 +53,22 @@ Rectangle { onWidthChanged: controller.reload() onHeightChanged: controller.reload() - function operatorPressed(operator) { CalcEngine.operatorPressed(operator) } - function digitPressed(digit) { CalcEngine.digitPressed(digit) } + function operatorPressed(operator) { + CalcEngine.operatorPressed(operator) + numPad.buttonPressed() + } + function digitPressed(digit) { + CalcEngine.digitPressed(digit) + numPad.buttonPressed() + } + function isButtonDisabled(op) { + return CalcEngine.disabled(op) + } Item { id: pad width: 180 - NumberPad { y: 10; anchors.horizontalCenter: parent.horizontalCenter } + NumberPad { id: numPad; y: 10; anchors.horizontalCenter: parent.horizontalCenter } } AnimationController { diff --git a/examples/quick/demos/calqlatr/content/Button.qml b/examples/quick/demos/calqlatr/content/Button.qml index fc6234414f..0748645274 100644 --- a/examples/quick/demos/calqlatr/content/Button.qml +++ b/examples/quick/demos/calqlatr/content/Button.qml @@ -41,12 +41,13 @@ import QtQuick 2.0 Item { + id: button property alias text: textItem.text - property alias color: textItem.color + property color color: "#eceeea" property bool operator: false - - signal clicked + property bool dimmable: false + property bool dimmed: false width: 30 height: 50 @@ -56,7 +57,18 @@ Item { font.pixelSize: 48 wrapMode: Text.WordWrap lineHeight: 0.75 - color: "white" + color: (dimmable && dimmed) ? Qt.darker(button.color) : button.color + Behavior on color { ColorAnimation { duration: 120; easing.type: Easing.OutElastic} } + states: [ + State { + name: "pressed" + when: mouse.pressed && !dimmed + PropertyChanges { + target: textItem + color: Qt.lighter(button.color) + } + } + ] } MouseArea { @@ -70,4 +82,13 @@ Item { window.digitPressed(parent.text) } } + + function updateDimmed() { + dimmed = window.isButtonDisabled(button.text) + } + + Component.onCompleted: { + numPad.buttonPressed.connect(updateDimmed) + updateDimmed() + } } diff --git a/examples/quick/demos/calqlatr/content/Display.qml b/examples/quick/demos/calqlatr/content/Display.qml index 97eed1e57e..efa7a1ab66 100644 --- a/examples/quick/demos/calqlatr/content/Display.qml +++ b/examples/quick/demos/calqlatr/content/Display.qml @@ -39,10 +39,16 @@ ****************************************************************************/ import QtQuick 2.0 +import QtQuick.Window 2.0 Item { id: display + property real fontSize: Math.floor(Screen.pixelDensity * 5.0) property bool enteringDigits: false + property int maxDigits: (width / fontSize) + 1 + property string displayedOperand + property string errorString: qsTr("ERROR") + property bool isError: displayedOperand === errorString function displayOperator(operator) { @@ -53,7 +59,8 @@ Item { function newLine(operator, operand) { - listView.model.append({ "operator": operator, "operand": operand }) + displayedOperand = displayNumber(operand) + listView.model.append({ "operator": operator, "operand": displayedOperand }) enteringDigits = false listView.positionViewAtEnd() } @@ -68,8 +75,16 @@ Item { listView.positionViewAtEnd() } + function setDigit(digit) + { + var i = listView.model.count - 1; + listView.model.get(i).operand = digit; + listView.positionViewAtEnd() + } + function clear() { + displayedOperand = "" if (enteringDigits) { var i = listView.model.count - 1 if (i >= 0) @@ -78,6 +93,42 @@ Item { } } + // Returns a string representation of a number that fits in + // display.maxDigits characters, trying to keep as much precision + // as possible. If the number cannot be displayed, returns an + // error string. + function displayNumber(num) { + if (typeof(num) != "number") + return errorString; + + var intNum = parseInt(num); + var intLen = intNum.toString().length; + + // Do not count the minus sign as a digit + var maxLen = num < 0 ? maxDigits + 1 : maxDigits; + + if (num.toString().length <= maxLen) { + if (isFinite(num)) + return num.toString(); + return errorString; + } + + // Integer part of the number is too long - try + // an exponential notation + if (intNum == num || intLen > maxLen - 3) { + var expVal = num.toExponential(maxDigits - 6).toString(); + if (expVal.length <= maxLen) + return expVal; + } + + // Try a float presentation with fixed number of digits + var floatStr = parseFloat(num).toFixed(maxDigits - intLen - 1).toString(); + if (floatStr.length <= maxLen) + return floatStr; + + return errorString; + } + Item { id: theItem width: parent.width + 32 @@ -121,16 +172,16 @@ Item { width: parent.width Text { id: operator - x: 8 - font.pixelSize: 18 + x: 6 + font.pixelSize: display.fontSize color: "#6da43d" text: model.operator } Text { id: operand - font.pixelSize: 18 + font.pixelSize: display.fontSize anchors.right: parent.right - anchors.rightMargin: 26 + anchors.rightMargin: 22 text: model.operand } } diff --git a/examples/quick/demos/calqlatr/content/NumberPad.qml b/examples/quick/demos/calqlatr/content/NumberPad.qml index c7f2680651..c4ae1bb582 100644 --- a/examples/quick/demos/calqlatr/content/NumberPad.qml +++ b/examples/quick/demos/calqlatr/content/NumberPad.qml @@ -45,6 +45,8 @@ Grid { columnSpacing: 32 rowSpacing: 16 + signal buttonPressed + Button { text: "7" } Button { text: "8" } Button { text: "9" } @@ -55,15 +57,15 @@ Grid { Button { text: "2" } Button { text: "3" } Button { text: "0" } - Button { text: "." } + Button { text: "."; dimmable: true } Button { text: " " } - Button { text: "±"; color: "#6da43d"; operator: true } - Button { text: "−"; color: "#6da43d"; operator: true } - Button { text: "+"; color: "#6da43d"; operator: true } - Button { text: "√"; color: "#6da43d"; operator: true } - Button { text: "÷"; color: "#6da43d"; operator: true } - Button { text: "×"; color: "#6da43d"; operator: true } + Button { text: "±"; color: "#6da43d"; operator: true; dimmable: true } + Button { text: "−"; color: "#6da43d"; operator: true; dimmable: true } + Button { text: "+"; color: "#6da43d"; operator: true; dimmable: true } + Button { text: "√"; color: "#6da43d"; operator: true; dimmable: true } + Button { text: "÷"; color: "#6da43d"; operator: true; dimmable: true } + Button { text: "×"; color: "#6da43d"; operator: true; dimmable: true } Button { text: "C"; color: "#6da43d"; operator: true } Button { text: " "; color: "#6da43d"; operator: true } - Button { text: "="; color: "#6da43d"; operator: true } + Button { text: "="; color: "#6da43d"; operator: true; dimmable: true } } diff --git a/examples/quick/demos/calqlatr/content/calculator.js b/examples/quick/demos/calqlatr/content/calculator.js index 906cb9d3b7..841ba9414c 100644 --- a/examples/quick/demos/calqlatr/content/calculator.js +++ b/examples/quick/demos/calqlatr/content/calculator.js @@ -38,7 +38,6 @@ ** ****************************************************************************/ - var curVal = 0 var memory = 0 var lastOp = "" @@ -46,9 +45,13 @@ var previousOperator = "" var digits = "" function disabled(op) { - if (op == "." && digits.toString().search(/\./) != -1) { + if (digits == "" && !((op >= "0" && op <= "9") || op == ".")) + return true + else if (op == '=' && previousOperator.length != 1) return true - } else if (op == window.squareRoot && digits.toString().search(/-/) != -1) { + else if (op == "." && digits.toString().search(/\./) != -1) { + return true + } else if (op == "√" && digits.toString().search(/-/) != -1) { return true } else { return false @@ -59,7 +62,7 @@ function digitPressed(op) { if (disabled(op)) return - if (digits.toString().length >= 8) + if (digits.toString().length >= display.maxDigits) return if (lastOp.toString().length == 1 && ((lastOp >= "0" && lastOp <= "9") || lastOp == ".") ) { digits = digits + op.toString() @@ -77,6 +80,12 @@ function operatorPressed(op) return lastOp = op + if (op == "±") { + digits = Number(digits.valueOf() * -1) + display.setDigit(display.displayNumber(digits)) + return + } + if (previousOperator == "+") { digits = Number(digits.valueOf()) + Number(curVal.valueOf()) } else if (previousOperator == "−") { @@ -85,7 +94,6 @@ function operatorPressed(op) digits = Number(curVal) * Number(digits.valueOf()) } else if (previousOperator == "÷") { digits = Number(curVal) / Number(digits.valueOf()) - } else if (previousOperator == "=") { } if (op == "+" || op == "−" || op == "×" || op == "÷") { @@ -97,10 +105,7 @@ function operatorPressed(op) } if (op == "=") { - if (digits.toString().length >= 9) - digits = digits.toExponential(2) - - display.newLine("=", digits.toString()) + display.newLine("=", digits.valueOf()) } curVal = 0 @@ -114,12 +119,9 @@ function operatorPressed(op) digits = (Math.abs(digits.valueOf())).toString() } else if (op == "Int") { digits = (Math.floor(digits.valueOf())).toString() - } else if (op == "±") { - digits = (digits.valueOf() * -1).toString() - display.clear() - display.appendDigit(digits) } else if (op == "√") { - digits = (Math.sqrt(digits.valueOf())).toString() + digits = Number(Math.sqrt(digits.valueOf())) + display.newLine("√", digits.valueOf()) } else if (op == "mc") { memory = 0; } else if (op == "m+") { @@ -134,17 +136,16 @@ function operatorPressed(op) display.appendDigit(digits) } else if (op == "Off") { Qt.quit(); - } else if (op == "C") { + } + + // Reset the state on 'C' operator or after + // an error occurred + if (op == "C" || display.isError) { display.clear() curVal = 0 memory = 0 lastOp = "" - digits ="0" - } else if (op == "AC") { - curVal = 0 - memory = 0 - lastOp = "" - digits ="0" + digits = "" } } diff --git a/examples/quick/demos/calqlatr/doc/src/calqlatr.qdoc b/examples/quick/demos/calqlatr/doc/src/calqlatr.qdoc index e72d048567..7316f27595 100644 --- a/examples/quick/demos/calqlatr/doc/src/calqlatr.qdoc +++ b/examples/quick/demos/calqlatr/doc/src/calqlatr.qdoc @@ -49,7 +49,6 @@ \li Button.qml \li Display.qml \li NumberPad.qml - \li StyleLabel.qml \endlist To use the custom types, we add an import statement to the main QML file, @@ -70,7 +69,7 @@ \printuntil } \printuntil } - Further, we use the Button type in the NumberPad type to create the + Further, we use the Button type in the \c NumberPad type to create the calculator buttons. Button.qml specifies the basic properties for a button that we can modify for each button instance in NumberPad.qml. For the digit and separator buttons, we additionally specify the text property using @@ -86,6 +85,11 @@ \skipto Grid \printuntil /^\}/ + Some of the buttons also have a \c dimmable property set, meaning that they + can be visually disabled (dimmed) whenever the calculator engine does not + accept input from that button. As an example, the button for square root + operator is dimmed for negative values. + \section1 Animating Components We use the Display type to display calculations. In Display.qml, we use @@ -100,7 +104,11 @@ is the id of our AnimationController: \quotefromfile demos/calqlatr/calqlatr.qml - \skipto onPressed + \skipto MouseArea + \printuntil { + \dots 12 + \skipto onReleased + \printuntil } \printuntil } Unlike other QML animation types, AnimationController is not driven by @@ -123,26 +131,63 @@ We use the easing curve of the type \c Easing.InOutQuad to accelerate the motion until halfway and then decelerate it. + In Button.qml, the text colors of the number pad buttons are also animated. + + \quotefromfile demos/calqlatr/content/Button.qml + \skipto Text + \printuntil id: + \dots 8 + \skipto color: + \printuntil ] + \printuntil } + + We use \l {QtQml::Qt::darker()}{Qt.darker()} to darken the color when the + button is dimmed, and \l {QtQml::Qt::lighter()}{Qt.lighter()} to \e {light up} + the button when pressed. The latter is done in a separate \l [QML] {State} + {state} called \e "pressed", which activates when the \c pressed + property of the button's MouseArea is set. + + The color changes are animated by defining a \l Behavior on the \c color + property. + + In order to dynamically change the \c dimmed property of all the buttons + of the \c NumberPad, we connect its \c buttonPressed signal to the + \c Button's \c updateDimmed() function in Button.qml: + + \quotefromfile demos/calqlatr/content/Button.qml + \skipto function updateDimmed() { + \printuntil buttonPressed.connect + \printuntil } + + This way, when a button is pressed, all buttons on the \c NumPad + receive a \c buttonPressed signal and are activated or deactivated + according to the state of the calculator engine. + \section1 Performing Calculations - The calculator.js file contains definitions for the functions to execute - when users press the digit and operator buttons. To use the functions, we + The calculator.js file defines our calculator engine. It contains variables + to store the calculator state, and functions that are called when the + user presses the digit and operator buttons. To use the engine, we import calculator.js in the calqlatr.qml file as \c CalcEngine: \code import "content/calculator.js" as CalcEngine \endcode - We can then declare the functions to execute depending on whether the - operator property for a button is set to \c true in NumberPad.qml: + Importing the engine creates a new instance of it. Therefore, we only do it + in the main QML file, \c calqlatr.qml. The root item defined in this file + contains helper functions that allow other types to access the calculator + engine: \quotefromfile demos/calqlatr/calqlatr.qml \skipto operatorPressed - \printuntil digitPressed + \printuntil CalcEngine.disabled + \printuntil } - When users press a digit or operator, the text from the digit appears on the - display. When they press the equals operator (=), the appropriate - calculation is performed, and the results appear on the display. + When users press a digit, the text from the digit appears on the + display. When they press an operator, the appropriate calculation is + performed, and the result can be displayed using the equals (=) operator. + The clear (C) operator resets the calculator engine. \section1 List of Files -- cgit v1.2.3 From 328f7bbab666c7af1aec2df69cbdd7ea1a3991db Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 2 Sep 2014 14:48:03 +0200 Subject: Fix compiler warning Add a matching operator delete to our operator new to shut up MSVC. Task-number: QTBUG-40652 Change-Id: I1396094d23c4d0cfc88a73fabbab05f1d4ec7b44 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4managed_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index 36cf8f9424..ce0ee973e8 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -212,6 +212,7 @@ struct Q_QML_PRIVATE_EXPORT Managed void *operator new(size_t, Managed *m) { return m; } void *operator new(size_t, Managed::Data *m) { return m; } + void operator delete(void *, Managed::Data *) {} }; Data data; V4_MANAGED(Managed) -- cgit v1.2.3 From 0322dddbca7cb0024d2b01fcfa25f996788ba57d Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 30 Sep 2014 10:40:40 +0200 Subject: Document that QQmlApplicationEngine's root item must be a window. Change-Id: I22466e82105c9b56894a53400394d1124191f93d Reviewed-by: Robin Burchell --- src/qml/qml/qqmlapplicationengine.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index 56eddfa478..240c01233b 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -160,6 +160,10 @@ void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o) } \endcode + Unlike QQuickView, QQmlApplicationEngine does not automatically create a root + window. If you are using visual items from Qt Quick, you will need to place + them inside of a \l [QML] {Window}. + You can also use QCoreApplication with QQmlApplicationEngine, if you are not using any QML modules which require a QGuiApplication (such as \c QtQuick). List of configuration changes from a default QQmlEngine: @@ -167,7 +171,7 @@ void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o) \list \li Connecting Qt.quit() to QCoreApplication::quit() \li Automatically loads translation files from an i18n directory adjacent to the main QML file. - \li Automatically sets an incubuation controller if the scene contains a QQuickWindow. + \li Automatically sets an incubation controller if the scene contains a QQuickWindow. \li Automatically sets a \c QQmlFileSelector as the url interceptor, applying file selectors to all QML files and assets. \endlist -- cgit v1.2.3 From 125c96476e98cb393d2cf133a8245cb0672109a1 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 26 Sep 2014 19:43:52 +0200 Subject: Make Canvas use texture atlas for smallish Image based canvases. This makes Canvas with Image batchable in the renderer which means that it is feasible to have 100s of small Canvases in a scene, for instance as static icons rendered with a bit of script. Change-Id: I3ad57360d632b7093fd6993afa88ed35c21d178a Reviewed-by: Mitch Curtis Reviewed-by: Laszlo Agocs --- src/quick/items/context2d/qquickcanvasitem.cpp | 2 +- src/quick/items/context2d/qquickcontext2dtexture.cpp | 19 ++++++------------- src/quick/items/context2d/qquickcontext2dtexture_p.h | 6 +++--- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 77a405907e..15eb28350e 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -749,7 +749,7 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData QQuickContext2D *ctx = qobject_cast(d->context); QQuickContext2DTexture *factory = ctx->texture(); - QSGTexture *texture = factory->textureForNextFrame(node->texture()); + QSGTexture *texture = factory->textureForNextFrame(node->texture(), window()); if (!texture) { delete node; d->node = 0; diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index a3b316a217..1dd8e50387 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -427,7 +427,7 @@ QVector2D QQuickContext2DFBOTexture::scaleFactor() const m_fbo->height() / m_fboSize.height()); } -QSGTexture *QQuickContext2DFBOTexture::textureForNextFrame(QSGTexture *lastTexture) +QSGTexture *QQuickContext2DFBOTexture::textureForNextFrame(QSGTexture *lastTexture, QQuickWindow *) { QSGPlainTexture *texture = static_cast(lastTexture); @@ -666,22 +666,15 @@ void QQuickContext2DImageTexture::grabImage(const QRectF& rf) QQuickContext2D::mutex.unlock(); } -QSGTexture *QQuickContext2DImageTexture::textureForNextFrame(QSGTexture *last) +QSGTexture *QQuickContext2DImageTexture::textureForNextFrame(QSGTexture *last, QQuickWindow *window) { - QSGPlainTexture *texture = static_cast(last); - if (m_onCustomThread) m_mutex.lock(); - if (!texture) { - texture = new QSGPlainTexture(); - texture->setHasAlphaChannel(true); - m_dirtyTexture = true; - } - if (m_dirtyTexture) { - texture->setImage(m_displayImage); - m_dirtyTexture = false; - } + delete last; + + QSGTexture *texture = window->createTextureFromImage(m_displayImage, QQuickWindow::TextureCanUseAtlas); + m_dirtyTexture = false; if (m_onCustomThread) m_mutex.unlock(); diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h index 10ac246d1b..3ff0cb12c1 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture_p.h +++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h @@ -102,7 +102,7 @@ public: bool isOnCustomThread() const { return m_onCustomThread; } // Called during sync() on the scene graph thread while GUI is blocked. - virtual QSGTexture *textureForNextFrame(QSGTexture *lastFrame) = 0; + virtual QSGTexture *textureForNextFrame(QSGTexture *lastFrame, QQuickWindow *window) = 0; bool event(QEvent *e); void initializeOpenGL(QOpenGLContext *gl, QOffscreenSurface *s) { @@ -173,7 +173,7 @@ public: virtual void compositeTile(QQuickContext2DTile* tile); QSize adjustedTileSize(const QSize &ts); - QSGTexture *textureForNextFrame(QSGTexture *); + QSGTexture *textureForNextFrame(QSGTexture *, QQuickWindow *window); protected: QVector2D scaleFactor() const Q_DECL_OVERRIDE; @@ -209,7 +209,7 @@ public: virtual void endPainting(); virtual void compositeTile(QQuickContext2DTile* tile); - virtual QSGTexture *textureForNextFrame(QSGTexture *lastFrame); + virtual QSGTexture *textureForNextFrame(QSGTexture *lastFrame, QQuickWindow *window); public Q_SLOTS: virtual void grabImage(const QRectF& region = QRectF()); -- cgit v1.2.3 From 64e2fa80015fb7d9e53cc66357870d4ea11f3590 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 1 Oct 2014 11:12:18 +0200 Subject: Partially revert d9c531781e6c95f80681b3c82700833e1de88794 This logic changed then timing for when the layer's m_dirtyTexture was set and unset, which had some side effects. Revert to the old and known-to-work behavior of using a connection. Change-Id: I4048e7ae70491afe36b2d766e6c506d9febc44ed Task-number: QTBUG-41451 Reviewed-by: Mitch Curtis Reviewed-by: Giulio Camuffo Reviewed-by: Simon Hausmann --- src/quick/items/qquickshadereffectsource.cpp | 24 +++++++++++++++++++----- src/quick/scenegraph/qsgadaptationlayer.cpp | 21 --------------------- src/quick/scenegraph/qsgadaptationlayer_p.h | 9 --------- src/quick/scenegraph/qsgdefaultlayer.cpp | 13 +++---------- src/quick/scenegraph/qsgdefaultlayer_p.h | 3 --- 5 files changed, 22 insertions(+), 48 deletions(-) diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index 120a8956eb..520a58a37b 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -74,7 +74,6 @@ public: QSGTexture::WrapMode horizontalWrap; QSGTexture::WrapMode verticalWrap; }; -#include "qquickshadereffectsource.moc" class QQuickShaderEffectSourceCleanup : public QRunnable { @@ -586,13 +585,24 @@ void QQuickShaderEffectSource::releaseResources() } } +class QQuickShaderSourceAttachedNode : public QObject, public QSGNode +{ + Q_OBJECT +public: + Q_SLOT void markTextureDirty() { + QSGNode *pn = QSGNode::parent(); + if (pn) { + Q_ASSERT(pn->type() == QSGNode::GeometryNodeType); + pn->markDirty(DirtyMaterial); + } + } +}; + QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { if (!m_sourceItem || m_sourceItem->width() <= 0 || m_sourceItem->height() <= 0) { - if (m_texture) { + if (m_texture) m_texture->setItem(0); - m_texture->setShaderSourceNode(0); - } delete oldNode; return 0; } @@ -658,7 +668,9 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint node = d->sceneGraphContext()->createImageNode(); node->setFlag(QSGNode::UsePreprocess); node->setTexture(m_texture); - m_texture->setShaderSourceNode(node); + QQuickShaderSourceAttachedNode *attached = new QQuickShaderSourceAttachedNode; + node->appendChildNode(attached); + connect(m_texture, SIGNAL(updateRequested()), attached, SLOT(markTextureDirty())); } // If live and recursive, update continuously. @@ -698,4 +710,6 @@ void QQuickShaderEffectSource::itemChange(ItemChange change, const ItemChangeDat QQuickItem::itemChange(change, value); } +#include "qquickshadereffectsource.moc" + QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index fb9fe00ee5..80234d54f5 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -339,25 +339,4 @@ void QSGNodeVisitorEx::visitChildren(QSGNode *node) } } -void QSGLayer::markDirtyTextureLater() -{ - QCoreApplication::postEvent(this, new QEvent(static_cast(markDirtyEventType()))); -} - -void QSGLayer::customEvent(QEvent *event) -{ - if (event->type() == markDirtyEventType()) - markDirtyTexture(); - else - QObject::customEvent(event); -} - -int QSGLayer::markDirtyEventType() -{ - static int type = QEvent::None; - if (type == QEvent::None) - type = QEvent::registerEventType(); - return type; -} - QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index 71033bd6d0..a63299fcde 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -198,7 +198,6 @@ class Q_QUICK_EXPORT QSGLayer : public QSGDynamicTexture Q_OBJECT public: virtual void setItem(QSGNode *item) = 0; - virtual void setShaderSourceNode(QSGNode *node) = 0; virtual void setRect(const QRectF &rect) = 0; virtual void setSize(const QSize &size) = 0; virtual void scheduleUpdate() = 0; @@ -211,17 +210,9 @@ public: Q_SLOT virtual void markDirtyTexture() = 0; Q_SLOT virtual void invalidated() = 0; - Q_SLOT void markDirtyTextureLater(); - Q_SIGNALS: void updateRequested(); void scheduledUpdateCompleted(); - -protected: - virtual void customEvent(QEvent *); - -private: - int markDirtyEventType(); }; class Q_QUICK_PRIVATE_EXPORT QSGGlyphNode : public QSGVisitableNode diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp index c93517fe3f..450a9fbee0 100644 --- a/src/quick/scenegraph/qsgdefaultlayer.cpp +++ b/src/quick/scenegraph/qsgdefaultlayer.cpp @@ -88,7 +88,6 @@ namespace QSGDefaultLayer::QSGDefaultLayer(QSGRenderContext *context) : QSGLayer() , m_item(0) - , m_shaderSourceNode(0) , m_device_pixel_ratio(1) , m_format(GL_RGBA) , m_renderer(0) @@ -259,11 +258,8 @@ void QSGDefaultLayer::scheduleUpdate() if (m_grab) return; m_grab = true; - if (m_dirtyTexture) { + if (m_dirtyTexture) emit updateRequested(); - if (m_shaderSourceNode) - m_shaderSourceNode->markDirty(QSGNode::DirtyMaterial); - } } void QSGDefaultLayer::setRecursive(bool recursive) @@ -274,11 +270,8 @@ void QSGDefaultLayer::setRecursive(bool recursive) void QSGDefaultLayer::markDirtyTexture() { m_dirtyTexture = true; - if (m_live || m_grab) { + if (m_live || m_grab) emit updateRequested(); - if (m_shaderSourceNode) - m_shaderSourceNode->markDirty(QSGNode::DirtyMaterial); - } } void QSGDefaultLayer::grab() @@ -299,7 +292,7 @@ void QSGDefaultLayer::grab() if (!m_renderer) { m_renderer = m_context->createRenderer(); - connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTextureLater())); + connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture())); } m_renderer->setDevicePixelRatio(m_device_pixel_ratio); m_renderer->setRootNode(static_cast(root)); diff --git a/src/quick/scenegraph/qsgdefaultlayer_p.h b/src/quick/scenegraph/qsgdefaultlayer_p.h index 47a0448846..44c74d7cfd 100644 --- a/src/quick/scenegraph/qsgdefaultlayer_p.h +++ b/src/quick/scenegraph/qsgdefaultlayer_p.h @@ -60,8 +60,6 @@ public: QSGNode *item() const { return m_item; } void setItem(QSGNode *item); - void setShaderSourceNode(QSGNode *node) { m_shaderSourceNode = node; } - QRectF rect() const { return m_rect; } void setRect(const QRectF &rect); @@ -100,7 +98,6 @@ private: void grab(); QSGNode *m_item; - QSGNode *m_shaderSourceNode; QRectF m_rect; QSize m_size; qreal m_device_pixel_ratio; -- cgit v1.2.3 From 564c1038d1645d76004ad93651aa392d71d45490 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 24 Sep 2014 17:36:53 +0200 Subject: qmldir parser: add support for "depends component version" syntax Dependency declarations are initially for the benefit of qmlimportscanner which does not (yet) use this parser. This patch adds support for dependencies into the qmldir parser for completeness, along with autotests. It is necessary to prevent errors at runtime when parsing a qmldir which contains the "depends" declaration. Task-number: QTBUG-41489 Change-Id: Ief2524a30140c42874f94f1735755b171e15dcf7 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/qml/qml/qqmldirparser.cpp | 27 ++++++++++++++++++ src/qml/qml/qqmldirparser_p.h | 3 ++ .../auto/qml/qqmldirparser/data/dependency/qmldir | 3 ++ tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp | 32 ++++++++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 tests/auto/qml/qqmldirparser/data/dependency/qmldir diff --git a/src/qml/qml/qqmldirparser.cpp b/src/qml/qml/qqmldirparser.cpp index 7068818f15..83e1c9c757 100644 --- a/src/qml/qml/qqmldirparser.cpp +++ b/src/qml/qml/qqmldirparser.cpp @@ -231,6 +231,28 @@ bool QQmlDirParser::parse(const QString &source) reportError(lineNumber, 0, QString::fromLatin1("designersupported does not expect any argument")); else _designerSupported = true; + } else if (sections[0] == QLatin1String("depends")) { + if (sectionCount != 3) { + reportError(lineNumber, 0, + QString::fromLatin1("depends requires 2 arguments, but %1 were provided").arg(sectionCount - 1)); + continue; + } + + const QString &version = sections[2]; + const int dotIndex = version.indexOf(QLatin1Char('.')); + bool validVersionNumber = false; + const int majorVersion = parseInt(QStringRef(&version, 0, dotIndex), &validVersionNumber); + if (validVersionNumber) { + const int minorVersion = parseInt(QStringRef(&version, dotIndex+1, version.length()-dotIndex-1), &validVersionNumber); + + if (validVersionNumber) { + Component entry(sections[1], QString(), majorVersion, minorVersion); + entry.internal = true; + _dependencies.insert(entry.typeName, entry); + } + } else { + reportError(lineNumber, 0, QString(QLatin1String("invalid version %1")).arg(version)); + } } else if (sectionCount == 2) { // No version specified (should only be used for relative qmldir files) const Component entry(sections[0], sections[1], -1, -1); @@ -348,6 +370,11 @@ QHash QQmlDirParser::components() const return _components; } +QHash QQmlDirParser::dependencies() const +{ + return _dependencies; +} + QList QQmlDirParser::scripts() const { return _scripts; diff --git a/src/qml/qml/qqmldirparser_p.h b/src/qml/qml/qqmldirparser_p.h index 54843a13b0..bbe61dfb96 100644 --- a/src/qml/qml/qqmldirparser_p.h +++ b/src/qml/qml/qqmldirparser_p.h @@ -119,6 +119,7 @@ public: }; QHash components() const; + QHash dependencies() const; QList