summaryrefslogtreecommitdiffstats
path: root/demos/shared
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 09:18:55 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 09:18:55 (GMT)
commite5fcad302d86d316390c6b0f62759a067313e8a9 (patch)
treec2afbf6f1066b6ce261f14341cf6d310e5595bc1 /demos/shared
downloadQt-e5fcad302d86d316390c6b0f62759a067313e8a9.zip
Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz
Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.bz2
Long live Qt 4.5!
Diffstat (limited to 'demos/shared')
-rw-r--r--demos/shared/arthurstyle.cpp452
-rw-r--r--demos/shared/arthurstyle.h79
-rw-r--r--demos/shared/arthurwidgets.cpp371
-rw-r--r--demos/shared/arthurwidgets.h118
-rw-r--r--demos/shared/hoverpoints.cpp333
-rw-r--r--demos/shared/hoverpoints.h160
-rw-r--r--demos/shared/images/bg_pattern.pngbin0 -> 104 bytes
-rw-r--r--demos/shared/images/button_normal_cap_left.pngbin0 -> 654 bytes
-rw-r--r--demos/shared/images/button_normal_cap_right.pngbin0 -> 674 bytes
-rw-r--r--demos/shared/images/button_normal_stretch.pngbin0 -> 185 bytes
-rw-r--r--demos/shared/images/button_pressed_cap_left.pngbin0 -> 710 bytes
-rw-r--r--demos/shared/images/button_pressed_cap_right.pngbin0 -> 785 bytes
-rw-r--r--demos/shared/images/button_pressed_stretch.pngbin0 -> 217 bytes
-rw-r--r--demos/shared/images/curve_thing_edit-6.pngbin0 -> 58097 bytes
-rw-r--r--demos/shared/images/frame_bottom.pngbin0 -> 166 bytes
-rw-r--r--demos/shared/images/frame_bottomleft.pngbin0 -> 602 bytes
-rw-r--r--demos/shared/images/frame_bottomright.pngbin0 -> 553 bytes
-rw-r--r--demos/shared/images/frame_left.pngbin0 -> 182 bytes
-rw-r--r--demos/shared/images/frame_right.pngbin0 -> 175 bytes
-rw-r--r--demos/shared/images/frame_top.pngbin0 -> 188 bytes
-rw-r--r--demos/shared/images/frame_topleft.pngbin0 -> 801 bytes
-rw-r--r--demos/shared/images/frame_topright.pngbin0 -> 851 bytes
-rw-r--r--demos/shared/images/groupframe_bottom_left.pngbin0 -> 397 bytes
-rw-r--r--demos/shared/images/groupframe_bottom_right.pngbin0 -> 383 bytes
-rw-r--r--demos/shared/images/groupframe_bottom_stretch.pngbin0 -> 141 bytes
-rw-r--r--demos/shared/images/groupframe_left_stretch.pngbin0 -> 132 bytes
-rw-r--r--demos/shared/images/groupframe_right_stretch.pngbin0 -> 113 bytes
-rw-r--r--demos/shared/images/groupframe_top_stretch.pngbin0 -> 115 bytes
-rw-r--r--demos/shared/images/groupframe_topleft.pngbin0 -> 412 bytes
-rw-r--r--demos/shared/images/groupframe_topright.pngbin0 -> 449 bytes
-rw-r--r--demos/shared/images/line_dash_dot.pngbin0 -> 151 bytes
-rw-r--r--demos/shared/images/line_dash_dot_dot.pngbin0 -> 155 bytes
-rw-r--r--demos/shared/images/line_dashed.pngbin0 -> 121 bytes
-rw-r--r--demos/shared/images/line_dotted.pngbin0 -> 116 bytes
-rw-r--r--demos/shared/images/line_solid.pngbin0 -> 110 bytes
-rw-r--r--demos/shared/images/radiobutton-off.pngbin0 -> 442 bytes
-rw-r--r--demos/shared/images/radiobutton-on.pngbin0 -> 474 bytes
-rw-r--r--demos/shared/images/radiobutton_off.pngbin0 -> 442 bytes
-rw-r--r--demos/shared/images/radiobutton_on.pngbin0 -> 499 bytes
-rw-r--r--demos/shared/images/slider_bar.pngbin0 -> 748 bytes
-rw-r--r--demos/shared/images/slider_thumb_off.pngbin0 -> 823 bytes
-rw-r--r--demos/shared/images/slider_thumb_on.pngbin0 -> 798 bytes
-rw-r--r--demos/shared/images/title_cap_left.pngbin0 -> 179 bytes
-rw-r--r--demos/shared/images/title_cap_right.pngbin0 -> 184 bytes
-rw-r--r--demos/shared/images/title_stretch.pngbin0 -> 106 bytes
-rw-r--r--demos/shared/shared.pri20
-rw-r--r--demos/shared/shared.pro33
-rw-r--r--demos/shared/shared.qrc39
48 files changed, 1605 insertions, 0 deletions
diff --git a/demos/shared/arthurstyle.cpp b/demos/shared/arthurstyle.cpp
new file mode 100644
index 0000000..846d2f3
--- /dev/null
+++ b/demos/shared/arthurstyle.cpp
@@ -0,0 +1,452 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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$
+**
+****************************************************************************/
+
+#include "arthurstyle.h"
+#include "arthurwidgets.h"
+#include <QLayout>
+#include <QPainter>
+#include <QPainterPath>
+#include <QPixmapCache>
+#include <QRadioButton>
+#include <QString>
+#include <QStyleOption>
+#include <QtDebug>
+
+QPixmap cached(const QString &img)
+{
+ if (QPixmap *p = QPixmapCache::find(img))
+ return *p;
+
+ QPixmap pm;
+ pm = QPixmap::fromImage(QImage(img), Qt::OrderedDither | Qt::OrderedAlphaDither);
+ if (pm.isNull())
+ return QPixmap();
+
+ QPixmapCache::insert(img, pm);
+ return pm;
+}
+
+
+ArthurStyle::ArthurStyle()
+ : QWindowsStyle()
+{
+ Q_INIT_RESOURCE(shared);
+}
+
+
+void ArthurStyle::drawHoverRect(QPainter *painter, const QRect &r) const
+{
+ qreal h = r.height();
+ qreal h2 = r.height() / qreal(2);
+ QPainterPath path;
+ 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(QColor(191, 215, 191));
+ painter->setRenderHint(QPainter::Antialiasing);
+ painter->drawPath(path);
+}
+
+
+void ArthurStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+
+ Q_ASSERT(option);
+ switch (element) {
+ case PE_FrameFocusRect:
+ break;
+
+ case PE_IndicatorRadioButton:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const 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 (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);
+
+ painter->save();
+ const QPushButton *pushButton = qobject_cast<const QPushButton *>(widget);
+ Q_ASSERT(pushButton);
+ QWidget *parent = pushButton->parentWidget();
+ if (parent && qobject_cast<QGroupBox *>(parent)) {
+ QLinearGradient lg(0, 0, 0, parent->height());
+ lg.setColorAt(0, QColor(224,224,224));
+ lg.setColorAt(1, QColor(255,255,255));
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(lg);
+ painter->setBrushOrigin(-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), QColor(31,127,31,63));
+ painter->restore();
+ }
+ break;
+
+ case PE_FrameGroupBox:
+ if (const QStyleOptionFrameV2 *group
+ = qstyleoption_cast<const QStyleOptionFrameV2 *>(option)) {
+ const QRect &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");
+ QLinearGradient lg(0, 0, 0, r.height());
+ lg.setColorAt(0, QColor(224,224,224));
+ lg.setColorAt(1, 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;
+}
+
+
+void ArthurStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ switch (control) {
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const 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 (const QStyleOptionGroupBox *groupBox
+ = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ QStyleOptionGroupBox groupBoxCopy(*groupBox);
+ groupBoxCopy.subControls &= ~SC_GroupBoxLabel;
+ QWindowsStyle::drawComplexControl(control, &groupBoxCopy, painter, widget);
+
+ if (groupBox->subControls & SC_GroupBoxLabel) {
+ const 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(QColor(0, 0, 0, opacity));
+ painter->drawText(tileRect.translated(0, 1),
+ Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
+ painter->drawText(tileRect.translated(2, 1),
+ Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
+ painter->setPen(QColor(0, 0, 0, opacity * 2));
+ painter->drawText(tileRect.translated(1, 1),
+ Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
+ painter->setPen(Qt::white);
+ painter->drawText(tileRect, Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
+ }
+ }
+ break;
+ default:
+ QWindowsStyle::drawComplexControl(control, option, painter, widget);
+ break;
+ }
+ return;
+}
+
+QRect ArthurStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ QRect rect;
+
+ switch (control) {
+ default:
+ rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+ break;
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *group
+ = qstyleoption_cast<const 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;
+}
+
+QSize ArthurStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const
+{
+ 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;
+}
+
+int ArthurStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWidget *widget) const
+{
+ if (pm == PM_SliderLength)
+ return 13;
+ return QWindowsStyle::pixelMetric(pm, opt, widget);
+}
+
+void ArthurStyle::polish(QWidget *widget)
+{
+ if (widget->layout() && qobject_cast<QGroupBox *>(widget)) {
+ if (qFindChildren<QGroupBox *>(widget).size() == 0) {
+ widget->layout()->setSpacing(0);
+ widget->layout()->setMargin(12);
+ } else {
+ widget->layout()->setMargin(13);
+ }
+ }
+
+ if (qobject_cast<QPushButton *>(widget)
+ || qobject_cast<QRadioButton *>(widget)
+ || qobject_cast<QSlider *>(widget)) {
+ widget->setAttribute(Qt::WA_Hover);
+ }
+
+ QPalette pal = widget->palette();
+ if (widget->isWindow()) {
+ pal.setColor(QPalette::Background, QColor(241, 241, 241));
+ widget->setPalette(pal);
+ }
+
+}
+
+void ArthurStyle::unpolish(QWidget *widget)
+{
+ if (qobject_cast<QPushButton *>(widget)
+ || qobject_cast<QRadioButton *>(widget)
+ || qobject_cast<QSlider *>(widget)) {
+ widget->setAttribute(Qt::WA_Hover, false);
+ }
+}
+
+void ArthurStyle::polish(QPalette &palette)
+{
+ palette.setColor(QPalette::Background, QColor(241, 241, 241));
+}
+
+QRect ArthurStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+ 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 (qobject_cast<const QRadioButton*>(widget))
+ r = r.adjusted(5, 0, -5, 0);
+
+ return r;
+}
diff --git a/demos/shared/arthurstyle.h b/demos/shared/arthurstyle.h
new file mode 100644
index 0000000..ec79361
--- /dev/null
+++ b/demos/shared/arthurstyle.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef ARTHURSTYLE_H
+#define ARTHURSTYLE_H
+
+#include <QWindowsStyle>
+
+QT_USE_NAMESPACE
+
+class ArthurStyle : public QWindowsStyle
+{
+public:
+ ArthurStyle();
+
+ void drawHoverRect(QPainter *painter, const QRect &rect) const;
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+// void drawControl(ControlElement element, const QStyleOption *option,
+// QPainter *painter, const QWidget *widget) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+// SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+// const QPoint &pos, const QWidget *widget = 0) const;
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const;
+
+ void polish(QPalette &palette);
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+};
+
+#endif
diff --git a/demos/shared/arthurwidgets.cpp b/demos/shared/arthurwidgets.cpp
new file mode 100644
index 0000000..f9eed99
--- /dev/null
+++ b/demos/shared/arthurwidgets.cpp
@@ -0,0 +1,371 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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$
+**
+****************************************************************************/
+
+#include "arthurwidgets.h"
+#include <QApplication>
+#include <QPainter>
+#include <QPainterPath>
+#include <QPixmapCache>
+#include <QtEvents>
+#include <QTextDocument>
+#include <QAbstractTextDocumentLayout>
+#include <QFile>
+#include <QTextBrowser>
+#include <QBoxLayout>
+
+#include <private/qpixmapdata_p.h>
+
+extern QPixmap cached(const QString &img);
+
+ArthurFrame::ArthurFrame(QWidget *parent)
+ : QWidget(parent)
+ , m_prefer_image(false)
+{
+#ifdef QT_OPENGL_SUPPORT
+ glw = 0;
+ m_use_opengl = false;
+ QGLFormat f = QGLFormat::defaultFormat();
+ f.setSampleBuffers(true);
+ f.setStencil(true);
+ f.setAlpha(true);
+ f.setAlphaBufferSize(8);
+ QGLFormat::setDefaultFormat(f);
+#endif
+ m_document = 0;
+ m_show_doc = false;
+
+ m_tile = QPixmap(128, 128);
+ m_tile.fill(Qt::white);
+ QPainter pt(&m_tile);
+ QColor color(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);
+
+#ifdef Q_WS_X11
+ QPixmap xRenderPixmap(1, 1);
+ m_prefer_image = xRenderPixmap.pixmapData()->classId() == QPixmapData::X11Class && !xRenderPixmap.x11PictureHandle();
+#endif
+}
+
+
+#ifdef QT_OPENGL_SUPPORT
+void ArthurFrame::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();
+}
+#endif
+
+void ArthurFrame::paintEvent(QPaintEvent *e)
+{
+#ifdef Q_WS_QWS
+ static QPixmap *static_image = 0;
+#else
+ static QImage *static_image = 0;
+#endif
+ QPainter painter;
+ if (preferImage()
+#ifdef QT_OPENGL_SUPPORT
+ && !m_use_opengl
+#endif
+ ) {
+ if (!static_image || static_image->size() != size()) {
+ delete static_image;
+#ifdef Q_WS_QWS
+ static_image = new QPixmap(size());
+#else
+ static_image = new QImage(size(), QImage::Format_RGB32);
+#endif
+ }
+ painter.begin(static_image);
+
+ int o = 10;
+
+ QBrush bg = palette().brush(QPalette::Background);
+ 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 {
+#ifdef QT_OPENGL_SUPPORT
+ if (m_use_opengl) {
+ painter.begin(glw);
+ painter.fillRect(QRectF(0, 0, glw->width(), glw->height()), palette().color(backgroundRole()));
+ } else {
+ painter.begin(this);
+ }
+#else
+ painter.begin(this);
+#endif
+ }
+
+ painter.setClipRect(e->rect());
+
+ painter.setRenderHint(QPainter::Antialiasing);
+
+ QPainterPath clipPath;
+
+ 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(QPen(QColor(level, level, level), 2));
+ painter.setBrush(Qt::NoBrush);
+ painter.drawPath(clipPath);
+
+ if (preferImage()
+#ifdef QT_OPENGL_SUPPORT
+ && !m_use_opengl
+#endif
+ ) {
+ painter.end();
+ painter.begin(this);
+#ifdef Q_WS_QWS
+ painter.drawPixmap(e->rect(), *static_image, e->rect());
+#else
+ painter.drawImage(e->rect(), *static_image, e->rect());
+#endif
+ }
+
+#ifdef QT_OPENGL_SUPPORT
+ if (m_use_opengl && (inherits("PathDeformRenderer") || inherits("PathStrokeRenderer") || inherits("CompositionRenderer") || m_show_doc))
+ glw->swapBuffers();
+#endif
+}
+
+void ArthurFrame::resizeEvent(QResizeEvent *e)
+{
+#ifdef QT_OPENGL_SUPPORT
+ if (glw)
+ glw->setGeometry(0, 0, e->size().width()-1, e->size().height()-1);
+#endif
+ QWidget::resizeEvent(e);
+}
+
+void ArthurFrame::setDescriptionEnabled(bool enabled)
+{
+ if (m_show_doc != enabled) {
+ m_show_doc = enabled;
+ emit descriptionEnabledChanged(m_show_doc);
+ update();
+ }
+}
+
+void ArthurFrame::loadDescription(const QString &fileName)
+{
+ QFile textFile(fileName);
+ QString text;
+ if (!textFile.open(QFile::ReadOnly))
+ text = QString("Unable to load resource file: '%1'").arg(fileName);
+ else
+ text = textFile.readAll();
+ setDescription(text);
+}
+
+
+void ArthurFrame::setDescription(const QString &text)
+{
+ m_document = new QTextDocument(this);
+ m_document->setHtml(text);
+}
+
+void ArthurFrame::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(QSize(pageWidth, pageHeight));
+ }
+
+ QRect textRect(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(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(QColor(255, 255, 255, 220));
+ painter->setPen(Qt::black);
+ painter->drawRect(clearRect);
+
+ painter->setClipRegion(textRect, Qt::IntersectClip);
+ painter->translate(textRect.topLeft());
+
+ QAbstractTextDocumentLayout::PaintContext ctx;
+
+ QLinearGradient g(0, 0, 0, textRect.height());
+ g.setColorAt(0, Qt::black);
+ g.setColorAt(0.9, Qt::black);
+ g.setColorAt(1, Qt::transparent);
+
+ QPalette pal = palette();
+ pal.setBrush(QPalette::Text, g);
+
+ ctx.palette = pal;
+ ctx.clip = QRect(0, 0, textRect.width(), textRect.height());
+ m_document->documentLayout()->draw(painter, ctx);
+}
+
+void ArthurFrame::loadSourceFile(const QString &sourceFile)
+{
+ m_sourceFileName = sourceFile;
+}
+
+void ArthurFrame::showSource()
+{
+ // Check for existing source
+ if (qFindChild<QTextBrowser *>(this))
+ return;
+
+ QString contents;
+ if (m_sourceFileName.isEmpty()) {
+ contents = QString("No source for widget: '%1'").arg(objectName());
+ } else {
+ QFile f(m_sourceFileName);
+ if (!f.open(QFile::ReadOnly))
+ contents = QString("Could not open file: '%1'").arg(m_sourceFileName);
+ else
+ contents = f.readAll();
+ }
+
+ contents.replace('&', "&amp;");
+ contents.replace('<', "&lt;");
+ contents.replace('>', "&gt;");
+
+ QStringList keywords;
+ keywords << "for " << "if " << "switch " << " int " << "#include " << "const"
+ << "void " << "uint " << "case " << "double " << "#define " << "static"
+ << "new" << "this";
+
+ foreach (QString keyword, keywords)
+ contents.replace(keyword, QLatin1String("<font color=olive>") + keyword + QLatin1String("</font>"));
+ contents.replace("(int ", "(<font color=olive><b>int </b></font>");
+
+ QStringList ppKeywords;
+ ppKeywords << "#ifdef" << "#ifndef" << "#if" << "#endif" << "#else";
+
+ foreach (QString keyword, ppKeywords)
+ contents.replace(keyword, QLatin1String("<font color=navy>") + keyword + QLatin1String("</font>"));
+
+ contents.replace(QRegExp("(\\d\\d?)"), QLatin1String("<font color=navy>\\1</font>"));
+
+ QRegExp commentRe("(//.+)\\n");
+ commentRe.setMinimal(true);
+ contents.replace(commentRe, QLatin1String("<font color=red>\\1</font>\n"));
+
+ QRegExp stringLiteralRe("(\".+\")");
+ stringLiteralRe.setMinimal(true);
+ contents.replace(stringLiteralRe, QLatin1String("<font color=green>\\1</font>"));
+
+ QString html = contents;
+ html.prepend("<html><pre>");
+ html.append("</pre></html>");
+
+ QTextBrowser *sourceViewer = new QTextBrowser(0);
+ sourceViewer->setWindowTitle("Source: " + m_sourceFileName.mid(5));
+ sourceViewer->setParent(this, Qt::Dialog);
+ sourceViewer->setAttribute(Qt::WA_DeleteOnClose);
+ sourceViewer->setLineWrapMode(QTextEdit::NoWrap);
+ sourceViewer->setHtml(html);
+ sourceViewer->resize(600, 600);
+ sourceViewer->show();
+}
diff --git a/demos/shared/arthurwidgets.h b/demos/shared/arthurwidgets.h
new file mode 100644
index 0000000..4d55b61
--- /dev/null
+++ b/demos/shared/arthurwidgets.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef ARTHURWIDGETS_H
+#define ARTHURWIDGETS_H
+
+#include "arthurstyle.h"
+#include <QBitmap>
+#include <QPushButton>
+#include <QGroupBox>
+
+#if defined(QT_OPENGL_SUPPORT)
+#include <QGLWidget>
+class GLWidget : public QGLWidget
+{
+public:
+ GLWidget(QWidget *parent)
+ : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) {}
+ void disableAutoBufferSwap() { setAutoBufferSwap(false); }
+ void paintEvent(QPaintEvent *) { parentWidget()->update(); }
+};
+#endif
+
+QT_FORWARD_DECLARE_CLASS(QTextDocument)
+QT_FORWARD_DECLARE_CLASS(QTextEdit)
+QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
+
+class ArthurFrame : public QWidget
+{
+ Q_OBJECT
+public:
+ ArthurFrame(QWidget *parent);
+ virtual void paint(QPainter *) {}
+
+
+ void paintDescription(QPainter *p);
+
+ void loadDescription(const QString &filename);
+ void setDescription(const QString &htmlDesc);
+
+ void loadSourceFile(const QString &fileName);
+
+ bool preferImage() const { return m_prefer_image; }
+
+#if defined(QT_OPENGL_SUPPORT)
+ QGLWidget *glWidget() const { return glw; }
+#endif
+
+public slots:
+ void setPreferImage(bool pi) { m_prefer_image = pi; }
+ void setDescriptionEnabled(bool enabled);
+ void showSource();
+
+#if defined(QT_OPENGL_SUPPORT)
+ void enableOpenGL(bool use_opengl);
+ bool usesOpenGL() { return m_use_opengl; }
+#endif
+
+signals:
+ void descriptionEnabledChanged(bool);
+
+protected:
+ void paintEvent(QPaintEvent *);
+ void resizeEvent(QResizeEvent *);
+
+#if defined(QT_OPENGL_SUPPORT)
+ GLWidget *glw;
+ bool m_use_opengl;
+#endif
+ QPixmap m_tile;
+
+ bool m_show_doc;
+ bool m_prefer_image;
+ QTextDocument *m_document;
+
+ QString m_sourceFileName;
+
+};
+
+#endif
diff --git a/demos/shared/hoverpoints.cpp b/demos/shared/hoverpoints.cpp
new file mode 100644
index 0000000..70062f6
--- /dev/null
+++ b/demos/shared/hoverpoints.cpp
@@ -0,0 +1,333 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifdef QT_OPENGL_SUPPORT
+#include <QGLWidget>
+#endif
+
+#include "arthurwidgets.h"
+#include "hoverpoints.h"
+
+#define printf
+
+HoverPoints::HoverPoints(QWidget *widget, PointShape shape)
+ : QObject(widget)
+{
+ m_widget = widget;
+ widget->installEventFilter(this);
+
+ m_connectionType = CurveConnection;
+ m_sortType = NoSort;
+ m_shape = shape;
+ m_pointPen = QPen(QColor(255, 255, 255, 191), 1);
+ m_connectionPen = QPen(QColor(255, 255, 255, 127), 2);
+ m_pointBrush = QBrush(QColor(191, 191, 191, 127));
+ m_pointSize = QSize(11, 11);
+ m_currentIndex = -1;
+ m_editable = true;
+ m_enabled = true;
+
+ connect(this, SIGNAL(pointsChanged(const QPolygonF &)),
+ m_widget, SLOT(update()));
+}
+
+
+void HoverPoints::setEnabled(bool enabled)
+{
+ if (m_enabled != enabled) {
+ m_enabled = enabled;
+ m_widget->update();
+ }
+}
+
+
+bool HoverPoints::eventFilter(QObject *object, QEvent *event)
+{
+ if (object == m_widget && m_enabled) {
+ switch (event->type()) {
+
+ case QEvent::MouseButtonPress:
+ {
+ QMouseEvent *me = (QMouseEvent *) event;
+
+ QPointF clickPos = me->pos();
+ int index = -1;
+ for (int i=0; i<m_points.size(); ++i) {
+ QPainterPath path;
+ if (m_shape == 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 == 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 == YSort) {
+ for (int i=0; i<m_points.size(); ++i)
+ if (m_points.at(i).y() > clickPos.y()) {
+ pos = i;
+ break;
+ }
+ }
+
+ m_points.insert(pos, clickPos);
+ m_locks.insert(pos, 0);
+ 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.remove(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, ((QMouseEvent *)event)->pos());
+ break;
+
+ case QEvent::Resize:
+ {
+ QResizeEvent *e = (QResizeEvent *) event;
+ if (e->oldSize().width() == 0 || e->oldSize().height() == 0)
+ break;
+ qreal stretch_x = e->size().width() / qreal(e->oldSize().width());
+ qreal stretch_y = e->size().height() / qreal(e->oldSize().height());
+ for (int i=0; i<m_points.size(); ++i) {
+ QPointF p = m_points[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 = 0;
+ QApplication::sendEvent(object, event);
+ m_widget = that_widget;
+ paintPoints();
+#ifdef QT_OPENGL_SUPPORT
+ ArthurFrame *af = qobject_cast<ArthurFrame *>(that_widget);
+ if (af && af->usesOpenGL())
+ af->glWidget()->swapBuffers();
+#endif
+ return true;
+ }
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
+
+void HoverPoints::paintPoints()
+{
+ QPainter p;
+#ifdef QT_OPENGL_SUPPORT
+ ArthurFrame *af = qobject_cast<ArthurFrame *>(m_widget);
+ if (af && af->usesOpenGL())
+ p.begin(af->glWidget());
+ else
+ p.begin(m_widget);
+#else
+ p.begin(m_widget);
+#endif
+
+ p.setRenderHint(QPainter::Antialiasing);
+
+ if (m_connectionPen.style() != Qt::NoPen && m_connectionType != NoConnection) {
+ p.setPen(m_connectionPen);
+
+ if (m_connectionType == CurveConnection) {
+ QPainterPath path;
+ 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 == CircleShape)
+ p.drawEllipse(bounds);
+ else
+ p.drawRect(bounds);
+ }
+}
+
+static QPointF bound_point(const QPointF &point, const 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::LockToLeft)) p.setX(left);
+ else if (p.x() > right || (lock & HoverPoints::LockToRight)) p.setX(right);
+
+ if (p.y() < top || (lock & HoverPoints::LockToTop)) p.setY(top);
+ else if (p.y() > bottom || (lock & HoverPoints::LockToBottom)) p.setY(bottom);
+
+ return p;
+}
+
+void HoverPoints::setPoints(const QPolygonF &points)
+{
+ m_points.clear();
+ for (int i=0; i<points.size(); ++i)
+ m_points << bound_point(points.at(i), boundingRect(), 0);
+
+ m_locks.clear();
+ if (m_points.size() > 0) {
+ m_locks.resize(m_points.size());
+
+ m_locks.fill(0);
+ }
+}
+
+
+void HoverPoints::movePoint(int index, const QPointF &point, bool emitUpdate)
+{
+ m_points[index] = bound_point(point, boundingRect(), m_locks.at(index));
+ if (emitUpdate)
+ firePointChange();
+}
+
+
+inline static bool x_less_than(const QPointF &p1, const QPointF &p2)
+{
+ return p1.x() < p2.x();
+}
+
+
+inline static bool y_less_than(const QPointF &p1, const QPointF &p2)
+{
+ return p1.y() < p2.y();
+}
+
+void HoverPoints::firePointChange()
+{
+// printf("HoverPoints::firePointChange(), current=%d\n", m_currentIndex);
+
+ if (m_sortType != NoSort) {
+
+ QPointF oldCurrent;
+ if (m_currentIndex != -1) {
+ oldCurrent = m_points[m_currentIndex];
+ }
+
+ if (m_sortType == XSort)
+ qSort(m_points.begin(), m_points.end(), x_less_than);
+ else if (m_sortType == YSort)
+ qSort(m_points.begin(), m_points.end(), y_less_than);
+
+ // Compensate for changed order...
+ if (m_currentIndex != -1) {
+ for (int i=0; i<m_points.size(); ++i) {
+ if (m_points[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));
+// }
+
+ emit pointsChanged(m_points);
+}
diff --git a/demos/shared/hoverpoints.h b/demos/shared/hoverpoints.h
new file mode 100644
index 0000000..cf8742d
--- /dev/null
+++ b/demos/shared/hoverpoints.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef HOVERPOINTS_H
+#define HOVERPOINTS_H
+
+#include <QtGui>
+
+QT_FORWARD_DECLARE_CLASS(QBypassWidget)
+
+class HoverPoints : public QObject
+{
+ Q_OBJECT
+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
+ };
+
+ HoverPoints(QWidget *widget, PointShape shape);
+
+ bool eventFilter(QObject *object, QEvent *event);
+
+ void paintPoints();
+
+ inline QRectF boundingRect() const;
+ void setBoundingRect(const QRectF &boundingRect) { m_bounds = boundingRect; }
+
+ QPolygonF points() const { return m_points; }
+ void setPoints(const QPolygonF &points);
+
+ QSizeF pointSize() const { return m_pointSize; }
+ void setPointSize(const QSizeF &size) { m_pointSize = size; }
+
+ SortType sortType() const { return m_sortType; }
+ void setSortType(SortType sortType) { m_sortType = sortType; }
+
+ ConnectionType connectionType() const { return m_connectionType; }
+ void setConnectionType(ConnectionType connectionType) { m_connectionType = connectionType; }
+
+ void setConnectionPen(const QPen &pen) { m_connectionPen = pen; }
+ void setShapePen(const QPen &pen) { m_pointPen = pen; }
+ void setShapeBrush(const QBrush &brush) { m_pointBrush = brush; }
+
+ void setPointLock(int pos, LockType lock) { m_locks[pos] = lock; }
+
+ void setEditable(bool editable) { m_editable = editable; }
+ bool editable() const { return m_editable; }
+
+public slots:
+ void setEnabled(bool enabled);
+ void setDisabled(bool disabled) { setEnabled(!disabled); }
+
+signals:
+ void pointsChanged(const QPolygonF &points);
+
+public:
+ void firePointChange();
+
+private:
+ inline QRectF pointBoundingRect(int i) const;
+ void movePoint(int i, const QPointF &newPos, bool emitChange = true);
+
+ QWidget *m_widget;
+
+ QPolygonF m_points;
+ QRectF m_bounds;
+ PointShape m_shape;
+ SortType m_sortType;
+ ConnectionType m_connectionType;
+
+ QVector<uint> m_locks;
+
+ QSizeF m_pointSize;
+ int m_currentIndex;
+ bool m_editable;
+ bool m_enabled;
+
+ QPen m_pointPen;
+ QBrush m_pointBrush;
+ QPen m_connectionPen;
+};
+
+
+inline QRectF HoverPoints::pointBoundingRect(int i) const
+{
+ 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 QRectF(x, y, w, h);
+}
+
+inline QRectF HoverPoints::boundingRect() const
+{
+ if (m_bounds.isEmpty())
+ return m_widget->rect();
+ else
+ return m_bounds;
+}
+
+#endif // HOVERPOINTS_H
diff --git a/demos/shared/images/bg_pattern.png b/demos/shared/images/bg_pattern.png
new file mode 100644
index 0000000..ee67026
--- /dev/null
+++ b/demos/shared/images/bg_pattern.png
Binary files differ
diff --git a/demos/shared/images/button_normal_cap_left.png b/demos/shared/images/button_normal_cap_left.png
new file mode 100644
index 0000000..db31dd9
--- /dev/null
+++ b/demos/shared/images/button_normal_cap_left.png
Binary files differ
diff --git a/demos/shared/images/button_normal_cap_right.png b/demos/shared/images/button_normal_cap_right.png
new file mode 100644
index 0000000..38ead1c
--- /dev/null
+++ b/demos/shared/images/button_normal_cap_right.png
Binary files differ
diff --git a/demos/shared/images/button_normal_stretch.png b/demos/shared/images/button_normal_stretch.png
new file mode 100644
index 0000000..87abe67
--- /dev/null
+++ b/demos/shared/images/button_normal_stretch.png
Binary files differ
diff --git a/demos/shared/images/button_pressed_cap_left.png b/demos/shared/images/button_pressed_cap_left.png
new file mode 100644
index 0000000..66bfc13
--- /dev/null
+++ b/demos/shared/images/button_pressed_cap_left.png
Binary files differ
diff --git a/demos/shared/images/button_pressed_cap_right.png b/demos/shared/images/button_pressed_cap_right.png
new file mode 100644
index 0000000..3d4cfe2
--- /dev/null
+++ b/demos/shared/images/button_pressed_cap_right.png
Binary files differ
diff --git a/demos/shared/images/button_pressed_stretch.png b/demos/shared/images/button_pressed_stretch.png
new file mode 100644
index 0000000..4dd4ad1
--- /dev/null
+++ b/demos/shared/images/button_pressed_stretch.png
Binary files differ
diff --git a/demos/shared/images/curve_thing_edit-6.png b/demos/shared/images/curve_thing_edit-6.png
new file mode 100644
index 0000000..034b474
--- /dev/null
+++ b/demos/shared/images/curve_thing_edit-6.png
Binary files differ
diff --git a/demos/shared/images/frame_bottom.png b/demos/shared/images/frame_bottom.png
new file mode 100644
index 0000000..889b40d
--- /dev/null
+++ b/demos/shared/images/frame_bottom.png
Binary files differ
diff --git a/demos/shared/images/frame_bottomleft.png b/demos/shared/images/frame_bottomleft.png
new file mode 100644
index 0000000..0b3023f
--- /dev/null
+++ b/demos/shared/images/frame_bottomleft.png
Binary files differ
diff --git a/demos/shared/images/frame_bottomright.png b/demos/shared/images/frame_bottomright.png
new file mode 100644
index 0000000..0021e35
--- /dev/null
+++ b/demos/shared/images/frame_bottomright.png
Binary files differ
diff --git a/demos/shared/images/frame_left.png b/demos/shared/images/frame_left.png
new file mode 100644
index 0000000..40f331c
--- /dev/null
+++ b/demos/shared/images/frame_left.png
Binary files differ
diff --git a/demos/shared/images/frame_right.png b/demos/shared/images/frame_right.png
new file mode 100644
index 0000000..023af8c
--- /dev/null
+++ b/demos/shared/images/frame_right.png
Binary files differ
diff --git a/demos/shared/images/frame_top.png b/demos/shared/images/frame_top.png
new file mode 100644
index 0000000..001f3a7
--- /dev/null
+++ b/demos/shared/images/frame_top.png
Binary files differ
diff --git a/demos/shared/images/frame_topleft.png b/demos/shared/images/frame_topleft.png
new file mode 100644
index 0000000..58c68d4
--- /dev/null
+++ b/demos/shared/images/frame_topleft.png
Binary files differ
diff --git a/demos/shared/images/frame_topright.png b/demos/shared/images/frame_topright.png
new file mode 100644
index 0000000..6a7e8d3
--- /dev/null
+++ b/demos/shared/images/frame_topright.png
Binary files differ
diff --git a/demos/shared/images/groupframe_bottom_left.png b/demos/shared/images/groupframe_bottom_left.png
new file mode 100644
index 0000000..af2fe06
--- /dev/null
+++ b/demos/shared/images/groupframe_bottom_left.png
Binary files differ
diff --git a/demos/shared/images/groupframe_bottom_right.png b/demos/shared/images/groupframe_bottom_right.png
new file mode 100644
index 0000000..fdf2e97
--- /dev/null
+++ b/demos/shared/images/groupframe_bottom_right.png
Binary files differ
diff --git a/demos/shared/images/groupframe_bottom_stretch.png b/demos/shared/images/groupframe_bottom_stretch.png
new file mode 100644
index 0000000..f47b67d
--- /dev/null
+++ b/demos/shared/images/groupframe_bottom_stretch.png
Binary files differ
diff --git a/demos/shared/images/groupframe_left_stretch.png b/demos/shared/images/groupframe_left_stretch.png
new file mode 100644
index 0000000..c122f46
--- /dev/null
+++ b/demos/shared/images/groupframe_left_stretch.png
Binary files differ
diff --git a/demos/shared/images/groupframe_right_stretch.png b/demos/shared/images/groupframe_right_stretch.png
new file mode 100644
index 0000000..1056b78
--- /dev/null
+++ b/demos/shared/images/groupframe_right_stretch.png
Binary files differ
diff --git a/demos/shared/images/groupframe_top_stretch.png b/demos/shared/images/groupframe_top_stretch.png
new file mode 100644
index 0000000..5746ef9
--- /dev/null
+++ b/demos/shared/images/groupframe_top_stretch.png
Binary files differ
diff --git a/demos/shared/images/groupframe_topleft.png b/demos/shared/images/groupframe_topleft.png
new file mode 100644
index 0000000..98d9cd9
--- /dev/null
+++ b/demos/shared/images/groupframe_topleft.png
Binary files differ
diff --git a/demos/shared/images/groupframe_topright.png b/demos/shared/images/groupframe_topright.png
new file mode 100644
index 0000000..1a0a328
--- /dev/null
+++ b/demos/shared/images/groupframe_topright.png
Binary files differ
diff --git a/demos/shared/images/line_dash_dot.png b/demos/shared/images/line_dash_dot.png
new file mode 100644
index 0000000..1c61442
--- /dev/null
+++ b/demos/shared/images/line_dash_dot.png
Binary files differ
diff --git a/demos/shared/images/line_dash_dot_dot.png b/demos/shared/images/line_dash_dot_dot.png
new file mode 100644
index 0000000..0d9bb97
--- /dev/null
+++ b/demos/shared/images/line_dash_dot_dot.png
Binary files differ
diff --git a/demos/shared/images/line_dashed.png b/demos/shared/images/line_dashed.png
new file mode 100644
index 0000000..d5bc7ea
--- /dev/null
+++ b/demos/shared/images/line_dashed.png
Binary files differ
diff --git a/demos/shared/images/line_dotted.png b/demos/shared/images/line_dotted.png
new file mode 100644
index 0000000..a2f9a35
--- /dev/null
+++ b/demos/shared/images/line_dotted.png
Binary files differ
diff --git a/demos/shared/images/line_solid.png b/demos/shared/images/line_solid.png
new file mode 100644
index 0000000..60ef3f9
--- /dev/null
+++ b/demos/shared/images/line_solid.png
Binary files differ
diff --git a/demos/shared/images/radiobutton-off.png b/demos/shared/images/radiobutton-off.png
new file mode 100644
index 0000000..af1753a
--- /dev/null
+++ b/demos/shared/images/radiobutton-off.png
Binary files differ
diff --git a/demos/shared/images/radiobutton-on.png b/demos/shared/images/radiobutton-on.png
new file mode 100644
index 0000000..f875838
--- /dev/null
+++ b/demos/shared/images/radiobutton-on.png
Binary files differ
diff --git a/demos/shared/images/radiobutton_off.png b/demos/shared/images/radiobutton_off.png
new file mode 100644
index 0000000..400906e
--- /dev/null
+++ b/demos/shared/images/radiobutton_off.png
Binary files differ
diff --git a/demos/shared/images/radiobutton_on.png b/demos/shared/images/radiobutton_on.png
new file mode 100644
index 0000000..50a049e
--- /dev/null
+++ b/demos/shared/images/radiobutton_on.png
Binary files differ
diff --git a/demos/shared/images/slider_bar.png b/demos/shared/images/slider_bar.png
new file mode 100644
index 0000000..1b3d62c
--- /dev/null
+++ b/demos/shared/images/slider_bar.png
Binary files differ
diff --git a/demos/shared/images/slider_thumb_off.png b/demos/shared/images/slider_thumb_off.png
new file mode 100644
index 0000000..d7f141d
--- /dev/null
+++ b/demos/shared/images/slider_thumb_off.png
Binary files differ
diff --git a/demos/shared/images/slider_thumb_on.png b/demos/shared/images/slider_thumb_on.png
new file mode 100644
index 0000000..8e1f510
--- /dev/null
+++ b/demos/shared/images/slider_thumb_on.png
Binary files differ
diff --git a/demos/shared/images/title_cap_left.png b/demos/shared/images/title_cap_left.png
new file mode 100644
index 0000000..2d47507
--- /dev/null
+++ b/demos/shared/images/title_cap_left.png
Binary files differ
diff --git a/demos/shared/images/title_cap_right.png b/demos/shared/images/title_cap_right.png
new file mode 100644
index 0000000..dc3ff85
--- /dev/null
+++ b/demos/shared/images/title_cap_right.png
Binary files differ
diff --git a/demos/shared/images/title_stretch.png b/demos/shared/images/title_stretch.png
new file mode 100644
index 0000000..1104334
--- /dev/null
+++ b/demos/shared/images/title_stretch.png
Binary files differ
diff --git a/demos/shared/shared.pri b/demos/shared/shared.pri
new file mode 100644
index 0000000..b551595
--- /dev/null
+++ b/demos/shared/shared.pri
@@ -0,0 +1,20 @@
+INCLUDEPATH += $$SHARED_FOLDER
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+contains(CONFIG, debug_and_release_target) {
+ CONFIG(debug, debug|release) {
+ LIBS+=-L$$SHARED_FOLDER/debug
+ } else {
+ LIBS+=-L$$SHARED_FOLDER/release
+ }
+} else {
+ LIBS += -L$$SHARED_FOLDER
+}
+
+hpux-acc*:LIBS += $$SHARED_FOLDER/libdemo_shared.a
+hpuxi-acc*:LIBS += $$SHARED_FOLDER/libdemo_shared.a
+!hpuxi-acc*:!hpux-acc*:LIBS += -ldemo_shared
+
diff --git a/demos/shared/shared.pro b/demos/shared/shared.pro
new file mode 100644
index 0000000..cabce25
--- /dev/null
+++ b/demos/shared/shared.pro
@@ -0,0 +1,33 @@
+TEMPLATE = lib
+CONFIG += static
+
+contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2) {
+ DEFINES += QT_OPENGL_SUPPORT
+ QT += opengl
+}
+
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+TARGET = demo_shared
+
+SOURCES += \
+ arthurstyle.cpp\
+ arthurwidgets.cpp \
+ hoverpoints.cpp
+
+HEADERS += \
+ arthurstyle.h \
+ arthurwidgets.h \
+ hoverpoints.h
+
+RESOURCES += shared.qrc
+
+# install
+target.path = $$[QT_INSTALL_DEMOS]/shared
+sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.pri images
+sources.path = $$[QT_INSTALL_DEMOS]/shared
+INSTALLS += sources
+!cross_compile:INSTALLS += target
+
diff --git a/demos/shared/shared.qrc b/demos/shared/shared.qrc
new file mode 100644
index 0000000..17336ec
--- /dev/null
+++ b/demos/shared/shared.qrc
@@ -0,0 +1,39 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/res">
+ <file>images/button_normal_cap_left.png</file>
+ <file>images/button_normal_cap_right.png</file>
+ <file>images/button_normal_stretch.png</file>
+ <file>images/button_pressed_cap_left.png</file>
+ <file>images/button_pressed_cap_right.png</file>
+ <file>images/button_pressed_stretch.png</file>
+ <file>images/radiobutton-on.png</file>
+ <file>images/radiobutton_on.png</file>
+ <file>images/radiobutton_off.png</file>
+ <file>images/slider_bar.png</file>
+ <file>images/slider_thumb_on.png</file>
+ <file>images/groupframe_topleft.png</file>
+ <file>images/groupframe_topright.png</file>
+ <file>images/groupframe_bottom_left.png</file>
+ <file>images/groupframe_bottom_right.png</file>
+ <file>images/groupframe_top_stretch.png</file>
+ <file>images/groupframe_bottom_stretch.png</file>
+ <file>images/groupframe_left_stretch.png</file>
+ <file>images/groupframe_right_stretch.png</file>
+ <file>images/frame_topleft.png</file>
+ <file>images/frame_topright.png</file>
+ <file>images/frame_bottomleft.png</file>
+ <file>images/frame_bottomright.png</file>
+ <file>images/frame_left.png</file>
+ <file>images/frame_top.png</file>
+ <file>images/frame_right.png</file>
+ <file>images/frame_bottom.png</file>
+ <file>images/title_cap_left.png</file>
+ <file>images/title_cap_right.png</file>
+ <file>images/title_stretch.png</file>
+ <file>images/line_dash_dot.png</file>
+ <file>images/line_dotted.png</file>
+ <file>images/line_dashed.png</file>
+ <file>images/line_solid.png</file>
+ <file>images/line_dash_dot_dot.png</file>
+</qresource>
+</RCC>