Mercurial > projects > qtd
changeset 310:5bcfe9e7db7f lifetime
Committing local changes
author | maxter <spambox@d-coding.com> |
---|---|
date | Wed, 23 Dec 2009 16:10:46 +0200 |
parents | a7b313b8b149 |
children | 8674fd5f34f4 |
files | build/core.txt cpp/qt_core/QMetaObject_shell.cpp demos/deform/main.d demos/deform/pathdeform.d demos/shared/arthurstyle.d demos/shared/arthurwidgets.d demos/shared/hoverpoints.d generator/abstractmetalang.cpp generator/abstractmetalang.h generator/cppgenerator.cpp generator/cppheadergenerator.cpp generator/cppimplgenerator.cpp generator/dgenerator.cpp generator/typesystem.h generator/typesystem_core-java.java generator/typesystem_core.xml mini/test1/build |
diffstat | 17 files changed, 2356 insertions(+), 2329 deletions(-) [+] |
line wrap: on
line diff
--- a/build/core.txt Tue Sep 22 15:22:37 2009 +0000 +++ b/build/core.txt Wed Dec 23 16:10:46 2009 +0200 @@ -10,16 +10,18 @@ qt_core/QModelIndex_shell qt_core/QMetaType_shell qt_core/QMetaObject_shell) ## Module specific d files. -set (d_files - QGlobal - qtd/Array +set (d_files qtd/ArrayOpsPrimitive qtd/Traits core/QString core/QMetaType core/QMetaObject) -set (d_version_files +set (d_version_files + Core + Memory + Array QtdObject + QGlobal Signal qtd/Str core/QLine core/QLineF core/QModelIndex
--- a/cpp/qt_core/QMetaObject_shell.cpp Tue Sep 22 15:22:37 2009 +0000 +++ b/cpp/qt_core/QMetaObject_shell.cpp Wed Dec 23 16:10:46 2009 +0200 @@ -1,7 +1,7 @@ -#include "qtd_core.h" -#include <qobjectdefs.h> - -extern "C" DLL_PUBLIC void* qtd_QMetaObject_superClass(void *nativeId) -{ - return (void*)((QMetaObject*)nativeId)->superClass(); +#include "qtd_core.h" +#include <qobjectdefs.h> + +extern "C" DLL_PUBLIC void* qtd_QMetaObject_superClass(void *nativeId) +{ + return (void*)((QMetaObject*)nativeId)->superClass(); } \ No newline at end of file
--- a/demos/deform/main.d Tue Sep 22 15:22:37 2009 +0000 +++ b/demos/deform/main.d Wed Dec 23 16:10:46 2009 +0200 @@ -1,74 +1,74 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** 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, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ -module main; - - -import qt.gui.QApplication; -import pathdeform; -import arthurstyle; - - -int main(string[] args) -{ - scope app = new QApplication(args); - - bool smallScreen = false; - foreach (arg; args) - { - if (arg == "-small-screen") - smallScreen = true; - } - - scope deformWidget = new PathDeformWidget(null, smallScreen); - - QStyle arthurStyle = new ArthurStyle(); - deformWidget.setWidgetStyle(arthurStyle); - QWidget[] widgets = deformWidget.findChildren!(QWidget); - foreach (w; widgets) - w.setStyle(arthurStyle); - - if (smallScreen) - deformWidget.showFullScreen(); - else - deformWidget.show(); - - return app.exec(); -} +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ +module main; + + +import qt.gui.QApplication; +import pathdeform; +import arthurstyle; + + +int main(string[] args) +{ + scope app = new QApplication(args); + + bool smallScreen = false; + foreach (arg; args) + { + if (arg == "-small-screen") + smallScreen = true; + } + + scope deformWidget = new PathDeformWidget(null, smallScreen); + + QStyle arthurStyle = new ArthurStyle(); + deformWidget.setWidgetStyle(arthurStyle); + QWidget[] widgets = deformWidget.findChildren!(QWidget); + foreach (w; widgets) + w.setStyle(arthurStyle); + + if (smallScreen) + deformWidget.showFullScreen(); + else + deformWidget.show(); + + return app.exec(); +}
--- a/demos/deform/pathdeform.d Tue Sep 22 15:22:37 2009 +0000 +++ b/demos/deform/pathdeform.d Wed Dec 23 16:10:46 2009 +0200 @@ -1,744 +1,744 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** 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, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ -module pathdeform; - - -import arthurwidgets, - qt.gui.QPainterPath, - qt.gui.QApplication, - qt.gui.QMouseEvent, - qt.core.QDateTime, - qt.core.QTimerEvent, - qt.core.QBasicTimer, - qt.gui.QLayout, - qt.gui.QLineEdit, - qt.gui.QPainter, - qt.gui.QSlider, - qt.gui.QLabel, - qt.gui.QDesktopWidget, - qt.gui.QGroupBox, - qt.gui.QPushButton, - qt.gui.QVBoxLayout, - qt.gui.QGridLayout, - qt.gui.QHBoxLayout, - qt.gui.QRadialGradient, - qt.opengl.QGLFormat, - tango.math.Math; - - -class PathDeformControls : QWidget -{ - private PathDeformRenderer m_renderer; - - mixin Signal!("okPressed"); - mixin Signal!("quitPressed"); - - this(QWidget parent, PathDeformRenderer renderer, bool smallScreen) - { - super(parent); - m_renderer = renderer; - - if (smallScreen) - layoutForSmallScreen(); - else - layoutForDesktop(); - } - - void layoutForDesktop() - { - QGroupBox mainGroup = new QGroupBox(this); - mainGroup.setTitle(tr("Controls")); - - QGroupBox radiusGroup = new QGroupBox(mainGroup); - radiusGroup.setTitle(tr("Lens Radius")); - QSlider radiusSlider = new QSlider(Qt.Horizontal, radiusGroup); - radiusSlider.setRange(15, 150); - radiusSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed); - - QGroupBox deformGroup = new QGroupBox(mainGroup); - deformGroup.setTitle(tr("Deformation")); - QSlider deformSlider = new QSlider(Qt.Horizontal, deformGroup); - deformSlider.setRange(-100, 100); - deformSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed); - - QGroupBox fontSizeGroup = new QGroupBox(mainGroup); - fontSizeGroup.setTitle(tr("Font Size")); - QSlider fontSizeSlider = new QSlider(Qt.Horizontal, fontSizeGroup); - fontSizeSlider.setRange(16, 200); - fontSizeSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed); - - QGroupBox textGroup = new QGroupBox(mainGroup); - textGroup.setTitle(tr("Text")); - QLineEdit textInput = new QLineEdit(textGroup); - - QPushButton animateButton = new QPushButton(mainGroup); - animateButton.setText(tr("Animated")); - animateButton.setCheckable(true); - - QPushButton showSourceButton = new QPushButton(mainGroup); - showSourceButton.setText(tr("Show Source")); - - version (QT_OPENGL_SUPPORT) - { - QPushButton enableOpenGLButton = new QPushButton(mainGroup); - enableOpenGLButton.setText(tr("Use OpenGL")); - enableOpenGLButton.setCheckable(true); - enableOpenGLButton.setChecked(m_renderer.usesOpenGL()); - if (!QGLFormat.hasOpenGL()) - enableOpenGLButton.hide(); - } - - QPushButton whatsThisButton = new QPushButton(mainGroup); - whatsThisButton.setText(tr("What's This?")); - whatsThisButton.setCheckable(true); - - mainGroup.setFixedWidth(180); - - QVBoxLayout mainGroupLayout = new QVBoxLayout(mainGroup); - mainGroupLayout.addWidget(radiusGroup); - mainGroupLayout.addWidget(deformGroup); - mainGroupLayout.addWidget(fontSizeGroup); - mainGroupLayout.addWidget(textGroup); - mainGroupLayout.addWidget(animateButton); - mainGroupLayout.addStretch(1); - version (QT_OPENGL_SUPPORT) - { - mainGroupLayout.addWidget(enableOpenGLButton); - } - mainGroupLayout.addWidget(showSourceButton); - mainGroupLayout.addWidget(whatsThisButton); - - QVBoxLayout radiusGroupLayout = new QVBoxLayout(radiusGroup); - radiusGroupLayout.addWidget(radiusSlider); - - QVBoxLayout deformGroupLayout = new QVBoxLayout(deformGroup); - deformGroupLayout.addWidget(deformSlider); - - QVBoxLayout fontSizeGroupLayout = new QVBoxLayout(fontSizeGroup); - fontSizeGroupLayout.addWidget(fontSizeSlider); - - QVBoxLayout textGroupLayout = new QVBoxLayout(textGroup); - textGroupLayout.addWidget(textInput); - - QVBoxLayout mainLayout = new QVBoxLayout(this); - mainLayout.addWidget(mainGroup); - mainLayout.setMargin(0); - - radiusSlider.valueChanged.connect(&m_renderer.setRadius); - deformSlider.valueChanged.connect(&m_renderer.setIntensity); - fontSizeSlider.valueChanged.connect(&m_renderer.setFontSize); - animateButton.clicked.connect(&m_renderer.setAnimated); - version (QT_OPENGL_SUPPORT) - { - enableOpenGLButton.clicked.connect(&m_renderer.enableOpenGL); - } - - textInput.textChanged.connect(&m_renderer.setText); - m_renderer.descriptionEnabledChanged.connect(&whatsThisButton.setChecked); - whatsThisButton.clicked.connect(&m_renderer.setDescriptionEnabled); - showSourceButton.clicked.connect(&m_renderer.showSource); - - animateButton.animateClick(); - deformSlider.setValue(80); - fontSizeSlider.setValue(120); - radiusSlider.setValue(100); - textInput.setText(tr("Qt")); - } - - void layoutForSmallScreen() - { - QGroupBox mainGroup = new QGroupBox(this); - mainGroup.setTitle(tr("Controls")); - - QLabel radiusLabel = new QLabel(mainGroup); - radiusLabel.setText(tr("Lens Radius:")); - QSlider radiusSlider = new QSlider(Qt.Horizontal, mainGroup); - radiusSlider.setRange(15, 150); - radiusSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed); - - QLabel deformLabel = new QLabel(mainGroup); - deformLabel.setText(tr("Deformation:")); - QSlider deformSlider = new QSlider(Qt.Horizontal, mainGroup); - deformSlider.setRange(-100, 100); - deformSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed); - - QLabel fontSizeLabel = new QLabel(mainGroup); - fontSizeLabel.setText(tr("Font Size:")); - QSlider fontSizeSlider = new QSlider(Qt.Horizontal, mainGroup); - fontSizeSlider.setRange(16, 200); - fontSizeSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed); - - QPushButton animateButton = new QPushButton(tr("Animated"), mainGroup); - animateButton.setCheckable(true); - - version (QT_OPENGL_SUPPORT) - { - QPushButton enableOpenGLButton = new QPushButton(mainGroup); - enableOpenGLButton.setText(tr("Use OpenGL")); - enableOpenGLButton.setCheckable(true); - enableOpenGLButton.setChecked(m_renderer.usesOpenGL()); - if (!QGLFormat.hasOpenGL()) - enableOpenGLButton.hide(); - } - - QPushButton quitButton = new QPushButton(tr("Quit"), mainGroup); - QPushButton okButton = new QPushButton(tr("OK"), mainGroup); - - - QGridLayout mainGroupLayout = new QGridLayout(mainGroup); - mainGroupLayout.setMargin(0); - mainGroupLayout.addWidget(radiusLabel, 0, 0, Qt.AlignRight); - mainGroupLayout.addWidget(radiusSlider, 0, 1); - mainGroupLayout.addWidget(deformLabel, 1, 0, Qt.AlignRight); - mainGroupLayout.addWidget(deformSlider, 1, 1); - mainGroupLayout.addWidget(fontSizeLabel, 2, 0, Qt.AlignRight); - mainGroupLayout.addWidget(fontSizeSlider, 2, 1); - mainGroupLayout.addWidget(animateButton, 3,0, 1,2); - version (QT_OPENGL_SUPPORT) - { - mainGroupLayout.addWidget(enableOpenGLButton, 4,0, 1,2); - } - - QVBoxLayout mainLayout = new QVBoxLayout(this); - mainLayout.addWidget(mainGroup); - mainLayout.addStretch(1); - mainLayout.addWidget(okButton); - mainLayout.addWidget(quitButton); - - quitButton.clicked.connect(&emitQuitSignal); - okButton.clicked.connect(&emitOkSignal); - radiusSlider.valueChanged.connect(&m_renderer.setRadius); - deformSlider.valueChanged.connect(&m_renderer.setIntensity); - fontSizeSlider.valueChanged.connect(&m_renderer.setFontSize); - animateButton.clicked.connect(&m_renderer.setAnimated); - version (QT_OPENGL_SUPPORT) - { - enableOpenGLButton.clicked.connect(&m_renderer.enableOpenGL); - } - - animateButton.animateClick(); - deformSlider.setValue(80); - fontSizeSlider.setValue(120); - - QRect screen_size = QApplication.desktop().screenGeometry(); - radiusSlider.setValue(qMin(screen_size.width(), screen_size.height())/5); - m_renderer.setText(tr("Qt")); - } - - void emitQuitSignal() - { - quitPressed.emit; - } - - void emitOkSignal() - { - okPressed.emit; - } -} - - -class PathDeformWidget : QWidget -{ -private: - - PathDeformRenderer m_renderer; - PathDeformControls m_controls; - -public: - - this(QWidget parent, bool smallScreen) - { - super(parent); - - setWindowTitle(tr("Vector Deformation")); - - m_renderer = new PathDeformRenderer(this, smallScreen); - m_renderer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding); - - // Layouts - QHBoxLayout mainLayout = new QHBoxLayout(this); - mainLayout.addWidget(m_renderer); - - m_controls = new PathDeformControls(null, m_renderer, smallScreen); - m_controls.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum); - - if (!smallScreen) - mainLayout.addWidget(m_controls); - - m_renderer.loadSourceFile(":res/deform/pathdeform.d"); - m_renderer.loadDescription(":res/deform/pathdeform.html"); - m_renderer.setDescriptionEnabled(false); - - m_renderer.clicked.connect(&showControls); - m_controls.okPressed.connect(&hideControls); - - m_controls.quitPressed.connect(&QApplication.quit); - } - - void showControls() - { - m_controls.showFullScreen; - } - - void hideControls() - { - m_controls.hide; - } - - void setWidgetStyle(QStyle style) // TODO: QWidget.setStyle is not virtual - { - super.setStyle(style); - if (m_controls) - { - m_controls.setStyle(style); - - QWidget[] widgets = m_controls.findChildren!(QWidget); - foreach (w; widgets) - w.setStyle(style); - } - } -} - -private QRect circle_bounds(QPointF center, qreal radius, qreal compensation) -{ - return QRect(qRound(center.x() - radius - compensation), - qRound(center.y() - radius - compensation), - qRound((radius + compensation) * 2), - qRound((radius + compensation) * 2)); -} - -enum -{ - LENS_EXTENT = 10 -} - -class PathDeformRenderer : ArthurFrame -{ -private: - - QBasicTimer m_repaintTimer; - // QBasicTimer m_fpsTimer; - // int m_fpsCounter; - QTime m_repaintTracker; - - QPainterPath[] m_paths; - QPointF[] m_advances; - QRectF m_pathBounds; - string m_text; - - QPixmap m_lens_pixmap; - QImage m_lens_image; - - int m_fontSize; - bool m_animated; - - qreal m_intensity; - qreal m_radius; - QPointF m_pos; - QPointF m_offset; - QPointF m_direction; - QPointF m_mousePress; - bool m_mouseDrag; - bool m_smallScreen; - -public: - - mixin Signal!("clicked"); - - this(QWidget widget, bool smallScreen) - { - super(widget); - m_radius = 100; - m_pos = QPointF(m_radius, m_radius); - m_direction = QPointF(1, 1); - m_fontSize = 24; - m_animated = true; - m_repaintTimer.start(25, this); - m_repaintTracker.start(); - m_intensity = 100; - m_smallScreen = smallScreen; - - // m_fpsTimer.start(1000, this); - // m_fpsCounter = 0; - - generateLensPixmap(); - } - - void setFontSize(int fontSize) - { - m_fontSize = fontSize; - setText(m_text); - } - - override QSize sizeHint() { return QSize(600, 500); } - - bool animated() { return m_animated; } - int radius() { return cast(int) m_radius; } - int fontSize() { return m_fontSize; } - int intensity() { return cast(int) m_intensity; } - string text() { return m_text; } - - void setText(string text) - { - m_text = text; - - auto f = new QFont("times new roman,utopia"); - f.setStyleStrategy(QFont.ForceOutline); - f.setPointSize(m_fontSize); - f.setStyleHint(QFont.Times); - - m_paths = null; - m_pathBounds = QRectF(); - - QPointF advance; - - bool do_quick = true; - for (int i = 0; i < text.length; ++i) { - if (text[i].unicode() >= 0x4ff && text.at(i).unicode() <= 0x1e00) { - do_quick = false; - break; - } - } - - if (do_quick) { - for (int i = 0; i < text.length; ++i) { - QPainterPath path = new QPainterPath; - path.addText(advance, f, text.mid(i, 1)); - m_pathBounds |= path.boundingRect(); - m_paths ~= path; - advance += QPointF(fm.width(text.mid(i, 1)), 0); - } - } else { - QPainterPath path = new QPainterPath; - path.addText(advance, f, text); - m_pathBounds |= path.boundingRect(); - m_paths ~= path; - } - - for (int i = 0; i < m_paths.length; ++i) - m_paths[i] = m_paths[i] * (new QMatrix(1, 0, 0, 1, -m_pathBounds.x(), -m_pathBounds.y())); - - update(); - } - - void generateLensPixmap() - { - qreal rad = m_radius + LENS_EXTENT; - - QRect bounds = circle_bounds(QPointF(), rad, 0); - - QPainter painter = new QPainter; - - if (preferImage()) { - m_lens_image = new QImage(bounds.size(), QImage.Format_ARGB32_Premultiplied); - m_lens_image.fill(0); - painter.begin(m_lens_image); - } else { - m_lens_pixmap = new QPixmap(bounds.size()); - m_lens_pixmap.fill(new QColor(Qt.transparent)); - painter.begin(m_lens_pixmap); - } - - auto gr = new QRadialGradient(rad, rad, rad, 3 * rad / 5, 3 * rad / 5); - gr.setColorAt(0.0, new QColor(255, 255, 255, 191)); - gr.setColorAt(0.2, new QColor(255, 255, 127, 191)); - gr.setColorAt(0.9, new QColor(150, 150, 200, 63)); - gr.setColorAt(0.95, new QColor(0, 0, 0, 127)); - gr.setColorAt(1, new QColor(0, 0, 0, 0)); - painter.setRenderHint(QPainter.Antialiasing); - painter.setBrush(gr); - painter.setPen(Qt.NoPen); - painter.drawEllipse(0, 0, bounds.width(), bounds.height()); - } - - void setAnimated(bool animated) - { - m_animated = animated; - - if (m_animated) { - // m_fpsTimer.start(1000, this); - // m_fpsCounter = 0; - m_repaintTimer.start(25, this); - m_repaintTracker.start(); - } else { - // m_fpsTimer.stop(); - m_repaintTimer.stop(); - } - } - - override void timerEvent(QTimerEvent e) - { - if (e.timerId == m_repaintTimer.timerId) - { - if ((QLineF(QPointF(0,0), m_direction)).length() > 1) - m_direction *= 0.995; - qreal time = m_repaintTracker.restart(); - - QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize); - - qreal dx = m_direction.x(); - qreal dy = m_direction.y(); - if (time > 0) { - dx = dx * time * .1; - dy = dy * time * .1; - } - - m_pos += QPointF(dx, dy); - - if (m_pos.x() - m_radius < 0) { - m_direction.x = -m_direction.x; - m_pos.x = m_radius; - } else if (m_pos.x + m_radius > width) { - m_direction.x = -m_direction.x; - m_pos.x = width - m_radius; - } - - if (m_pos.y - m_radius < 0) { - m_direction.y = -m_direction.y; - m_pos.y = m_radius; - } else if (m_pos.y + m_radius > height) { - m_direction.y = -m_direction.y; - m_pos.y = height - m_radius; - } - - void noGLUpdate() - { - QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize); - update(rectAfter.united(rectBefore)); - QApplication.syncX(); - } - - version (QT_OPENGL_SUPPORT) - { - if (usesOpenGL()) { - update; - } - else - noGLUpdate; - } - else - noGLUpdate; - } - // else if (e.timerId() == m_fpsTimer.timerId()) { - // printf("fps: %d\n", m_fpsCounter); - // emit frameRate(m_fpsCounter); - // m_fpsCounter = 0; - - // } - } - - override void mousePressEvent(QMouseEvent e) - { - setDescriptionEnabled(false); - - m_repaintTimer.stop(); - m_offset = QPointF(); - if ((QLineF(m_pos, QPointF(e.pos))).length <= m_radius) - m_offset = m_pos - QPointF(e.pos); - - m_mousePress = QPointF(e.pos); - - // If we're not running in small screen mode, always assume we're dragging - m_mouseDrag = !m_smallScreen; - - mouseMoveEvent(e); - } - - override void mouseReleaseEvent(QMouseEvent e) - { - if (e.buttons() == Qt.NoButton && m_animated) { - m_repaintTimer.start(10, this); - m_repaintTracker.start(); - } - - if (!m_mouseDrag && m_smallScreen) - clicked.emit; - } - - override void mouseMoveEvent(QMouseEvent e) - { - auto epos = QPointF(e.pos); - - if (!m_mouseDrag && (QLineF(m_mousePress, QPointF(e.pos))).length() > 25.0) - m_mouseDrag = true; - - if (m_mouseDrag) - { - QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize); - if (e.type() == QEvent.MouseMove) { - QLineF line = QLineF(m_pos, epos + m_offset); - line.setLength(line.length() * .1); - auto dir = QPointF(line.dx(), line.dy()); - m_direction = (m_direction + dir) / 2; - } - m_pos = epos + m_offset; - - void noGLUpdate() - { - QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize); - update(rectBefore.united(rectAfter)); - } - - version (QT_OPENGL_SUPPORT) - { - if (usesOpenGL()) { - update; - } else - noGLUpdate; - } - else - noGLUpdate; - } - } - - QPainterPath lensDeform(QPainterPath source, QPointF offset) - { - auto path = new QPainterPath; - path.addPath(source); - - qreal flip = m_intensity / 100.0; - - for (int i=0; i<path.elementCount; ++i) - { - auto e = path.elementAt(i); - - qreal x = e.x + offset.x(); - qreal y = e.y + offset.y(); - - qreal dx = x - m_pos.x(); - qreal dy = y - m_pos.y(); - qreal len = m_radius - sqrt(dx * dx + dy * dy); - - if (len > 0) { - path.setElementPositionAt(i, - x + flip * dx * len / m_radius, - y + flip * dy * len / m_radius); - } else { - path.setElementPositionAt(i, x, y); - } - } - - return path; - } - - override void paint(QPainter painter) - { - int pad_x = 5; - int pad_y = 5; - - int skip_x = qRound(m_pathBounds.width() + pad_x + m_fontSize/2); - int skip_y = qRound(m_pathBounds.height() + pad_y); - - painter.setPen(Qt.NoPen); - painter.setBrush(new QColor(Qt.black)); - - auto clip = painter.clipPath().boundingRect(); - - int overlap = pad_x / 2; - - for (int start_y=0; start_y < height(); start_y += skip_y) - { - if (start_y > clip.bottom()) - break; - - int start_x = -overlap; - for (; start_x < width(); start_x += skip_x) - { - if (start_y + skip_y >= clip.top() && - start_x + skip_x >= clip.left() && - start_x <= clip.right()) - { - for (int i=0; i<m_paths.length; ++i) { - QPainterPath path = lensDeform(m_paths[i], QPointF(start_x, start_y)); - painter.drawPath(path); - } - } - } - overlap = skip_x - (start_x - width()); - } - - if (preferImage) { - painter.drawImage(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), m_lens_image); - } else { - painter.drawPixmap(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), m_lens_pixmap); - } - } - - void setRadius(int radius) - { - qreal max = max(m_radius, cast(qreal)radius); - m_radius = radius; - generateLensPixmap(); - if (!m_animated || m_radius < max) - { - auto noGLUpdate = (){ update(circle_bounds(m_pos, max, m_fontSize)); }; - - version (QT_OPENGL_SUPPORT) - { - if (usesOpenGL()) - update(); - else - noGLUpdate(); - } - else - noGLUpdate(); - } - } - - void setIntensity(int intensity) - { - m_intensity = intensity; - if (!m_animated) - { - auto noGLUpdate = (){ update(circle_bounds(m_pos, m_radius, m_fontSize)); }; - - version (QT_OPENGL_SUPPORT) - { - if (usesOpenGL()) { - update(); - } else - noGLUpdate(); - } - else - noGLUpdate(); - } - } -} +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ +module pathdeform; + + +import arthurwidgets, + qt.gui.QPainterPath, + qt.gui.QApplication, + qt.gui.QMouseEvent, + qt.core.QDateTime, + qt.core.QTimerEvent, + qt.core.QBasicTimer, + qt.gui.QLayout, + qt.gui.QLineEdit, + qt.gui.QPainter, + qt.gui.QSlider, + qt.gui.QLabel, + qt.gui.QDesktopWidget, + qt.gui.QGroupBox, + qt.gui.QPushButton, + qt.gui.QVBoxLayout, + qt.gui.QGridLayout, + qt.gui.QHBoxLayout, + qt.gui.QRadialGradient, + qt.opengl.QGLFormat, + tango.math.Math; + + +class PathDeformControls : QWidget +{ + private PathDeformRenderer m_renderer; + + mixin Signal!("okPressed"); + mixin Signal!("quitPressed"); + + this(QWidget parent, PathDeformRenderer renderer, bool smallScreen) + { + super(parent); + m_renderer = renderer; + + if (smallScreen) + layoutForSmallScreen(); + else + layoutForDesktop(); + } + + void layoutForDesktop() + { + QGroupBox mainGroup = new QGroupBox(this); + mainGroup.setTitle(tr("Controls")); + + QGroupBox radiusGroup = new QGroupBox(mainGroup); + radiusGroup.setTitle(tr("Lens Radius")); + QSlider radiusSlider = new QSlider(Qt.Horizontal, radiusGroup); + radiusSlider.setRange(15, 150); + radiusSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed); + + QGroupBox deformGroup = new QGroupBox(mainGroup); + deformGroup.setTitle(tr("Deformation")); + QSlider deformSlider = new QSlider(Qt.Horizontal, deformGroup); + deformSlider.setRange(-100, 100); + deformSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed); + + QGroupBox fontSizeGroup = new QGroupBox(mainGroup); + fontSizeGroup.setTitle(tr("Font Size")); + QSlider fontSizeSlider = new QSlider(Qt.Horizontal, fontSizeGroup); + fontSizeSlider.setRange(16, 200); + fontSizeSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed); + + QGroupBox textGroup = new QGroupBox(mainGroup); + textGroup.setTitle(tr("Text")); + QLineEdit textInput = new QLineEdit(textGroup); + + QPushButton animateButton = new QPushButton(mainGroup); + animateButton.setText(tr("Animated")); + animateButton.setCheckable(true); + + QPushButton showSourceButton = new QPushButton(mainGroup); + showSourceButton.setText(tr("Show Source")); + + version (QT_OPENGL_SUPPORT) + { + QPushButton enableOpenGLButton = new QPushButton(mainGroup); + enableOpenGLButton.setText(tr("Use OpenGL")); + enableOpenGLButton.setCheckable(true); + enableOpenGLButton.setChecked(m_renderer.usesOpenGL()); + if (!QGLFormat.hasOpenGL()) + enableOpenGLButton.hide(); + } + + QPushButton whatsThisButton = new QPushButton(mainGroup); + whatsThisButton.setText(tr("What's This?")); + whatsThisButton.setCheckable(true); + + mainGroup.setFixedWidth(180); + + QVBoxLayout mainGroupLayout = new QVBoxLayout(mainGroup); + mainGroupLayout.addWidget(radiusGroup); + mainGroupLayout.addWidget(deformGroup); + mainGroupLayout.addWidget(fontSizeGroup); + mainGroupLayout.addWidget(textGroup); + mainGroupLayout.addWidget(animateButton); + mainGroupLayout.addStretch(1); + version (QT_OPENGL_SUPPORT) + { + mainGroupLayout.addWidget(enableOpenGLButton); + } + mainGroupLayout.addWidget(showSourceButton); + mainGroupLayout.addWidget(whatsThisButton); + + QVBoxLayout radiusGroupLayout = new QVBoxLayout(radiusGroup); + radiusGroupLayout.addWidget(radiusSlider); + + QVBoxLayout deformGroupLayout = new QVBoxLayout(deformGroup); + deformGroupLayout.addWidget(deformSlider); + + QVBoxLayout fontSizeGroupLayout = new QVBoxLayout(fontSizeGroup); + fontSizeGroupLayout.addWidget(fontSizeSlider); + + QVBoxLayout textGroupLayout = new QVBoxLayout(textGroup); + textGroupLayout.addWidget(textInput); + + QVBoxLayout mainLayout = new QVBoxLayout(this); + mainLayout.addWidget(mainGroup); + mainLayout.setMargin(0); + + radiusSlider.valueChanged.connect(&m_renderer.setRadius); + deformSlider.valueChanged.connect(&m_renderer.setIntensity); + fontSizeSlider.valueChanged.connect(&m_renderer.setFontSize); + animateButton.clicked.connect(&m_renderer.setAnimated); + version (QT_OPENGL_SUPPORT) + { + enableOpenGLButton.clicked.connect(&m_renderer.enableOpenGL); + } + + textInput.textChanged.connect(&m_renderer.setText); + m_renderer.descriptionEnabledChanged.connect(&whatsThisButton.setChecked); + whatsThisButton.clicked.connect(&m_renderer.setDescriptionEnabled); + showSourceButton.clicked.connect(&m_renderer.showSource); + + animateButton.animateClick(); + deformSlider.setValue(80); + fontSizeSlider.setValue(120); + radiusSlider.setValue(100); + textInput.setText(tr("Qt")); + } + + void layoutForSmallScreen() + { + QGroupBox mainGroup = new QGroupBox(this); + mainGroup.setTitle(tr("Controls")); + + QLabel radiusLabel = new QLabel(mainGroup); + radiusLabel.setText(tr("Lens Radius:")); + QSlider radiusSlider = new QSlider(Qt.Horizontal, mainGroup); + radiusSlider.setRange(15, 150); + radiusSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed); + + QLabel deformLabel = new QLabel(mainGroup); + deformLabel.setText(tr("Deformation:")); + QSlider deformSlider = new QSlider(Qt.Horizontal, mainGroup); + deformSlider.setRange(-100, 100); + deformSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed); + + QLabel fontSizeLabel = new QLabel(mainGroup); + fontSizeLabel.setText(tr("Font Size:")); + QSlider fontSizeSlider = new QSlider(Qt.Horizontal, mainGroup); + fontSizeSlider.setRange(16, 200); + fontSizeSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed); + + QPushButton animateButton = new QPushButton(tr("Animated"), mainGroup); + animateButton.setCheckable(true); + + version (QT_OPENGL_SUPPORT) + { + QPushButton enableOpenGLButton = new QPushButton(mainGroup); + enableOpenGLButton.setText(tr("Use OpenGL")); + enableOpenGLButton.setCheckable(true); + enableOpenGLButton.setChecked(m_renderer.usesOpenGL()); + if (!QGLFormat.hasOpenGL()) + enableOpenGLButton.hide(); + } + + QPushButton quitButton = new QPushButton(tr("Quit"), mainGroup); + QPushButton okButton = new QPushButton(tr("OK"), mainGroup); + + + QGridLayout mainGroupLayout = new QGridLayout(mainGroup); + mainGroupLayout.setMargin(0); + mainGroupLayout.addWidget(radiusLabel, 0, 0, Qt.AlignRight); + mainGroupLayout.addWidget(radiusSlider, 0, 1); + mainGroupLayout.addWidget(deformLabel, 1, 0, Qt.AlignRight); + mainGroupLayout.addWidget(deformSlider, 1, 1); + mainGroupLayout.addWidget(fontSizeLabel, 2, 0, Qt.AlignRight); + mainGroupLayout.addWidget(fontSizeSlider, 2, 1); + mainGroupLayout.addWidget(animateButton, 3,0, 1,2); + version (QT_OPENGL_SUPPORT) + { + mainGroupLayout.addWidget(enableOpenGLButton, 4,0, 1,2); + } + + QVBoxLayout mainLayout = new QVBoxLayout(this); + mainLayout.addWidget(mainGroup); + mainLayout.addStretch(1); + mainLayout.addWidget(okButton); + mainLayout.addWidget(quitButton); + + quitButton.clicked.connect(&emitQuitSignal); + okButton.clicked.connect(&emitOkSignal); + radiusSlider.valueChanged.connect(&m_renderer.setRadius); + deformSlider.valueChanged.connect(&m_renderer.setIntensity); + fontSizeSlider.valueChanged.connect(&m_renderer.setFontSize); + animateButton.clicked.connect(&m_renderer.setAnimated); + version (QT_OPENGL_SUPPORT) + { + enableOpenGLButton.clicked.connect(&m_renderer.enableOpenGL); + } + + animateButton.animateClick(); + deformSlider.setValue(80); + fontSizeSlider.setValue(120); + + QRect screen_size = QApplication.desktop().screenGeometry(); + radiusSlider.setValue(qMin(screen_size.width(), screen_size.height())/5); + m_renderer.setText(tr("Qt")); + } + + void emitQuitSignal() + { + quitPressed.emit; + } + + void emitOkSignal() + { + okPressed.emit; + } +} + + +class PathDeformWidget : QWidget +{ +private: + + PathDeformRenderer m_renderer; + PathDeformControls m_controls; + +public: + + this(QWidget parent, bool smallScreen) + { + super(parent); + + setWindowTitle(tr("Vector Deformation")); + + m_renderer = new PathDeformRenderer(this, smallScreen); + m_renderer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding); + + // Layouts + QHBoxLayout mainLayout = new QHBoxLayout(this); + mainLayout.addWidget(m_renderer); + + m_controls = new PathDeformControls(null, m_renderer, smallScreen); + m_controls.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum); + + if (!smallScreen) + mainLayout.addWidget(m_controls); + + m_renderer.loadSourceFile(":res/deform/pathdeform.d"); + m_renderer.loadDescription(":res/deform/pathdeform.html"); + m_renderer.setDescriptionEnabled(false); + + m_renderer.clicked.connect(&showControls); + m_controls.okPressed.connect(&hideControls); + + m_controls.quitPressed.connect(&QApplication.quit); + } + + void showControls() + { + m_controls.showFullScreen; + } + + void hideControls() + { + m_controls.hide; + } + + void setWidgetStyle(QStyle style) // TODO: QWidget.setStyle is not virtual + { + super.setStyle(style); + if (m_controls) + { + m_controls.setStyle(style); + + QWidget[] widgets = m_controls.findChildren!(QWidget); + foreach (w; widgets) + w.setStyle(style); + } + } +} + +private QRect circle_bounds(QPointF center, qreal radius, qreal compensation) +{ + return QRect(qRound(center.x() - radius - compensation), + qRound(center.y() - radius - compensation), + qRound((radius + compensation) * 2), + qRound((radius + compensation) * 2)); +} + +enum +{ + LENS_EXTENT = 10 +} + +class PathDeformRenderer : ArthurFrame +{ +private: + + QBasicTimer m_repaintTimer; + // QBasicTimer m_fpsTimer; + // int m_fpsCounter; + QTime m_repaintTracker; + + QPainterPath[] m_paths; + QPointF[] m_advances; + QRectF m_pathBounds; + string m_text; + + QPixmap m_lens_pixmap; + QImage m_lens_image; + + int m_fontSize; + bool m_animated; + + qreal m_intensity; + qreal m_radius; + QPointF m_pos; + QPointF m_offset; + QPointF m_direction; + QPointF m_mousePress; + bool m_mouseDrag; + bool m_smallScreen; + +public: + + mixin Signal!("clicked"); + + this(QWidget widget, bool smallScreen) + { + super(widget); + m_radius = 100; + m_pos = QPointF(m_radius, m_radius); + m_direction = QPointF(1, 1); + m_fontSize = 24; + m_animated = true; + m_repaintTimer.start(25, this); + m_repaintTracker.start(); + m_intensity = 100; + m_smallScreen = smallScreen; + + // m_fpsTimer.start(1000, this); + // m_fpsCounter = 0; + + generateLensPixmap(); + } + + void setFontSize(int fontSize) + { + m_fontSize = fontSize; + setText(m_text); + } + + override QSize sizeHint() { return QSize(600, 500); } + + bool animated() { return m_animated; } + int radius() { return cast(int) m_radius; } + int fontSize() { return m_fontSize; } + int intensity() { return cast(int) m_intensity; } + string text() { return m_text; } + + void setText(string text) + { + m_text = text; + + auto f = new QFont("times new roman,utopia"); + f.setStyleStrategy(QFont.ForceOutline); + f.setPointSize(m_fontSize); + f.setStyleHint(QFont.Times); + + m_paths = null; + m_pathBounds = QRectF(); + + QPointF advance; + + bool do_quick = true; + for (int i = 0; i < text.length; ++i) { + if (text[i].unicode() >= 0x4ff && text.at(i).unicode() <= 0x1e00) { + do_quick = false; + break; + } + } + + if (do_quick) { + for (int i = 0; i < text.length; ++i) { + QPainterPath path = new QPainterPath; + path.addText(advance, f, text.mid(i, 1)); + m_pathBounds |= path.boundingRect(); + m_paths ~= path; + advance += QPointF(fm.width(text.mid(i, 1)), 0); + } + } else { + QPainterPath path = new QPainterPath; + path.addText(advance, f, text); + m_pathBounds |= path.boundingRect(); + m_paths ~= path; + } + + for (int i = 0; i < m_paths.length; ++i) + m_paths[i] = m_paths[i] * (new QMatrix(1, 0, 0, 1, -m_pathBounds.x(), -m_pathBounds.y())); + + update(); + } + + void generateLensPixmap() + { + qreal rad = m_radius + LENS_EXTENT; + + QRect bounds = circle_bounds(QPointF(), rad, 0); + + QPainter painter = new QPainter; + + if (preferImage()) { + m_lens_image = new QImage(bounds.size(), QImage.Format_ARGB32_Premultiplied); + m_lens_image.fill(0); + painter.begin(m_lens_image); + } else { + m_lens_pixmap = new QPixmap(bounds.size()); + m_lens_pixmap.fill(new QColor(Qt.transparent)); + painter.begin(m_lens_pixmap); + } + + auto gr = new QRadialGradient(rad, rad, rad, 3 * rad / 5, 3 * rad / 5); + gr.setColorAt(0.0, new QColor(255, 255, 255, 191)); + gr.setColorAt(0.2, new QColor(255, 255, 127, 191)); + gr.setColorAt(0.9, new QColor(150, 150, 200, 63)); + gr.setColorAt(0.95, new QColor(0, 0, 0, 127)); + gr.setColorAt(1, new QColor(0, 0, 0, 0)); + painter.setRenderHint(QPainter.Antialiasing); + painter.setBrush(gr); + painter.setPen(Qt.NoPen); + painter.drawEllipse(0, 0, bounds.width(), bounds.height()); + } + + void setAnimated(bool animated) + { + m_animated = animated; + + if (m_animated) { + // m_fpsTimer.start(1000, this); + // m_fpsCounter = 0; + m_repaintTimer.start(25, this); + m_repaintTracker.start(); + } else { + // m_fpsTimer.stop(); + m_repaintTimer.stop(); + } + } + + override void timerEvent(QTimerEvent e) + { + if (e.timerId == m_repaintTimer.timerId) + { + if ((QLineF(QPointF(0,0), m_direction)).length() > 1) + m_direction *= 0.995; + qreal time = m_repaintTracker.restart(); + + QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize); + + qreal dx = m_direction.x(); + qreal dy = m_direction.y(); + if (time > 0) { + dx = dx * time * .1; + dy = dy * time * .1; + } + + m_pos += QPointF(dx, dy); + + if (m_pos.x() - m_radius < 0) { + m_direction.x = -m_direction.x; + m_pos.x = m_radius; + } else if (m_pos.x + m_radius > width) { + m_direction.x = -m_direction.x; + m_pos.x = width - m_radius; + } + + if (m_pos.y - m_radius < 0) { + m_direction.y = -m_direction.y; + m_pos.y = m_radius; + } else if (m_pos.y + m_radius > height) { + m_direction.y = -m_direction.y; + m_pos.y = height - m_radius; + } + + void noGLUpdate() + { + QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize); + update(rectAfter.united(rectBefore)); + QApplication.syncX(); + } + + version (QT_OPENGL_SUPPORT) + { + if (usesOpenGL()) { + update; + } + else + noGLUpdate; + } + else + noGLUpdate; + } + // else if (e.timerId() == m_fpsTimer.timerId()) { + // printf("fps: %d\n", m_fpsCounter); + // emit frameRate(m_fpsCounter); + // m_fpsCounter = 0; + + // } + } + + override void mousePressEvent(QMouseEvent e) + { + setDescriptionEnabled(false); + + m_repaintTimer.stop(); + m_offset = QPointF(); + if ((QLineF(m_pos, QPointF(e.pos))).length <= m_radius) + m_offset = m_pos - QPointF(e.pos); + + m_mousePress = QPointF(e.pos); + + // If we're not running in small screen mode, always assume we're dragging + m_mouseDrag = !m_smallScreen; + + mouseMoveEvent(e); + } + + override void mouseReleaseEvent(QMouseEvent e) + { + if (e.buttons() == Qt.NoButton && m_animated) { + m_repaintTimer.start(10, this); + m_repaintTracker.start(); + } + + if (!m_mouseDrag && m_smallScreen) + clicked.emit; + } + + override void mouseMoveEvent(QMouseEvent e) + { + auto epos = QPointF(e.pos); + + if (!m_mouseDrag && (QLineF(m_mousePress, QPointF(e.pos))).length() > 25.0) + m_mouseDrag = true; + + if (m_mouseDrag) + { + QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize); + if (e.type() == QEvent.MouseMove) { + QLineF line = QLineF(m_pos, epos + m_offset); + line.setLength(line.length() * .1); + auto dir = QPointF(line.dx(), line.dy()); + m_direction = (m_direction + dir) / 2; + } + m_pos = epos + m_offset; + + void noGLUpdate() + { + QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize); + update(rectBefore.united(rectAfter)); + } + + version (QT_OPENGL_SUPPORT) + { + if (usesOpenGL()) { + update; + } else + noGLUpdate; + } + else + noGLUpdate; + } + } + + QPainterPath lensDeform(QPainterPath source, QPointF offset) + { + auto path = new QPainterPath; + path.addPath(source); + + qreal flip = m_intensity / 100.0; + + for (int i=0; i<path.elementCount; ++i) + { + auto e = path.elementAt(i); + + qreal x = e.x + offset.x(); + qreal y = e.y + offset.y(); + + qreal dx = x - m_pos.x(); + qreal dy = y - m_pos.y(); + qreal len = m_radius - sqrt(dx * dx + dy * dy); + + if (len > 0) { + path.setElementPositionAt(i, + x + flip * dx * len / m_radius, + y + flip * dy * len / m_radius); + } else { + path.setElementPositionAt(i, x, y); + } + } + + return path; + } + + override void paint(QPainter painter) + { + int pad_x = 5; + int pad_y = 5; + + int skip_x = qRound(m_pathBounds.width() + pad_x + m_fontSize/2); + int skip_y = qRound(m_pathBounds.height() + pad_y); + + painter.setPen(Qt.NoPen); + painter.setBrush(new QColor(Qt.black)); + + auto clip = painter.clipPath().boundingRect(); + + int overlap = pad_x / 2; + + for (int start_y=0; start_y < height(); start_y += skip_y) + { + if (start_y > clip.bottom()) + break; + + int start_x = -overlap; + for (; start_x < width(); start_x += skip_x) + { + if (start_y + skip_y >= clip.top() && + start_x + skip_x >= clip.left() && + start_x <= clip.right()) + { + for (int i=0; i<m_paths.length; ++i) { + QPainterPath path = lensDeform(m_paths[i], QPointF(start_x, start_y)); + painter.drawPath(path); + } + } + } + overlap = skip_x - (start_x - width()); + } + + if (preferImage) { + painter.drawImage(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), m_lens_image); + } else { + painter.drawPixmap(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), m_lens_pixmap); + } + } + + void setRadius(int radius) + { + qreal max = max(m_radius, cast(qreal)radius); + m_radius = radius; + generateLensPixmap(); + if (!m_animated || m_radius < max) + { + auto noGLUpdate = (){ update(circle_bounds(m_pos, max, m_fontSize)); }; + + version (QT_OPENGL_SUPPORT) + { + if (usesOpenGL()) + update(); + else + noGLUpdate(); + } + else + noGLUpdate(); + } + } + + void setIntensity(int intensity) + { + m_intensity = intensity; + if (!m_animated) + { + auto noGLUpdate = (){ update(circle_bounds(m_pos, m_radius, m_fontSize)); }; + + version (QT_OPENGL_SUPPORT) + { + if (usesOpenGL()) { + update(); + } else + noGLUpdate(); + } + else + noGLUpdate(); + } + } +}
--- a/demos/shared/arthurstyle.d Tue Sep 22 15:22:37 2009 +0000 +++ b/demos/shared/arthurstyle.d Wed Dec 23 16:10:46 2009 +0200 @@ -1,450 +1,450 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** 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, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ -module arthurstyle; - - -import - qt.gui.QLayout, - qt.gui.QWindowsStyle, - qt.gui.QPainter, - qt.gui.QPainterPath, - qt.gui.QPixmapCache, - qt.gui.QRadioButton, - qt.gui.QPushButton, - qt.gui.QGroupBox, - qt.gui.QLinearGradient, - qt.gui.QStyleOption, - qt.gui.QStyleOptionFrameV2; - - -class ArthurStyle : QWindowsStyle -{ - QPixmap cached(string img) - { - QPixmap pm = new QPixmap; - if (QPixmapCache.find(img, pm)) - return pm; - - pm = QPixmap.fromImage(new QImage(img), Qt.OrderedDither | Qt.OrderedAlphaDither); - if (pm.isNull) - return new QPixmap; - - QPixmapCache.insert(img, pm); - return pm; - } - - this() - { - //Q_INIT_RESOURCE(shared); - } - - void drawHoverRect(QPainter painter, QRect r) - { - qreal h = r.height(); - qreal h2 = r.height() / 2.0; - QPainterPath path = new QPainterPath; - path.addRect(r.x() + h2, r.y() + 0, r.width() - h2 * 2, r.height()); - path.addEllipse(r.x(), r.y(), h, h); - path.addEllipse(r.x() + r.width() - h, r.y(), h, h); - path.setFillRule(Qt.WindingFill); - painter.setPen(Qt.NoPen); - painter.setBrush(new QColor(191, 215, 191)); - painter.setRenderHint(QPainter.Antialiasing); - painter.drawPath(path); - } - - override void drawPrimitive(PrimitiveElement element, QStyleOption option, QPainter painter, QWidget widget) - { - assert(option); - switch (element) - { - case PE_FrameFocusRect: - break; - - case PE_IndicatorRadioButton: - if (QStyleOptionButton button = cast(QStyleOptionButton)(option)) { - bool hover = (button.state & State_Enabled) && (button.state & State_MouseOver); - painter.save; - QPixmap radio; - if (hover) - drawHoverRect(painter, widget.rect); - - if (button.state & State_Sunken) - radio = cached(":res/images/radiobutton-on.png"); - else if (button.state & State_On) - radio = cached(":res/images/radiobutton_on.png"); - else - radio = cached(":res/images/radiobutton_off.png"); - painter.drawPixmap(button.rect.topLeft, radio); - - painter.restore(); - } - break; - - case PE_PanelButtonCommand: - if (QStyleOptionButton button = cast(QStyleOptionButton)(option)) { - bool hover = (button.state & State_Enabled) && (button.state & State_MouseOver); - - painter.save(); - QPushButton pushButton = cast(QPushButton)(widget); - assert(pushButton); - auto parent = pushButton.parentWidget; - if (parent && cast(QGroupBox)(parent)) { - auto lg = new QLinearGradient(0, 0, 0, parent.height); - lg.setColorAt(0, new QColor(224,224,224)); - lg.setColorAt(1, new QColor(255,255,255)); - painter.setPen(Qt.NoPen); - painter.setBrush(lg); - painter.setBrushOrigin(QPoint() - widget.mapToParent(QPoint(0,0))); - painter.drawRect(button.rect); - painter.setBrushOrigin(0, 0); - } - - bool down = (button.state & State_Sunken) || (button.state & State_On); - - QPixmap left, right, mid; - if (down) { - left = cached(":res/images/button_pressed_cap_left.png"); - right = cached(":res/images/button_pressed_cap_right.png"); - mid = cached(":res/images/button_pressed_stretch.png"); - } else { - left = cached(":res/images/button_normal_cap_left.png"); - right = cached(":res/images/button_normal_cap_right.png"); - mid = cached(":res/images/button_normal_stretch.png"); - } - painter.drawPixmap(button.rect.topLeft, left); - painter.drawTiledPixmap(QRect(button.rect.x + left.width, - button.rect.y, - button.rect.width - left.width - right.width, - left.height), - mid); - painter.drawPixmap(button.rect.x + button.rect.width - right.width, - button.rect.y, - right); - if (hover) - painter.fillRect(widget.rect.adjusted(3,5,-3,-5), new QColor(31,127,31,63)); - painter.restore; - } - break; - - case PE_FrameGroupBox: - if (QStyleOptionFrameV2 group = cast(QStyleOptionFrameV2)(option)) { - auto r = group.rect; - - painter.save(); - int radius = 14; - int radius2 = radius*2; - QPainterPath clipPath; - clipPath.moveTo(radius, 0); - clipPath.arcTo(r.right() - radius2, 0, radius2, radius2, 90, -90); - clipPath.arcTo(r.right() - radius2, r.bottom() - radius2, radius2, radius2, 0, -90); - clipPath.arcTo(r.left(), r.bottom() - radius2, radius2, radius2, 270, -90); - clipPath.arcTo(r.left(), r.top(), radius2, radius2, 180, -90); - painter.setClipPath(clipPath); - QPixmap titleStretch = cached(":res/images/title_stretch.png"); - QPixmap topLeft = cached(":res/images/groupframe_topleft.png"); - QPixmap topRight = cached(":res/images/groupframe_topright.png"); - QPixmap bottomLeft = cached(":res/images/groupframe_bottom_left.png"); - QPixmap bottomRight = cached(":res/images/groupframe_bottom_right.png"); - QPixmap leftStretch = cached(":res/images/groupframe_left_stretch.png"); - QPixmap topStretch = cached(":res/images/groupframe_top_stretch.png"); - QPixmap rightStretch = cached(":res/images/groupframe_right_stretch.png"); - QPixmap bottomStretch = cached(":res/images/groupframe_bottom_stretch.png"); - auto lg = new QLinearGradient(0, 0, 0, r.height()); - lg.setColorAt(0, new QColor(224,224,224)); - lg.setColorAt(1, new QColor(255,255,255)); - painter.setPen(Qt.NoPen); - painter.setBrush(lg); - painter.drawRect(r.adjusted(0, titleStretch.height()/2, 0, 0)); - painter.setClipping(false); - - int topFrameOffset = titleStretch.height()/2 - 2; - painter.drawPixmap(r.topLeft() + QPoint(0, topFrameOffset), topLeft); - painter.drawPixmap(r.topRight() - QPoint(topRight.width()-1, 0) + QPoint(0, topFrameOffset), topRight); - painter.drawPixmap(r.bottomLeft() - QPoint(0, bottomLeft.height()-1), bottomLeft); - painter.drawPixmap(r.bottomRight() - QPoint(bottomRight.width()-1, bottomRight.height()-1), bottomRight); - - QRect left = r; - left.setY(r.y() + topLeft.height() + topFrameOffset); - left.setWidth(leftStretch.width()); - left.setHeight(r.height() - topLeft.height() - bottomLeft.height() - topFrameOffset); - painter.drawTiledPixmap(left, leftStretch); - - QRect top = r; - top.setX(r.x() + topLeft.width()); - top.setY(r.y() + topFrameOffset); - top.setWidth(r.width() - topLeft.width() - topRight.width()); - top.setHeight(topLeft.height()); - painter.drawTiledPixmap(top, topStretch); - - QRect right = r; - right.setX(r.right() - rightStretch.width()+1); - right.setY(r.y() + topRight.height() + topFrameOffset); - right.setWidth(rightStretch.width()); - right.setHeight(r.height() - topRight.height() - bottomRight.height() - topFrameOffset); - painter.drawTiledPixmap(right, rightStretch); - - QRect bottom = r; - bottom.setX(r.x() + bottomLeft.width()); - bottom.setY(r.bottom() - bottomStretch.height()+1); - bottom.setWidth(r.width() - bottomLeft.width() - bottomRight.width()); - bottom.setHeight(bottomLeft.height()); - painter.drawTiledPixmap(bottom, bottomStretch); - painter.restore(); - } - break; - - default: - QWindowsStyle.drawPrimitive(element, option, painter, widget); - break; - } - return; - } - - override void drawComplexControl(ComplexControl control, QStyleOptionComplex option, - QPainter painter, QWidget widget) - { - switch (control) { - case CC_Slider: - if (QStyleOptionSlider slider = cast(QStyleOptionSlider)(option)) { - QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget); - QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget); - - painter.save; - - bool hover = (slider.state & State_Enabled) && (slider.state & State_MouseOver); - if (hover) { - QRect moderated = widget.rect().adjusted(0, 4, 0, -4); - drawHoverRect(painter, moderated); - } - - if ((option.subControls & SC_SliderGroove) && groove.isValid()) { - QPixmap grv = cached(":res/images/slider_bar.png"); - painter.drawPixmap(QRect(groove.x() + 5, groove.y(), - groove.width() - 10, grv.height()), - grv); - } - if ((option.subControls & SC_SliderHandle) && handle.isValid()) { - QPixmap hndl = cached(":res/images/slider_thumb_on.png"); - painter.drawPixmap(handle.topLeft(), hndl); - } - - painter.restore(); - } - break; - case CC_GroupBox: - if (QStyleOptionGroupBox groupBox - = cast(QStyleOptionGroupBox)(option)) { - auto groupBoxCopy = new QStyleOptionGroupBox(groupBox); - groupBoxCopy.setSubControls = groupBoxCopy.subControls & ~SC_GroupBoxLabel; - QWindowsStyle.drawComplexControl(control, groupBoxCopy, painter, widget); - - if (groupBox.subControls & SC_GroupBoxLabel) { - QRect r = groupBox.rect; - QPixmap titleLeft = cached(":res/images/title_cap_left.png"); - QPixmap titleRight = cached(":res/images/title_cap_right.png"); - QPixmap titleStretch = cached(":res/images/title_stretch.png"); - int txt_width = groupBox.fontMetrics.width(groupBox.text) + 20; - painter.drawPixmap(r.center().x() - txt_width/2, 0, titleLeft); - QRect tileRect = subControlRect(control, groupBox, SC_GroupBoxLabel, widget); - painter.drawTiledPixmap(tileRect, titleStretch); - painter.drawPixmap(tileRect.x() + tileRect.width(), 0, titleRight); - int opacity = 31; - painter.setPen(new QColor(0, 0, 0, opacity)); - painter.drawText(tileRect.translated(0, 1), - cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null); - painter.drawText(tileRect.translated(2, 1), - cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null); - painter.setPen(new QColor(0, 0, 0, opacity * 2)); - painter.drawText(tileRect.translated(1, 1), - cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null); - painter.setPen(new QColor(Qt.white)); - painter.drawText(tileRect, cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null); - } - } - break; - default: - QWindowsStyle.drawComplexControl(control, option, painter, widget); - break; - } - return; - } - - override QRect subControlRect(QStyle_ComplexControl control, QStyleOptionComplex option, - int sc, QWidget widget = null) - { - QRect rect; - - auto subControl = cast(SubControl)sc; - - switch (control) { - default: - rect = QWindowsStyle.subControlRect(control, option, subControl, widget); - break; - case CC_GroupBox: - if (QStyleOptionGroupBox group - = cast(QStyleOptionGroupBox)(option)) { - switch (subControl) { - default: - rect = QWindowsStyle.subControlRect(control, option, subControl, widget); - break; - case SC_GroupBoxContents: - rect = QWindowsStyle.subControlRect(control, option, subControl, widget); - rect.adjust(0, -8, 0, 0); - break; - case SC_GroupBoxFrame: - rect = group.rect; - break; - case SC_GroupBoxLabel: - QPixmap titleLeft = cached(":res/images/title_cap_left.png"); - QPixmap titleRight = cached(":res/images/title_cap_right.png"); - QPixmap titleStretch = cached(":res/images/title_stretch.png"); - int txt_width = group.fontMetrics.width(group.text) + 20; - rect = QRect(group.rect.center().x() - txt_width/2 + titleLeft.width(), 0, - txt_width - titleLeft.width() - titleRight.width(), - titleStretch.height()); - break; - } - } - break; - } - - if (control == CC_Slider && subControl == SC_SliderHandle) { - rect.setWidth(13); - rect.setHeight(27); - } else if (control == CC_Slider && subControl == SC_SliderGroove) { - rect.setHeight(9); - rect.moveTop(27/2 - 9/2); - } - return rect; - } - - override QSize sizeFromContents(ContentsType type, QStyleOption option, - QSize size, QWidget widget) - { - QSize newSize = QWindowsStyle.sizeFromContents(type, option, size, widget); - - switch (type) { - case CT_RadioButton: - newSize += QSize(20, 0); - break; - - case CT_PushButton: - newSize.setHeight(26); - break; - - case CT_Slider: - newSize.setHeight(27); - break; - - default: - break; - } - - return newSize; - } - - override int pixelMetric(PixelMetric pm, QStyleOption opt, QWidget widget) - { - if (pm == PM_SliderLength) - return 13; - return QWindowsStyle.pixelMetric(pm, opt, widget); - } - - override void polish(QWidget widget) - { - if (widget.layout() && cast(QGroupBox)(widget)) { - if (widget.findChildren!(QGroupBox).length == 0) { - widget.layout().setWidgetSpacing(0); // Why setSpacing was renamed to setWidgetSpacing? - widget.layout().setMargin(12); - } else { - widget.layout().setMargin(13); - } - } - - if (cast(QPushButton)(widget) - || cast(QRadioButton)(widget) - || cast(QSlider)(widget)) { - widget.setAttribute(Qt.WA_Hover); - } - - QPalette pal = widget.palette(); - if (widget.isWindow()) { - pal.setColor(QPalette.Window, new QColor(241, 241, 241)); - widget.setPalette(pal); - } - } - - override void unpolish(QWidget widget) - { - if (cast(QPushButton)(widget) - || cast(QRadioButton)(widget) - || cast(QSlider)(widget)) { - widget.setAttribute(Qt.WA_Hover, false); - } - } - - override void polish(QPalette palette) - { - palette.setColor(QPalette.Window, new QColor(241, 241, 241)); - } - - override QRect subElementRect(SubElement element, QStyleOption option, QWidget widget) - { - QRect r; - switch(element) { - case SE_RadioButtonClickRect: - r = widget.rect(); - break; - case SE_RadioButtonContents: - r = widget.rect().adjusted(20, 0, 0, 0); - break; - default: - r = QWindowsStyle.subElementRect(element, option, widget); - break; - } - - if (cast(QRadioButton)(widget)) - r = r.adjusted(5, 0, -5, 0); - - return r; - } -} +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ +module arthurstyle; + + +import + qt.gui.QLayout, + qt.gui.QWindowsStyle, + qt.gui.QPainter, + qt.gui.QPainterPath, + qt.gui.QPixmapCache, + qt.gui.QRadioButton, + qt.gui.QPushButton, + qt.gui.QGroupBox, + qt.gui.QLinearGradient, + qt.gui.QStyleOption, + qt.gui.QStyleOptionFrameV2; + + +class ArthurStyle : QWindowsStyle +{ + QPixmap cached(string img) + { + QPixmap pm = new QPixmap; + if (QPixmapCache.find(img, pm)) + return pm; + + pm = QPixmap.fromImage(new QImage(img), Qt.OrderedDither | Qt.OrderedAlphaDither); + if (pm.isNull) + return new QPixmap; + + QPixmapCache.insert(img, pm); + return pm; + } + + this() + { + //Q_INIT_RESOURCE(shared); + } + + void drawHoverRect(QPainter painter, QRect r) + { + qreal h = r.height(); + qreal h2 = r.height() / 2.0; + QPainterPath path = new QPainterPath; + path.addRect(r.x() + h2, r.y() + 0, r.width() - h2 * 2, r.height()); + path.addEllipse(r.x(), r.y(), h, h); + path.addEllipse(r.x() + r.width() - h, r.y(), h, h); + path.setFillRule(Qt.WindingFill); + painter.setPen(Qt.NoPen); + painter.setBrush(new QColor(191, 215, 191)); + painter.setRenderHint(QPainter.Antialiasing); + painter.drawPath(path); + } + + override void drawPrimitive(PrimitiveElement element, QStyleOption option, QPainter painter, QWidget widget) + { + assert(option); + switch (element) + { + case PE_FrameFocusRect: + break; + + case PE_IndicatorRadioButton: + if (QStyleOptionButton button = cast(QStyleOptionButton)(option)) { + bool hover = (button.state & State_Enabled) && (button.state & State_MouseOver); + painter.save; + QPixmap radio; + if (hover) + drawHoverRect(painter, widget.rect); + + if (button.state & State_Sunken) + radio = cached(":res/images/radiobutton-on.png"); + else if (button.state & State_On) + radio = cached(":res/images/radiobutton_on.png"); + else + radio = cached(":res/images/radiobutton_off.png"); + painter.drawPixmap(button.rect.topLeft, radio); + + painter.restore(); + } + break; + + case PE_PanelButtonCommand: + if (QStyleOptionButton button = cast(QStyleOptionButton)(option)) { + bool hover = (button.state & State_Enabled) && (button.state & State_MouseOver); + + painter.save(); + QPushButton pushButton = cast(QPushButton)(widget); + assert(pushButton); + auto parent = pushButton.parentWidget; + if (parent && cast(QGroupBox)(parent)) { + auto lg = new QLinearGradient(0, 0, 0, parent.height); + lg.setColorAt(0, new QColor(224,224,224)); + lg.setColorAt(1, new QColor(255,255,255)); + painter.setPen(Qt.NoPen); + painter.setBrush(lg); + painter.setBrushOrigin(QPoint() - widget.mapToParent(QPoint(0,0))); + painter.drawRect(button.rect); + painter.setBrushOrigin(0, 0); + } + + bool down = (button.state & State_Sunken) || (button.state & State_On); + + QPixmap left, right, mid; + if (down) { + left = cached(":res/images/button_pressed_cap_left.png"); + right = cached(":res/images/button_pressed_cap_right.png"); + mid = cached(":res/images/button_pressed_stretch.png"); + } else { + left = cached(":res/images/button_normal_cap_left.png"); + right = cached(":res/images/button_normal_cap_right.png"); + mid = cached(":res/images/button_normal_stretch.png"); + } + painter.drawPixmap(button.rect.topLeft, left); + painter.drawTiledPixmap(QRect(button.rect.x + left.width, + button.rect.y, + button.rect.width - left.width - right.width, + left.height), + mid); + painter.drawPixmap(button.rect.x + button.rect.width - right.width, + button.rect.y, + right); + if (hover) + painter.fillRect(widget.rect.adjusted(3,5,-3,-5), new QColor(31,127,31,63)); + painter.restore; + } + break; + + case PE_FrameGroupBox: + if (QStyleOptionFrameV2 group = cast(QStyleOptionFrameV2)(option)) { + auto r = group.rect; + + painter.save(); + int radius = 14; + int radius2 = radius*2; + QPainterPath clipPath; + clipPath.moveTo(radius, 0); + clipPath.arcTo(r.right() - radius2, 0, radius2, radius2, 90, -90); + clipPath.arcTo(r.right() - radius2, r.bottom() - radius2, radius2, radius2, 0, -90); + clipPath.arcTo(r.left(), r.bottom() - radius2, radius2, radius2, 270, -90); + clipPath.arcTo(r.left(), r.top(), radius2, radius2, 180, -90); + painter.setClipPath(clipPath); + QPixmap titleStretch = cached(":res/images/title_stretch.png"); + QPixmap topLeft = cached(":res/images/groupframe_topleft.png"); + QPixmap topRight = cached(":res/images/groupframe_topright.png"); + QPixmap bottomLeft = cached(":res/images/groupframe_bottom_left.png"); + QPixmap bottomRight = cached(":res/images/groupframe_bottom_right.png"); + QPixmap leftStretch = cached(":res/images/groupframe_left_stretch.png"); + QPixmap topStretch = cached(":res/images/groupframe_top_stretch.png"); + QPixmap rightStretch = cached(":res/images/groupframe_right_stretch.png"); + QPixmap bottomStretch = cached(":res/images/groupframe_bottom_stretch.png"); + auto lg = new QLinearGradient(0, 0, 0, r.height()); + lg.setColorAt(0, new QColor(224,224,224)); + lg.setColorAt(1, new QColor(255,255,255)); + painter.setPen(Qt.NoPen); + painter.setBrush(lg); + painter.drawRect(r.adjusted(0, titleStretch.height()/2, 0, 0)); + painter.setClipping(false); + + int topFrameOffset = titleStretch.height()/2 - 2; + painter.drawPixmap(r.topLeft() + QPoint(0, topFrameOffset), topLeft); + painter.drawPixmap(r.topRight() - QPoint(topRight.width()-1, 0) + QPoint(0, topFrameOffset), topRight); + painter.drawPixmap(r.bottomLeft() - QPoint(0, bottomLeft.height()-1), bottomLeft); + painter.drawPixmap(r.bottomRight() - QPoint(bottomRight.width()-1, bottomRight.height()-1), bottomRight); + + QRect left = r; + left.setY(r.y() + topLeft.height() + topFrameOffset); + left.setWidth(leftStretch.width()); + left.setHeight(r.height() - topLeft.height() - bottomLeft.height() - topFrameOffset); + painter.drawTiledPixmap(left, leftStretch); + + QRect top = r; + top.setX(r.x() + topLeft.width()); + top.setY(r.y() + topFrameOffset); + top.setWidth(r.width() - topLeft.width() - topRight.width()); + top.setHeight(topLeft.height()); + painter.drawTiledPixmap(top, topStretch); + + QRect right = r; + right.setX(r.right() - rightStretch.width()+1); + right.setY(r.y() + topRight.height() + topFrameOffset); + right.setWidth(rightStretch.width()); + right.setHeight(r.height() - topRight.height() - bottomRight.height() - topFrameOffset); + painter.drawTiledPixmap(right, rightStretch); + + QRect bottom = r; + bottom.setX(r.x() + bottomLeft.width()); + bottom.setY(r.bottom() - bottomStretch.height()+1); + bottom.setWidth(r.width() - bottomLeft.width() - bottomRight.width()); + bottom.setHeight(bottomLeft.height()); + painter.drawTiledPixmap(bottom, bottomStretch); + painter.restore(); + } + break; + + default: + QWindowsStyle.drawPrimitive(element, option, painter, widget); + break; + } + return; + } + + override void drawComplexControl(ComplexControl control, QStyleOptionComplex option, + QPainter painter, QWidget widget) + { + switch (control) { + case CC_Slider: + if (QStyleOptionSlider slider = cast(QStyleOptionSlider)(option)) { + QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget); + QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget); + + painter.save; + + bool hover = (slider.state & State_Enabled) && (slider.state & State_MouseOver); + if (hover) { + QRect moderated = widget.rect().adjusted(0, 4, 0, -4); + drawHoverRect(painter, moderated); + } + + if ((option.subControls & SC_SliderGroove) && groove.isValid()) { + QPixmap grv = cached(":res/images/slider_bar.png"); + painter.drawPixmap(QRect(groove.x() + 5, groove.y(), + groove.width() - 10, grv.height()), + grv); + } + if ((option.subControls & SC_SliderHandle) && handle.isValid()) { + QPixmap hndl = cached(":res/images/slider_thumb_on.png"); + painter.drawPixmap(handle.topLeft(), hndl); + } + + painter.restore(); + } + break; + case CC_GroupBox: + if (QStyleOptionGroupBox groupBox + = cast(QStyleOptionGroupBox)(option)) { + auto groupBoxCopy = new QStyleOptionGroupBox(groupBox); + groupBoxCopy.setSubControls = groupBoxCopy.subControls & ~SC_GroupBoxLabel; + QWindowsStyle.drawComplexControl(control, groupBoxCopy, painter, widget); + + if (groupBox.subControls & SC_GroupBoxLabel) { + QRect r = groupBox.rect; + QPixmap titleLeft = cached(":res/images/title_cap_left.png"); + QPixmap titleRight = cached(":res/images/title_cap_right.png"); + QPixmap titleStretch = cached(":res/images/title_stretch.png"); + int txt_width = groupBox.fontMetrics.width(groupBox.text) + 20; + painter.drawPixmap(r.center().x() - txt_width/2, 0, titleLeft); + QRect tileRect = subControlRect(control, groupBox, SC_GroupBoxLabel, widget); + painter.drawTiledPixmap(tileRect, titleStretch); + painter.drawPixmap(tileRect.x() + tileRect.width(), 0, titleRight); + int opacity = 31; + painter.setPen(new QColor(0, 0, 0, opacity)); + painter.drawText(tileRect.translated(0, 1), + cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null); + painter.drawText(tileRect.translated(2, 1), + cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null); + painter.setPen(new QColor(0, 0, 0, opacity * 2)); + painter.drawText(tileRect.translated(1, 1), + cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null); + painter.setPen(new QColor(Qt.white)); + painter.drawText(tileRect, cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null); + } + } + break; + default: + QWindowsStyle.drawComplexControl(control, option, painter, widget); + break; + } + return; + } + + override QRect subControlRect(QStyle_ComplexControl control, QStyleOptionComplex option, + int sc, QWidget widget = null) + { + QRect rect; + + auto subControl = cast(SubControl)sc; + + switch (control) { + default: + rect = QWindowsStyle.subControlRect(control, option, subControl, widget); + break; + case CC_GroupBox: + if (QStyleOptionGroupBox group + = cast(QStyleOptionGroupBox)(option)) { + switch (subControl) { + default: + rect = QWindowsStyle.subControlRect(control, option, subControl, widget); + break; + case SC_GroupBoxContents: + rect = QWindowsStyle.subControlRect(control, option, subControl, widget); + rect.adjust(0, -8, 0, 0); + break; + case SC_GroupBoxFrame: + rect = group.rect; + break; + case SC_GroupBoxLabel: + QPixmap titleLeft = cached(":res/images/title_cap_left.png"); + QPixmap titleRight = cached(":res/images/title_cap_right.png"); + QPixmap titleStretch = cached(":res/images/title_stretch.png"); + int txt_width = group.fontMetrics.width(group.text) + 20; + rect = QRect(group.rect.center().x() - txt_width/2 + titleLeft.width(), 0, + txt_width - titleLeft.width() - titleRight.width(), + titleStretch.height()); + break; + } + } + break; + } + + if (control == CC_Slider && subControl == SC_SliderHandle) { + rect.setWidth(13); + rect.setHeight(27); + } else if (control == CC_Slider && subControl == SC_SliderGroove) { + rect.setHeight(9); + rect.moveTop(27/2 - 9/2); + } + return rect; + } + + override QSize sizeFromContents(ContentsType type, QStyleOption option, + QSize size, QWidget widget) + { + QSize newSize = QWindowsStyle.sizeFromContents(type, option, size, widget); + + switch (type) { + case CT_RadioButton: + newSize += QSize(20, 0); + break; + + case CT_PushButton: + newSize.setHeight(26); + break; + + case CT_Slider: + newSize.setHeight(27); + break; + + default: + break; + } + + return newSize; + } + + override int pixelMetric(PixelMetric pm, QStyleOption opt, QWidget widget) + { + if (pm == PM_SliderLength) + return 13; + return QWindowsStyle.pixelMetric(pm, opt, widget); + } + + override void polish(QWidget widget) + { + if (widget.layout() && cast(QGroupBox)(widget)) { + if (widget.findChildren!(QGroupBox).length == 0) { + widget.layout().setWidgetSpacing(0); // Why setSpacing was renamed to setWidgetSpacing? + widget.layout().setMargin(12); + } else { + widget.layout().setMargin(13); + } + } + + if (cast(QPushButton)(widget) + || cast(QRadioButton)(widget) + || cast(QSlider)(widget)) { + widget.setAttribute(Qt.WA_Hover); + } + + QPalette pal = widget.palette(); + if (widget.isWindow()) { + pal.setColor(QPalette.Window, new QColor(241, 241, 241)); + widget.setPalette(pal); + } + } + + override void unpolish(QWidget widget) + { + if (cast(QPushButton)(widget) + || cast(QRadioButton)(widget) + || cast(QSlider)(widget)) { + widget.setAttribute(Qt.WA_Hover, false); + } + } + + override void polish(QPalette palette) + { + palette.setColor(QPalette.Window, new QColor(241, 241, 241)); + } + + override QRect subElementRect(SubElement element, QStyleOption option, QWidget widget) + { + QRect r; + switch(element) { + case SE_RadioButtonClickRect: + r = widget.rect(); + break; + case SE_RadioButtonContents: + r = widget.rect().adjusted(20, 0, 0, 0); + break; + default: + r = QWindowsStyle.subElementRect(element, option, widget); + break; + } + + if (cast(QRadioButton)(widget)) + r = r.adjusted(5, 0, -5, 0); + + return r; + } +}
--- a/demos/shared/arthurwidgets.d Tue Sep 22 15:22:37 2009 +0000 +++ b/demos/shared/arthurwidgets.d Wed Dec 23 16:10:46 2009 +0200 @@ -1,414 +1,414 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** 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, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ -module arthurwidgets; - - -import qt.core.QFile, - qt.gui.QApplication, - qt.gui.QPainter, - qt.gui.QPainterPath, - qt.gui.QPixmapCache, - qt.gui.QTextDocument, - qt.gui.QAbstractTextDocumentLayout, - qt.gui.QLinearGradient, - qt.gui.QTextBrowser, - qt.gui.QBoxLayout, - qt.opengl.QGL, - qt.Signal, - tango.text.Util; - -import tango.text.Regex : Regex; - -//#include <private/qpixmapdata_p.h> - -//extern QPixmap cached(const QString &img); - -version (QT_OPENGL_SUPPORT) -{ - import qt.opengl.QGLWidget; - class GLWidget : QGLWidget - { - this(QWidget parent) - { - super(new QGLFormat(QGL.SampleBuffers), parent); - } - - void disableAutoBufferSwap() { setAutoBufferSwap(false); } - override void paintEvent(QPaintEvent) { parentWidget().update(); } - } -} - -class ArthurFrame : QWidget -{ -protected: - - version(QT_OPENGL_SUPPORT) - { - GLWidget glw; - bool m_use_opengl; - } - - QPixmap m_tile; - - bool m_show_doc; - bool m_prefer_image; - QTextDocument m_document; - - string m_sourceFileName; - -public: - mixin Signal!("descriptionEnabledChanged", bool); - - bool preferImage() { return m_prefer_image; } - - void paint(QPainter) {} - - this(QWidget parent) - { - super(parent); - - version (QT_OPENGL_SUPPORT) - { - QGLFormat f = QGLFormat.defaultFormat(); - f.setSampleBuffers(true); - f.setStencil(true); - f.setAlpha(true); - f.setAlphaBufferSize(8); - QGLFormat.setDefaultFormat(f); - } - - m_tile = new QPixmap(128, 128); - m_tile.fill(new QColor(Qt.white)); - scope pt = new QPainter(m_tile); - auto color = new QColor(230, 230, 230); - pt.fillRect(0, 0, 64, 64, color); - pt.fillRect(64, 64, 64, 64, color); - pt.end(); - - // QPalette pal = palette(); - // pal.setBrush(backgroundRole(), m_tile); - // setPalette(pal); - - version (Q_WS_X11) - { - auto xRenderPixmap = new QPixmap(1, 1); - m_prefer_image = xRenderPixmap.pixmapData().classId() == QPixmapData.X11Class && !xRenderPixmap.x11PictureHandle(); - } - } - - version (QT_OPENGL_SUPPORT) - { - void enableOpenGL(bool use_opengl) - { - m_use_opengl = use_opengl; - - if (!glw) { - glw = new GLWidget(this); - glw.setAutoFillBackground(false); - glw.disableAutoBufferSwap(); - QApplication.postEvent(this, new QResizeEvent(size(), size())); - } - - if (use_opengl) { - glw.show(); - } else { - glw.hide(); - } - - update(); - } - - bool usesOpenGL() { return m_use_opengl; } - QGLWidget glWidget(){ return glw; } - } - - override void paintEvent(QPaintEvent e) - { - version (Q_WS_QWS) - static QPixmap static_image; - else - static QImage static_image; - - auto painter = new QPainter; - - version (QT_OPENGL_SUPPORT) - auto prefImage = preferImage && !m_use_opengl; - else - auto prefImage = preferImage; - - if (prefImage) { - if (!static_image || static_image.size() != size()) { - delete static_image; - version (Q_WS_QWS) - static_image = new QPixmap(size()); - else - static_image = new QImage(size(), QImage.Format_RGB32); - } - painter.begin(static_image); - - int o = 10; - - QBrush bg = palette().brush(QPalette.Window); - painter.fillRect(0, 0, o, o, bg); - painter.fillRect(width() - o, 0, o, o, bg); - painter.fillRect(0, height() - o, o, o, bg); - painter.fillRect(width() - o, height() - o, o, o, bg); - } else { - version (QT_OPENGL_SUPPORT) - { - if (m_use_opengl) { - painter.begin(glw); - painter.fillRect(new QRectF(0, 0, glw.width(), glw.height()), palette().color(backgroundRole())); - } else { - painter.begin(this); - } - } - else - painter.begin(this); - } - - painter.setClipRect(e.rect()); - - painter.setRenderHint(QPainter.Antialiasing); - - auto clipPath = new QPainterPath; - - QRect r = rect(); - qreal left = r.x() + 1; - qreal top = r.y() + 1; - qreal right = r.right(); - qreal bottom = r.bottom(); - qreal radius2 = 8 * 2; - - clipPath.moveTo(right - radius2, top); - clipPath.arcTo(right - radius2, top, radius2, radius2, 90, -90); - clipPath.arcTo(right - radius2, bottom - radius2, radius2, radius2, 0, -90); - clipPath.arcTo(left, bottom - radius2, radius2, radius2, 270, -90); - clipPath.arcTo(left, top, radius2, radius2, 180, -90); - clipPath.closeSubpath(); - - painter.save(); - painter.setClipPath(clipPath, Qt.IntersectClip); - - painter.drawTiledPixmap(rect(), m_tile); - - // client painting - - paint(painter); - painter.restore(); - - painter.save(); - if (m_show_doc) - paintDescription(painter); - painter.restore(); - - int level = 180; - painter.setPen(new QPen(new QBrush(new QColor(level, level, level)), 2)); - painter.setBrush(Qt.NoBrush); - painter.drawPath(clipPath); - - if (prefImage) { - painter.end(); - painter.begin(this); - version (Q_WS_QWS) - painter.drawPixmap(e.rect(), static_image, e.rect()); - else - painter.drawImage(e.rect(), static_image, e.rect()); - } - - // TODO: this sucks - version (QT_OPENGL_SUPPORT) { - if (m_use_opengl && (inherits("PathDeformRenderer") || inherits("PathStrokeRenderer") || inherits("CompositionRenderer") || m_show_doc)) - glw.swapBuffers(); - } - } - - void resizeEvent(QResizeEvent e) - { - version (QT_OPENGL_SUPPORT) - { - if (glw) - glw.setGeometry(0, 0, e.size().width()-1, e.size().height()-1); - } - super.resizeEvent(e); - } - - void setDescriptionEnabled(bool enabled) - { - if (m_show_doc != enabled) { - m_show_doc = enabled; - descriptionEnabledChanged.emit(m_show_doc); - update(); - } - } - - void loadDescription(string fileName) - { - auto textFile = new QFile(fileName); - string text; - if (!textFile.open(QFile.ReadOnly)) - text = "Unable to load resource file: " ~ fileName; - else - text = textFile.readAll().toString; // TODO: excessive copying - setDescription(text); - } - - void setDescription(string text) - { - m_document = new QTextDocument(this); - m_document.setHtml(text); - } - - void paintDescription(QPainter painter) - { - if (!m_document) - return; - - int pageWidth = qMax(width() - 100, 100); - int pageHeight = qMax(height() - 100, 100); - if (pageWidth != m_document.pageSize().width()) { - m_document.setPageSize(QSizeF(pageWidth, pageHeight)); - } - - auto textRect = new QRect(width() / 2 - pageWidth / 2, - height() / 2 - pageHeight / 2, - pageWidth, - pageHeight); - int pad = 10; - QRect clearRect = textRect.adjusted(-pad, -pad, pad, pad); - painter.setPen(Qt.NoPen); - painter.setBrush(new QColor(0, 0, 0, 63)); - int shade = 10; - painter.drawRect(clearRect.x() + clearRect.width() + 1, - clearRect.y() + shade, - shade, - clearRect.height() + 1); - painter.drawRect(clearRect.x() + shade, - clearRect.y() + clearRect.height() + 1, - clearRect.width() - shade + 1, - shade); - - painter.setRenderHint(QPainter.Antialiasing, false); - painter.setBrush(new QColor(255, 255, 255, 220)); - painter.setPen(new QColor(Qt.black)); - painter.drawRect(clearRect); - - painter.setClipRect(textRect, Qt.IntersectClip); - painter.translate(textRect.topLeft()); - - auto ctx = new QAbstractTextDocumentLayout_PaintContext; - - auto g = new QLinearGradient(0, 0, 0, textRect.height()); - g.setColorAt(0, new QColor(Qt.black)); - g.setColorAt(0.9, new QColor(Qt.black)); - g.setColorAt(1, new QColor(Qt.transparent)); - - QPalette pal = palette(); - pal.setBrush(QPalette.Text, new QBrush(g)); - - ctx.setPalette(pal); - ctx.setClip(new QRectF(0, 0, textRect.width(), textRect.height())); - m_document.documentLayout().draw(painter, ctx); - } - - void loadSourceFile(string sourceName) - { - m_sourceFileName = sourceName; - } - - void showSource() - { - // Check for existing source - if (findChild!(QTextBrowser)) - return; - - string contents; - if (!m_sourceFileName.length) { - contents = "No source for widget: " ~ objectName(); - } else { - auto f = new QFile(m_sourceFileName); - if (!f.open(QFile.ReadOnly)) - contents = "Could not open file: " ~ m_sourceFileName; - else - contents = f.readAll.toString; - } - - contents = contents.substitute("&", "&"); - contents = contents.substitute("<", "<"); - contents = contents.substitute(">", ">"); - - static const string[] keywords = - ["for ", "if ", "switch ", " int ", "#include ", "const" - , "void ", "uint ", "case ", "double ", "#define ", "static" - , "new", "this"]; - - foreach (keyword; keywords) - contents = contents.substitute(keyword, "<font color=olive>" ~ keyword ~ "</font>"); - contents = contents.substitute("(int ", "(<font color=olive><b>int </b></font>"); - - static const string[] ppKeywords = - ["#ifdef", "#ifndef", "#if", "#endif", "#else"]; - - foreach (keyword; ppKeywords) - contents = contents.substitute(keyword, "<font color=navy>" ~ keyword ~ "</font>"); - - auto ddRe = new Regex("(\\d\\d?)"); - contents = ddRe.replaceAll(contents, "<font color=navy>\\1</font>"); - - auto commentRe = new Regex("(//.+?)\\n"); - contents = commentRe.replaceAll(contents, "<font color=red>\\1</font>\n"); - - auto stringLiteralRe = new Regex("(\".+?\")"); - contents = stringLiteralRe.replaceAll(contents, "<font color=green>\\1</font>"); - - auto html = contents.dup; - html = "<html><pre>" ~ html ~ "</pre></html>"; - - QTextBrowser sourceViewer = new QTextBrowser(null); - sourceViewer.setWindowTitle("Source: " ~ m_sourceFileName[5..$]); - sourceViewer.setParent(this, Qt.Dialog); - sourceViewer.setAttribute(Qt.WA_DeleteOnClose); - sourceViewer.setLineWrapMode(QTextEdit.NoWrap); - sourceViewer.setHtml(html); - sourceViewer.resize(600, 600); - sourceViewer.show(); - } -} +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ +module arthurwidgets; + + +import qt.core.QFile, + qt.gui.QApplication, + qt.gui.QPainter, + qt.gui.QPainterPath, + qt.gui.QPixmapCache, + qt.gui.QTextDocument, + qt.gui.QAbstractTextDocumentLayout, + qt.gui.QLinearGradient, + qt.gui.QTextBrowser, + qt.gui.QBoxLayout, + qt.opengl.QGL, + qt.Signal, + tango.text.Util; + +import tango.text.Regex : Regex; + +//#include <private/qpixmapdata_p.h> + +//extern QPixmap cached(const QString &img); + +version (QT_OPENGL_SUPPORT) +{ + import qt.opengl.QGLWidget; + class GLWidget : QGLWidget + { + this(QWidget parent) + { + super(new QGLFormat(QGL.SampleBuffers), parent); + } + + void disableAutoBufferSwap() { setAutoBufferSwap(false); } + override void paintEvent(QPaintEvent) { parentWidget().update(); } + } +} + +class ArthurFrame : QWidget +{ +protected: + + version(QT_OPENGL_SUPPORT) + { + GLWidget glw; + bool m_use_opengl; + } + + QPixmap m_tile; + + bool m_show_doc; + bool m_prefer_image; + QTextDocument m_document; + + string m_sourceFileName; + +public: + mixin Signal!("descriptionEnabledChanged", bool); + + bool preferImage() { return m_prefer_image; } + + void paint(QPainter) {} + + this(QWidget parent) + { + super(parent); + + version (QT_OPENGL_SUPPORT) + { + QGLFormat f = QGLFormat.defaultFormat(); + f.setSampleBuffers(true); + f.setStencil(true); + f.setAlpha(true); + f.setAlphaBufferSize(8); + QGLFormat.setDefaultFormat(f); + } + + m_tile = new QPixmap(128, 128); + m_tile.fill(new QColor(Qt.white)); + scope pt = new QPainter(m_tile); + auto color = new QColor(230, 230, 230); + pt.fillRect(0, 0, 64, 64, color); + pt.fillRect(64, 64, 64, 64, color); + pt.end(); + + // QPalette pal = palette(); + // pal.setBrush(backgroundRole(), m_tile); + // setPalette(pal); + + version (Q_WS_X11) + { + auto xRenderPixmap = new QPixmap(1, 1); + m_prefer_image = xRenderPixmap.pixmapData().classId() == QPixmapData.X11Class && !xRenderPixmap.x11PictureHandle(); + } + } + + version (QT_OPENGL_SUPPORT) + { + void enableOpenGL(bool use_opengl) + { + m_use_opengl = use_opengl; + + if (!glw) { + glw = new GLWidget(this); + glw.setAutoFillBackground(false); + glw.disableAutoBufferSwap(); + QApplication.postEvent(this, new QResizeEvent(size(), size())); + } + + if (use_opengl) { + glw.show(); + } else { + glw.hide(); + } + + update(); + } + + bool usesOpenGL() { return m_use_opengl; } + QGLWidget glWidget(){ return glw; } + } + + override void paintEvent(QPaintEvent e) + { + version (Q_WS_QWS) + static QPixmap static_image; + else + static QImage static_image; + + auto painter = new QPainter; + + version (QT_OPENGL_SUPPORT) + auto prefImage = preferImage && !m_use_opengl; + else + auto prefImage = preferImage; + + if (prefImage) { + if (!static_image || static_image.size() != size()) { + delete static_image; + version (Q_WS_QWS) + static_image = new QPixmap(size()); + else + static_image = new QImage(size(), QImage.Format_RGB32); + } + painter.begin(static_image); + + int o = 10; + + QBrush bg = palette().brush(QPalette.Window); + painter.fillRect(0, 0, o, o, bg); + painter.fillRect(width() - o, 0, o, o, bg); + painter.fillRect(0, height() - o, o, o, bg); + painter.fillRect(width() - o, height() - o, o, o, bg); + } else { + version (QT_OPENGL_SUPPORT) + { + if (m_use_opengl) { + painter.begin(glw); + painter.fillRect(new QRectF(0, 0, glw.width(), glw.height()), palette().color(backgroundRole())); + } else { + painter.begin(this); + } + } + else + painter.begin(this); + } + + painter.setClipRect(e.rect()); + + painter.setRenderHint(QPainter.Antialiasing); + + auto clipPath = new QPainterPath; + + QRect r = rect(); + qreal left = r.x() + 1; + qreal top = r.y() + 1; + qreal right = r.right(); + qreal bottom = r.bottom(); + qreal radius2 = 8 * 2; + + clipPath.moveTo(right - radius2, top); + clipPath.arcTo(right - radius2, top, radius2, radius2, 90, -90); + clipPath.arcTo(right - radius2, bottom - radius2, radius2, radius2, 0, -90); + clipPath.arcTo(left, bottom - radius2, radius2, radius2, 270, -90); + clipPath.arcTo(left, top, radius2, radius2, 180, -90); + clipPath.closeSubpath(); + + painter.save(); + painter.setClipPath(clipPath, Qt.IntersectClip); + + painter.drawTiledPixmap(rect(), m_tile); + + // client painting + + paint(painter); + painter.restore(); + + painter.save(); + if (m_show_doc) + paintDescription(painter); + painter.restore(); + + int level = 180; + painter.setPen(new QPen(new QBrush(new QColor(level, level, level)), 2)); + painter.setBrush(Qt.NoBrush); + painter.drawPath(clipPath); + + if (prefImage) { + painter.end(); + painter.begin(this); + version (Q_WS_QWS) + painter.drawPixmap(e.rect(), static_image, e.rect()); + else + painter.drawImage(e.rect(), static_image, e.rect()); + } + + // TODO: this sucks + version (QT_OPENGL_SUPPORT) { + if (m_use_opengl && (inherits("PathDeformRenderer") || inherits("PathStrokeRenderer") || inherits("CompositionRenderer") || m_show_doc)) + glw.swapBuffers(); + } + } + + void resizeEvent(QResizeEvent e) + { + version (QT_OPENGL_SUPPORT) + { + if (glw) + glw.setGeometry(0, 0, e.size().width()-1, e.size().height()-1); + } + super.resizeEvent(e); + } + + void setDescriptionEnabled(bool enabled) + { + if (m_show_doc != enabled) { + m_show_doc = enabled; + descriptionEnabledChanged.emit(m_show_doc); + update(); + } + } + + void loadDescription(string fileName) + { + auto textFile = new QFile(fileName); + string text; + if (!textFile.open(QFile.ReadOnly)) + text = "Unable to load resource file: " ~ fileName; + else + text = textFile.readAll().toString; // TODO: excessive copying + setDescription(text); + } + + void setDescription(string text) + { + m_document = new QTextDocument(this); + m_document.setHtml(text); + } + + void paintDescription(QPainter painter) + { + if (!m_document) + return; + + int pageWidth = qMax(width() - 100, 100); + int pageHeight = qMax(height() - 100, 100); + if (pageWidth != m_document.pageSize().width()) { + m_document.setPageSize(QSizeF(pageWidth, pageHeight)); + } + + auto textRect = new QRect(width() / 2 - pageWidth / 2, + height() / 2 - pageHeight / 2, + pageWidth, + pageHeight); + int pad = 10; + QRect clearRect = textRect.adjusted(-pad, -pad, pad, pad); + painter.setPen(Qt.NoPen); + painter.setBrush(new QColor(0, 0, 0, 63)); + int shade = 10; + painter.drawRect(clearRect.x() + clearRect.width() + 1, + clearRect.y() + shade, + shade, + clearRect.height() + 1); + painter.drawRect(clearRect.x() + shade, + clearRect.y() + clearRect.height() + 1, + clearRect.width() - shade + 1, + shade); + + painter.setRenderHint(QPainter.Antialiasing, false); + painter.setBrush(new QColor(255, 255, 255, 220)); + painter.setPen(new QColor(Qt.black)); + painter.drawRect(clearRect); + + painter.setClipRect(textRect, Qt.IntersectClip); + painter.translate(textRect.topLeft()); + + auto ctx = new QAbstractTextDocumentLayout_PaintContext; + + auto g = new QLinearGradient(0, 0, 0, textRect.height()); + g.setColorAt(0, new QColor(Qt.black)); + g.setColorAt(0.9, new QColor(Qt.black)); + g.setColorAt(1, new QColor(Qt.transparent)); + + QPalette pal = palette(); + pal.setBrush(QPalette.Text, new QBrush(g)); + + ctx.setPalette(pal); + ctx.setClip(new QRectF(0, 0, textRect.width(), textRect.height())); + m_document.documentLayout().draw(painter, ctx); + } + + void loadSourceFile(string sourceName) + { + m_sourceFileName = sourceName; + } + + void showSource() + { + // Check for existing source + if (findChild!(QTextBrowser)) + return; + + string contents; + if (!m_sourceFileName.length) { + contents = "No source for widget: " ~ objectName(); + } else { + auto f = new QFile(m_sourceFileName); + if (!f.open(QFile.ReadOnly)) + contents = "Could not open file: " ~ m_sourceFileName; + else + contents = f.readAll.toString; + } + + contents = contents.substitute("&", "&"); + contents = contents.substitute("<", "<"); + contents = contents.substitute(">", ">"); + + static const string[] keywords = + ["for ", "if ", "switch ", " int ", "#include ", "const" + , "void ", "uint ", "case ", "double ", "#define ", "static" + , "new", "this"]; + + foreach (keyword; keywords) + contents = contents.substitute(keyword, "<font color=olive>" ~ keyword ~ "</font>"); + contents = contents.substitute("(int ", "(<font color=olive><b>int </b></font>"); + + static const string[] ppKeywords = + ["#ifdef", "#ifndef", "#if", "#endif", "#else"]; + + foreach (keyword; ppKeywords) + contents = contents.substitute(keyword, "<font color=navy>" ~ keyword ~ "</font>"); + + auto ddRe = new Regex("(\\d\\d?)"); + contents = ddRe.replaceAll(contents, "<font color=navy>\\1</font>"); + + auto commentRe = new Regex("(//.+?)\\n"); + contents = commentRe.replaceAll(contents, "<font color=red>\\1</font>\n"); + + auto stringLiteralRe = new Regex("(\".+?\")"); + contents = stringLiteralRe.replaceAll(contents, "<font color=green>\\1</font>"); + + auto html = contents.dup; + html = "<html><pre>" ~ html ~ "</pre></html>"; + + QTextBrowser sourceViewer = new QTextBrowser(null); + sourceViewer.setWindowTitle("Source: " ~ m_sourceFileName[5..$]); + sourceViewer.setParent(this, Qt.Dialog); + sourceViewer.setAttribute(Qt.WA_DeleteOnClose); + sourceViewer.setLineWrapMode(QTextEdit.NoWrap); + sourceViewer.setHtml(html); + sourceViewer.resize(600, 600); + sourceViewer.show(); + } +}
--- a/demos/shared/hoverpoints.d Tue Sep 22 15:22:37 2009 +0000 +++ b/demos/shared/hoverpoints.d Wed Dec 23 16:10:46 2009 +0200 @@ -1,440 +1,440 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** 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, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ -module hoverpoints; - -version (QT_OPENGL_SUPPORT) - import qt.opengl.QGLWidget; - -version (D_Version2) {} -else - import tango.core.Array : sort; - -import - qt.gui.QWidget, - qt.qtd.Array, - arthurwidgets; - -final class HoverPoints : QObject -{ -public: - enum PointShape { - CircleShape, - RectangleShape - } - - enum LockType { - LockToLeft = 0x01, - LockToRight = 0x02, - LockToTop = 0x04, - LockToBottom = 0x08 - } - - enum SortType { - NoSort, - XSort, - YSort - } - - enum ConnectionType { - NoConnection, - LineConnection, - CurveConnection - } - -private: - QWidget m_widget; - - QPolygonF m_points; - QRectF m_bounds; - PointShape m_shape; - SortType m_sortType; - ConnectionType m_connectionType; - - uint[] m_locks; - - QSizeF m_pointSize; - int m_currentIndex; - bool m_editable; - bool m_enabled; - - QPen m_pointPen; - QBrush m_pointBrush; - QPen m_connectionPen; - -public: - mixin Signal!("pointsChanged", QPolygonF /*points*/); - - this(QWidget widget, PointShape shape) - { - super(widget); - - m_widget = widget; - widget.installEventFilter(this); - - m_connectionType = ConnectionType.CurveConnection; - m_sortType = SortType.NoSort; - m_shape = shape; - m_pointPen = new QPen(new QBrush(new QColor(255, 255, 255, 191)), 1); - m_connectionPen = new QPen(new QBrush(new QColor(255, 255, 255, 127)), 2); - m_pointBrush = new QBrush(new QColor(191, 191, 191, 127)); - m_pointSize = QSizeF(11, 11); - m_currentIndex = -1; - m_editable = true; - m_enabled = true; - - pointsChanged.connect(&m_widget.update); - } - - void setBoundingRect(QRectF boundingRect) { m_bounds = boundingRect; } - - - QRectF pointBoundingRect(int i) - { - QPointF p = m_points.at(i); - qreal w = m_pointSize.width(); - qreal h = m_pointSize.height(); - qreal x = p.x() - w / 2; - qreal y = p.y() - h / 2; - return new QRectF(x, y, w, h); - } - - QRectF boundingRect() - { - if (m_bounds.isEmpty()) - return new QRectF(m_widget.rect()); - else - return m_bounds; - } - - QPolygonF points() { return m_points; } - - QSizeF pointSize() { return m_pointSize; } - void setPointSize(QSizeF size) { m_pointSize = size; } - - SortType sortType() { return m_sortType; } - void setSortType(SortType sortType) { m_sortType = sortType; } - - ConnectionType connectionType() { return m_connectionType; } - void setConnectionType(ConnectionType connectionType) { m_connectionType = connectionType; } - - void setConnectionPen(QPen pen) { m_connectionPen = pen; } - void setShapePen(QPen pen) { m_pointPen = pen; } - void setShapeBrush(QBrush brush) { m_pointBrush = brush; } - - void setPointLock(int pos, LockType lock) { m_locks[pos] = lock; } - - void setEditable(bool editable) { m_editable = editable; } - bool editable() { return m_editable; } - - void setEnabled(bool enabled) - { - if (m_enabled != enabled) { - m_enabled = enabled; - m_widget.update(); - } - } - - - override bool eventFilter(QObject object, QEvent event) - { - if ((object == m_widget) && m_enabled) { - switch (event.type()) { - - case QEvent.MouseButtonPress: - { - QMouseEvent me = cast(QMouseEvent) event; - - QPointF clickPos = me.pos(); - int index = -1; - for (int i=0; i<m_points.size(); ++i) { - auto path = new QPainterPath; - if (m_shape == PointShape.CircleShape) - path.addEllipse(pointBoundingRect(i)); - else - path.addRect(pointBoundingRect(i)); - - if (path.contains(clickPos)) { - index = i; - break; - } - } - - if (me.button() == Qt.LeftButton) { - if (index == -1) { - if (!m_editable) - return false; - int pos = 0; - // Insert sort for x or y - if (m_sortType == SortType.XSort) { - for (int i=0; i<m_points.size(); ++i) - if (m_points.at(i).x() > clickPos.x()) { - pos = i; - break; - } - } else if (m_sortType == SortType.YSort) { - for (int i=0; i<m_points.size(); ++i) - if (m_points.at(i).y() > clickPos.y()) { - pos = i; - break; - } - } - - // TODO: implement QPoligon(F).insert - auto tmpPoints = m_points.toList; - tmpPoints.insert(pos, clickPos); - m_points = new QPolygonF(tmpPoints); - - m_locks.insert(pos, 0u); - m_currentIndex = pos; - firePointChange(); - } else { - m_currentIndex = index; - } - return true; - - } else if (me.button() == Qt.RightButton) { - if ((index >= 0) && m_editable) { - if (m_locks[index] == 0) { - m_locks.removeAt(index); - m_points.remove(index); - } - firePointChange(); - return true; - } - } - - } - break; - - case QEvent.MouseButtonRelease: - m_currentIndex = -1; - break; - - case QEvent.MouseMove: - if (m_currentIndex >= 0) - movePoint(m_currentIndex, QPointF((cast(QMouseEvent)event).pos)); - break; - - case QEvent.Resize: - { - QResizeEvent e = cast(QResizeEvent) event; - if (e.oldSize().width() == 0 || e.oldSize().height() == 0) - break; - qreal stretch_x = e.size().width() / cast(qreal)e.oldSize.width; - qreal stretch_y = e.size().height() / cast(qreal)e.oldSize.height; - for (int i=0; i<m_points.size(); ++i) { - QPointF p = m_points.at(i); - movePoint(i, QPointF(p.x() * stretch_x, p.y() * stretch_y), false); - } - - firePointChange(); - break; - } - - case QEvent.Paint: - { - QWidget that_widget = m_widget; - m_widget = null; - QApplication.sendEvent(object, event); - m_widget = that_widget; - paintPoints(); - version (QT_OPENGL_SUPPORT) - { - ArthurFrame af = cast(ArthurFrame)(that_widget); - if (af && af.usesOpenGL()) - af.glWidget().swapBuffers(); - } - - return true; - } - default: - break; - } - } - - return false; - } - - - void paintPoints() - { - scope p = new QPainter; - version (QT_OPENGL_SUPPORT) - { - ArthurFrame af = cast(ArthurFrame)(m_widget); - if (af && af.usesOpenGL()) - p.begin(af.glWidget()); - else - p.begin(m_widget); - } - else - p.begin(m_widget); - - p.setRenderHint(QPainter.Antialiasing); - - if (m_connectionPen.style() != Qt.NoPen && m_connectionType != ConnectionType.NoConnection) { - p.setPen(m_connectionPen); - - if (m_connectionType == ConnectionType.CurveConnection) { - auto path = new QPainterPath; - path.moveTo(m_points.at(0)); - for (int i=1; i<m_points.size(); ++i) { - QPointF p1 = m_points.at(i-1); - QPointF p2 = m_points.at(i); - qreal distance = p2.x() - p1.x(); - - path.cubicTo(p1.x() + distance / 2, p1.y(), - p1.x() + distance / 2, p2.y(), - p2.x(), p2.y()); - } - p.drawPath(path); - } else { - p.drawPolyline(m_points); - } - } - - p.setPen(m_pointPen); - p.setBrush(m_pointBrush); - - for (int i=0; i<m_points.size(); ++i) { - QRectF bounds = pointBoundingRect(i); - if (m_shape == PointShape.CircleShape) - p.drawEllipse(bounds); - else - p.drawRect(bounds); - } - } - - - void setPoints(QPolygonF points) - { - delete m_points; - for (int i=0; i<points.size; ++i) - m_points.append(bound_point(points.at(i), boundingRect(), 0)); - - delete m_locks; - if (m_points.size > 0) { - m_locks.length = m_points.size; - - m_locks[] = 0; - } - } - - void movePoint(int index, QPointF point, bool emitUpdate = true) - { - m_points.replace(index, bound_point(point, boundingRect(), m_locks[index])); - if (emitUpdate) - firePointChange(); - } - - void firePointChange() - { - // printf("HoverPoints.firePointChange(), current=%d\n", m_currentIndex); - - if (m_sortType != SortType.NoSort) { - - QPointF oldCurrent; - if (m_currentIndex != -1) { - oldCurrent = m_points.at(m_currentIndex); - } - - if (m_sortType == SortType.XSort) - { - auto tmpPoints = m_points.toList; - sort(tmpPoints, &x_less_than); - m_points = new QPolygonF(tmpPoints); - } - else if (m_sortType == SortType.YSort) - { - auto tmpPoints = m_points.toList; - sort(tmpPoints, &y_less_than); - m_points = new QPolygonF(tmpPoints); - } - - // Compensate for changed order... - if (m_currentIndex != -1) { - for (int i=0; i<m_points.size; ++i) { - if (m_points.at(i) == oldCurrent) { - m_currentIndex = i; - break; - } - } - } - - // printf(" - firePointChange(), current=%d\n", m_currentIndex); - } - - // for (int i=0; i<m_points.size(); ++i) { - // printf(" - point(%2d)=[%.2f, %.2f], lock=%d\n", - // i, m_points.at(i).x(), m_points.at(i).y(), m_locks.at(i)); - // } - - pointsChanged.emit(m_points); - } -} - -private QPointF bound_point(QPointF point, QRectF bounds, int lock) -{ - QPointF p = point; - - qreal left = bounds.left(); - qreal right = bounds.right(); - qreal top = bounds.top(); - qreal bottom = bounds.bottom(); - - if (p.x() < left || (lock & HoverPoints.LockType.LockToLeft)) p.x = left; - else if (p.x() > right || (lock & HoverPoints.LockType.LockToRight)) p.x = right; - - if (p.y() < top || (lock & HoverPoints.LockType.LockToTop)) p.y = top; - else if (p.y() > bottom || (lock & HoverPoints.LockType.LockToBottom)) p.y = bottom; - - return p; -} - -private bool x_less_than(QPointF p1, QPointF p2) -{ - return p1.x() < p2.x(); -} - -private bool y_less_than(QPointF p1, QPointF p2) -{ - return p1.y() < p2.y(); -} +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ +module hoverpoints; + +version (QT_OPENGL_SUPPORT) + import qt.opengl.QGLWidget; + +version (D_Version2) {} +else + import tango.core.Array : sort; + +import + qt.gui.QWidget, + qt.qtd.Array, + arthurwidgets; + +final class HoverPoints : QObject +{ +public: + enum PointShape { + CircleShape, + RectangleShape + } + + enum LockType { + LockToLeft = 0x01, + LockToRight = 0x02, + LockToTop = 0x04, + LockToBottom = 0x08 + } + + enum SortType { + NoSort, + XSort, + YSort + } + + enum ConnectionType { + NoConnection, + LineConnection, + CurveConnection + } + +private: + QWidget m_widget; + + QPolygonF m_points; + QRectF m_bounds; + PointShape m_shape; + SortType m_sortType; + ConnectionType m_connectionType; + + uint[] m_locks; + + QSizeF m_pointSize; + int m_currentIndex; + bool m_editable; + bool m_enabled; + + QPen m_pointPen; + QBrush m_pointBrush; + QPen m_connectionPen; + +public: + mixin Signal!("pointsChanged", QPolygonF /*points*/); + + this(QWidget widget, PointShape shape) + { + super(widget); + + m_widget = widget; + widget.installEventFilter(this); + + m_connectionType = ConnectionType.CurveConnection; + m_sortType = SortType.NoSort; + m_shape = shape; + m_pointPen = new QPen(new QBrush(new QColor(255, 255, 255, 191)), 1); + m_connectionPen = new QPen(new QBrush(new QColor(255, 255, 255, 127)), 2); + m_pointBrush = new QBrush(new QColor(191, 191, 191, 127)); + m_pointSize = QSizeF(11, 11); + m_currentIndex = -1; + m_editable = true; + m_enabled = true; + + pointsChanged.connect(&m_widget.update); + } + + void setBoundingRect(QRectF boundingRect) { m_bounds = boundingRect; } + + + QRectF pointBoundingRect(int i) + { + QPointF p = m_points.at(i); + qreal w = m_pointSize.width(); + qreal h = m_pointSize.height(); + qreal x = p.x() - w / 2; + qreal y = p.y() - h / 2; + return new QRectF(x, y, w, h); + } + + QRectF boundingRect() + { + if (m_bounds.isEmpty()) + return new QRectF(m_widget.rect()); + else + return m_bounds; + } + + QPolygonF points() { return m_points; } + + QSizeF pointSize() { return m_pointSize; } + void setPointSize(QSizeF size) { m_pointSize = size; } + + SortType sortType() { return m_sortType; } + void setSortType(SortType sortType) { m_sortType = sortType; } + + ConnectionType connectionType() { return m_connectionType; } + void setConnectionType(ConnectionType connectionType) { m_connectionType = connectionType; } + + void setConnectionPen(QPen pen) { m_connectionPen = pen; } + void setShapePen(QPen pen) { m_pointPen = pen; } + void setShapeBrush(QBrush brush) { m_pointBrush = brush; } + + void setPointLock(int pos, LockType lock) { m_locks[pos] = lock; } + + void setEditable(bool editable) { m_editable = editable; } + bool editable() { return m_editable; } + + void setEnabled(bool enabled) + { + if (m_enabled != enabled) { + m_enabled = enabled; + m_widget.update(); + } + } + + + override bool eventFilter(QObject object, QEvent event) + { + if ((object == m_widget) && m_enabled) { + switch (event.type()) { + + case QEvent.MouseButtonPress: + { + QMouseEvent me = cast(QMouseEvent) event; + + QPointF clickPos = me.pos(); + int index = -1; + for (int i=0; i<m_points.size(); ++i) { + auto path = new QPainterPath; + if (m_shape == PointShape.CircleShape) + path.addEllipse(pointBoundingRect(i)); + else + path.addRect(pointBoundingRect(i)); + + if (path.contains(clickPos)) { + index = i; + break; + } + } + + if (me.button() == Qt.LeftButton) { + if (index == -1) { + if (!m_editable) + return false; + int pos = 0; + // Insert sort for x or y + if (m_sortType == SortType.XSort) { + for (int i=0; i<m_points.size(); ++i) + if (m_points.at(i).x() > clickPos.x()) { + pos = i; + break; + } + } else if (m_sortType == SortType.YSort) { + for (int i=0; i<m_points.size(); ++i) + if (m_points.at(i).y() > clickPos.y()) { + pos = i; + break; + } + } + + // TODO: implement QPoligon(F).insert + auto tmpPoints = m_points.toList; + tmpPoints.insert(pos, clickPos); + m_points = new QPolygonF(tmpPoints); + + m_locks.insert(pos, 0u); + m_currentIndex = pos; + firePointChange(); + } else { + m_currentIndex = index; + } + return true; + + } else if (me.button() == Qt.RightButton) { + if ((index >= 0) && m_editable) { + if (m_locks[index] == 0) { + m_locks.removeAt(index); + m_points.remove(index); + } + firePointChange(); + return true; + } + } + + } + break; + + case QEvent.MouseButtonRelease: + m_currentIndex = -1; + break; + + case QEvent.MouseMove: + if (m_currentIndex >= 0) + movePoint(m_currentIndex, QPointF((cast(QMouseEvent)event).pos)); + break; + + case QEvent.Resize: + { + QResizeEvent e = cast(QResizeEvent) event; + if (e.oldSize().width() == 0 || e.oldSize().height() == 0) + break; + qreal stretch_x = e.size().width() / cast(qreal)e.oldSize.width; + qreal stretch_y = e.size().height() / cast(qreal)e.oldSize.height; + for (int i=0; i<m_points.size(); ++i) { + QPointF p = m_points.at(i); + movePoint(i, QPointF(p.x() * stretch_x, p.y() * stretch_y), false); + } + + firePointChange(); + break; + } + + case QEvent.Paint: + { + QWidget that_widget = m_widget; + m_widget = null; + QApplication.sendEvent(object, event); + m_widget = that_widget; + paintPoints(); + version (QT_OPENGL_SUPPORT) + { + ArthurFrame af = cast(ArthurFrame)(that_widget); + if (af && af.usesOpenGL()) + af.glWidget().swapBuffers(); + } + + return true; + } + default: + break; + } + } + + return false; + } + + + void paintPoints() + { + scope p = new QPainter; + version (QT_OPENGL_SUPPORT) + { + ArthurFrame af = cast(ArthurFrame)(m_widget); + if (af && af.usesOpenGL()) + p.begin(af.glWidget()); + else + p.begin(m_widget); + } + else + p.begin(m_widget); + + p.setRenderHint(QPainter.Antialiasing); + + if (m_connectionPen.style() != Qt.NoPen && m_connectionType != ConnectionType.NoConnection) { + p.setPen(m_connectionPen); + + if (m_connectionType == ConnectionType.CurveConnection) { + auto path = new QPainterPath; + path.moveTo(m_points.at(0)); + for (int i=1; i<m_points.size(); ++i) { + QPointF p1 = m_points.at(i-1); + QPointF p2 = m_points.at(i); + qreal distance = p2.x() - p1.x(); + + path.cubicTo(p1.x() + distance / 2, p1.y(), + p1.x() + distance / 2, p2.y(), + p2.x(), p2.y()); + } + p.drawPath(path); + } else { + p.drawPolyline(m_points); + } + } + + p.setPen(m_pointPen); + p.setBrush(m_pointBrush); + + for (int i=0; i<m_points.size(); ++i) { + QRectF bounds = pointBoundingRect(i); + if (m_shape == PointShape.CircleShape) + p.drawEllipse(bounds); + else + p.drawRect(bounds); + } + } + + + void setPoints(QPolygonF points) + { + delete m_points; + for (int i=0; i<points.size; ++i) + m_points.append(bound_point(points.at(i), boundingRect(), 0)); + + delete m_locks; + if (m_points.size > 0) { + m_locks.length = m_points.size; + + m_locks[] = 0; + } + } + + void movePoint(int index, QPointF point, bool emitUpdate = true) + { + m_points.replace(index, bound_point(point, boundingRect(), m_locks[index])); + if (emitUpdate) + firePointChange(); + } + + void firePointChange() + { + // printf("HoverPoints.firePointChange(), current=%d\n", m_currentIndex); + + if (m_sortType != SortType.NoSort) { + + QPointF oldCurrent; + if (m_currentIndex != -1) { + oldCurrent = m_points.at(m_currentIndex); + } + + if (m_sortType == SortType.XSort) + { + auto tmpPoints = m_points.toList; + sort(tmpPoints, &x_less_than); + m_points = new QPolygonF(tmpPoints); + } + else if (m_sortType == SortType.YSort) + { + auto tmpPoints = m_points.toList; + sort(tmpPoints, &y_less_than); + m_points = new QPolygonF(tmpPoints); + } + + // Compensate for changed order... + if (m_currentIndex != -1) { + for (int i=0; i<m_points.size; ++i) { + if (m_points.at(i) == oldCurrent) { + m_currentIndex = i; + break; + } + } + } + + // printf(" - firePointChange(), current=%d\n", m_currentIndex); + } + + // for (int i=0; i<m_points.size(); ++i) { + // printf(" - point(%2d)=[%.2f, %.2f], lock=%d\n", + // i, m_points.at(i).x(), m_points.at(i).y(), m_locks.at(i)); + // } + + pointsChanged.emit(m_points); + } +} + +private QPointF bound_point(QPointF point, QRectF bounds, int lock) +{ + QPointF p = point; + + qreal left = bounds.left(); + qreal right = bounds.right(); + qreal top = bounds.top(); + qreal bottom = bounds.bottom(); + + if (p.x() < left || (lock & HoverPoints.LockType.LockToLeft)) p.x = left; + else if (p.x() > right || (lock & HoverPoints.LockType.LockToRight)) p.x = right; + + if (p.y() < top || (lock & HoverPoints.LockType.LockToTop)) p.y = top; + else if (p.y() > bottom || (lock & HoverPoints.LockType.LockToBottom)) p.y = bottom; + + return p; +} + +private bool x_less_than(QPointF p1, QPointF p2) +{ + return p1.x() < p2.x(); +} + +private bool y_less_than(QPointF p1, QPointF p2) +{ + return p1.y() < p2.y(); +}
--- a/generator/abstractmetalang.cpp Tue Sep 22 15:22:37 2009 +0000 +++ b/generator/abstractmetalang.cpp Wed Dec 23 16:10:46 2009 +0200 @@ -1159,13 +1159,15 @@ bool AbstractMetaClass::generateShellClass() const { - return m_force_shell_class || - m_has_virtual_destructor || - (!isFinal() - && (hasVirtualFunctions() + return m_force_shell_class || + ( /*!isFinal() + && ( */ + isPolymorphic() || hasProtectedFunctions() || hasFieldAccessors() - || typeEntry()->isObject())); // qtd2 for being more consistent + //|| typeEntry()->isObject() // qtd2 for being more consistent + /*)*/ + ); } QPropertySpec *AbstractMetaClass::propertySpecForRead(const QString &name) const @@ -1340,7 +1342,7 @@ f->setImplementingClass(this); f->setOriginalAttributes(f->attributes()); - /*addFunction*/(f); + addFunction(f); } bool AbstractMetaClass::hasFunction(const AbstractMetaFunction *f) const
--- a/generator/abstractmetalang.h Tue Sep 22 15:22:37 2009 +0000 +++ b/generator/abstractmetalang.h Wed Dec 23 16:10:46 2009 +0200 @@ -784,12 +784,49 @@ void setForceShellClass(bool on) { m_force_shell_class = on; } bool generateShellClass() const; - bool hasVirtualSlots() const { return m_has_virtual_slots; } - bool hasVirtualFunctions() const { return !isFinal() && (m_has_virtuals || hasVirtualDestructor()); } + bool hasVirtualSlots() const { return m_has_virtual_slots; } + + // returns true if this class has overridable virtual functions other than + // the virtual destructor if one exists. + bool hasVirtualFunctions() const { return !isFinal() && m_has_virtuals; } + + // returns true if this class or its base classes define a + // virtual destructor bool hasVirtualDestructor() const { return m_has_virtual_destructor - || (m_base_class && m_base_class->hasVirtualDestructor()); } + || m_base_class && m_base_class->hasVirtualDestructor(); } + + // returns the uppermost base class having virtual functions + const AbstractMetaClass* polymorphicBase() const + { + const AbstractMetaClass* ret = this; + for (const AbstractMetaClass* base = this->m_base_class; base; base = base->m_base_class) + { + if (base->m_has_virtuals || base->m_has_virtual_destructor) + ret = base; + } + return ret; + } + + // returns true if this class or its base classes have any virtual functions + bool isPolymorphic() const { return m_has_virtuals + || m_has_virtual_destructor + || m_base_class && m_base_class->isPolymorphic(); + } + + // returns the uppermost base class with virtual destructors + const AbstractMetaClass* virtualDestructorBase() const + { + const AbstractMetaClass* ret = NULL; + for (const AbstractMetaClass* base = this; base; base = base->m_base_class) + { + if (base->m_has_virtual_destructor) + ret = base; + } + return ret; + } + bool setHasVirtualDestructor(bool value) { m_has_virtual_destructor = value; } - bool isPolymorphic() const { return typeEntry()->isObject() && (hasVirtualFunctions() || hasVirtualDestructor()); } + bool hasProtectedFunctions() const; QList<TypeEntry *> templateArguments() const { return m_template_args; }
--- a/generator/cppgenerator.cpp Tue Sep 22 15:22:37 2009 +0000 +++ b/generator/cppgenerator.cpp Wed Dec 23 16:10:46 2009 +0200 @@ -230,7 +230,7 @@ s << "("; const AbstractMetaClass *owner = java_function->ownerClass(); - bool has_d_ptr = java_function->isConstructor() && owner && owner->typeEntry()->isObject(); + bool has_d_ptr = java_function->isConstructor() && owner && owner->isPolymorphic(); const AbstractMetaArgumentList arg_list = java_function->arguments(); if (has_d_ptr) { s << "void *d_ptr";
--- a/generator/cppheadergenerator.cpp Tue Sep 22 15:22:37 2009 +0000 +++ b/generator/cppheadergenerator.cpp Wed Dec 23 16:10:46 2009 +0200 @@ -250,7 +250,7 @@ s << "};" << endl << endl; if (!java_class->isQObject() && java_class->isPolymorphic() && java_class->baseClass()) - s << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->rootClass()->name() << "_dId(void *nativeId);" << endl; + s << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->polymorphicBase()->name() << "_dId(void *nativeId);" << endl; s << "#endif // " << include_block << endl;
--- a/generator/cppimplgenerator.cpp Tue Sep 22 15:22:37 2009 +0000 +++ b/generator/cppimplgenerator.cpp Wed Dec 23 16:10:46 2009 +0200 @@ -589,7 +589,7 @@ if (hasCustomDestructor(java_class)) */ - if (java_class->hasPublicDestructor() && (!java_class->baseClass() || !java_class->hasVirtualFunctions())) + if (java_class->hasPublicDestructor() && !java_class->hasVirtualDestructor()) writeDestructor(s, java_class); if (java_class->isQObject()) @@ -601,7 +601,7 @@ writeShellConstructor(s, function); } - if (java_class->hasVirtualFunctions()) + if (java_class->isPolymorphic()) writeShellDestructor(s, java_class); if (java_class->isQObject()) @@ -618,6 +618,7 @@ // qtd writeShellFunction(s, function, java_class, pos); writeShellVirtualFunction(s, function, java_class, pos); } + s << "// end ------------------------" << endl << endl; if (cpp_shared) writeInitCallbacks(s, java_class); @@ -629,6 +630,7 @@ const AbstractMetaFunction *function = shellFunctions.at(i); writeShellFunction(s, function, java_class, -1); } + s << "// end ------------------------" << endl << endl; // Write public overrides for functions that are protected in the base class // so they can be accessed from the native callback @@ -639,6 +641,7 @@ continue; writePublicFunctionOverride(s, function, java_class); } + s << "// end ------------------------" << endl << endl; // Write virtual function overries used to decide on static/virtual calls s << "// Write virtual function overries used to decide on static/virtual calls" << endl; @@ -648,6 +651,7 @@ continue; writeVirtualFunctionOverride(s, function, java_class); } + s << "// end ------------------------" << endl << endl;; } writeExtraFunctions(s, java_class); @@ -663,15 +667,14 @@ for (int i=0; i<signal_functions.size(); ++i) writeSignalFunction(s, signal_functions.at(i), java_class, i); */ - s << "// ---externC---" << endl; - + s << "// extern C" << endl; // Native callbacks (all java functions require native callbacks) AbstractMetaFunctionList class_funcs = java_class->functionsInTargetLang(); foreach (AbstractMetaFunction *function, class_funcs) { if (!function->isEmptyFunction()) writeFinalFunction(s, function, java_class); } - s << "// ---externC---end" << endl; + s << "// end ------------------------" << endl << endl; class_funcs = java_class->queryFunctions(AbstractMetaClass::NormalFunctions | AbstractMetaClass::AbstractFunctions | AbstractMetaClass::NotRemovedFromTargetLang); @@ -687,6 +690,8 @@ if (field->wasPublic() || (field->wasProtected() && !java_class->isFinal())) writeFieldAccessors(s, field); } + s << "// end ------------------------" << endl << endl; + /* s << "// writeFromNativeFunction" << endl; writeFromNativeFunction(s, java_class); @@ -711,7 +716,7 @@ if (java_class->isQObject()) { s << endl << endl - << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_staticMetaObject() {" << endl + << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_staticTypeId() {" << endl << " return (void*)&" << java_class->name() << "::staticMetaObject;" << endl << "}" << endl; } @@ -1391,7 +1396,7 @@ if (cls->isQObject()) s << "," << endl << " QtD_QObjectEntity(this, d_ptr)"; - else if (cls->hasVirtualFunctions()) + else if (cls->isPolymorphic()) s << "," << endl << " QtD_Entity(d_ptr)"; /* qtd s << " m_meta_object(0)," << endl; s << " m_vtable(0)," << endl @@ -1736,7 +1741,27 @@ void CppImplGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *java_class) { - if (java_class->isPolymorphic()) + if (java_class == java_class->polymorphicBase()) + { + if (java_class->isPolymorphic()) + { + s << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_dId(void *nativeId)" << endl + << "{" << endl + << " QtD_Entity *e = dynamic_cast<QtD_Entity*>((" << java_class->qualifiedCppName() << "*)nativeId);" << endl + << " return e ? e->dId : NULL;" << endl + << "}" << endl << endl; + } + + if (!java_class->isQObject()) + { + s << "extern \"C\" DLL_PUBLIC const void* qtd_" << java_class->name() << "_typeId(void *nativeId)" << endl + << "{" << endl + << " return &typeid((" << java_class->qualifiedCppName() << "*)nativeId);" << endl + << "}" << endl << endl; + } + } + + if (!java_class->isQObject()) { s << "extern \"C\" DLL_PUBLIC const void* qtd_" << java_class->name() << "_staticTypeId()" << endl; s << "{" << endl; @@ -1745,20 +1770,6 @@ s << INDENT << "return &typeid(" << java_class->qualifiedCppName() << ");" << endl; } s << "}" << endl << endl; - - if (!java_class->baseClass()) - { - s << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_dId(void *nativeId)" << endl - << "{" << endl - << " QtD_Entity *a = dynamic_cast<QtD_Entity*>((" << java_class->qualifiedCppName() << "*)nativeId);" << endl - << " return a ? a->dId : NULL;" << endl - << "}" << endl << endl - - << "extern \"C\" DLL_PUBLIC const void* qtd_" << java_class->name() << "_typeId(void *nativeId)" << endl - << "{" << endl - << " return &typeid((" << java_class->qualifiedCppName() << "*)nativeId);" << endl - << "}" << endl << endl; - } } } @@ -1883,7 +1894,7 @@ const AbstractMetaClass *cls = java_function->ownerClass(); if (java_function->isConstructor() && - cls->hasVirtualFunctions()) + cls->isPolymorphic()) { s << "void *d_ptr"; nativeArgCount++; @@ -2104,7 +2115,7 @@ if (java_class->isQObject()) s << "QtD_QObjectEntity::getQObjectEntity((QObject*)__this_nativeId) : false;" << endl; else - s << "qtd_" << java_class->rootClass()->name() << "_dId(__this_nativeId) : false;" << endl; + s << "qtd_" << java_class->polymorphicBase()->name() << "_dId(__this_nativeId) : false;" << endl; } else { option = OriginalName; } @@ -2312,14 +2323,13 @@ if (!cls->hasConstructors()) return; - s << INDENT << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_destructor(void *ptr)" << endl - << INDENT << "{" << endl; + if (cls->polymorphicBase() == cls) { - QString className = cls->hasVirtualFunctions() ? cls->typeEntry()->name() : shellClassName(cls); - s << INDENT << "delete (" << className << " *)ptr;" << endl; + s << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_delete(void *ptr){" << endl; + QString className = cls->generateShellClass() ? shellClassName(cls) : cls->typeEntry()->name(); + s << " delete (" << className << " *)ptr;" << endl + << "}" << endl << endl; } - - s << INDENT << "}" << endl << endl; } void CppImplGenerator::writeFinalConstructor(QTextStream &s, @@ -2666,6 +2676,8 @@ const AbstractMetaFunction *java_function, int argument_index) { + s << "//writeJavaToQt" << endl; // TMP + // Conversion to C++: Shell code for return values, native code for arguments TypeSystem::Language lang = argument_index == 0 ? TypeSystem::ShellCode : TypeSystem::NativeCode; if (writeConversionRule(s, lang, java_function, argument_index, qt_name, java_name)) @@ -2694,6 +2706,8 @@ int argument_index, Option options) { + s << "//writeJavaToQt 2" << endl; // TMP + // Conversion to C++: Shell code for return values, native code for arguments TypeSystem::Language lang = argument_index == 0 ? TypeSystem::ShellCode : TypeSystem::NativeCode; if (java_function && writeConversionRule(s, lang, java_function, argument_index, qt_name, java_name)) @@ -2930,6 +2944,7 @@ int argument_index, Option option) { + s << "writeQtToJava" << endl; // Conversion to Java: Native code for return values, shell code for arguments TypeSystem::Language lang = argument_index == 0 ? TypeSystem::NativeCode : TypeSystem::ShellCode; @@ -3531,7 +3546,7 @@ int written_arguments = 0; const AbstractMetaClass *cls = java_function->ownerClass(); - if (java_function->isConstructor() && cls->hasVirtualFunctions()) { + if (java_function->isConstructor() && cls->isPolymorphic()) { s << "d_ptr"; written_arguments++; }
--- a/generator/dgenerator.cpp Tue Sep 22 15:22:37 2009 +0000 +++ b/generator/dgenerator.cpp Wed Dec 23 16:10:46 2009 +0200 @@ -23,7 +23,7 @@ * are described in the Nokia Qt GPL Exception version 1.2, included in * the file GPL_EXCEPTION.txt in this package. * -* Qt for Windows(R) Licensees +* Qt for Win1782dows(R) Licensees * As a special exception, Nokia, as the sole copyright holder for Qt * Designer, grants users of the Qt/Eclipse Integration plug-in the * right for the Qt/Eclipse Integration to link to functionality @@ -772,7 +772,7 @@ if (d_function->isConstructor() && ( d_function->implementingClass()->isPolymorphic() - || d_function->implementingClass()->typeEntry()->isObject() ) ) { // qtd + /*|| d_function->implementingClass()->typeEntry()->isObject()*/ ) ) { // qtd s << "cast(void*) this"; if (arguments.count() > 0) s << ", "; @@ -1680,18 +1680,23 @@ if (!d_class->hasConstructors()) return; - s << " override void __deleteNative() {" << endl - << " qtd_" << d_class->name() << "_destructor(__nativeId);" << endl - << " }" << endl; + if (d_class->polymorphicBase() == d_class) + { + s << " override void __deleteNative() {" << endl + << " qtd_" << d_class->polymorphicBase()->name() << "_delete(__nativeId);" << endl + << " }" << endl; + } } void DGenerator::writeOwnershipSetter(QTextStream &s, const AbstractMetaClass *d_class) { if (d_class->isInterface() || d_class->isNamespace()) - s << INDENT << "void __nativeOwnership(bool value);"; + { + //s << INDENT << "void __nativeOwnership(bool value);"; + } else if (d_class->typeEntry()->isObject()) {// COMPILER BUG: - s << INDENT << "void __nativeOwnership(bool value) { super.__nativeOwnership = value; }"; + //s << INDENT << "void __nativeOwnership(bool value) { super.__nativeOwnership = value; }"; } } @@ -1756,30 +1761,12 @@ { bool resetAfterUse = !type->isQObject() && signal->resetObjectAfterUse(argument->argumentIndex() + 1); - if ((static_cast<const ComplexTypeEntry*>(type->typeEntry()))->isPolymorphic()) - { - QString flags; - if (resetAfterUse) - flags = "QtdObjectFlags.stackAllocated | QtdObjectFlags.skipNativeDelete"; - else - flags = "QtdObjectFlags.none"; - - s << INDENT << "auto " << arg_name << " = " << type->typeEntry()->name() << ".__wrap(" << arg_name - << ", cast(QtdObjectFlags)(" << flags << "));" << endl; - - if (resetAfterUse) - { - s << INDENT << "scope(exit) {" << endl - << INDENT << " if (" << arg_name << "_d_ref.__flags & QtdObjectFlags.stackAllocated)" << endl - << INDENT << " delete " << arg_name << ";" << endl - << INDENT << "}" << endl; - } - } + if (resetAfterUse) + s << "auto " << arg_name << " = scopeObject!(" << type->typeEntry()->name() << ")(" << arg_name << ");"; else { - s << INDENT << (resetAfterUse ? "scope " : "auto ") - << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags." - << (resetAtferUse ? "skipNativeDelete" : "none") << ");" << endl; + s << INDENT << "auto " << arg_name << " = " << type->typeEntry()->name() << ".__wrap(" << arg_name + << ");" << endl; } } @@ -1813,7 +1800,7 @@ auxFile.isDone = true; auxFile.stream << "module " << auxModName << ";" << endl << endl; - bool staticInit = (d_class->typeEntry()->isObject() && d_class->isPolymorphic()) || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface()); + bool staticInit = d_class->isPolymorphic() || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface()); if (staticInit) { auxFile.isDone = false; @@ -1921,7 +1908,7 @@ << "public import qt.core.Qt;" << endl << "public import qt.QtdObject;" << endl << "private import qt.core.QString;" << endl - << "private import qt.qtd.Array;" << endl; + << "private import qt.Array;" << endl; if (d_class->isQObject()) { s << "public import qt.core.QMetaObject;" << endl; s << "public import qt.Signal;" << endl; @@ -1952,7 +1939,8 @@ s << "import std.stdio;" << endl << "import std.string;" << endl << "import std.utf;" << endl - << "import core.memory;" << endl; + << "import core.memory;" << endl + << "import qt.Core;" << endl; } else { @@ -2023,11 +2011,10 @@ if (d_class->baseClass()) { s << d_class->baseClass()->name(); } else { - if (d_class->typeEntry()->isValue()) + if (d_class->isQObject()) s << "QtdObjectBase"; - else if (d_class->typeEntry()->isObject()) + else s << "QtdObject"; - } }/* qtd else if (d_class->isInterface()) { s << " extends QtJambiInterface"; @@ -2109,18 +2096,17 @@ s << INDENT << "@SuppressWarnings(\"unused\")" << endl; */ if (actions != ReferenceCount::Set && actions != ReferenceCount::Ignore) { // qtd2 - - s << INDENT; - switch (access) { - case ReferenceCount::Private: - s << "package "; break; // qtd - case ReferenceCount::Protected: - s << "protected "; break; - case ReferenceCount::Public: - s << "public "; break; - default: // friendly - } - + s << INDENT; + switch (access) { + case ReferenceCount::Private: + s << "package "; break; // qtd + case ReferenceCount::Protected: + s << "protected "; break; + case ReferenceCount::Public: + s << "public "; break; + default: // friendly + break; + } } // qtd2 if (isStatic) @@ -2220,36 +2206,13 @@ writeFieldAccessors(s, field); } - if (d_class->typeEntry()->isObject()) - { - if (d_class->isQObject()) - writeQObjectFunctions(s, d_class); - else - writeObjectFunctions(s, d_class); - - if (d_class->isPolymorphic()) - { - s << " static QtdObjectBase __createWrapper(void* nativeId, QtdObjectFlags flags) {" << endl; - - QString className = d_class->name(); - if (d_class->isAbstract()) - className += "_ConcreteWrapper"; - - s << " auto obj = new(flags) " << className << "(nativeId, flags);" << endl; - - if (d_class->isQObject()) - s << " qtd_" << d_class->name() << "_createEntity(nativeId, cast(void*)obj);" << endl; - - s << " return obj;" << endl - << " }" << endl << endl; - } - } - - if (d_class->hasPublicDestructor() && (!d_class->baseClass() || !d_class->hasVirtualFunctions())) - writeDestructor(s, d_class); + writeDestructor(s, d_class); // Add dummy constructor for use when constructing subclasses if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) { + + writeObjectFunctions(s, d_class); + s << endl << INDENT << "public " << "this"; @@ -2485,21 +2448,19 @@ s << INDENT << "}" << endl << endl; } - if (d_class->isPolymorphic()) + + if (d_class->isPolymorphic() && d_class->polymorphicBase() == d_class) { - if (!d_class->typeEntry()->isQObject()) - { - s << "extern(C) void* qtd_" << d_class->name() << "_dId(void *q_ptr);" << endl << endl; - s << "extern(C) void* qtd_" << d_class->name() << "_typeId(void* nativeId);" << endl; - } - - s << "extern(C) void* qtd_" << d_class->name() << "_staticTypeId();" << endl; + s << "extern(C) void* qtd_" << d_class->name() << "_dId(void *nativeId);" << endl << endl; + s << "extern(C) void* qtd_" << d_class->name() << "_typeId(void* nativeId);" << endl; } + s << "extern(C) void* qtd_" << d_class->name() << "_staticTypeId();" << endl; + // if (d_class->needsConversionFunc) // writeConversionFunction(s, d_class); - if (d_class->hasConstructors()) + if (d_class->hasConstructors() && d_class->polymorphicBase() == d_class) s << "extern(C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl; // qtd @@ -2558,10 +2519,8 @@ s << "extern(C) void static_init_" << d_class->name() << "() {" << endl; - if (d_class->isPolymorphic()) { - s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl - << INDENT << " " << d_class->name() << ".createStaticMetaObject;" << endl << endl; - } + if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) + s << " " << d_class->name() << ".__createMetaObject;" << endl << endl; if (cpp_shared) { // virtual functions @@ -2614,10 +2573,7 @@ if (d_class->isQObject()) - { - s << "private extern(C) void* qtd_" << d_class->name() << "_staticMetaObject();" << endl << endl - << "private extern(C) void qtd_" << d_class->name() << "_createEntity(void* nativeId, void* dId);" << endl << endl; - } + s << "private extern(C) void qtd_" << d_class->name() << "_createEntity(void* nativeId, void* dId);" << endl << endl; } /* @@ -2657,6 +2613,7 @@ } */ +/* void DGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) { // polymorphic @@ -2703,47 +2660,80 @@ << " }" << endl << endl; } else - { - s << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl - << " return new " << d_class->name() << "(nativeId, flags);" - << " }" << endl << endl; + { } } - -void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) +*/ + +void DGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) { QString concreteArg; if (d_class->isAbstract()) concreteArg += ", " + d_class->name() + "_ConcreteWrapper"; - s << " private static QMetaObject _staticMetaObject;" << endl - << " protected static void createStaticMetaObject() {" << endl - << " assert(!_staticMetaObject);" << endl - << " QMetaObject base;" << endl; - - if (d_class->name() != "QObject") - { - QString baseName = d_class->baseClassName(); - s << " if (!" << baseName << "._staticMetaObject)" << endl - << " " << baseName << ".createStaticMetaObject;" << endl - << " base = " << baseName << "._staticMetaObject;" << endl; + bool isQObject = d_class->isQObject(); + QString moName = isQObject ? "QMetaObject" : "QtdMetaObject"; + + s << " private static __gshared " << moName << " _staticMetaObject;" << endl + << " static void __createMetaObject(){" << endl + << " if (!_staticMetaObject){" << endl + << " QtdMetaObjectBase base;" << endl + << " static if (is(typeof(super.__createMetaObject))) {" << endl + << " alias typeof(super) Base;" << endl + << " Base.__createMetaObject();" << endl + << " base = Base._staticMetaObject;" << endl + << " }" << endl + << " _staticMetaObject = new " << moName << "(qtd_" << d_class->name() << "_staticTypeId, base, &__createWrapper);" << endl + << " }" << endl + << " }" << endl << endl + + << " " << moName << " metaObject(){" << endl + << " return _staticMetaObject;" << endl + << " }" << endl << endl + << " static " << moName << " staticMetaObject() {" << endl + << " return _staticMetaObject;" << endl + << " }" << endl << endl + + << " static QtdObjectBase __createWrapper(void* nativeId, QtdObjectFlags flags) {" << endl; + + QString className = d_class->name(); + if (d_class->isAbstract()) + className += "_ConcreteWrapper"; + + s << " auto obj = new(flags) " << className << "(nativeId, flags);" << endl; + + if (d_class->isQObject()) + s << " qtd_" << d_class->name() << "_createEntity(nativeId, cast(void*)obj);" << endl; + + s << " return obj;" << endl + << " }" << endl << endl; + + if (!isQObject) + { + if (d_class->isPolymorphic()) + { + const AbstractMetaClass* polyBase = d_class->polymorphicBase(); + s << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl + << " auto obj = cast(" << d_class->name() << ") qtd_" << polyBase->name() << "_dId(nativeId);" << endl + << " if (!obj)" << endl + << " obj = static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, " + "qtd_" << polyBase->name() << "_typeId(nativeId), flags));" << endl + << " return obj;" << endl + << " }" << endl << endl; + } + else + { + s << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl + << " return new(flags) " << d_class->name() << "(nativeId, flags);" << endl + << " }" << endl << endl; + } } - - s << " _staticMetaObject = new QMetaObject(qtd_" << d_class->name() << "_staticMetaObject, base);" << endl - << " _staticMetaObject.construct!(" << d_class->name() << concreteArg << ");" << endl - << " }" << endl << endl - - << " QMetaObject metaObject() {" << endl - << " return _staticMetaObject;" << endl - << " }" << endl << endl - - << " static QMetaObject staticMetaObject() {" << endl - << " return _staticMetaObject;" << endl - << " }" << endl << endl - - << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl - << " return static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, flags));" << endl - << " }" << endl << endl; + else + { + s << " static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl + << " return static_cast!" << d_class->name() << "(" << d_class->name() << "._staticMetaObject.wrap(nativeId, flags));" << endl + << " }" << endl << endl; + } } /* @@ -2908,30 +2898,13 @@ { bool resetAfterUse = !type->isQObject() && d_function->resetObjectAfterUse(argument->argumentIndex() + 1); - if ((static_cast<const ComplexTypeEntry*>(type->typeEntry()))->isPolymorphic()) - { - QString flags; - if (resetAfterUse) - flags = "QtdObjectFlags.stackAllocated | QtdObjectFlags.skipNativeDelete"; - else - flags = "QtdObjectFlags.none"; - - s << INDENT << "auto " << arg_name << "_d_ref = " << type->typeEntry()->name() << ".__wrap(" << arg_name - << ", cast(QtdObjectFlags)(" << flags << "));" << endl; - - if (resetAfterUse) - { - s << INDENT << "scope(exit) {" << endl - << INDENT << " if (" << arg_name << "_d_ref.__flags & QtdObjectFlags.stackAllocated)" << endl - << INDENT << " delete " << arg_name << ";" << endl - << INDENT << "}" << endl; - } - } + + if (resetAfterUse) + s << INDENT << "auto " << arg_name << "_d_ref = scopeObject!(" << type->typeEntry()->name() << ")(" << arg_name << ");"; else { - s << INDENT << (resetAfterUse ? "scope " : "auto ") - << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags." - << (resetAtferUse ? "skipNativeDelete" : "none") << ");" << endl; + s << INDENT << "auto " << arg_name << "_d_ref = " << type->typeEntry()->name() << ".__wrap(" << arg_name + << ");" << endl; } } else
--- a/generator/typesystem.h Tue Sep 22 15:22:37 2009 +0000 +++ b/generator/typesystem.h Wed Dec 23 16:10:46 2009 +0200 @@ -912,7 +912,7 @@ uint m_polymorphic_base : 1; uint m_generic_class : 1; - QString m_polymorphic_id_value;e + QString m_polymorphic_id_value; QString m_lookup_name; QString m_target_type; ExpensePolicy m_expense_policy;
--- a/generator/typesystem_core-java.java Tue Sep 22 15:22:37 2009 +0000 +++ b/generator/typesystem_core-java.java Wed Dec 23 16:10:46 2009 +0200 @@ -72,8 +72,8 @@ } } */ - - override void onSignalHandlerCreated(ref SignalHandler sh) + + void onSignalHandlerCreated(ref SignalHandler sh) { sh.signalEvent = &onSignalEvent; } @@ -135,7 +135,7 @@ find(children); return result; - } + } }// class abstract class QAbstractItemModel___ extends QAbstractItemModel {
--- a/generator/typesystem_core.xml Tue Sep 22 15:22:37 2009 +0000 +++ b/generator/typesystem_core.xml Wed Dec 23 16:10:46 2009 +0200 @@ -2374,7 +2374,7 @@ new QtD_QObjectEntity((QObject*)nativeId, dId); } -extern "C" DLL_PUBLIC void* qtd_QObject_metaObject(void* nativeId) +extern "C" DLL_PUBLIC void* qtd_QObject_typeId(void* nativeId) { return (void*)((QObject*)nativeId)->metaObject(); } @@ -2402,10 +2402,8 @@ <inject-code class="java-free"> extern(C) void* qtd_get_d_qobject(void* nativeId); extern(C) void* qtd_create_qobject_entity(void* nativeId, void* dId); -extern(C) void* qtd_QObject_metaObject(void* nativeId); extern(C) void qtd_connect(void *nativeId, cstringz signal, int id, bool hasDId); extern(C) void qtd_disconnect(void *nativeId, cstringz signal, int id, bool hasDId); - </inject-code> <modify-function signature="childEvent(QChildEvent*)">
--- a/mini/test1/build Tue Sep 22 15:22:37 2009 +0000 +++ b/mini/test1/build Wed Dec 23 16:10:46 2009 +0200 @@ -1,3 +1,3 @@ #! /bin/bash -dmd main.d -gc -debug -debug=QtdVerbose -L-L../../output/build/lib -L-lqtdcore -I../../output/build -I../../ -I../../qt/d1 -L-lQtCore -L-lQtGui \ No newline at end of file +dmd main.d -gc -debug -debug=QtdVerbose -L-L../../output/build/lib -L-lqtdcore -L-lqtdgui -I../../output/build -I../../ -I../../qt/d1 -L-lQtCore -L-lQtGui \ No newline at end of file