From 3b221697ff1b0f5e9e54e7c733f14ee7c065139a Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 22 Nov 2013 17:02:12 +0100 Subject: QmlProfiler: Remove a couple of empty lines Change-Id: I5da7f2971dfd957d0188149eb8b4fde198609e6b Reviewed-by: Ulf Hermann Reviewed-by: Kai Koehne --- src/plugins/qmlprofiler/qmlprofilerplugin.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/plugins/qmlprofiler') diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.h b/src/plugins/qmlprofiler/qmlprofilerplugin.h index 0550fa1eec..aafdea86b9 100644 --- a/src/plugins/qmlprofiler/qmlprofilerplugin.h +++ b/src/plugins/qmlprofiler/qmlprofilerplugin.h @@ -58,8 +58,6 @@ public: private: QList timelineModels; - - }; } // namespace Internal -- cgit v1.2.1 From 30d914d4e794ce4dd406ae5bb8fc1484689fd495 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 22 Nov 2013 17:01:39 +0100 Subject: QmlProfiler: Set parent for the QmlProfiler actions Change-Id: Ia67d98855548c4d2c80ad76ff633a2399e30ad9c Reviewed-by: Ulf Hermann Reviewed-by: Kai Koehne --- src/plugins/qmlprofiler/qmlprofilerplugin.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/plugins/qmlprofiler') diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp index e4fd95a5a4..342035c19a 100644 --- a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp @@ -46,7 +46,7 @@ namespace Internal { class QmlProfilerAction : public AnalyzerAction { public: - QmlProfilerAction() {} + explicit QmlProfilerAction(QObject *parent = 0) : AnalyzerAction(parent) { } }; bool QmlProfilerPlugin::debugOutput = false; @@ -65,7 +65,7 @@ bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorS "The QML Profiler can be used to find performance bottlenecks in " "applications using QML."); - action = new QmlProfilerAction; + action = new QmlProfilerAction(this); action->setId("QmlProfiler.Local"); action->setTool(tool); action->setText(tr("QML Profiler")); @@ -74,7 +74,7 @@ bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorS action->setMenuGroup(Constants::G_ANALYZER_TOOLS); AnalyzerManager::addAction(action); - action = new QmlProfilerAction; + action = new QmlProfilerAction(this); action->setId("QmlProfiler.Remote"); action->setTool(tool); action->setText(tr("QML Profiler (External)")); -- cgit v1.2.1 From 2f8f51912c68123b6bf526f84a8a7d2f2c0ecead Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 20 Nov 2013 15:57:07 +0100 Subject: QmlProfiler: improve selection behavior in timeline When selecting ranges in the timeline the selector would sometimes hang or behave weirdly when moving back. This was due to incorrect logic in the selection bounds calculation and because the vertical flicking would steal mouse events. Change-Id: I14074463422d1d9a0aa8ecd1f88847e7330c9b6b Reviewed-by: Kai Koehne Reviewed-by: Ulf Hermann Reviewed-by: Eike Ziller --- src/plugins/qmlprofiler/qml/MainView.qml | 10 ++++++++-- src/plugins/qmlprofiler/qml/SelectionRange.qml | 21 ++++++++++++++------- 2 files changed, 22 insertions(+), 9 deletions(-) (limited to 'src/plugins/qmlprofiler') diff --git a/src/plugins/qmlprofiler/qml/MainView.qml b/src/plugins/qmlprofiler/qml/MainView.qml index e8bce8ea0d..8d8fe25d69 100644 --- a/src/plugins/qmlprofiler/qml/MainView.qml +++ b/src/plugins/qmlprofiler/qml/MainView.qml @@ -309,8 +309,11 @@ Rectangle { boundsBehavior: Flickable.StopAtBounds // ScrollView will try to deinteractivate it. We don't want that - // as the horizontal flickable is interactive, too. - onInteractiveChanged: interactive = true + // as the horizontal flickable is interactive, too. We do occasionally + // switch to non-interactive ourselves, though. + property bool stayInteractive: true + onInteractiveChanged: interactive = stayInteractive + onStayInteractiveChanged: interactive = stayInteractive // ***** child items TimeMarks { @@ -429,6 +432,9 @@ Rectangle { onPressed: { selectionRange.pressedOnCreation(); } + onCanceled: { + selectionRange.releasedOnCreation(); + } onPositionChanged: { selectionRange.movedOnCreation(); } diff --git a/src/plugins/qmlprofiler/qml/SelectionRange.qml b/src/plugins/qmlprofiler/qml/SelectionRange.qml index 78e09cfb40..381aa27c74 100644 --- a/src/plugins/qmlprofiler/qml/SelectionRange.qml +++ b/src/plugins/qmlprofiler/qml/SelectionRange.qml @@ -42,6 +42,7 @@ RangeMover { property real duration: Math.max(getWidth() * viewTimePerPixel, 500) property real viewTimePerPixel: 1 property int creationState : 0 + property int creationReference : 0 Connections { target: zoomControl @@ -65,6 +66,7 @@ RangeMover { function reset(setVisible) { setRight(getLeft() + 1); creationState = 0; + creationReference = 0; visible = setVisible; } @@ -75,18 +77,21 @@ RangeMover { pos = width; switch (creationState) { - case 1: { + case 1: + creationReference = pos; setLeft(pos); setRight(pos + 1); break; - } - case 2: { - setLeft(Math.min(getLeft(), pos)); - setRight(Math.max(getRight(), pos)); + case 2: + if (pos > creationReference) { + setLeft(creationReference); + setRight(pos); + } else if (pos < creationReference) { + setLeft(pos); + setRight(creationReference); + } break; } - default: return; - } } @@ -104,6 +109,7 @@ RangeMover { function releasedOnCreation() { if (selectionRange.creationState === 2) { flick.interactive = true; + vertflick.stayInteractive = true; selectionRange.creationState = 3; selectionRangeControl.enabled = false; } @@ -112,6 +118,7 @@ RangeMover { function pressedOnCreation() { if (selectionRange.creationState === 1) { flick.interactive = false; + vertflick.stayInteractive = false; selectionRange.setPos(selectionRangeControl.mouseX + flick.contentX); selectionRange.creationState = 2; } -- cgit v1.2.1 From 06a23c6da5a91c338396c3cbf8aa4d3c9d6fb838 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 28 Nov 2013 14:42:03 +0100 Subject: QmlProfiler: Handle enable and show signals for zoomslider in C++ As it's hard to pass arguments for signals from non-QML-mapped objects to QML objects handle the signal in C++ instead and just directly set the properties. Task-number: QTCREATORBUG-10943 Change-Id: I039f6938db3d7e64ca1a4bcff2f0f6aa79c65219 Reviewed-by: Kai Koehne Reviewed-by: Eike Ziller --- src/plugins/qmlprofiler/qml/MainView.qml | 2 -- src/plugins/qmlprofiler/qmlprofilertraceview.cpp | 18 +++++++++++++++--- src/plugins/qmlprofiler/qmlprofilertraceview.h | 2 ++ 3 files changed, 17 insertions(+), 5 deletions(-) (limited to 'src/plugins/qmlprofiler') diff --git a/src/plugins/qmlprofiler/qml/MainView.qml b/src/plugins/qmlprofiler/qml/MainView.qml index 8d8fe25d69..bc40aa5437 100644 --- a/src/plugins/qmlprofiler/qml/MainView.qml +++ b/src/plugins/qmlprofiler/qml/MainView.qml @@ -514,8 +514,6 @@ Rectangle { x: 0 y: 0 - function toggleEnabled() {enabled = !enabled} - function toggleVisible() {visible = !visible} function updateZoomLevel() { zoomSlider.externalUpdate = true; zoomSlider.value = Math.pow((view.endTime - view.startTime) / qmlProfilerModelProxy.traceDuration(), 1 / zoomSlider.exponent) * zoomSlider.maximumValue; diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp index 645c17b60b..395be21696 100644 --- a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp @@ -192,10 +192,22 @@ void QmlProfilerTraceView::reset() connect(this, SIGNAL(jumpToNext()), rootObject, SLOT(nextEvent())); connect(rootObject, SIGNAL(selectedEventChanged(int)), this, SIGNAL(selectedEventChanged(int))); connect(rootObject, SIGNAL(changeToolTip(QString)), this, SLOT(updateToolTip(QString))); + connect(this, SIGNAL(enableToolbar(bool)), this, SLOT(setZoomSliderEnabled(bool))); + connect(this, SIGNAL(showZoomSlider(bool)), this, SLOT(setZoomSliderVisible(bool))); +} - QObject *zoomSlider = rootObject->findChild(QLatin1String("zoomSliderToolBar")); - connect(this, SIGNAL(enableToolbar(bool)), zoomSlider, SLOT(toggleEnabled())); - connect(this, SIGNAL(showZoomSlider(bool)), zoomSlider, SLOT(toggleVisible())); +void QmlProfilerTraceView::setZoomSliderEnabled(bool enabled) +{ + QQuickItem *zoomSlider = d->m_mainView->rootObject()->findChild(QLatin1String("zoomSliderToolBar")); + if (zoomSlider->isEnabled() != enabled) + zoomSlider->setEnabled(enabled); +} + +void QmlProfilerTraceView::setZoomSliderVisible(bool visible) +{ + QQuickItem *zoomSlider = d->m_mainView->rootObject()->findChild(QLatin1String("zoomSliderToolBar")); + if (zoomSlider->isVisible() != visible) + zoomSlider->setVisible(visible); } QWidget *QmlProfilerTraceView::createToolbar() diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.h b/src/plugins/qmlprofiler/qmlprofilertraceview.h index da8f66966a..d027a4dabf 100644 --- a/src/plugins/qmlprofiler/qmlprofilertraceview.h +++ b/src/plugins/qmlprofiler/qmlprofilertraceview.h @@ -102,6 +102,8 @@ private slots: void profilerStateChanged(); void clientRecordingChanged(); void serverRecordingChanged(); + void setZoomSliderEnabled(bool enabled); + void setZoomSliderVisible(bool visible); signals: void gotoSourceLocation(const QString &fileUrl, int lineNumber, int columNumber); -- cgit v1.2.1 From 68740869efbddb8b6f03fe312fe6ba6e89af58ce Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 2 Dec 2013 16:16:33 +0100 Subject: QmlProfiler: Update timeline contentWidth also if width changes As the contentWidth depends on both the width of the flickable and the currently selected time range it should be updated if either of them change. Otherwise we can miss changes and show stale data. Change-Id: Iab9e17eef3490531175a2374fb3da0e0071f3bd1 Reviewed-by: Christian Stenger Reviewed-by: Kai Koehne Reviewed-by: Eike Ziller --- src/plugins/qmlprofiler/qml/MainView.qml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/plugins/qmlprofiler') diff --git a/src/plugins/qmlprofiler/qml/MainView.qml b/src/plugins/qmlprofiler/qml/MainView.qml index bc40aa5437..c7e12a3de7 100644 --- a/src/plugins/qmlprofiler/qml/MainView.qml +++ b/src/plugins/qmlprofiler/qml/MainView.qml @@ -76,19 +76,12 @@ Rectangle { onRangeChanged: { var startTime = zoomControl.startTime(); var endTime = zoomControl.endTime(); - var duration = Math.abs(endTime - startTime); - mainviewTimePerPixel = duration / root.width; + mainviewTimePerPixel = Math.abs(endTime - startTime) / root.width; backgroundMarks.updateMarks(startTime, endTime); view.updateFlickRange(startTime, endTime); - if (duration > 0) { - var candidateWidth = qmlProfilerModelProxy.traceDuration() * - flick.width / duration; - if (flick.contentWidth !== candidateWidth) - flick.contentWidth = candidateWidth; - } - + flick.setContentWidth(); } } @@ -325,6 +318,12 @@ Rectangle { } Flickable { + function setContentWidth() { + var duration = Math.abs(zoomControl.endTime() - zoomControl.startTime()); + if (duration > 0) + contentWidth = qmlProfilerModelProxy.traceDuration() * width / duration; + } + id: flick anchors.top: parent.top anchors.topMargin: labels.y @@ -336,6 +335,8 @@ Rectangle { boundsBehavior: Flickable.StopAtBounds onContentXChanged: view.updateZoomControl() + onWidthChanged: setContentWidth() + clip:true SelectionRange { -- cgit v1.2.1 From d36cb8b476f59ca48fb877221db597e4664c0d62 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 28 Nov 2013 15:29:29 +0100 Subject: QmlProfiler: Remove custom canvas implementation The canvas integrated in QtQuick does the same thing. We can remove a lot of code like this. Change-Id: I6425ae4e1b542107defd9d76fa5755712a0f8613 Reviewed-by: Ulf Hermann Reviewed-by: Christian Stenger Reviewed-by: Kai Koehne --- src/plugins/qmlprofiler/canvas/canvas.pri | 9 - .../qmlprofiler/canvas/qdeclarativecanvas.cpp | 242 ----- .../qmlprofiler/canvas/qdeclarativecanvas_p.h | 107 -- .../qmlprofiler/canvas/qdeclarativecanvastimer.cpp | 85 -- .../qmlprofiler/canvas/qdeclarativecanvastimer_p.h | 62 -- .../qmlprofiler/canvas/qdeclarativecontext2d.cpp | 1134 -------------------- .../qmlprofiler/canvas/qdeclarativecontext2d_p.h | 326 ------ .../qmlprofiler/canvas/qmlprofilercanvas.cpp | 105 -- src/plugins/qmlprofiler/canvas/qmlprofilercanvas.h | 76 -- src/plugins/qmlprofiler/qml/CategoryLabel.qml | 2 +- src/plugins/qmlprofiler/qml/Overview.qml | 13 +- src/plugins/qmlprofiler/qml/TimeDisplay.qml | 61 +- src/plugins/qmlprofiler/qml/TimeMarks.qml | 61 +- src/plugins/qmlprofiler/qmlprofiler.pro | 1 - src/plugins/qmlprofiler/qmlprofiler.qbs | 11 - src/plugins/qmlprofiler/qmlprofilertool.cpp | 6 - 16 files changed, 71 insertions(+), 2230 deletions(-) delete mode 100644 src/plugins/qmlprofiler/canvas/canvas.pri delete mode 100644 src/plugins/qmlprofiler/canvas/qdeclarativecanvas.cpp delete mode 100644 src/plugins/qmlprofiler/canvas/qdeclarativecanvas_p.h delete mode 100644 src/plugins/qmlprofiler/canvas/qdeclarativecanvastimer.cpp delete mode 100644 src/plugins/qmlprofiler/canvas/qdeclarativecanvastimer_p.h delete mode 100644 src/plugins/qmlprofiler/canvas/qdeclarativecontext2d.cpp delete mode 100644 src/plugins/qmlprofiler/canvas/qdeclarativecontext2d_p.h delete mode 100644 src/plugins/qmlprofiler/canvas/qmlprofilercanvas.cpp delete mode 100644 src/plugins/qmlprofiler/canvas/qmlprofilercanvas.h (limited to 'src/plugins/qmlprofiler') diff --git a/src/plugins/qmlprofiler/canvas/canvas.pri b/src/plugins/qmlprofiler/canvas/canvas.pri deleted file mode 100644 index 2960e94527..0000000000 --- a/src/plugins/qmlprofiler/canvas/canvas.pri +++ /dev/null @@ -1,9 +0,0 @@ -HEADERS += $$PWD/qdeclarativecontext2d_p.h \ - $$PWD/qdeclarativecanvas_p.h \ - $$PWD/qmlprofilercanvas.h \ - $$PWD/qdeclarativecanvastimer_p.h - -SOURCES += $$PWD/qdeclarativecontext2d.cpp \ - $$PWD/qdeclarativecanvas.cpp \ - $$PWD/qmlprofilercanvas.cpp \ - $$PWD/qdeclarativecanvastimer.cpp diff --git a/src/plugins/qmlprofiler/canvas/qdeclarativecanvas.cpp b/src/plugins/qmlprofiler/canvas/qdeclarativecanvas.cpp deleted file mode 100644 index 4611d7096b..0000000000 --- a/src/plugins/qmlprofiler/canvas/qdeclarativecanvas.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** 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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, 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. -** -****************************************************************************/ - -#include "qdeclarativecanvas_p.h" -#include "qdeclarativecanvastimer_p.h" -#include "qdeclarativecontext2d_p.h" - -#include - -QT_BEGIN_NAMESPACE - -Canvas::Canvas(QQuickPaintedItem *parent) - : QQuickPaintedItem(parent), - m_context(new Context2D(this)), - m_canvasWidth(0), - m_canvasHeight(0), - m_fillMode(Canvas::Stretch), - m_color(Qt::white) -{ -} - - -void Canvas::componentComplete() -{ - if (m_canvasWidth == 0 && m_canvasHeight == 0) - m_context->setSize(width(), height()); - else - m_context->setSize(m_canvasWidth, m_canvasHeight); - - connect(m_context, SIGNAL(changed()), this, SLOT(requestPaint())); - emit init(); - QQuickItem::componentComplete(); -} - -void Canvas::paint(QPainter *painter) -{ - m_context->setInPaint(true); - emit paint(); - - bool oldAA = painter->testRenderHint(QPainter::Antialiasing); - bool oldSmooth = painter->testRenderHint(QPainter::SmoothPixmapTransform); - if (smooth()) - painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, smooth()); - - if (m_context->pixmap().isNull()) { - painter->fillRect(0, 0, width(), height(), m_color); - } else if (width() != m_context->pixmap().width() || height() != m_context->pixmap().height()) { - if (m_fillMode>= Tile) { - if (m_fillMode== Tile) { - painter->drawTiledPixmap(QRectF(0,0,width(),height()), m_context->pixmap()); - } else { - qreal widthScale = width() / qreal(m_context->pixmap().width()); - qreal heightScale = height() / qreal(m_context->pixmap().height()); - - QTransform scale; - if (m_fillMode== TileVertically) { - scale.scale(widthScale, 1.0); - QTransform old = painter->transform(); - painter->setWorldTransform(scale * old); - painter->drawTiledPixmap(QRectF(0,0,m_context->pixmap().width(),height()), m_context->pixmap()); - painter->setWorldTransform(old); - } else { - scale.scale(1.0, heightScale); - QTransform old = painter->transform(); - painter->setWorldTransform(scale * old); - painter->drawTiledPixmap(QRectF(0,0,width(),m_context->pixmap().height()), m_context->pixmap()); - painter->setWorldTransform(old); - } - } - } else { - qreal widthScale = width() / qreal(m_context->pixmap().width()); - qreal heightScale = height() / qreal(m_context->pixmap().height()); - - QTransform scale; - - if (m_fillMode== PreserveAspectFit) { - if (widthScale <= heightScale) { - heightScale = widthScale; - scale.translate(0, (height() - heightScale * m_context->pixmap().height()) / 2); - } else if (heightScale < widthScale) { - widthScale = heightScale; - scale.translate((width() - widthScale * m_context->pixmap().width()) / 2, 0); - } - } else if (m_fillMode== PreserveAspectCrop) { - if (widthScale < heightScale) { - widthScale = heightScale; - scale.translate((width() - widthScale * m_context->pixmap().width()) / 2, 0); - } else if (heightScale < widthScale) { - heightScale = widthScale; - scale.translate(0, (height() - heightScale * m_context->pixmap().height()) / 2); - } - } - if (clip()) { - painter->save(); - painter->setClipRect(boundingRect(), Qt::IntersectClip); - } - scale.scale(widthScale, heightScale); - QTransform old = painter->transform(); - painter->setWorldTransform(scale * old); - painter->drawPixmap(0, 0, m_context->pixmap()); - painter->setWorldTransform(old); - if (clip()) - painter->restore(); - } - } else { - painter->drawPixmap(0, 0, m_context->pixmap()); - } - - if (smooth()) { - painter->setRenderHint(QPainter::Antialiasing, oldAA); - painter->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth); - } - m_context->setInPaint(false); -} - -Context2D *Canvas::getContext(const QString &contextId) -{ - if (contextId == QLatin1String("2d")) - return m_context; - qDebug("Canvas:requesting unsupported context"); - return 0; -} - -void Canvas::requestPaint() -{ - update(); -} - -void Canvas::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) -{ - if (m_canvasWidth == 0 && m_canvasHeight == 0 - && newGeometry.width() > 0 && newGeometry.height() > 0) { - m_context->setSize(width(), height()); - } - QQuickItem::geometryChanged(newGeometry, oldGeometry); -} - -void Canvas::setCanvasWidth(int newWidth) -{ - if (m_canvasWidth != newWidth) { - m_canvasWidth = newWidth; - m_context->setSize(m_canvasWidth, m_canvasHeight); - emit canvasWidthChanged(); - } -} - -void Canvas::setCanvasHeight(int newHeight) -{ - if (m_canvasHeight != newHeight) { - m_canvasHeight = newHeight; - m_context->setSize(m_canvasWidth, m_canvasHeight); - emit canvasHeightChanged(); - } -} - -void Canvas::setFillMode(FillMode mode) -{ - if (m_fillMode == mode) - return; - - m_fillMode = mode; - update(); - emit fillModeChanged(); -} - -QColor Canvas::color() -{ - return m_color; -} - -void Canvas::setColor(const QColor &color) -{ - if (m_color !=color) { - m_color = color; - colorChanged(); - } -} - -Canvas::FillMode Canvas::fillMode() const -{ - return m_fillMode; -} - -bool Canvas::save(const QString &filename) const -{ - return m_context->pixmap().save(filename); -} - -CanvasImage *Canvas::toImage() const -{ - return new CanvasImage(m_context->pixmap()); -} - -void Canvas::setTimeout(const QJSValue &handler, long timeout) -{ - if (handler.isCallable()) - CanvasTimer::createTimer(this, handler, timeout, true); -} - -void Canvas::setInterval(const QJSValue &handler, long interval) -{ - if (handler.isCallable()) - CanvasTimer::createTimer(this, handler, interval, false); -} - -void Canvas::clearTimeout(const QJSValue &handler) -{ - CanvasTimer::removeTimer(handler); -} - -void Canvas::clearInterval(const QJSValue &handler) -{ - CanvasTimer::removeTimer(handler); -} - -QT_END_NAMESPACE diff --git a/src/plugins/qmlprofiler/canvas/qdeclarativecanvas_p.h b/src/plugins/qmlprofiler/canvas/qdeclarativecanvas_p.h deleted file mode 100644 index 3f4fd8b0dd..0000000000 --- a/src/plugins/qmlprofiler/canvas/qdeclarativecanvas_p.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** 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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, 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. -** -****************************************************************************/ - -#ifndef QDECLARATIVECANVAS_P_H -#define QDECLARATIVECANVAS_P_H - -#include - -#include "qdeclarativecontext2d_p.h" -#include "qdeclarativecanvastimer_p.h" - -QT_BEGIN_NAMESPACE - -class Canvas : public QQuickPaintedItem -{ - Q_OBJECT - - Q_ENUMS(FillMode) - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged); - Q_PROPERTY(int canvasWidth READ canvasWidth WRITE setCanvasWidth NOTIFY canvasWidthChanged); - Q_PROPERTY(int canvasHeight READ canvasHeight WRITE setCanvasHeight NOTIFY canvasHeightChanged); - Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged) - -public: - Canvas(QQuickPaintedItem *parent = 0); - enum FillMode { Stretch, PreserveAspectFit, PreserveAspectCrop, Tile, TileVertically, TileHorizontally }; - - - void paint(QPainter *); - void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); - void setCanvasWidth(int newWidth); - int canvasWidth() {return m_canvasWidth;} - - void setCanvasHeight(int canvasHeight); - int canvasHeight() {return m_canvasHeight;} - - void componentComplete(); - - -public Q_SLOTS: - Context2D *getContext(const QString & = QLatin1String("2d")); - void requestPaint(); - - FillMode fillMode() const; - void setFillMode(FillMode); - - QColor color(); - void setColor(const QColor &); - - // Save current canvas to disk - bool save(const QString& filename) const; - - // Timers - void setInterval(const QJSValue &handler, long timeout); - void setTimeout(const QJSValue &handler, long timeout); - void clearInterval(const QJSValue &handler); - void clearTimeout(const QJSValue &handler); - -Q_SIGNALS: - void fillModeChanged(); - void canvasWidthChanged(); - void canvasHeightChanged(); - void colorChanged(); - void init(); - void paint(); - -private: - // Return canvas contents as a drawable image - CanvasImage *toImage() const; - Context2D *m_context; - int m_canvasWidth; - int m_canvasHeight; - FillMode m_fillMode; - QColor m_color; - - friend class Context2D; -}; - -QT_END_NAMESPACE - -#endif //QDECLARATIVECANVAS_P_H diff --git a/src/plugins/qmlprofiler/canvas/qdeclarativecanvastimer.cpp b/src/plugins/qmlprofiler/canvas/qdeclarativecanvastimer.cpp deleted file mode 100644 index 8069fbbcb7..0000000000 --- a/src/plugins/qmlprofiler/canvas/qdeclarativecanvastimer.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** 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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, 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. -** -****************************************************************************/ - -#include "qdeclarativecanvastimer_p.h" - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -Q_GLOBAL_STATIC(QList , activeTimers); - -CanvasTimer::CanvasTimer(QObject *parent, const QJSValue &data) - : QTimer(parent), m_value(data) -{ -} - -void CanvasTimer::handleTimeout() -{ - Q_ASSERT(m_value.isCallable()); - m_value.call(); - if (isSingleShot()) - removeTimer(this); -} - -void CanvasTimer::createTimer(QObject *parent, const QJSValue &val, long timeout, bool singleshot) -{ - - CanvasTimer *timer = new CanvasTimer(parent, val); - timer->setInterval(timeout); - timer->setSingleShot(singleshot); - connect(timer, SIGNAL(timeout()), timer, SLOT(handleTimeout())); - activeTimers()->append(timer); - timer->start(); -} - -void CanvasTimer::removeTimer(CanvasTimer *timer) -{ - activeTimers()->removeAll(timer); - timer->deleteLater(); -} - -void CanvasTimer::removeTimer(const QJSValue &val) -{ - if (!val.isCallable()) - return; - - for (int i = 0 ; i < activeTimers()->count() ; ++i) { - CanvasTimer *timer = activeTimers()->at(i); - if (timer->equals(val)) { - removeTimer(timer); - return; - } - } -} - -QT_END_NAMESPACE - diff --git a/src/plugins/qmlprofiler/canvas/qdeclarativecanvastimer_p.h b/src/plugins/qmlprofiler/canvas/qdeclarativecanvastimer_p.h deleted file mode 100644 index b25a98eb44..0000000000 --- a/src/plugins/qmlprofiler/canvas/qdeclarativecanvastimer_p.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** 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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, 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. -** -****************************************************************************/ - -#ifndef QDECLARATIVECANVASTIMER_P_H -#define QDECLARATIVECANVASTIMER_P_H - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class CanvasTimer : public QTimer -{ - Q_OBJECT - -public: - CanvasTimer(QObject *parent, const QJSValue &data); - -public Q_SLOTS: - void handleTimeout(); - bool equals(const QJSValue &value){return m_value.equals(value);} - -public: - static void createTimer(QObject *parent, const QJSValue &val, long timeout, bool singleshot); - static void removeTimer(CanvasTimer *timer); - static void removeTimer(const QJSValue &); - -private: - QJSValue m_value; - -}; - -QT_END_NAMESPACE - -#endif // QDECLARATIVECANVASTIMER_P_H diff --git a/src/plugins/qmlprofiler/canvas/qdeclarativecontext2d.cpp b/src/plugins/qmlprofiler/canvas/qdeclarativecontext2d.cpp deleted file mode 100644 index f006657bfc..0000000000 --- a/src/plugins/qmlprofiler/canvas/qdeclarativecontext2d.cpp +++ /dev/null @@ -1,1134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** 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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, 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. -** -****************************************************************************/ - -#include "qdeclarativecontext2d_p.h" - -#include "qdeclarativecanvas_p.h" - -#include -#include - -#include -#include -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -static const double Q_PI = 3.14159265358979323846; // pi - -class CustomDropShadowEffect : public QGraphicsDropShadowEffect -{ -public: - void draw(QPainter *painter) { QGraphicsDropShadowEffect::draw(painter);} - void drawSource(QPainter *painter) { QGraphicsDropShadowEffect::drawSource(painter);} -}; - -// Note, this is exported but in a private header as qtopengl depends on it. -// But it really should be considered private API -void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0); -void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0); - -#define DEGREES(t) ((t) * 180.0 / Q_PI) - -#define qClamp(val, min, max) qMin(qMax(val, min), max) -static QList parseNumbersList(QString::const_iterator &itr) -{ - QList points; - QString temp; - while ((*itr).isSpace()) - ++itr; - while ((*itr).isNumber() || - (*itr) == QLatin1Char('-') || (*itr) == QLatin1Char('+') || (*itr) == QLatin1Char('.')) { - temp.clear(); - - if ((*itr) == QLatin1Char('-')) - temp += *itr++; - else if ((*itr) == QLatin1Char('+')) - temp += *itr++; - while ((*itr).isDigit()) - temp += *itr++; - if ((*itr) == QLatin1Char('.')) - temp += *itr++; - while ((*itr).isDigit()) - temp += *itr++; - while ((*itr).isSpace()) - ++itr; - if ((*itr) == QLatin1Char(',')) - ++itr; - points.append(temp.toDouble()); - //eat spaces - while ((*itr).isSpace()) - ++itr; - } - - return points; -} - -QColor colorFromString(const QString &name) -{ - QString::const_iterator itr = name.constBegin(); - QList compo; - if (name.startsWith(QLatin1String("rgba("))) { - ++itr; ++itr; ++itr; ++itr; ++itr; - compo = parseNumbersList(itr); - if (compo.size() != 4) - return QColor(); - //alpha seems to be always between 0-1 - compo[3] *= 255; - return QColor((int)compo[0], (int)compo[1], - (int)compo[2], (int)compo[3]); - } else if (name.startsWith(QLatin1String("rgb("))) { - ++itr; ++itr; ++itr; ++itr; - compo = parseNumbersList(itr); - if (compo.size() != 3) - return QColor(); - return QColor((int)qClamp(compo[0], qreal(0), qreal(255)), - (int)qClamp(compo[1], qreal(0), qreal(255)), - (int)qClamp(compo[2], qreal(0), qreal(255))); - } else if (name.startsWith(QLatin1String("hsla("))) { - ++itr; ++itr; ++itr; ++itr; ++itr; - compo = parseNumbersList(itr); - if (compo.size() != 4) - return QColor(); - return QColor::fromHslF(compo[0], compo[1], - compo[2], compo[3]); - } else if (name.startsWith(QLatin1String("hsl("))) { - ++itr; ++itr; ++itr; ++itr; ++itr; - compo = parseNumbersList(itr); - if (compo.size() != 3) - return QColor(); - return QColor::fromHslF(compo[0], compo[1], - compo[2]); - } else { - //QRgb color; - //CSSParser::parseColor(name, color); - return QColor(name); - } -} - - -static QPainter::CompositionMode compositeOperatorFromString(const QString &compositeOperator) -{ - if (compositeOperator == QLatin1String("source-over")) - return QPainter::CompositionMode_SourceOver; - else if (compositeOperator == QLatin1String("source-out")) - return QPainter::CompositionMode_SourceOut; - else if (compositeOperator == QLatin1String("source-in")) - return QPainter::CompositionMode_SourceIn; - else if (compositeOperator == QLatin1String("source-atop")) - return QPainter::CompositionMode_SourceAtop; - else if (compositeOperator == QLatin1String("destination-atop")) - return QPainter::CompositionMode_DestinationAtop; - else if (compositeOperator == QLatin1String("destination-in")) - return QPainter::CompositionMode_DestinationIn; - else if (compositeOperator == QLatin1String("destination-out")) - return QPainter::CompositionMode_DestinationOut; - else if (compositeOperator == QLatin1String("destination-over")) - return QPainter::CompositionMode_DestinationOver; - else if (compositeOperator == QLatin1String("darker")) - return QPainter::CompositionMode_SourceOver; - else if (compositeOperator == QLatin1String("lighter")) - return QPainter::CompositionMode_SourceOver; - else if (compositeOperator == QLatin1String("copy")) - return QPainter::CompositionMode_Source; - else if (compositeOperator == QLatin1String("xor")) - return QPainter::CompositionMode_Xor; - - return QPainter::CompositionMode_SourceOver; -} - -static QString compositeOperatorToString(QPainter::CompositionMode op) -{ - switch (op) { - case QPainter::CompositionMode_SourceOver: - return QLatin1String("source-over"); - case QPainter::CompositionMode_DestinationOver: - return QLatin1String("destination-over"); - case QPainter::CompositionMode_Clear: - return QLatin1String("clear"); - case QPainter::CompositionMode_Source: - return QLatin1String("source"); - case QPainter::CompositionMode_Destination: - return QLatin1String("destination"); - case QPainter::CompositionMode_SourceIn: - return QLatin1String("source-in"); - case QPainter::CompositionMode_DestinationIn: - return QLatin1String("destination-in"); - case QPainter::CompositionMode_SourceOut: - return QLatin1String("source-out"); - case QPainter::CompositionMode_DestinationOut: - return QLatin1String("destination-out"); - case QPainter::CompositionMode_SourceAtop: - return QLatin1String("source-atop"); - case QPainter::CompositionMode_DestinationAtop: - return QLatin1String("destination-atop"); - case QPainter::CompositionMode_Xor: - return QLatin1String("xor"); - case QPainter::CompositionMode_Plus: - return QLatin1String("plus"); - case QPainter::CompositionMode_Multiply: - return QLatin1String("multiply"); - case QPainter::CompositionMode_Screen: - return QLatin1String("screen"); - case QPainter::CompositionMode_Overlay: - return QLatin1String("overlay"); - case QPainter::CompositionMode_Darken: - return QLatin1String("darken"); - case QPainter::CompositionMode_Lighten: - return QLatin1String("lighten"); - case QPainter::CompositionMode_ColorDodge: - return QLatin1String("color-dodge"); - case QPainter::CompositionMode_ColorBurn: - return QLatin1String("color-burn"); - case QPainter::CompositionMode_HardLight: - return QLatin1String("hard-light"); - case QPainter::CompositionMode_SoftLight: - return QLatin1String("soft-light"); - case QPainter::CompositionMode_Difference: - return QLatin1String("difference"); - case QPainter::CompositionMode_Exclusion: - return QLatin1String("exclusion"); - default: - break; - } - return QString(); -} - -void Context2D::save() -{ - m_stateStack.push(m_state); -} - - -void Context2D::restore() -{ - if (!m_stateStack.isEmpty()) { - m_state = m_stateStack.pop(); - m_state.flags = AllIsFullOfDirt; - } -} - - -void Context2D::scale(qreal x, qreal y) -{ - m_state.matrix.scale(x, y); - m_state.flags |= DirtyTransformationMatrix; -} - - -void Context2D::rotate(qreal angle) -{ - m_state.matrix.rotate(DEGREES(angle)); - m_state.flags |= DirtyTransformationMatrix; -} - - -void Context2D::translate(qreal x, qreal y) -{ - m_state.matrix.translate(x, y); - m_state.flags |= DirtyTransformationMatrix; -} - - -void Context2D::transform(qreal m11, qreal m12, qreal m21, qreal m22, - qreal dx, qreal dy) -{ - QMatrix mat(m11, m12, - m21, m22, - dx, dy); - m_state.matrix *= mat; - m_state.flags |= DirtyTransformationMatrix; -} - - -void Context2D::setTransform(qreal m11, qreal m12, qreal m21, qreal m22, - qreal dx, qreal dy) -{ - QMatrix mat(m11, m12, - m21, m22, - dx, dy); - m_state.matrix = mat; - m_state.flags |= DirtyTransformationMatrix; -} - - -QString Context2D::globalCompositeOperation() const -{ - return compositeOperatorToString(m_state.globalCompositeOperation); -} - -void Context2D::setGlobalCompositeOperation(const QString &op) -{ - QPainter::CompositionMode mode = - compositeOperatorFromString(op); - m_state.globalCompositeOperation = mode; - m_state.flags |= DirtyGlobalCompositeOperation; -} - -QVariant Context2D::strokeStyle() const -{ - return m_state.strokeStyle; -} - -void Context2D::setStrokeStyle(const QVariant &style) -{ - CanvasGradient * gradient= qobject_cast(style.value()); - if (gradient) { - m_state.strokeStyle = gradient->value(); - } else { - QColor color = colorFromString(style.toString()); - m_state.strokeStyle = color; - } - m_state.flags |= DirtyStrokeStyle; -} - -QVariant Context2D::fillStyle() const -{ - return m_state.fillStyle; -} - -void Context2D::setFillStyle(const QVariant &style) -{ - CanvasGradient * gradient= qobject_cast(style.value()); - if (gradient) { - m_state.fillStyle = gradient->value(); - } else { - QColor color = colorFromString(style.toString()); - m_state.fillStyle = color; - } - m_state.flags |= DirtyFillStyle; -} - -qreal Context2D::globalAlpha() const -{ - return m_state.globalAlpha; -} - -void Context2D::setGlobalAlpha(qreal alpha) -{ - m_state.globalAlpha = alpha; - m_state.flags |= DirtyGlobalAlpha; -} - -CanvasImage *Context2D::createImage(const QString &url) -{ - return new CanvasImage(url); -} - -CanvasGradient *Context2D::createLinearGradient(qreal x0, qreal y0, - qreal x1, qreal y1) -{ - QLinearGradient g(x0, y0, x1, y1); - return new CanvasGradient(g); -} - - -CanvasGradient *Context2D::createRadialGradient(qreal x0, qreal y0, - qreal r0, qreal x1, - qreal y1, qreal r1) -{ - QRadialGradient g(QPointF(x1, y1), r0+r1, QPointF(x0, y0)); - return new CanvasGradient(g); -} - -qreal Context2D::lineWidth() const -{ - return m_state.lineWidth; -} - -void Context2D::setLineWidth(qreal w) -{ - m_state.lineWidth = w; - m_state.flags |= DirtyLineWidth; -} - -QString Context2D::lineCap() const -{ - switch (m_state.lineCap) { - case Qt::FlatCap: - return QLatin1String("butt"); - case Qt::SquareCap: - return QLatin1String("square"); - case Qt::RoundCap: - return QLatin1String("round"); - default: ; - } - return QString(); -} - -void Context2D::setLineCap(const QString &capString) -{ - Qt::PenCapStyle style; - if (capString == QLatin1String("round")) - style = Qt::RoundCap; - else if (capString == QLatin1String("square")) - style = Qt::SquareCap; - else //if (capString == QLatin1String("butt")) - style = Qt::FlatCap; - m_state.lineCap = style; - m_state.flags |= DirtyLineCap; -} - -QString Context2D::lineJoin() const -{ - switch (m_state.lineJoin) { - case Qt::RoundJoin: - return QLatin1String("round"); - case Qt::BevelJoin: - return QLatin1String("bevel"); - case Qt::MiterJoin: - return QLatin1String("miter"); - default: ; - } - return QString(); -} - -void Context2D::setLineJoin(const QString &joinString) -{ - Qt::PenJoinStyle style; - if (joinString == QLatin1String("round")) - style = Qt::RoundJoin; - else if (joinString == QLatin1String("bevel")) - style = Qt::BevelJoin; - else //if (joinString == "miter") - style = Qt::MiterJoin; - m_state.lineJoin = style; - m_state.flags |= DirtyLineJoin; -} - -qreal Context2D::miterLimit() const -{ - return m_state.miterLimit; -} - -void Context2D::setMiterLimit(qreal m) -{ - m_state.miterLimit = m; - m_state.flags |= DirtyMiterLimit; -} - -void Context2D::setShadowOffsetX(qreal x) -{ - if (m_state.shadowOffsetX == x) - return; - m_state.shadowOffsetX = x; - updateShadowBuffer(); - if (m_painter.device() == &m_shadowbuffer && m_state.shadowBlur>0) - endPainting(); - m_state.flags |= DirtyShadowOffsetX; -} - -const QList &Context2D::mouseAreas() const -{ - return m_mouseAreas; -} - -void Context2D::updateShadowBuffer() { - if (m_shadowbuffer.isNull() || m_shadowbuffer.width() != m_width+m_state.shadowOffsetX || - m_shadowbuffer.height() != m_height+m_state.shadowOffsetY) { - m_shadowbuffer = QImage(m_width+m_state.shadowOffsetX, m_height+m_state.shadowOffsetY, QImage::Format_ARGB32); - m_shadowbuffer.fill(Qt::transparent); - } -} - -void Context2D::setShadowOffsetY(qreal y) -{ - if (m_state.shadowOffsetY == y) - return; - m_state.shadowOffsetY = y; - updateShadowBuffer(); - if (m_painter.device() == &m_shadowbuffer && m_state.shadowBlur>0) - endPainting(); - - m_state.flags |= DirtyShadowOffsetY; -} - -void Context2D::setShadowBlur(qreal b) -{ - if (m_state.shadowBlur == b) - return; - m_state.shadowBlur = b; - updateShadowBuffer(); - if (m_painter.device() == &m_shadowbuffer && m_state.shadowBlur>0) - endPainting(); - m_state.flags |= DirtyShadowBlur; -} - -void Context2D::setShadowColor(const QString &str) -{ - m_state.shadowColor = colorFromString(str); - if (m_painter.device() == &m_shadowbuffer && m_state.shadowBlur>0) - endPainting(); - m_state.flags |= DirtyShadowColor; -} - -QString Context2D::textBaseline() -{ - switch (m_state.textBaseline) { - case Context2D::Alphabetic: - return QLatin1String("alphabetic"); - case Context2D::Hanging: - return QLatin1String("hanging"); - case Context2D::Bottom: - return QLatin1String("bottom"); - case Context2D::Top: - return QLatin1String("top"); - case Context2D::Middle: - return QLatin1String("middle"); - default: - Q_ASSERT("invalid value"); - return QLatin1String("start"); - } -} - -void Context2D::setTextBaseline(const QString &baseline) -{ - if (baseline==QLatin1String("alphabetic")) { - m_state.textBaseline = Context2D::Alphabetic; - } else if (baseline == QLatin1String("hanging")) { - m_state.textBaseline = Context2D::Hanging; - } else if (baseline == QLatin1String("top")) { - m_state.textBaseline = Context2D::Top; - } else if (baseline == QLatin1String("bottom")) { - m_state.textBaseline = Context2D::Bottom; - } else if (baseline == QLatin1String("middle")) { - m_state.textBaseline = Context2D::Middle; - } else { - m_state.textBaseline = Context2D::Alphabetic; - qWarning() << (QLatin1String("Context2D: invalid baseline:") + baseline); - } - m_state.flags |= DirtyTextBaseline; -} - -QString Context2D::textAlign() -{ - switch (m_state.textAlign) { - case Context2D::Left: - return QLatin1String("left"); - case Context2D::Right: - return QLatin1String("right"); - case Context2D::Center: - return QLatin1String("center"); - case Context2D::Start: - return QLatin1String("start"); - case Context2D::End: - return QLatin1String("end"); - default: - Q_ASSERT("invalid value"); - qWarning() << ("Context2D::invalid textAlign"); - return QLatin1String("start"); - } -} - -void Context2D::setTextAlign(const QString &baseline) -{ - if (baseline==QLatin1String("start")) { - m_state.textAlign = Context2D::Start; - } else if (baseline == QLatin1String("end")) { - m_state.textAlign = Context2D::End; - } else if (baseline == QLatin1String("left")) { - m_state.textAlign = Context2D::Left; - } else if (baseline == QLatin1String("right")) { - m_state.textAlign = Context2D::Right; - } else if (baseline == QLatin1String("center")) { - m_state.textAlign = Context2D::Center; - } else { - m_state.textAlign= Context2D::Start; - qWarning("Context2D: invalid text align"); - } - // ### alphabetic, ideographic, hanging - m_state.flags |= DirtyTextBaseline; -} - -void Context2D::setFont(const QString &fontString) -{ - QFont font; - // ### this is simplified and incomplete - QStringList tokens = fontString.split(QLatin1Char(QLatin1Char(' '))); - foreach (const QString &token, tokens) { - if (token == QLatin1String("italic")) { - font.setItalic(true); - } else if (token == QLatin1String("bold")) { - font.setBold(true); - } else if (token.endsWith(QLatin1String("px"))) { - QString number = token; - number.remove(QLatin1String("px")); -#ifdef Q_OS_MACX - // compensating the extra antialias space with bigger fonts - // this class is only used by the QML Profiler - // not much harm can be inflicted by this dirty hack - font.setPointSizeF(number.trimmed().toFloat()*4.0f/3.0f); -#else - font.setPointSizeF(number.trimmed().toFloat()); -#endif - } else { - font.setFamily(token); - } - } - m_state.font = font; - m_state.flags |= DirtyFont; -} - -QString Context2D::font() -{ - return m_state.font.toString(); -} - -qreal Context2D::shadowOffsetX() const -{ - return m_state.shadowOffsetX; -} - -qreal Context2D::shadowOffsetY() const -{ - return m_state.shadowOffsetY; -} - - -qreal Context2D::shadowBlur() const -{ - return m_state.shadowBlur; -} - - -QString Context2D::shadowColor() const -{ - return m_state.shadowColor.name(); -} - - -void Context2D::clearRect(qreal x, qreal y, qreal w, qreal h) -{ - beginPainting(); - m_painter.save(); - m_painter.setMatrix(worldMatrix(), false); - m_painter.setCompositionMode(QPainter::CompositionMode_Source); - QColor fillColor = parent()->property("color").value(); - - m_painter.fillRect(QRectF(x, y, w, h), fillColor); - m_painter.restore(); - scheduleChange(); -} - -void Context2D::fillRect(qreal x, qreal y, qreal w, qreal h) -{ - beginPainting(); - m_painter.save(); - m_painter.setMatrix(worldMatrix(), false); - m_painter.fillRect(QRectF(x, y, w, h), m_painter.brush()); - m_painter.restore(); - scheduleChange(); -} - -int Context2D::baseLineOffset(Context2D::TextBaseLine value, const QFontMetrics &metrics) -{ - int offset = 0; - switch (value) { - case Context2D::Top: - break; - case Context2D::Alphabetic: - case Context2D::Middle: - case Context2D::Hanging: - offset = metrics.ascent(); - break; - case Context2D::Bottom: - offset = metrics.height(); - break; - } - return offset; -} - -int Context2D::textAlignOffset(Context2D::TextAlign value, const QFontMetrics &metrics, const QString &text) -{ - int offset = 0; - if (value == Context2D::Start) - value = qApp->layoutDirection() == Qt::LeftToRight ? Context2D::Left : Context2D::Right; - else if (value == Context2D::End) - value = qApp->layoutDirection() == Qt::LeftToRight ? Context2D::Right: Context2D::Left; - switch (value) { - case Context2D::Center: - offset = metrics.width(text)/2; - break; - case Context2D::Right: - offset = metrics.width(text); - case Context2D::Left: - default: - break; - } - return offset; -} - -void Context2D::fillText(const QString &text, qreal x, qreal y) -{ - beginPainting(); - m_painter.save(); - m_painter.setPen(QPen(m_state.fillStyle, m_state.lineWidth)); - m_painter.setMatrix(worldMatrix(), false); - QFont font; - font.setBold(true); - m_painter.setFont(m_state.font); - int yoffset = baseLineOffset(m_state.textBaseline, m_painter.fontMetrics()); - int xoffset = textAlignOffset(m_state.textAlign, m_painter.fontMetrics(), text); - QTextOption opt; // Adjust baseLine etc - m_painter.drawText(QRectF(x-xoffset, y-yoffset, QWIDGETSIZE_MAX, m_painter.fontMetrics().height()), text, opt); - m_painter.restore(); - endPainting(); - scheduleChange(); -} - -void Context2D::strokeText(const QString &text, qreal x, qreal y) -{ - beginPainting(); - m_painter.save(); - m_painter.setPen(QPen(m_state.fillStyle,0)); - m_painter.setMatrix(worldMatrix(), false); - - QPainterPath textPath; - QFont font = m_state.font; - font.setStyleStrategy(QFont::ForceOutline); - m_painter.setFont(font); - const QFontMetrics &metrics = m_painter.fontMetrics(); - int yoffset = baseLineOffset(m_state.textBaseline, metrics); - int xoffset = textAlignOffset(m_state.textAlign, metrics, text); - textPath.addText(x-xoffset, y-yoffset+metrics.ascent(), font, text); - m_painter.strokePath(textPath, QPen(m_state.fillStyle, m_state.lineWidth)); - m_painter.restore(); - endPainting(); - scheduleChange(); -} - -void Context2D::strokeRect(qreal x, qreal y, qreal w, qreal h) -{ - QPainterPath path; - path.addRect(x, y, w, h); - beginPainting(); - m_painter.save(); - m_painter.setMatrix(worldMatrix(), false); - m_painter.strokePath(path, m_painter.pen()); - m_painter.restore(); - scheduleChange(); -} - -void Context2D::mouseArea(qreal x, qreal y, qreal w, qreal h, const QJSValue &callback, - const QJSValue &data) -{ - MouseArea a = { callback, data, QRectF(x, y, w, h), m_state.matrix }; - m_mouseAreas << a; -} - -void Context2D::beginPath() -{ - m_path = QPainterPath(); -} - - -void Context2D::closePath() -{ - m_path.closeSubpath(); -} - - -void Context2D::moveTo(qreal x, qreal y) -{ - QPointF pt = worldMatrix().map(QPointF(x, y)); - m_path.moveTo(pt); -} - - -void Context2D::lineTo(qreal x, qreal y) -{ - QPointF pt = worldMatrix().map(QPointF(x, y)); - m_path.lineTo(pt); -} - - -void Context2D::quadraticCurveTo(qreal cpx, qreal cpy, qreal x, qreal y) -{ - QPointF cp = worldMatrix().map(QPointF(cpx, cpy)); - QPointF xy = worldMatrix().map(QPointF(x, y)); - m_path.quadTo(cp, xy); -} - - -void Context2D::bezierCurveTo(qreal cp1x, qreal cp1y, - qreal cp2x, qreal cp2y, qreal x, qreal y) -{ - QPointF cp1 = worldMatrix().map(QPointF(cp1x, cp1y)); - QPointF cp2 = worldMatrix().map(QPointF(cp2x, cp2y)); - QPointF end = worldMatrix().map(QPointF(x, y)); - m_path.cubicTo(cp1, cp2, end); -} - - -void Context2D::arcTo(qreal x1, qreal y1, qreal x2, qreal y2, qreal radius) -{ - //FIXME: this is surely busted - QPointF st = worldMatrix().map(QPointF(x1, y1)); - QPointF end = worldMatrix().map(QPointF(x2, y2)); - m_path.arcTo(st.x(), st.y(), - end.x()-st.x(), end.y()-st.y(), - radius, 90); -} - - -void Context2D::rect(qreal x, qreal y, qreal w, qreal h) -{ - QPainterPath path; path.addRect(x, y, w, h); - path = worldMatrix().map(path); - m_path.addPath(path); -} - -void Context2D::arc(qreal xc, qreal yc, qreal radius, - qreal sar, qreal ear, - bool anticlockwise) -{ - //### HACK - // In Qt we don't switch the coordinate system for degrees - // and still use the 0,0 as bottom left for degrees so we need - // to switch - sar = -sar; - ear = -ear; - anticlockwise = !anticlockwise; - //end hack - - float sa = DEGREES(sar); - float ea = DEGREES(ear); - - double span = 0; - - double xs = xc - radius; - double ys = yc - radius; - double width = radius*2; - double height = radius*2; - - if (!anticlockwise && (ea < sa)) - span += 360; - else if (anticlockwise && (sa < ea)) - span -= 360; - - //### this is also due to switched coordinate system - // we would end up with a 0 span instead of 360 - if (!(qFuzzyCompare(span + (ea - sa) + 1, 1) && - qFuzzyCompare(qAbs(span), 360))) { - span += ea - sa; - } - - QPainterPath path; - path.moveTo(QPointF(xc + radius * cos(sar), - yc - radius * sin(sar))); - - path.arcTo(xs, ys, width, height, sa, span); - path = worldMatrix().map(path); - m_path.addPath(path); -} - - -void Context2D::fill() -{ - beginPainting(); - m_painter.fillPath(m_path, m_painter.brush()); - scheduleChange(); -} - - -void Context2D::stroke() -{ - beginPainting(); - m_painter.save(); - m_painter.setMatrix(worldMatrix(), false); - QPainterPath tmp = worldMatrix().inverted().map(m_path); - m_painter.strokePath(tmp, m_painter.pen()); - m_painter.restore(); - scheduleChange(); -} - - -void Context2D::clip() -{ - m_state.clipPath = m_path; - m_state.flags |= DirtyClippingRegion; -} - - -bool Context2D::isPointInPath(qreal x, qreal y) const -{ - return m_path.contains(QPointF(x, y)); -} - - -ImageData Context2D::getImageData(qreal sx, qreal sy, qreal sw, qreal sh) -{ - Q_UNUSED(sx); - Q_UNUSED(sy); - Q_UNUSED(sw); - Q_UNUSED(sh); - return ImageData(); -} - - -void Context2D::putImageData(ImageData image, qreal dx, qreal dy) -{ - Q_UNUSED(image); - Q_UNUSED(dx); - Q_UNUSED(dy); -} - -Context2D::Context2D(QObject *parent) - : QObject(parent), m_changeTimerId(-1), m_width(0), m_height(0), m_inPaint(false) -{ - reset(); -} - -void Context2D::setupPainter() -{ - m_painter.setRenderHint(QPainter::Antialiasing, true); - if ((m_state.flags & DirtyClippingRegion) && !m_state.clipPath.isEmpty()) - m_painter.setClipPath(m_state.clipPath); - if (m_state.flags & DirtyFillStyle) - m_painter.setBrush(m_state.fillStyle); - if (m_state.flags & DirtyGlobalAlpha) - m_painter.setOpacity(m_state.globalAlpha); - if (m_state.flags & DirtyGlobalCompositeOperation) - m_painter.setCompositionMode(m_state.globalCompositeOperation); - if (m_state.flags & MDirtyPen) { - QPen pen = m_painter.pen(); - if (m_state.flags & DirtyStrokeStyle) - pen.setBrush(m_state.strokeStyle); - if (m_state.flags & DirtyLineWidth) - pen.setWidthF(m_state.lineWidth); - if (m_state.flags & DirtyLineCap) - pen.setCapStyle(m_state.lineCap); - if (m_state.flags & DirtyLineJoin) - pen.setJoinStyle(m_state.lineJoin); - if (m_state.flags & DirtyMiterLimit) - pen.setMiterLimit(m_state.miterLimit); - m_painter.setPen(pen); - } -} - -void Context2D::beginPainting() -{ - if (m_pixmap.width() != m_width || m_pixmap.height() != m_height) { - if (m_painter.isActive()) - m_painter.end(); - m_pixmap = QPixmap(m_width, m_height); - m_pixmap.fill(parent()->property("color").value()); - } - - if (m_state.shadowBlur > 0 && m_painter.device() != &m_shadowbuffer) { - if (m_painter.isActive()) - m_painter.end(); - updateShadowBuffer(); - m_painter.begin(&m_shadowbuffer); - m_painter.setViewport(m_state.shadowOffsetX, - m_state.shadowOffsetY, - m_shadowbuffer.width(), - m_shadowbuffer.height()); - m_shadowbuffer.fill(Qt::transparent); - } - - if (!m_painter.isActive()) { - m_painter.begin(&m_pixmap); - m_painter.setRenderHint(QPainter::Antialiasing); - if (!m_state.clipPath.isEmpty()) - m_painter.setClipPath(m_state.clipPath); - m_painter.setBrush(m_state.fillStyle); - m_painter.setOpacity(m_state.globalAlpha); - QPen pen; - pen.setBrush(m_state.strokeStyle); - if (pen.style() == Qt::NoPen) - pen.setStyle(Qt::SolidLine); - pen.setCapStyle(m_state.lineCap); - pen.setJoinStyle(m_state.lineJoin); - pen.setWidthF(m_state.lineWidth); - pen.setMiterLimit(m_state.miterLimit); - m_painter.setPen(pen); - } else { - setupPainter(); - m_state.flags = 0; - } -} - -void Context2D::endPainting() -{ - if (m_state.shadowBlur > 0) { - QImage alphaChannel = m_shadowbuffer.alphaChannel(); - - qt_blurImage(alphaChannel, m_state.shadowBlur, false, 1); - - QRect imageRect = m_shadowbuffer.rect(); - - if (m_shadowColorIndexBuffer.isEmpty() || m_shadowColorBuffer != m_state.shadowColor) { - m_shadowColorIndexBuffer.clear(); - m_shadowColorBuffer = m_state.shadowColor; - - for (int i = 0; i < 256; ++i) { - m_shadowColorIndexBuffer << qRgba(qRound(255 * m_state.shadowColor.redF()), - qRound(255 * m_state.shadowColor.greenF()), - qRound(255 * m_state.shadowColor.blueF()), - i); - } - } - alphaChannel.setColorTable(m_shadowColorIndexBuffer); - - if (m_painter.isActive()) - m_painter.end(); - - m_painter.begin(&m_pixmap); - - // draw the blurred drop shadow... - m_painter.save(); - QTransform tf = m_painter.transform(); - m_painter.translate(0, imageRect.height()); - m_painter.rotate(-90); - m_painter.drawImage(0, 0, alphaChannel); - m_painter.setTransform(tf); - m_painter.restore(); - - // draw source - m_painter.drawImage(-m_state.shadowOffsetX, -m_state.shadowOffsetY, m_shadowbuffer.copy()); - m_painter.end(); - } -} - -void Context2D::clear() -{ - m_painter.fillRect(QRect(QPoint(0,0), size()), Qt::white); -} - -void Context2D::reset() -{ - m_stateStack.clear(); - m_state.matrix = QMatrix(); - m_state.clipPath = QPainterPath(); - m_state.strokeStyle = Qt::black; - m_state.fillStyle = Qt::black; - m_state.globalAlpha = 1.0; - m_state.lineWidth = 1; - m_state.lineCap = Qt::FlatCap; - m_state.lineJoin = Qt::MiterJoin; - m_state.miterLimit = 10; - m_state.shadowOffsetX = 0; - m_state.shadowOffsetY = 0; - m_state.shadowBlur = 0; - m_state.shadowColor = qRgba(0, 0, 0, 0); - m_state.globalCompositeOperation = QPainter::CompositionMode_SourceOver; - m_state.font = QFont(); - m_state.textAlign = Start; - m_state.textBaseline = Alphabetic; - m_state.flags = AllIsFullOfDirt; - m_mouseAreas.clear(); - clear(); -} - -void Context2D::drawImage(const QVariant &var, qreal sx, qreal sy, - qreal sw = 0, qreal sh = 0) -{ - CanvasImage *image = qobject_cast(var.value()); - if (!image) { - Canvas *canvas = qobject_cast(var.value()); - if (canvas) - image = canvas->toImage(); - } - if (image) { - beginPainting(); - if (sw == sh && sh == 0) - m_painter.drawPixmap(QPointF(sx, sy), image->value()); - else - m_painter.drawPixmap(QRect(sx, sy, sw, sh), image->value()); - - scheduleChange(); - } -} - -void Context2D::setSize(int width, int height) -{ - endPainting(); - m_width = width; - m_height = height; - - scheduleChange(); -} - -void Context2D::setSize(const QSize &size) -{ - setSize(size.width(), size.height()); -} - -QSize Context2D::size() const -{ - return m_pixmap.size(); -} - -QPoint Context2D::painterTranslate() const -{ - return m_painterTranslate; -} - -void Context2D::setPainterTranslate(const QPoint &translate) -{ - m_painterTranslate = translate; - m_state.flags |= DirtyTransformationMatrix; -} - -void Context2D::scheduleChange() -{ - QMetaObject::invokeMethod(this, "onScheduleChange", Qt::QueuedConnection, Q_ARG(int, 0)); -} - -void Context2D::onScheduleChange(int interval) -{ - if (m_changeTimerId == -1 && !m_inPaint) - m_changeTimerId = startTimer(interval); -} - -void Context2D::timerEvent(QTimerEvent *e) -{ - if (e->timerId() == m_changeTimerId) { - killTimer(m_changeTimerId); - m_changeTimerId = -1; - endPainting(); - emit changed(); - } else { - QObject::timerEvent(e); - } -} - -QMatrix Context2D::worldMatrix() const -{ - QMatrix mat; - mat.translate(m_painterTranslate.x(), m_painterTranslate.y()); - mat *= m_state.matrix; - return mat; -} - -QT_END_NAMESPACE diff --git a/src/plugins/qmlprofiler/canvas/qdeclarativecontext2d_p.h b/src/plugins/qmlprofiler/canvas/qdeclarativecontext2d_p.h deleted file mode 100644 index cd84e1fa2b..0000000000 --- a/src/plugins/qmlprofiler/canvas/qdeclarativecontext2d_p.h +++ /dev/null @@ -1,326 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** 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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, 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. -** -****************************************************************************/ - -#ifndef QDECLARATIVECONTEXT2D_P_H -#define QDECLARATIVECONTEXT2D_P_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -QColor colorFromString(const QString &name); - -class CanvasGradient : public QObject -{ - Q_OBJECT -public: - CanvasGradient(const QGradient &gradient) : m_gradient(gradient) {} - -public slots: - QGradient value() { return m_gradient; } - void addColorStop(float pos, const QString &color) { m_gradient.setColorAt(pos, colorFromString(color));} - -public: - QGradient m_gradient; -}; - -class CanvasImage: public QObject -{ - Q_OBJECT - Q_PROPERTY(QString src READ src WRITE setSrc NOTIFY sourceChanged) - Q_PROPERTY(int width READ width) - Q_PROPERTY(int height READ height) - -public: - CanvasImage() {} - CanvasImage(const QString &url) : m_image(url), m_src(url) {} - CanvasImage(const QPixmap &pixmap) {m_image = pixmap;} - -public slots: - int width() { return m_image.width(); } - int height() { return m_image.height(); } - QPixmap &value() { return m_image; } - QString src() { return m_src; } - void setSrc(const QString &src) { m_src = src; m_image.load(src); emit sourceChanged();} -signals: - void sourceChanged(); - -private: - QPixmap m_image; - QString m_src; -}; - - -class ImageData { -}; - -class Context2D : public QObject -{ - Q_OBJECT - // compositing - Q_PROPERTY(qreal globalAlpha READ globalAlpha WRITE setGlobalAlpha) - Q_PROPERTY(QString globalCompositeOperation READ globalCompositeOperation WRITE setGlobalCompositeOperation) - Q_PROPERTY(QVariant strokeStyle READ strokeStyle WRITE setStrokeStyle) - Q_PROPERTY(QVariant fillStyle READ fillStyle WRITE setFillStyle) - // line caps/joins - Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth) - Q_PROPERTY(QString lineCap READ lineCap WRITE setLineCap) - Q_PROPERTY(QString lineJoin READ lineJoin WRITE setLineJoin) - Q_PROPERTY(qreal miterLimit READ miterLimit WRITE setMiterLimit) - // shadows - Q_PROPERTY(qreal shadowOffsetX READ shadowOffsetX WRITE setShadowOffsetX) - Q_PROPERTY(qreal shadowOffsetY READ shadowOffsetY WRITE setShadowOffsetY) - Q_PROPERTY(qreal shadowBlur READ shadowBlur WRITE setShadowBlur) - Q_PROPERTY(QString shadowColor READ shadowColor WRITE setShadowColor) - // fonts - Q_PROPERTY(QString font READ font WRITE setFont) - Q_PROPERTY(QString textBaseline READ textBaseline WRITE setTextBaseline) - Q_PROPERTY(QString textAlign READ textAlign WRITE setTextAlign) - - enum TextBaseLine { Alphabetic=0, Top, Middle, Bottom, Hanging}; - enum TextAlign { Start=0, End, Left, Right, Center}; - -public: - Context2D(QObject *parent = 0); - void setSize(int width, int height); - void setSize(const QSize &size); - QSize size() const; - - QPoint painterTranslate() const; - void setPainterTranslate(const QPoint &); - - void scheduleChange(); - void timerEvent(QTimerEvent *e); - - void clear(); - void reset(); - - QPixmap pixmap() { return m_pixmap; } - - // compositing - qreal globalAlpha() const; // (default 1.0) - QString globalCompositeOperation() const; // (default over) - QVariant strokeStyle() const; // (default black) - QVariant fillStyle() const; // (default black) - - void setGlobalAlpha(qreal alpha); - void setGlobalCompositeOperation(const QString &op); - void setStrokeStyle(const QVariant &style); - void setFillStyle(const QVariant &style); - - // line caps/joins - qreal lineWidth() const; // (default 1) - QString lineCap() const; // "butt", "round", "square" (default "butt") - QString lineJoin() const; // "round", "bevel", "miter" (default "miter") - qreal miterLimit() const; // (default 10) - - void setLineWidth(qreal w); - void setLineCap(const QString &s); - void setLineJoin(const QString &s); - void setMiterLimit(qreal m); - - void setFont(const QString &font); - QString font(); - void setTextBaseline(const QString &font); - QString textBaseline(); - void setTextAlign(const QString &font); - QString textAlign(); - - // shadows - qreal shadowOffsetX() const; // (default 0) - qreal shadowOffsetY() const; // (default 0) - qreal shadowBlur() const; // (default 0) - QString shadowColor() const; // (default black) - - void setShadowOffsetX(qreal x); - void setShadowOffsetY(qreal y); - void setShadowBlur(qreal b); - void setShadowColor(const QString &str); - - struct MouseArea { - QJSValue callback; - QJSValue data; - QRectF rect; - QMatrix matrix; - }; - const QList &mouseAreas() const; - -public slots: - void save(); // push state on state stack - void restore(); // pop state stack and restore state - - void fillText(const QString &text, qreal x, qreal y); - void strokeText(const QString &text, qreal x, qreal y); - - void setInPaint(bool val){m_inPaint = val;} - void scale(qreal x, qreal y); - void rotate(qreal angle); - void translate(qreal x, qreal y); - void transform(qreal m11, qreal m12, qreal m21, qreal m22, - qreal dx, qreal dy); - void setTransform(qreal m11, qreal m12, qreal m21, qreal m22, - qreal dx, qreal dy); - - CanvasGradient *createLinearGradient(qreal x0, qreal y0, - qreal x1, qreal y1); - CanvasGradient *createRadialGradient(qreal x0, qreal y0, - qreal r0, qreal x1, - qreal y1, qreal r1); - - // rects - void clearRect(qreal x, qreal y, qreal w, qreal h); - void fillRect(qreal x, qreal y, qreal w, qreal h); - void strokeRect(qreal x, qreal y, qreal w, qreal h); - - // mouse - void mouseArea(qreal x, qreal y, qreal w, qreal h, const QJSValue &, const QJSValue & = QJSValue()); - - // path API - void beginPath(); - void closePath(); - void moveTo(qreal x, qreal y); - void lineTo(qreal x, qreal y); - void quadraticCurveTo(qreal cpx, qreal cpy, qreal x, qreal y); - void bezierCurveTo(qreal cp1x, qreal cp1y, - qreal cp2x, qreal cp2y, qreal x, qreal y); - void arcTo(qreal x1, qreal y1, qreal x2, qreal y2, qreal radius); - void rect(qreal x, qreal y, qreal w, qreal h); - void arc(qreal x, qreal y, qreal radius, - qreal startAngle, qreal endAngle, - bool anticlockwise); - void fill(); - void stroke(); - void clip(); - bool isPointInPath(qreal x, qreal y) const; - - CanvasImage *createImage(const QString &url); - - // drawing images (no overloads due to QTBUG-11604) - void drawImage(const QVariant &var, qreal dx, qreal dy, qreal dw, qreal dh); - - // pixel manipulation - ImageData getImageData(qreal sx, qreal sy, qreal sw, qreal sh); - void putImageData(ImageData image, qreal dx, qreal dy); - void endPainting(); - -private slots: - void onScheduleChange(int interval); - -signals: - void changed(); - -private: - void setupPainter(); - void beginPainting(); - void updateShadowBuffer(); - - int m_changeTimerId; - QPainterPath m_path; - - enum DirtyFlag { - DirtyTransformationMatrix = 0x00001, - DirtyClippingRegion = 0x00002, - DirtyStrokeStyle = 0x00004, - DirtyFillStyle = 0x00008, - DirtyGlobalAlpha = 0x00010, - DirtyLineWidth = 0x00020, - DirtyLineCap = 0x00040, - DirtyLineJoin = 0x00080, - DirtyMiterLimit = 0x00100, - MDirtyPen = DirtyStrokeStyle - | DirtyLineWidth - | DirtyLineCap - | DirtyLineJoin - | DirtyMiterLimit, - DirtyShadowOffsetX = 0x00200, - DirtyShadowOffsetY = 0x00400, - DirtyShadowBlur = 0x00800, - DirtyShadowColor = 0x01000, - DirtyGlobalCompositeOperation = 0x2000, - DirtyFont = 0x04000, - DirtyTextAlign = 0x08000, - DirtyTextBaseline = 0x10000, - AllIsFullOfDirt = 0xfffff - }; - - struct State { - State() : flags(0) {} - QMatrix matrix; - QPainterPath clipPath; - QBrush strokeStyle; - QBrush fillStyle; - qreal globalAlpha; - qreal lineWidth; - Qt::PenCapStyle lineCap; - Qt::PenJoinStyle lineJoin; - qreal miterLimit; - qreal shadowOffsetX; - qreal shadowOffsetY; - qreal shadowBlur; - QColor shadowColor; - QPainter::CompositionMode globalCompositeOperation; - QFont font; - Context2D::TextAlign textAlign; - Context2D::TextBaseLine textBaseline; - int flags; - }; - - int baseLineOffset(Context2D::TextBaseLine value, const QFontMetrics &metrics); - int textAlignOffset(Context2D::TextAlign value, const QFontMetrics &metrics, const QString &string); - - QMatrix worldMatrix() const; - - QPoint m_painterTranslate; - State m_state; - QStack m_stateStack; - QPixmap m_pixmap; - QList m_mouseAreas; - QImage m_shadowbuffer; - QVector m_shadowColorIndexBuffer; - QColor m_shadowColorBuffer; - QPainter m_painter; - int m_width, m_height; - bool m_inPaint; -}; - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(CanvasImage*) -Q_DECLARE_METATYPE(CanvasGradient*) - -#endif // QDECLARATIVECONTEXT2D_P_H diff --git a/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.cpp b/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.cpp deleted file mode 100644 index 3503807896..0000000000 --- a/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** 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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, 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. -** -****************************************************************************/ - -#include "qmlprofilercanvas.h" - -#include "qdeclarativecontext2d_p.h" - -#include -#include - -namespace QmlProfiler { -namespace Internal { - -QmlProfilerCanvas::QmlProfilerCanvas() - : m_context2d(new Context2D(this)) -{ - setAcceptedMouseButtons(Qt::LeftButton); - m_drawTimer.setSingleShot(true); - connect(&m_drawTimer, SIGNAL(timeout()), this, SLOT(draw())); - - m_drawTimer.start(); -} - -void QmlProfilerCanvas::requestPaint() -{ - if (m_context2d->size().width() != width() - || m_context2d->size().height() != height()) { - m_drawTimer.start(); - } else { - update(); - } -} - -void QmlProfilerCanvas::requestRedraw() -{ - m_drawTimer.start(); -} - -// called from GUI thread. Draws into m_context2d. -void QmlProfilerCanvas::draw() -{ - QMutexLocker lock(&m_pixmapMutex); - m_context2d->reset(); - m_context2d->setSize(width(), height()); - - if (width() > 0 && height() > 0) - emit drawRegion(m_context2d, QRect(0, 0, width(), height())); - update(); -} - -// called from OpenGL thread. Renders m_context2d into OpenGL buffer. -void QmlProfilerCanvas::paint(QPainter *p) -{ - QMutexLocker lock(&m_pixmapMutex); - p->drawPixmap(0, 0, m_context2d->pixmap()); -} - -void QmlProfilerCanvas::componentComplete() -{ - const QMetaObject *metaObject = this->metaObject(); - int propertyCount = metaObject->propertyCount(); - int requestPaintMethod = metaObject->indexOfMethod("requestPaint()"); - for (int ii = QmlProfilerCanvas::staticMetaObject.propertyCount(); ii < propertyCount; ++ii) { - QMetaProperty p = metaObject->property(ii); - if (p.hasNotifySignal()) - QMetaObject::connect(this, p.notifySignalIndex(), this, requestPaintMethod, 0, 0); - } - QQuickItem::componentComplete(); - requestRedraw(); -} - -void QmlProfilerCanvas::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) -{ - QQuickItem::geometryChanged(newGeometry, oldGeometry); - requestRedraw(); -} - -} -} diff --git a/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.h b/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.h deleted file mode 100644 index 4a360d012c..0000000000 --- a/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.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 Qt Creator. -** -** 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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, 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. -** -****************************************************************************/ - -#ifndef QMLPROFILERCANVAS_H -#define QMLPROFILERCANVAS_H - -#include -#include -#include - -QT_BEGIN_NAMESPACE -class Context2D; -QT_END_NAMESPACE - -namespace QmlProfiler { -namespace Internal { - -class QmlProfilerCanvas : public QQuickPaintedItem -{ - Q_OBJECT - -public: - QmlProfilerCanvas(); - -signals: - void drawRegion(Context2D *ctxt, const QRect ®ion); - -public slots: - void requestPaint(); - void requestRedraw(); - -private slots: - void draw(); - -protected: - virtual void paint(QPainter *); - virtual void componentComplete(); - virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); - -private: - Context2D *m_context2d; - - QTimer m_drawTimer; - QMutex m_pixmapMutex; -}; - -} -} - -#endif // QMLPROFILERCANVAS_H diff --git a/src/plugins/qmlprofiler/qml/CategoryLabel.qml b/src/plugins/qmlprofiler/qml/CategoryLabel.qml index f8cc12d859..5837918344 100644 --- a/src/plugins/qmlprofiler/qml/CategoryLabel.qml +++ b/src/plugins/qmlprofiler/qml/CategoryLabel.qml @@ -47,7 +47,7 @@ Item { onExpandedChanged: { qmlProfilerModelProxy.setExpanded(modelIndex, categoryIndex, expanded); - backgroundMarks.requestRedraw(); + backgroundMarks.requestPaint(); getDescriptions(); updateHeight(); } diff --git a/src/plugins/qmlprofiler/qml/Overview.qml b/src/plugins/qmlprofiler/qml/Overview.qml index 2168ea79ad..51d1fdb1f6 100644 --- a/src/plugins/qmlprofiler/qml/Overview.qml +++ b/src/plugins/qmlprofiler/qml/Overview.qml @@ -31,9 +31,10 @@ import QtQuick 2.1 import Monitor 1.0 import "Overview.js" as Plotter -Canvas2D { +Canvas { id: canvas objectName: "Overview" + contextType: "2d" // ***** properties height: 50 @@ -45,7 +46,7 @@ Canvas2D { function clearDisplay() { dataReady = false; - requestRedraw(); + requestPaint(); } function updateRange() { @@ -84,18 +85,18 @@ Canvas2D { target: qmlProfilerModelProxy onDataAvailable: { dataReady = true; - requestRedraw(); + requestPaint(); } } // ***** slots - onDrawRegion: { + onPaint: { Plotter.qmlProfilerModelProxy = qmlProfilerModelProxy; if (dataReady) { - Plotter.plot(canvas, ctxt, region); + Plotter.plot(canvas, context, region); } else { - Plotter.drawGraph(canvas, ctxt, region) //just draw the background + Plotter.drawGraph(canvas, context, region) //just draw the background } } diff --git a/src/plugins/qmlprofiler/qml/TimeDisplay.qml b/src/plugins/qmlprofiler/qml/TimeDisplay.qml index c7340cfa39..97c469f5d3 100644 --- a/src/plugins/qmlprofiler/qml/TimeDisplay.qml +++ b/src/plugins/qmlprofiler/qml/TimeDisplay.qml @@ -30,9 +30,10 @@ import QtQuick 2.1 import Monitor 1.0 -Canvas2D { +Canvas { id: timeDisplay objectName: "TimeDisplay" + contextType: "2d" property real startTime : 0 property real endTime : 0 @@ -43,13 +44,13 @@ Canvas2D { onRangeChanged: { startTime = zoomControl.startTime(); endTime = zoomControl.endTime(); - requestRedraw(); + requestPaint(); } } - onDrawRegion: { - ctxt.fillStyle = "white"; - ctxt.fillRect(0, 0, width, height); + onPaint: { + context.fillStyle = "white"; + context.fillRect(0, 0, width, height); var totalTime = endTime - startTime; var spacing = width / totalTime; @@ -67,50 +68,50 @@ Canvas2D { var initialColor = Math.floor(realStartTime/timePerBlock) % 2; - ctxt.fillStyle = "#000000"; - ctxt.font = "8px sans-serif"; + context.fillStyle = "#000000"; + context.font = "8px sans-serif"; for (var ii = 0; ii < blockCount+1; ii++) { var x = Math.floor(ii*pixelsPerBlock - realStartPos); - ctxt.fillStyle = (ii+initialColor)%2 ? "#E6E6E6":"white"; - ctxt.fillRect(x, 0, pixelsPerBlock, height); + context.fillStyle = (ii+initialColor)%2 ? "#E6E6E6":"white"; + context.fillRect(x, 0, pixelsPerBlock, height); - ctxt.strokeStyle = "#B0B0B0"; - ctxt.beginPath(); - ctxt.moveTo(x, 0); - ctxt.lineTo(x, height); - ctxt.stroke(); + context.strokeStyle = "#B0B0B0"; + context.beginPath(); + context.moveTo(x, 0); + context.lineTo(x, height); + context.stroke(); - ctxt.fillStyle = "#000000"; - ctxt.fillText(prettyPrintTime(ii*timePerBlock + realStartTime), x + 5, height/2 + 5); + context.fillStyle = "#000000"; + context.fillText(prettyPrintTime(ii*timePerBlock + realStartTime), x + 5, height/2 + 5); } - ctxt.strokeStyle = "#525252"; - ctxt.beginPath(); - ctxt.moveTo(0, height-1); - ctxt.lineTo(width, height-1); - ctxt.stroke(); + context.strokeStyle = "#525252"; + context.beginPath(); + context.moveTo(0, height-1); + context.lineTo(width, height-1); + context.stroke(); // gradient borders var gradientDark = "rgba(0, 0, 0, 0.53125)"; var gradientClear = "rgba(0, 0, 0, 0)"; - var grad = ctxt.createLinearGradient(0, 0, 0, 6); + var grad = context.createLinearGradient(0, 0, 0, 6); grad.addColorStop(0,gradientDark); grad.addColorStop(1,gradientClear); - ctxt.fillStyle = grad; - ctxt.fillRect(0, 0, width, 6); + context.fillStyle = grad; + context.fillRect(0, 0, width, 6); - grad = ctxt.createLinearGradient(0, 0, 6, 0); + grad = context.createLinearGradient(0, 0, 6, 0); grad.addColorStop(0,gradientDark); grad.addColorStop(1,gradientClear); - ctxt.fillStyle = grad; - ctxt.fillRect(0, 0, 6, height); + context.fillStyle = grad; + context.fillRect(0, 0, 6, height); - grad = ctxt.createLinearGradient(width, 0, width-6, 0); + grad = context.createLinearGradient(width, 0, width-6, 0); grad.addColorStop(0,gradientDark); grad.addColorStop(1,gradientClear); - ctxt.fillStyle = grad; - ctxt.fillRect(width-6, 0, 6, height); + context.fillStyle = grad; + context.fillRect(width-6, 0, 6, height); } function prettyPrintTime( t ) diff --git a/src/plugins/qmlprofiler/qml/TimeMarks.qml b/src/plugins/qmlprofiler/qml/TimeMarks.qml index 433d35578f..2cef16edf4 100644 --- a/src/plugins/qmlprofiler/qml/TimeMarks.qml +++ b/src/plugins/qmlprofiler/qml/TimeMarks.qml @@ -30,9 +30,10 @@ import QtQuick 2.1 import Monitor 1.0 -Canvas2D { - id: timeDisplay +Canvas { + id: timeMarks objectName: "TimeMarks" + contextType: "2d" property real startTime property real endTime @@ -40,11 +41,13 @@ Canvas2D { Connections { target: labels - onHeightChanged: { requestRedraw(); } + onHeightChanged: requestPaint() } - onDrawRegion: { - drawBackgroundBars( ctxt, region ); + onYChanged: requestPaint() + + onPaint: { + drawBackgroundBars( context, region ); var totalTime = endTime - startTime; var spacing = width / totalTime; @@ -63,23 +66,23 @@ Canvas2D { var lineStart = y < 0 ? -y : 0; var lineEnd = Math.min(height, labels.height - y); - ctxt.fillStyle = "#000000"; - ctxt.font = "8px sans-serif"; + context.fillStyle = "#000000"; + context.font = "8px sans-serif"; for (var ii = 0; ii < blockCount+1; ii++) { var x = Math.floor(ii*pixelsPerBlock - realStartPos); - ctxt.strokeStyle = "#B0B0B0"; - ctxt.beginPath(); - ctxt.moveTo(x, lineStart); - ctxt.lineTo(x, lineEnd); - ctxt.stroke(); + context.strokeStyle = "#B0B0B0"; + context.beginPath(); + context.moveTo(x, lineStart); + context.lineTo(x, lineEnd); + context.stroke(); - ctxt.strokeStyle = "#CCCCCC"; + context.strokeStyle = "#CCCCCC"; for (var jj=1; jj < 5; jj++) { var xx = Math.floor(ii*pixelsPerBlock + jj*pixelsPerSection - realStartPos); - ctxt.beginPath(); - ctxt.moveTo(xx, lineStart); - ctxt.lineTo(xx, lineEnd); - ctxt.stroke(); + context.beginPath(); + context.moveTo(xx, lineStart); + context.lineTo(xx, lineEnd); + context.stroke(); } } } @@ -88,19 +91,19 @@ Canvas2D { if (startTime !== start || endTime !== end) { startTime = start; endTime = end; - requestRedraw(); + requestPaint(); } } - function drawBackgroundBars( ctxt, region ) { + function drawBackgroundBars( context, region ) { var colorIndex = true; // row background var backgroundOffset = y < 0 ? -y : -(y % (2 * root.singleRowHeight)); for (var currentY= backgroundOffset; currentY < Math.min(height, labels.height - y); currentY += root.singleRowHeight) { - ctxt.fillStyle = colorIndex ? "#f0f0f0" : "white"; - ctxt.strokeStyle = colorIndex ? "#f0f0f0" : "white"; - ctxt.fillRect(0, currentY, width, root.singleRowHeight); + context.fillStyle = colorIndex ? "#f0f0f0" : "white"; + context.strokeStyle = colorIndex ? "#f0f0f0" : "white"; + context.fillRect(0, currentY, width, root.singleRowHeight); colorIndex = !colorIndex; } @@ -112,18 +115,18 @@ Canvas2D { if (cumulatedHeight < y) continue; - ctxt.strokeStyle = "#B0B0B0"; - ctxt.beginPath(); - ctxt.moveTo(0, cumulatedHeight - y); - ctxt.lineTo(width, cumulatedHeight - y); - ctxt.stroke(); + context.strokeStyle = "#B0B0B0"; + context.beginPath(); + context.moveTo(0, cumulatedHeight - y); + context.lineTo(width, cumulatedHeight - y); + context.stroke(); } } // bottom if (height > labels.height - y) { - ctxt.fillStyle = "#f5f5f5"; - ctxt.fillRect(0, labels.height - y, width, Math.min(height - labels.height + y, labelsTail.height)); + context.fillStyle = "#f5f5f5"; + context.fillRect(0, labels.height - y, width, Math.min(height - labels.height + y, labelsTail.height)); } } } diff --git a/src/plugins/qmlprofiler/qmlprofiler.pro b/src/plugins/qmlprofiler/qmlprofiler.pro index 8be8423533..c43d3043a3 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.pro +++ b/src/plugins/qmlprofiler/qmlprofiler.pro @@ -3,7 +3,6 @@ DEFINES += QMLPROFILER_LIBRARY QT += network qml quick include(../../qtcreatorplugin.pri) -include(canvas/canvas.pri) SOURCES += \ qmlprofilerplugin.cpp \ diff --git a/src/plugins/qmlprofiler/qmlprofiler.qbs b/src/plugins/qmlprofiler/qmlprofiler.qbs index 507ce1093e..bba8e13c79 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.qbs +++ b/src/plugins/qmlprofiler/qmlprofiler.qbs @@ -55,17 +55,6 @@ QtcPlugin { ] } - Group { - name: "Canvas" - prefix: "canvas/" - files: [ - "qdeclarativecanvas.cpp", "qdeclarativecanvas_p.h", - "qdeclarativecanvastimer.cpp", "qdeclarativecanvastimer_p.h", - "qdeclarativecontext2d.cpp", "qdeclarativecontext2d_p.h", - "qmlprofilercanvas.cpp", "qmlprofilercanvas.h" - ] - } - Group { name: "QML" prefix: "qml/" diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 5fbb3307b5..2f4afa09d7 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -41,9 +41,6 @@ #include #include -#include "canvas/qdeclarativecontext2d_p.h" -#include "canvas/qmlprofilercanvas.h" - #include #include #include @@ -119,9 +116,6 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent) d->m_profilerState = 0; d->m_viewContainer = 0; - qmlRegisterType("Monitor", 1, 0, "Canvas2D"); - qmlRegisterType(); - qmlRegisterType(); qmlRegisterType("Monitor", 1, 0,"TimelineRenderer"); d->m_profilerState = new QmlProfilerStateManager(this); -- cgit v1.2.1 From 8799b64073ab460791476cdaba0037b7a3b0655f Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 4 Dec 2013 16:00:24 +0100 Subject: QmlProfiler: Add model template for range data In order to unify the uses of range data and the calculation of first and last ranges in visible areas we need a template class to provide the respective algorithms. Change-Id: I1c2e9c9fa9ae048262026236c4ff39017ab7913f Reviewed-by: Kai Koehne --- src/plugins/qmlprofiler/qmlprofiler.pro | 6 +- src/plugins/qmlprofiler/qmlprofiler.qbs | 1 + src/plugins/qmlprofiler/sortedtimelinemodel.cpp | 110 ++++++++++++++ src/plugins/qmlprofiler/sortedtimelinemodel.h | 187 ++++++++++++++++++++++++ 4 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 src/plugins/qmlprofiler/sortedtimelinemodel.cpp create mode 100644 src/plugins/qmlprofiler/sortedtimelinemodel.h (limited to 'src/plugins/qmlprofiler') diff --git a/src/plugins/qmlprofiler/qmlprofiler.pro b/src/plugins/qmlprofiler/qmlprofiler.pro index c43d3043a3..aa23d616c8 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.pro +++ b/src/plugins/qmlprofiler/qmlprofiler.pro @@ -30,7 +30,8 @@ SOURCES += \ qmlprofilertracefile.cpp \ abstracttimelinemodel.cpp \ timelinemodelaggregator.cpp \ - qmlprofilerpainteventsmodelproxy.cpp + qmlprofilerpainteventsmodelproxy.cpp \ + sortedtimelinemodel.cpp HEADERS += \ qmlprofilerconstants.h \ @@ -61,7 +62,8 @@ HEADERS += \ qmlprofilertracefile.h \ abstracttimelinemodel.h \ timelinemodelaggregator.h \ - qmlprofilerpainteventsmodelproxy.h + qmlprofilerpainteventsmodelproxy.h \ + sortedtimelinemodel.h RESOURCES += \ qml/qmlprofiler.qrc diff --git a/src/plugins/qmlprofiler/qmlprofiler.qbs b/src/plugins/qmlprofiler/qmlprofiler.qbs index bba8e13c79..018019c49a 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.qbs +++ b/src/plugins/qmlprofiler/qmlprofiler.qbs @@ -50,6 +50,7 @@ QtcPlugin { "qmlprofilerviewmanager.cpp", "qmlprofilerviewmanager.h", "qv8profilerdatamodel.cpp", "qv8profilerdatamodel.h", "qv8profilereventview.h", "qv8profilereventview.cpp", + "sortedtimelinemodel.h", "sortedtimelinemodel.cpp", "timelinemodelaggregator.cpp", "timelinemodelaggregator.h", "timelinerenderer.cpp", "timelinerenderer.h", ] diff --git a/src/plugins/qmlprofiler/sortedtimelinemodel.cpp b/src/plugins/qmlprofiler/sortedtimelinemodel.cpp new file mode 100644 index 0000000000..567c44981f --- /dev/null +++ b/src/plugins/qmlprofiler/sortedtimelinemodel.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** 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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, 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. +** +****************************************************************************/ + +/*! + \class QmlProfiler::SortedTimelineModel + \brief Sorted model for timeline data + + The SortedTimelineModel lets you keep any kind of range data sorted by + both start and end times, so that visible ranges can easily be computed. +*/ + +/*! + \fn SortedTimelineModel::clear() + Clears the ranges and their end times. +*/ + +/*! + \fn int SortedTimelineModel::count() const + Returns the number of ranges in the model. +*/ + +/*! + \fn qint64 SortedTimelineModel::firstStartTime() const + Returns the begin of the first range in the model. +*/ + +/*! + \fn qint64 SortedTimelineModel::lastEndTime() const + Returns the end of the last range in the model. +*/ + +/*! + \fn const SortedTimelineModel::Range &SortedTimelineModel::range(int index) const + Returns the range data at the specified index. +*/ + +/*! + \fn Data &SortedTimelineModel::data(int index) + Returns modifiable user data for the range at the specified index. +*/ + +/*! + \fn int SortedTimelineModel::insert(qint64 startTime, qint64 duration, const Data &item) + Inserts the given data at the given time position and returns its index. +*/ + +/*! + \fn int SortedTimelineModel::insertStart(qint64 startTime, const Data &item) + Inserts the given data as range start at the given time position and + returns its index. The range end isn't set. +*/ + +/*! + \fn int SortedTimelineModel::insertEnd(int index, qint64 duration) + Adds a range end for the given start index. +*/ + +/*! + \fn int SortedTimelineModel::findFirstIndexNoParents(qint64 startTime) const + Looks up the first range with an end time greater than the given time and + returns its index. If no such range is found it returns -1. +*/ + +/*! + \fn int SortedTimelineModel::findFirstIndex(qint64 startTime) const + Looks up the first range with an end time greater than the given time and + returns its parent's index. If no such range is found it returns -1. If there + is no parent it returns the found range's index. The parent of a range is the + range with the lowest start time that completely covers the child range. + "Completely covers" means: + parent.startTime <= child.startTime && parent.endTime >= child.endTime +*/ + +/*! + \fn int SortedTimelineModel::findLastIndex(qint64 endTime) const + Looks up the last range with a start time smaller than the given time and + returns its index. If no such range is found it returns -1. +*/ + +/*! + \fn void computeNesting() + Compute all ranges' parents. + \sa findFirstIndex +*/ diff --git a/src/plugins/qmlprofiler/sortedtimelinemodel.h b/src/plugins/qmlprofiler/sortedtimelinemodel.h new file mode 100644 index 0000000000..80f78f2fe2 --- /dev/null +++ b/src/plugins/qmlprofiler/sortedtimelinemodel.h @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** 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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, 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. +** +****************************************************************************/ + +#ifndef SORTEDTIMELINEMODEL_H +#define SORTEDTIMELINEMODEL_H + +#include +#include + +namespace QmlProfiler { + +template +class SortedTimelineModel { +public: + struct Range : public Data { + Range() : Data(), start(-1), duration(-1), parent(-1) {} + Range(qint64 start, qint64 duration, const Data &item) : + Data(item), start(start), duration(duration), parent(-1) {} + qint64 start; + qint64 duration; + int parent; + inline qint64 timestamp() const {return start;} + }; + + struct RangeEnd { + RangeEnd() : startIndex(-1), end(-1) {} + RangeEnd(int startIndex, qint64 end) : + startIndex(startIndex), end(end) {} + int startIndex; + qint64 end; + inline qint64 timestamp() const {return end;} + }; + + void clear() + { + ranges.clear(); + endTimes.clear(); + } + + inline int count() const { return ranges.count(); } + + inline qint64 lastEndTime() const { return endTimes.last().end; } + inline qint64 firstStartTime() const { return ranges.first().start; } + + inline const Range &range(int index) { return ranges[index]; } + inline Data &data(int index) { return ranges[index]; } + + inline int insert(qint64 startTime, qint64 duration, const Data &item) + { + /* Doing insert-sort here is preferable as most of the time the times will actually be + * presorted in the right way. So usually this will just result in appending. */ + int index = insertSorted(ranges, Range(startTime, duration, item)); + insertSorted(endTimes, RangeEnd(index, startTime + duration)); + return index; + } + + inline int insertStart(qint64 startTime, const Data &item) + { + return insertSorted(ranges, Range(startTime, 0, item)); + } + + inline void insertEnd(int index, qint64 duration) + { + ranges[index].duration = duration; + insertSorted(endTimes, RangeEnd(index, ranges[index].start + duration)); + } + + inline int findFirstIndex(qint64 startTime) const + { + int index = findFirstIndexNoParents(startTime); + if (index == -1) + return -1; + int parent = ranges[index].parent; + return parent == -1 ? index : parent; + } + + inline int findFirstIndexNoParents(qint64 startTime) const + { + // in the "endtime" list, find the first event that ends after startTime + if (endTimes.isEmpty()) + return -1; + if (endTimes.count() == 1 || endTimes.first().end >= startTime) + return endTimes.first().startIndex; + if (endTimes.last().end <= startTime) + return -1; + + return endTimes[lowerBound(endTimes, startTime) + 1].startIndex; + } + + inline int findLastIndex(qint64 endTime) const + { + // in the "starttime" list, find the last event that starts before endtime + if (ranges.isEmpty() || ranges.first().start >= endTime) + return -1; + if (ranges.count() == 1) + return 0; + if (ranges.last().start <= endTime) + return ranges.count() - 1; + + return lowerBound(ranges, endTime); + } + + inline void computeNesting() + { + QLinkedList parents; + for (int range = 0; range != count(); ++range) { + Range ¤t = ranges[range]; + for (QLinkedList::iterator parent = parents.begin(); parent != parents.end();) { + qint64 parentEnd = ranges[*parent].start + ranges[*parent].duration; + if (parentEnd < current.start) { + parent = parents.erase(parent); + } else if (parentEnd >= current.start + current.duration) { + current.parent = *parent; + break; + } else { + ++parent; + } + } + parents.append(range); + } + } + +protected: + template + static inline int insertSorted(QVector &container, const RangeDelimiter &item) + { + for (int i = container.count();;) { + if (i == 0) { + container.prepend(item); + return 0; + } + if (container[--i].timestamp() <= item.timestamp()) { + container.insert(++i, item); + return i; + } + } + } + + template + static inline int lowerBound(const QVector container, qint64 time) + { + int fromIndex = 0; + int toIndex = container.count() - 1; + while (toIndex - fromIndex > 1) { + int midIndex = (fromIndex + toIndex)/2; + if (container[midIndex].timestamp() < time) + fromIndex = midIndex; + else + toIndex = midIndex; + } + + return fromIndex; + } + + QVector ranges; + QVector endTimes; +}; + +} + +#endif -- cgit v1.2.1