diff options
Diffstat (limited to 'src/gui')
27 files changed, 555 insertions, 293 deletions
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index 297c900..eb5fed0 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -3022,6 +3022,12 @@ bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) { case Qt::Key_Escape: q->hide(); return true; +#ifdef QT_KEYPAD_NAVIGATION + case Qt::Key_Down: + case Qt::Key_Up: + return (QApplication::navigationMode() != Qt::NavigationModeKeypadTabOrder + && QApplication::navigationMode() != Qt::NavigationModeKeypadDirectional); +#endif default: break; } @@ -3142,7 +3148,17 @@ void QFileDialogListView::keyPressEvent(QKeyEvent *e) if (!d_ptr->itemViewKeyboardEvent(e)) { QListView::keyPressEvent(e); } +#ifdef QT_KEYPAD_NAVIGATION + if ((QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder + || QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) + && !hasEditFocus()) { + e->ignore(); + } else { + e->accept(); + } +#else e->accept(); +#endif } QFileDialogTreeView::QFileDialogTreeView(QWidget *parent) : QTreeView(parent) @@ -3189,7 +3205,11 @@ void QFileDialogLineEdit::keyPressEvent(QKeyEvent *e) { int key = e->key(); QLineEdit::keyPressEvent(e); - if (key != Qt::Key_Escape) + if (key != Qt::Key_Escape +#ifdef QT_KEYPAD_NAVIGATION + && QApplication::navigationMode() == Qt::NavigationModeNone +#endif + ) e->accept(); if (hideOnEsc && (key == Qt::Key_Escape || key == Qt::Key_Return || key == Qt::Key_Enter)) { e->accept(); diff --git a/src/gui/embedded/qvfbhdr.h b/src/gui/embedded/qvfbhdr.h index f02286e..eff5fc2 100644 --- a/src/gui/embedded/qvfbhdr.h +++ b/src/gui/embedded/qvfbhdr.h @@ -56,6 +56,7 @@ QT_MODULE(Gui) #define QT_QWS_TEMP_DIR "/tmp" #endif +#ifdef QT_PRIVATE_QWS #define QT_VFB_DATADIR(DISPLAY) QString("%1/qtembedded-%2-%3") \ .arg(QT_QWS_TEMP_DIR).arg(getuid()).arg(DISPLAY) @@ -67,7 +68,22 @@ QT_MODULE(Gui) .append("/qtvfb_map") #define QT_VFB_SOUND_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \ .append("/qt_soundserver") -#define QTE_PIPE "QtEmbedded" +#define QTE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \ + .append("/QtEmbedded") +#define QTE_PIPE_QVFB QTE_PIPE +#else +#define QT_VFB_DATADIR(DISPLAY) QString("%1/qtembedded-%2") \ + .arg(QT_QWS_TEMP_DIR).arg(DISPLAY) +#define QT_VFB_MOUSE_PIPE(DISPLAY) QString("/tmp/.qtvfb_mouse-%1").arg(DISPLAY) +#define QT_VFB_KEYBOARD_PIPE(DISPLAY) QString("/tmp/.qtvfb_keyboard-%1").arg(DISPLAY) +#define QT_VFB_MAP(DISPLAY) QString("/tmp/.qtvfb_map-%1").arg(DISPLAY) +#define QT_VFB_SOUND_PIPE(DISPLAY) QString("/tmp/.qt_soundserver-%1").arg(DISPLAY) +#define QTE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \ + .append("/QtEmbedded-%1") \ + .arg(DISPLAY) +#define QTE_PIPE_QVFB(DISPLAY) QString("/tmp/qtembedded-%1/QtEmbedded-%1") \ + .arg(DISPLAY) +#endif struct QVFbHeader { diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index fdb1708..ffbb67c 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -118,9 +118,13 @@ QGraphicsAnchor::~QGraphicsAnchor() } /*! - Set the spacing for the anchor to \a spacing. + \property QGraphicsAnchor::spacing + \brief the space between items in the QGraphicsAnchorLayout. - \sa spacing(), unsetSpacing() + Depending on the anchor type, the default spacing is either + 0 or a value returned from the style. + + \sa QGraphicsAnchorLayout::anchor() */ void QGraphicsAnchor::setSpacing(qreal spacing) { @@ -128,23 +132,12 @@ void QGraphicsAnchor::setSpacing(qreal spacing) d->setSpacing(spacing); } -/*! - Returns the spacing for the anchor - - \sa setSpacing() -*/ qreal QGraphicsAnchor::spacing() const { Q_D(const QGraphicsAnchor); return d->spacing(); } -/*! - Resets the spacing of the anchor point to be the default spacing. Depending on the anchor type, - the default spacing is either 0 or a value returned from the style. - - \sa setSpacing(), spacing(), QGraphicsAnchorLayout::anchor() -*/ void QGraphicsAnchor::unsetSpacing() { Q_D(QGraphicsAnchor); diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.h b/src/gui/graphicsview/qgraphicsanchorlayout.h index d9a87ba..99dbf92 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout.h @@ -61,7 +61,7 @@ class QGraphicsAnchorLayoutPrivate; class Q_GUI_EXPORT QGraphicsAnchor : public QObject { Q_OBJECT - Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing) + Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing RESET unsetSpacing) public: void setSpacing(qreal spacing); void unsetSpacing(); diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 912cfb6..d766acc 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -609,6 +609,7 @@ /*! \enum QGraphicsItem::PanelModality + \since 4.6 This enum specifies the behavior of a modal panel. A modal panel is one that blocks input to other panels. Note that items that diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 4f44109..bea1e8d 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE -struct QImageData { // internal image data +struct Q_GUI_EXPORT QImageData { // internal image data QImageData(); ~QImageData(); static QImageData *create(const QSize &size, QImage::Format format, int numColors = 0); diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 4938442..326dd10 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -64,7 +64,7 @@ const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; -/*! +/* \class QSymbianFbsClient \since 4.6 \internal @@ -145,7 +145,7 @@ void QSymbianFbsHeapLock::relock() qt_symbianFbsClient()->lockHeap(); } -/*! +/* \class QSymbianBitmapDataAccess \since 4.6 \internal diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index f77d200..6cde898 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -67,6 +67,7 @@ #include <private/qt_x11_p.h> #include "qx11info_x11.h" #include <private/qdrawhelper_p.h> +#include <private/qimage_p.h> #include <stdlib.h> @@ -369,6 +370,30 @@ void QX11PixmapData::resize(int width, int height) #endif // QT_NO_XRENDER } +struct QX11AlphaDetector +{ + bool hasAlpha() const { + if (checked) + return has; + // Will implicitly also check format and return quickly for opaque types... + checked = true; + has = const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels(); + return has; + } + + bool hasXRenderAndAlpha() const { + if (!X11->use_xrender) + return false; + return hasAlpha(); + } + + QX11AlphaDetector(const QImage *i) : image(i), checked(false), has(false) { } + + const QImage *image; + mutable bool checked; + mutable bool has; +}; + void QX11PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags) { @@ -402,7 +427,9 @@ void QX11PixmapData::fromImage(const QImage &img, return; } - int dd = X11->use_xrender && img.hasAlphaChannel() ? 32 : xinfo.depth(); + QX11AlphaDetector alphaCheck(&img); + int dd = alphaCheck.hasXRenderAndAlpha() ? 32 : xinfo.depth(); + if (qt_x11_preferred_pixmap_depth) dd = qt_x11_preferred_pixmap_depth; @@ -454,7 +481,7 @@ void QX11PixmapData::fromImage(const QImage &img, uchar *newbits= 0; #ifndef QT_NO_XRENDER - if (X11->use_xrender && image.hasAlphaChannel()) { + if (alphaCheck.hasXRenderAndAlpha()) { const QImage &cimage = image; d = 32; @@ -1091,7 +1118,7 @@ void QX11PixmapData::fromImage(const QImage &img, } #endif - if (image.hasAlphaChannel()) { + if (alphaCheck.hasAlpha()) { QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags)); setMask(m); } diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 0fae959..18cab13 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -87,6 +87,7 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate() dragDropMode(QAbstractItemView::NoDragDrop), overwrite(false), dropIndicatorPosition(QAbstractItemView::OnItem), + defaultDropAction(Qt::IgnoreAction), #endif #ifdef QT_SOFTKEYS_ENABLED doneSoftKey(0), @@ -1371,6 +1372,28 @@ QAbstractItemView::DragDropMode QAbstractItemView::dragDropMode() const return NoDragDrop; } +/*! + \property QAbstractItemView::defaultDropAction + \brief the drop action that will be used by default in QAbstractItemView::drag() + + If the property is not set, the drop action is CopyAction when the supported + actions support CopyAction. + + \since 4.6 + \sa showDropIndicator dragDropOverwriteMode +*/ +void QAbstractItemView::setDefaultDropAction(Qt::DropAction dropAction) +{ + Q_D(QAbstractItemView); + d->defaultDropAction = dropAction; +} + +Qt::DropAction QAbstractItemView::defaultDropAction() const +{ + Q_D(const QAbstractItemView); + return d->defaultDropAction; +} + #endif // QT_NO_DRAGANDDROP /*! @@ -3297,7 +3320,9 @@ void QAbstractItemView::startDrag(Qt::DropActions supportedActions) drag->setMimeData(data); drag->setHotSpot(d->pressedPosition - rect.topLeft()); Qt::DropAction defaultDropAction = Qt::IgnoreAction; - if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove) + if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction)) + defaultDropAction = d->defaultDropAction; + else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove) defaultDropAction = Qt::CopyAction; if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction) d->clearOrRemove(); diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h index 7d5c765..b4f0957 100644 --- a/src/gui/itemviews/qabstractitemview.h +++ b/src/gui/itemviews/qabstractitemview.h @@ -74,6 +74,7 @@ class Q_GUI_EXPORT QAbstractItemView : public QAbstractScrollArea Q_PROPERTY(bool dragEnabled READ dragEnabled WRITE setDragEnabled) Q_PROPERTY(bool dragDropOverwriteMode READ dragDropOverwriteMode WRITE setDragDropOverwriteMode) Q_PROPERTY(DragDropMode dragDropMode READ dragDropMode WRITE setDragDropMode) + Q_PROPERTY(Qt::DropAction defaultDropAction READ defaultDropAction WRITE setDefaultDropAction) #endif Q_PROPERTY(bool alternatingRowColors READ alternatingRowColors WRITE setAlternatingRowColors) Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) @@ -181,7 +182,11 @@ public: void setDragDropMode(DragDropMode behavior); DragDropMode dragDropMode() const; + + void setDefaultDropAction(Qt::DropAction dropAction); + Qt::DropAction defaultDropAction() const; #endif + void setAlternatingRowColors(bool enable); bool alternatingRowColors() const; diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 84c0892..fcf381a 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -117,7 +117,7 @@ public: virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end); virtual void _q_modelDestroyed(); virtual void _q_layoutChanged(); - + void fetchMore(); bool shouldEdit(QAbstractItemView::EditTrigger trigger, const QModelIndex &index) const; @@ -315,7 +315,7 @@ public: } return ref; } - + /** * return true if the index is registered as a QPersistentModelIndex */ @@ -356,8 +356,8 @@ public: Qt::KeyboardModifiers pressedModifiers; QPoint pressedPosition; bool pressedAlreadySelected; - - //forces the next mouseMoveEvent to send the viewportEntered signal + + //forces the next mouseMoveEvent to send the viewportEntered signal //if the mouse is over the viewport and not over an item bool viewportEnteredNeeded; @@ -377,6 +377,7 @@ public: QAbstractItemView::DragDropMode dragDropMode; bool overwrite; QAbstractItemView::DropIndicatorPosition dropIndicatorPosition; + Qt::DropAction defaultDropAction; #endif #ifdef QT_SOFTKEYS_ENABLED diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp index 01c64f1..634f23a 100644 --- a/src/gui/kernel/qapplication_qws.cpp +++ b/src/gui/kernel/qapplication_qws.cpp @@ -232,7 +232,7 @@ QString qws_dataDir() // Get the filename of the pipe Qt for Embedded Linux uses for server/client comms Q_GUI_EXPORT QString qws_qtePipeFilename() { - return (qws_dataDir().append(QTE_PIPE)); + return QTE_PIPE(qws_display_id); } static void setMaxWindowRect(const QRect &rect) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index d50e7e1..807a17f 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -780,7 +780,7 @@ TCoeInputCapabilities QSymbianControl::InputCapabilities() const } #endif -void QSymbianControl::Draw(const TRect& r) const +void QSymbianControl::Draw(const TRect& controlRect) const { QWindowSurface *surface = qwidget->windowSurface(); QPaintEngine *engine = surface ? surface->paintDevice()->paintEngine() : NULL; @@ -788,6 +788,11 @@ void QSymbianControl::Draw(const TRect& r) const if (!engine) return; + // Map source rectangle into coordinates of the backing store. + const QPoint controlBase(controlRect.iTl.iX, controlRect.iTl.iY); + const QPoint backingStoreBase = qwidget->mapTo(qwidget->window(), controlBase); + const TRect backingStoreRect(TPoint(backingStoreBase.x(), backingStoreBase.y()), controlRect.Size()); + if (engine->type() == QPaintEngine::Raster) { QS60WindowSurface *s60Surface = static_cast<QS60WindowSurface *>(qwidget->windowSurface()); CFbsBitmap *bitmap = s60Surface->symbianBitmap(); @@ -796,10 +801,10 @@ void QSymbianControl::Draw(const TRect& r) const if(!qwidget->d_func()->extraData()->disableBlit) { if (qwidget->d_func()->isOpaque) gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); - gc.BitBlt(r.iTl, bitmap, r); - } + gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect); + } } else { - surface->flush(qwidget, QRegion(qt_TRect2QRect(r)), QPoint()); + surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint()); } } @@ -950,13 +955,14 @@ void QSymbianControl::setFocusSafely(bool focus) /*! \typedef QApplication::QS60MainApplicationFactory + \since 4.6 This is a typedef for a pointer to a function with the following signature: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 47 - \sa QApplication::QApplication(QApplication::QS60MainApplicationFactory, int &, char **) + \sa QApplication::QApplication() */ /*! diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index 00839d1..237ce46 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -67,6 +67,7 @@ private: /*! \class QGesture \since 4.6 + \preliminary \brief The QGesture class is the base class for implementing custom gestures. diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index bcc411a..3cfb987 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -57,6 +57,7 @@ QWidgetPrivate *qt_widget_private(QWidget *widget); /*! \class QPanGesture + \preliminary \since 4.6 \brief The QPanGesture class represents a Pan gesture, @@ -339,6 +340,7 @@ QSizeF QPanGesture::offset() const /*! \class QPinchGesture + \preliminary \since 4.6 \brief The QPinchGesture class represents a Pinch gesture, @@ -667,6 +669,7 @@ QPointF QPinchGesture::startCenterPoint() const /*! \class QSwipeGesture + \preliminary \since 4.6 \brief The QSwipeGesture class represents a swipe gesture, diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 0b75b06..2359812 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -923,7 +923,7 @@ void QWidget::setAutoFillBackground(bool enabled) Note: Currently softkeys are only supported on the Symbian Platform. - \sa addAction, QAction, QMenuBar + \sa addAction(), QAction, QMenuBar */ @@ -11444,19 +11444,32 @@ QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction) QWidget *targetWidget = 0; int shortestDistance = INT_MAX; foreach(QWidget *targetCandidate, QApplication::allWidgets()) { - - if (targetCandidate->focusProxy()) //skip if focus proxy set - continue; const QRect targetCandidateRect = targetCandidate->rect().translated(targetCandidate->mapToGlobal(QPoint())); + + // For focus proxies, the child widget handling the focus can have keypad navigation focus, + // but the owner of the proxy cannot. + // Additionally, empty widgets should be ignored. + if (targetCandidate->focusProxy() || targetCandidateRect.isEmpty()) + continue; + + // Only navigate to a target widget that... if ( targetCandidate != sourceWidget + // ...takes the focus, && targetCandidate->focusPolicy() & Qt::TabFocus + // ...is above if DirectionNorth, && !(direction == DirectionNorth && targetCandidateRect.bottom() > sourceRect.top()) + // ...is on the right if DirectionEast, && !(direction == DirectionEast && targetCandidateRect.left() < sourceRect.right()) + // ...is below if DirectionSouth, && !(direction == DirectionSouth && targetCandidateRect.top() < sourceRect.bottom()) + // ...is on the left if DirectionWest, && !(direction == DirectionWest && targetCandidateRect.right() > sourceRect.left()) + // ...is enabled, && targetCandidate->isEnabled() + // ...is visible, && targetCandidate->isVisible() + // ...is in the same window, && targetCandidate->window() == sourceWindow) { const int targetCandidateDistance = pointToRect(sourcePoint, targetCandidateRect); if (targetCandidateDistance < shortestDistance) { diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 6c879be..c06ef73 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -294,6 +294,7 @@ public: void setMask_sys(const QRegion &); #ifdef Q_OS_SYMBIAN void setSoftKeys_sys(const QList<QAction*> &softkeys); + void activateSymbianWindow(); #endif void raise_sys(); diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 05db8ca..3328cee 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -194,8 +194,8 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &) } if (jump && data.winid) { - RWindow *const window = static_cast<RWindow *>(data.winid->DrawableWindow()); - window->Invalidate(TRect(0, 0, wrect.width(), wrect.height())); + RWindow *const window = static_cast<RWindow *>(data.winid->DrawableWindow()); + window->Invalidate(TRect(0, 0, wrect.width(), wrect.height())); } } @@ -411,6 +411,14 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de int x, y, w, h; data.crect.getRect(&x, &y, &w, &h); control->SetRect(TRect(TPoint(x, y), TSize(w, h))); + + RDrawableWindow *const drawableWindow = control->DrawableWindow(); + // Request mouse move events. + drawableWindow->PointerFilter(EPointerFilterEnterExit + | EPointerFilterMove | EPointerFilterDrag, 0); + + if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) + activateSymbianWindow(); } if (destroyw) { @@ -440,12 +448,11 @@ void QWidgetPrivate::show_sys() } if (q->internalWinId()) { - - QSymbianControl *id = static_cast<QSymbianControl *>(q->internalWinId()); - if (!extra->activated) { - QT_TRAP_THROWING(id->ActivateL()); - extra->activated = 1; - } + if (!extra->activated) + activateSymbianWindow(); + + QSymbianControl *id = static_cast<QSymbianControl *>(q->internalWinId()); + id->MakeVisible(true); if(q->isWindow()) @@ -461,6 +468,19 @@ void QWidgetPrivate::show_sys() invalidateBuffer(q->rect()); } +void QWidgetPrivate::activateSymbianWindow() +{ + Q_Q(QWidget); + + Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); + Q_ASSERT(q->testAttribute(Qt::WA_Mapped)); + Q_ASSERT(!extra->activated); + + WId id = q->internalWinId(); + QT_TRAP_THROWING(id->ActivateL()); + extra->activated = 1; +} + void QWidgetPrivate::hide_sys() { Q_Q(QWidget); @@ -1016,9 +1036,9 @@ QPoint QWidget::mapFromGlobal(const QPoint &pos) const } // Native window case - const TPoint widgetScreenOffset = internalWinId()->PositionRelativeToScreen(); - const QPoint widgetPos = pos - QPoint(widgetScreenOffset.iX, widgetScreenOffset.iY); - return widgetPos; + const TPoint widgetScreenOffset = internalWinId()->PositionRelativeToScreen(); + const QPoint widgetPos = pos - QPoint(widgetScreenOffset.iX, widgetScreenOffset.iY); + return widgetPos; } void QWidget::setWindowState(Qt::WindowStates newstate) diff --git a/src/gui/painting/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp index 716300e..c20d8d8 100644 --- a/src/gui/painting/qdrawutil.cpp +++ b/src/gui/painting/qdrawutil.cpp @@ -45,6 +45,9 @@ #include "qapplication.h" #include "qpainter.h" #include "qpalette.h" +#include <private/qpaintengineex_p.h> +#include <qvarlengtharray.h> +#include <qmath.h> QT_BEGIN_NAMESPACE @@ -1078,91 +1081,7 @@ void qDrawItem(QPainter *p, Qt::GUIStyle gs, according to the \a margins structure. */ -static inline void qVerticalRepeat(QPainter *painter, - const QRect &target, - const QPixmap &pixmap, - const QRect &source, - void (*drawPixmap)(QPainter*, - const QRect&, - const QPixmap&, - const QRect&)) -{ - const int x = target.x(); - const int width = target.width(); - const int height = source.height(); - const int bottom = target.bottom() - height; - int y = target.y(); - for (; y < bottom; y += height) - (*drawPixmap)(painter, QRect(x, y, width, height), pixmap, source); - const QRect remaining(source.x(), source.y(), source.width(), target.bottom() - y + 1); - (*drawPixmap)(painter, QRect(x, y, width, remaining.height()), pixmap, remaining); -} - -static inline void qHorizontalRepeat(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source, - void (*drawPixmap)(QPainter*, const QRect&, const QPixmap&, const QRect&)) -{ - const int y = target.y(); - const int width = source.width(); - const int height = target.height(); - const int right = target.right() - width; - int x = target.x(); - for (; x < right; x += width) - (*drawPixmap)(painter, QRect(x, y, width, height), pixmap, source); - const QRect remaining(source.x(), source.y(), target.right() - x + 1, source.height()); - (*drawPixmap)(painter, QRect(x, y, remaining.width(), height), pixmap, remaining); -} - -static inline void qVerticalRound(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source, - void (*drawPixmap)(QPainter*, const QRect&, const QPixmap&, const QRect&)) -{ - // qreal based - slow on non-fpu devices - const qreal x = target.x(); - const qreal width = target.width(); - const qreal verticalFactor = static_cast<qreal>(target.height()) / static_cast<qreal>(source.height()); - const qreal verticalIncrement = static_cast<qreal>(target.height()) / static_cast<int>(verticalFactor + 0.5); - const qreal bottom = target.bottom(); - for (qreal y = static_cast<qreal>(target.y()); y < bottom; y += verticalIncrement) - (*drawPixmap)(painter, QRectF(x, y, width, verticalIncrement).toRect(), pixmap, source); - -} - -static inline void qHorizontalRound(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source, - void (*drawPixmap)(QPainter*, const QRect&, const QPixmap&, const QRect&)) -{ - // qreal based - slow on non-fpu devices - const qreal y = target.y(); - const qreal height = target.height(); - const qreal horizontalFactor = static_cast<qreal>(target.width()) / static_cast<qreal>(source.width()); - const qreal horizontalIncrement = static_cast<qreal>(target.width()) / static_cast<int>(horizontalFactor + 0.5); - const qreal right = target.right(); - for (qreal x = target.x(); x < right; x += horizontalIncrement) - (*drawPixmap)(painter, QRectF(x, y, horizontalIncrement, height).toRect(), pixmap, source); -} - -static inline void qDrawPixmap(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source) -{ - painter->drawPixmap(target, pixmap, source); -} - -static inline void qDrawVerticallyRepeatedPixmap(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source) -{ - qVerticalRepeat(painter, target, pixmap, source, qDrawPixmap); -} - -static inline void qDrawHorizontallyRepeatedPixmap(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source) -{ - qHorizontalRepeat(painter, target, pixmap, source, qDrawPixmap); -} - -static inline void qDrawVerticallyRoundedPixmap(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source) -{ - qVerticalRound(painter, target, pixmap, source, qDrawPixmap); -} - -static inline void qDrawHorizontallyRoundedPixmap(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source) -{ - qHorizontalRound(painter, target, pixmap, source, qDrawPixmap); -} +typedef QVarLengthArray<QDrawPixmaps::Data, 16> QDrawPixmapsDataArray; /*! \since 4.6 @@ -1179,176 +1098,282 @@ static inline void qDrawHorizontallyRoundedPixmap(QPainter *painter, const QRect \sa Qt::TileRule, QTileRules, QMargins */ -void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins, const QPixmap &pixmap, - const QRect &sourceRect, const QMargins &sourceMargins, const QTileRules &rules) +void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins, + const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins, + const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints) { + QDrawPixmaps::Data d; + d.opacity = 1.0; + d.rotation = 0.0; + + QDrawPixmapsDataArray opaqueData; + QDrawPixmapsDataArray translucentData; + // source center - const int sourceTop = sourceRect.top(); - const int sourceLeft = sourceRect.left(); - const int sourceCenterTop = sourceTop + sourceMargins.top(); - const int sourceCenterLeft = sourceLeft + sourceMargins.left(); + const int sourceCenterTop = sourceRect.top() + sourceMargins.top(); + const int sourceCenterLeft = sourceRect.left() + sourceMargins.left(); const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1; const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1; - const int sourceCenterWidth = sourceCenterRight - sourceMargins.left(); - const int sourceCenterHeight = sourceCenterBottom - sourceMargins.top(); + const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft; + const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop; // target center - const int targetTop = targetRect.top(); - const int targetLeft = targetRect.left(); - const int targetCenterTop = targetTop + targetMargins.top(); - const int targetCenterLeft = targetLeft + targetMargins.left(); + const int targetCenterTop = targetRect.top() + targetMargins.top(); + const int targetCenterLeft = targetRect.left() + targetMargins.left(); const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1; const int targetCenterRight = targetRect.right() - targetMargins.right() + 1; const int targetCenterWidth = targetCenterRight - targetCenterLeft; const int targetCenterHeight = targetCenterBottom - targetCenterTop; + QVarLengthArray<qreal, 16> xTarget; // x-coordinates of target rectangles + QVarLengthArray<qreal, 16> yTarget; // y-coordinates of target rectangles + + int columns = 3; + int rows = 3; + if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0) + columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth))); + if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0) + rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight))); + + xTarget.resize(columns + 1); + yTarget.resize(rows + 1); + + xTarget[0] = targetRect.left(); + xTarget[1] = targetCenterLeft; + xTarget[columns - 1] = targetCenterRight; + xTarget[columns] = targetRect.left() + targetRect.width(); + + yTarget[0] = targetRect.top(); + yTarget[1] = targetCenterTop; + yTarget[rows - 1] = targetCenterBottom; + yTarget[rows] = targetRect.top() + targetRect.height(); + + qreal dx; + qreal dy; + + switch (rules.horizontal) { + case Qt::StretchTile: + dx = targetCenterWidth; + break; + case Qt::RepeatTile: + dx = sourceCenterWidth; + break; + case Qt::RoundTile: + dx = targetCenterWidth / qreal(columns - 2); + break; + } + + for (int i = 2; i < columns - 1; ++i) + xTarget[i] = xTarget[i - 1] + dx; + + switch (rules.vertical) { + case Qt::StretchTile: + dy = targetCenterHeight; + break; + case Qt::RepeatTile: + dy = sourceCenterHeight; + break; + case Qt::RoundTile: + dy = targetCenterHeight / qreal(rows - 2); + break; + } + + for (int i = 2; i < rows - 1; ++i) + yTarget[i] = yTarget[i - 1] + dy; + // corners if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left - const QRect targetTopLeftRect(targetLeft, targetTop, targetMargins.left(), targetMargins.top()); - const QRect sourceTopLeftRect(sourceLeft, sourceTop, sourceMargins.left(), sourceMargins.top()); - qDrawPixmap(painter, targetTopLeftRect, pixmap, sourceTopLeftRect); + d.point.setX(0.5 * (xTarget[1] + xTarget[0])); + d.point.setY(0.5 * (yTarget[1] + yTarget[0])); + d.source = QRectF(sourceRect.left(), sourceRect.top(), sourceMargins.left(), sourceMargins.top()); + d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width(); + d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height(); + if (hints & QDrawBorderPixmap::OpaqueTopLeft) + opaqueData.append(d); + else + translucentData.append(d); } if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right - const QRect targetTopRightRect(targetCenterRight, targetTop, targetMargins.right(), targetMargins.top()); - const QRect sourceTopRightRect(sourceCenterRight, sourceTop, sourceMargins.right(), sourceMargins.top()); - qDrawPixmap(painter, targetTopRightRect, pixmap, sourceTopRightRect); + d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1])); + d.point.setY(0.5 * (yTarget[1] + yTarget[0])); + d.source = QRectF(sourceCenterRight, sourceRect.top(), sourceMargins.right(), sourceMargins.top()); + d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width(); + d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height(); + if (hints & QDrawBorderPixmap::OpaqueTopRight) + opaqueData.append(d); + else + translucentData.append(d); } if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left - const QRect targetBottomLeftRect(targetLeft, targetCenterBottom, targetMargins.left(), targetMargins.bottom()); - const QRect sourceBottomLeftRect(sourceLeft, sourceCenterBottom, sourceMargins.left(), sourceMargins.bottom()); - qDrawPixmap(painter, targetBottomLeftRect, pixmap, sourceBottomLeftRect); + d.point.setX(0.5 * (xTarget[1] + xTarget[0])); + d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1])); + d.source = QRectF(sourceRect.left(), sourceCenterBottom, sourceMargins.left(), sourceMargins.bottom()); + d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width(); + d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height(); + if (hints & QDrawBorderPixmap::OpaqueBottomLeft) + opaqueData.append(d); + else + translucentData.append(d); } if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right - const QRect targetBottomRightRect(targetCenterRight, targetCenterBottom, targetMargins.right(), targetMargins.bottom()); - const QRect sourceBottomRightRect(sourceCenterRight, sourceCenterBottom, sourceMargins.right(), sourceMargins.bottom()); - qDrawPixmap(painter, targetBottomRightRect, pixmap, sourceBottomRightRect); + d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1])); + d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1])); + d.source = QRectF(sourceCenterRight, sourceCenterBottom, sourceMargins.right(), sourceMargins.bottom()); + d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width(); + d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height(); + if (hints & QDrawBorderPixmap::OpaqueBottomRight) + opaqueData.append(d); + else + translucentData.append(d); } // horizontal edges - switch (rules.horizontal) { - case Qt::Stretch: - if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top - const QRect targetTopRect(targetCenterLeft, targetTop, targetCenterWidth, targetMargins.top()); - const QRect sourceTopRect(sourceCenterLeft, sourceTop, sourceCenterWidth, sourceMargins.top()); - qDrawPixmap(painter, targetTopRect, pixmap, sourceTopRect); - } - if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom - const QRect targetBottomRect(targetCenterLeft, targetCenterBottom, targetCenterWidth, targetMargins.bottom()); - const QRect sourceBottomRect(sourceCenterLeft, sourceCenterBottom, sourceCenterWidth, sourceMargins.bottom()); - qDrawPixmap(painter, targetBottomRect, pixmap, sourceBottomRect); - } - break; - case Qt::Repeat: - if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top - const QRect targetTopRect(targetCenterLeft, targetTop, targetCenterWidth, targetMargins.top()); - const QRect sourceTopRect(sourceCenterLeft, sourceTop, sourceCenterWidth, sourceMargins.top()); - qDrawHorizontallyRepeatedPixmap(painter, targetTopRect, pixmap, sourceTopRect); - } - if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom - const QRect targetBottomRect(targetCenterLeft, targetCenterBottom, targetCenterWidth, targetMargins.bottom()); - const QRect sourceBottomRect(sourceCenterLeft, sourceCenterBottom, sourceCenterWidth, sourceMargins.bottom()); - qDrawHorizontallyRepeatedPixmap(painter, targetBottomRect, pixmap, sourceBottomRect); - } - break; - case Qt::Round: + if (targetCenterWidth > 0 && sourceCenterWidth > 0) { if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top - const QRect targetTopRect(targetCenterLeft, targetTop, targetCenterWidth, targetMargins.top()); - const QRect sourceTopRect(sourceCenterLeft, sourceTop, sourceCenterWidth, sourceMargins.top()); - qDrawHorizontallyRoundedPixmap(painter, targetTopRect, pixmap, sourceTopRect); + QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData; + d.source = QRectF(sourceCenterLeft, sourceRect.top(), sourceCenterWidth, sourceMargins.top()); + d.point.setY(0.5 * (yTarget[1] + yTarget[0])); + d.scaleX = dx / d.source.width(); + d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height(); + for (int i = 1; i < columns - 1; ++i) { + d.point.setX(0.5 * (xTarget[i + 1] + xTarget[i])); + data.append(d); + } + if (rules.horizontal == Qt::RepeatTile) + data[data.size() - 1].source.setWidth((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); } if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom - const QRect targetBottomRect(targetCenterLeft, targetCenterBottom, targetCenterWidth, targetMargins.bottom()); - const QRect sourceBottomRect(sourceCenterLeft, sourceCenterBottom, sourceCenterWidth, sourceMargins.bottom()); - qDrawHorizontallyRoundedPixmap(painter, targetBottomRect, pixmap, sourceBottomRect); + QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData; + d.source = QRectF(sourceCenterLeft, sourceCenterBottom, sourceCenterWidth, sourceMargins.bottom());; + d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1])); + d.scaleX = dx / d.source.width(); + d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height(); + for (int i = 1; i < columns - 1; ++i) { + d.point.setX(0.5 * (xTarget[i + 1] + xTarget[i])); + data.append(d); + } + if (rules.horizontal == Qt::RepeatTile) + data[data.size() - 1].source.setWidth((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); } - break; } // vertical edges - switch (rules.vertical) { - case Qt::Stretch: - if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left - const QRect targetLeftRect(targetLeft, targetCenterTop, targetMargins.left(), targetCenterHeight); - const QRect sourceLeftRect(sourceLeft, sourceCenterTop, sourceMargins.left(), sourceCenterHeight); - qDrawPixmap(painter, targetLeftRect, pixmap, sourceLeftRect); - } - if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right - const QRect targetRightRect(targetCenterRight, targetCenterTop, targetMargins.right(), targetCenterHeight); - const QRect sourceRightRect(sourceCenterRight, sourceCenterTop, sourceMargins.right(), sourceCenterHeight); - qDrawPixmap(painter, targetRightRect, pixmap, sourceRightRect); - } - break; - case Qt::Repeat: - if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left - const QRect targetLeftRect(targetLeft, targetCenterTop, targetMargins.left(), targetCenterHeight); - const QRect sourceLeftRect(sourceLeft, sourceCenterTop, sourceMargins.left(), sourceCenterHeight); - qDrawVerticallyRepeatedPixmap(painter, targetLeftRect, pixmap, sourceLeftRect); - } - if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right - const QRect targetRightRect(targetCenterRight, targetCenterTop, targetMargins.right(), targetCenterHeight); - const QRect sourceRightRect(sourceCenterRight, sourceCenterTop, sourceMargins.right(), sourceCenterHeight); - qDrawVerticallyRepeatedPixmap(painter, targetRightRect, pixmap, sourceRightRect); - } - break; - case Qt::Round: + if (targetCenterHeight > 0 && sourceCenterHeight > 0) { if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left - const QRect targetLeftRect(targetLeft, targetCenterTop, targetMargins.left(), targetCenterHeight); - const QRect sourceLeftRect(sourceLeft, sourceCenterTop, sourceMargins.left(), sourceCenterHeight); - qDrawVerticallyRoundedPixmap(painter, targetLeftRect, pixmap, sourceLeftRect); + QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData; + d.source = QRectF(sourceRect.left(), sourceCenterTop, sourceMargins.left(), sourceCenterHeight); + d.point.setX(0.5 * (xTarget[1] + xTarget[0])); + d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width(); + d.scaleY = dy / d.source.height(); + for (int i = 1; i < rows - 1; ++i) { + d.point.setY(0.5 * (yTarget[i + 1] + yTarget[i])); + data.append(d); + } + if (rules.vertical == Qt::RepeatTile) + data[data.size() - 1].source.setHeight((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); } if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right - const QRect targetRightRect(targetCenterRight, targetCenterTop, targetMargins.right(), targetCenterHeight); - const QRect sourceRightRect(sourceCenterRight, sourceCenterTop, sourceMargins.right(), sourceCenterHeight); - qDrawVerticallyRoundedPixmap(painter, targetRightRect, pixmap, sourceRightRect); + QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData; + d.source = QRectF(sourceCenterRight, sourceCenterTop, sourceMargins.right(), sourceCenterHeight); + d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1])); + d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width(); + d.scaleY = dy / d.source.height(); + for (int i = 1; i < rows - 1; ++i) { + d.point.setY(0.5 * (yTarget[i + 1] + yTarget[i])); + data.append(d); + } + if (rules.vertical == Qt::RepeatTile) + data[data.size() - 1].source.setHeight((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); } - break; } // center if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) { - const QRect targetCenterRect(targetCenterLeft, targetCenterTop, targetCenterWidth, targetCenterHeight); - const QRect sourceCenterRect(sourceCenterLeft, sourceCenterTop, sourceCenterWidth, sourceCenterHeight); - switch (rules.horizontal) { - case Qt::Stretch: - switch (rules.vertical) { - case Qt::Stretch: // stretch stretch - qDrawPixmap(painter, targetCenterRect, pixmap, sourceCenterRect); - break; - case Qt::Repeat: // stretch repeat - qVerticalRepeat(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawPixmap); - break; - case Qt::Round: // stretch round - qVerticalRound(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawPixmap); - break; - } - break; - case Qt::Repeat: - switch (rules.vertical) { - case Qt::Stretch: // repeat stretch - qHorizontalRepeat(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawPixmap); - break; - case Qt::Repeat: // repeat repeat - qVerticalRepeat(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawHorizontallyRepeatedPixmap); - break; - case Qt::Round: // repeat round - qVerticalRound(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawHorizontallyRepeatedPixmap); - break; + QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData; + d.source = QRectF(sourceCenterLeft, sourceCenterTop, sourceCenterWidth, sourceCenterHeight); + d.scaleX = dx / d.source.width(); + d.scaleY = dy / d.source.height(); + + qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX; + qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY; + + for (int j = 1; j < rows - 1; ++j) { + d.point.setY(0.5 * (yTarget[j + 1] + yTarget[j])); + for (int i = 1; i < columns - 1; ++i) { + d.point.setX(0.5 * (xTarget[i + 1] + xTarget[i])); + data.append(d); } - break; - case Qt::Round: - switch (rules.vertical) { - case Qt::Stretch: // round stretch - qHorizontalRound(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawPixmap); - break; - case Qt::Repeat: // round repeat - qHorizontalRound(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawVerticallyRepeatedPixmap); - break; - case Qt::Round: // round round - qHorizontalRound(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawVerticallyRoundedPixmap); - break; - } - break; + if (rules.horizontal == Qt::RepeatTile) + data[data.size() - 1].source.setWidth(repeatWidth); + } + if (rules.vertical == Qt::RepeatTile) { + for (int i = 1; i < columns - 1; ++i) + data[data.size() - i].source.setHeight(repeatHeight); } } + + if (opaqueData.size()) + qDrawPixmaps(painter, opaqueData.data(), opaqueData.size(), pixmap, QDrawPixmaps::OpaqueHint); + if (translucentData.size()) + qDrawPixmaps(painter, translucentData.data(), translucentData.size(), pixmap); +} + +/*! + \class QDrawPixmaps::Data + \since 4.6 + \internal + + This structure is used with the qDrawPixmaps() function. + + QPointF point: Specifies the center of the target rectangle. + QRectF source: Specifies the source rectangle in the pixmap passed into the qDrawPixmaps() call. + qreal scaleX: Specifies the horizontal scale of the target rectangle. + qreal scaleY: Specifies the vertical scale of the target rectangle. + qreal rotation: Specifies the rotation of the target rectangle in degrees. + The target rectangle is rotated after scaling. + qreal opacity: Specifies the opacity of the rectangle. +*/ + +/*! + \enum QDrawPixmaps::DrawingHint + \internal +*/ + +/*! + \internal + \since 4.6 + + This function is used to draw \a pixmap, or a sub-rectangle of \a pixmap, at multiple positions + with different scale, rotation and opacity on \a painter. \a drawingData is an array of \a + dataCount elements specifying the parameters used to draw each pixmap instance. + This can be used for example to implement a particle system. +*/ +void qDrawPixmaps(QPainter *painter, const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints) +{ + QPaintEngine *engine = painter->paintEngine(); + if (!engine) + return; + + if (engine->isExtended()) { + static_cast<QPaintEngineEx *>(engine)->drawPixmaps(drawingData, dataCount, pixmap, hints); + } else { + qreal oldOpacity = painter->opacity(); + QTransform oldTransform = painter->transform(); + + for (int i = 0; i < dataCount; ++i) { + QTransform transform = oldTransform; + transform.translate(drawingData[i].point.x(), drawingData[i].point.y()); + transform.rotate(drawingData[i].rotation); + painter->setOpacity(oldOpacity * drawingData[i].opacity); + painter->setTransform(transform); + + qreal w = drawingData[i].scaleX * drawingData[i].source.width(); + qreal h = drawingData[i].scaleY * drawingData[i].source.height(); + painter->drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source); + } + + painter->setOpacity(oldOpacity); + painter->setTransform(oldTransform); + } } QT_END_NAMESPACE diff --git a/src/gui/painting/qdrawutil.h b/src/gui/painting/qdrawutil.h index 3a2dd0e..fff1cc1 100644 --- a/src/gui/painting/qdrawutil.h +++ b/src/gui/painting/qdrawutil.h @@ -137,27 +137,82 @@ struct QTileRules { inline QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule) : horizontal(horizontalRule), vertical(verticalRule) {} - inline QTileRules(Qt::TileRule rule = Qt::Stretch) + inline QTileRules(Qt::TileRule rule = Qt::StretchTile) : horizontal(rule), vertical(rule) {} Qt::TileRule horizontal; Qt::TileRule vertical; }; -Q_GUI_EXPORT void qDrawBorderPixmap(QPainter *painter, - const QRect &targetRect, - const QMargins &targetMargins, +#ifndef Q_QDOC +// For internal use only. +namespace QDrawBorderPixmap +{ + enum DrawingHint + { + OpaqueTopLeft = 0x0001, + OpaqueTop = 0x0002, + OpaqueTopRight = 0x0004, + OpaqueLeft = 0x0008, + OpaqueCenter = 0x0010, + OpaqueRight = 0x0020, + OpaqueBottomLeft = 0x0040, + OpaqueBottom = 0x0080, + OpaqueBottomRight = 0x0100, + OpaqueCorners = OpaqueTopLeft | OpaqueTopRight | OpaqueBottomLeft | OpaqueBottomRight, + OpaqueEdges = OpaqueTop | OpaqueLeft | OpaqueRight | OpaqueBottom, + OpaqueFrame = OpaqueCorners | OpaqueEdges, + OpaqueAll = OpaqueCenter | OpaqueFrame + }; + + Q_DECLARE_FLAGS(DrawingHints, DrawingHint) +} +#endif + +Q_GUI_EXPORT void qDrawBorderPixmap(QPainter *painter, + const QRect &targetRect, + const QMargins &targetMargins, const QPixmap &pixmap, - const QRect &sourceRect, - const QMargins &sourceMargins, - const QTileRules &rules = QTileRules()); -inline void qDrawBorderPixmap(QPainter *painter, - const QRect &target, - const QMargins &margins, + const QRect &sourceRect, + const QMargins &sourceMargins, + const QTileRules &rules = QTileRules() +#ifndef Q_QDOC + , QDrawBorderPixmap::DrawingHints hints = 0 +#endif + ); + +inline void qDrawBorderPixmap(QPainter *painter, + const QRect &target, + const QMargins &margins, const QPixmap &pixmap) { qDrawBorderPixmap(painter, target, margins, pixmap, pixmap.rect(), margins); } +// For internal use only. +namespace QDrawPixmaps +{ + struct Data + { + QPointF point; + QRectF source; + qreal scaleX; + qreal scaleY; + qreal rotation; + qreal opacity; + }; + + enum DrawingHint + { + OpaqueHint = 0x01 + }; + + Q_DECLARE_FLAGS(DrawingHints, DrawingHint) +} + +// This function is private and may change without notice. Do not use outside Qt!!! +Q_GUI_EXPORT void qDrawPixmaps(QPainter *painter, const QDrawPixmaps::Data *drawingData, + int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints = 0); + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 60e4df6..d712669 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -932,6 +932,31 @@ void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, con fill(path, brush); } +void QPaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints) +{ + qreal oldOpacity = state()->opacity; + QTransform oldTransform = state()->matrix; + + for (int i = 0; i < dataCount; ++i) { + QTransform transform = oldTransform; + transform.translate(drawingData[i].point.x(), drawingData[i].point.y()); + transform.rotate(drawingData[i].rotation); + state()->opacity = oldOpacity * drawingData[i].opacity; + state()->matrix = transform; + opacityChanged(); + transformChanged(); + + qreal w = drawingData[i].scaleX * drawingData[i].source.width(); + qreal h = drawingData[i].scaleY * drawingData[i].source.height(); + drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source); + } + + state()->opacity = oldOpacity; + state()->matrix = oldTransform; + opacityChanged(); + transformChanged(); +} + void QPaintEngineEx::setState(QPainterState *s) { QPaintEngine::state = s; diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h index 814a0f0..81ed06b 100644 --- a/src/gui/painting/qpaintengineex_p.h +++ b/src/gui/painting/qpaintengineex_p.h @@ -71,6 +71,11 @@ class QPainterState; class QPaintEngineExPrivate; struct StrokeHandler; +namespace QDrawPixmaps +{ + struct Data; + enum DrawingHint; +} struct QIntRect { int x1, y1, x2, y2; @@ -133,8 +138,6 @@ public: qreal pts[8]; }; - - #ifndef QT_NO_DEBUG_STREAM QDebug Q_GUI_EXPORT &operator<<(QDebug &, const QVectorPath &path); #endif @@ -198,6 +201,8 @@ public: virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); + virtual void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QFlags<QDrawPixmaps::DrawingHint> hints); + virtual void updateState(const QPaintEngineState &state); virtual void setState(QPainterState *s); diff --git a/src/gui/s60framework/qs60mainapplication.cpp b/src/gui/s60framework/qs60mainapplication.cpp index 54fb3b1..2973c97 100644 --- a/src/gui/s60framework/qs60mainapplication.cpp +++ b/src/gui/s60framework/qs60mainapplication.cpp @@ -63,7 +63,7 @@ _LIT(KQtWrapperResourceFile, "\\resource\\apps\\s60main.rsc"); * \class QS60MainApplication * \obsolete * \since 4.6 - * \brief Helper class for S60 migration + * \brief The QS60MainApplication class provides support for migration from S60. * * The QS60MainApplication provides a helper class for use in migrating from existing S60 based * applications to Qt based applications. It is used in the exact same way as the @@ -80,7 +80,7 @@ _LIT(KQtWrapperResourceFile, "\\resource\\apps\\s60main.rsc"); * Unlike other Qt classes, QS60MainApplication behaves like an S60 class, and can throw Symbian * leaves. * - * \sa QS60MainDocument, QS60MainAppUi, QApplication::QApplication(QApplication::QS60MainApplicationFactory, int &, char **) + * \sa QS60MainDocument, QS60MainAppUi, QApplication::QS60MainApplicationFactory */ /*! diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 0f3a88b..707b05e 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -1126,7 +1126,7 @@ void QRenderRule::fixupBorder(int nativeWidth) void QRenderRule::drawBorderImage(QPainter *p, const QRect& rect) { static const Qt::TileRule tileMode2TileRule[] = { - Qt::Stretch, Qt::Round, Qt::Stretch, Qt::Repeat, Qt::Stretch }; + Qt::StretchTile, Qt::RoundTile, Qt::StretchTile, Qt::RepeatTile, Qt::StretchTile }; const QStyleSheetBorderImageData *borderImageData = border()->borderImage(); const int *targetBorders = border()->borders; diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp index c3289b4..19a8b63 100644 --- a/src/gui/widgets/qabstractslider.cpp +++ b/src/gui/widgets/qabstractslider.cpp @@ -693,13 +693,8 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e) if (e->orientation() != d->orientation && !rect().contains(e->pos())) return; - int step = qMin(QApplication::wheelScrollLines() * d->singleStep, d->pageStep); - if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) - step = d->pageStep; - - qreal currentOffset = qreal(e->delta()) * step / 120; - d->offset_accumulated += d->invertedControls ? -currentOffset : currentOffset; - + qreal currentOffset = qreal(e->delta()) / 120; + d->offset_accumulated += currentOffset; if (int(d->offset_accumulated) == 0) { // QAbstractSlider works on integer values. So if the accumulated // offset is less than +/- 1, we need to wait until we get more @@ -708,8 +703,27 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e) return; } + int stepsToScroll; + if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) { + stepsToScroll = currentOffset > 0 ? d->pageStep : -d->pageStep; + } else { + // Calculate the number of steps to scroll (per 15 degrees of rotate): +#ifdef Q_OS_MAC + // On mac, since mouse wheel scrolling is accelerated and + // fine tuned by the OS, we skip applying acceleration: + stepsToScroll = int(d->offset_accumulated); +#else + stepsToScroll = int(d->offset_accumulated) * QApplication::wheelScrollLines() * d->singleStep; +#endif + if (qAbs(stepsToScroll) > d->pageStep) + stepsToScroll = currentOffset > 0 ? d->pageStep : -d->pageStep; + } + + if (d->invertedControls) + stepsToScroll = -stepsToScroll; + int prevValue = d->value; - d->position = d->overflowSafeAdd(int(d->offset_accumulated)); // value will be updated by triggerAction() + d->position = d->overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction() triggerAction(SliderMove); if (prevValue == d->value) { diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp index 5ff323a..5ba0571 100644 --- a/src/gui/widgets/qlabel.cpp +++ b/src/gui/widgets/qlabel.cpp @@ -886,7 +886,18 @@ void QLabel::focusInEvent(QFocusEvent *ev) void QLabel::focusOutEvent(QFocusEvent *ev) { Q_D(QLabel); - d->sendControlEvent(ev); + if (d->control) { + d->sendControlEvent(ev); + QTextCursor cursor = d->control->textCursor(); + Qt::FocusReason reason = ev->reason(); + if (reason != Qt::ActiveWindowFocusReason + && reason != Qt::PopupFocusReason + && cursor.hasSelection()) { + cursor.clearSelection(); + d->control->setTextCursor(cursor); + } + } + QFrame::focusOutEvent(ev); } diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index 3fe9bb4..dc78fd5 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -174,13 +174,8 @@ void QTextEditPrivate::init(const QString &html) if (!html.isEmpty()) control->setHtml(html); -#ifdef Q_OS_MAC - hbar->setSingleStep(1); - vbar->setSingleStep(1); -#else hbar->setSingleStep(20); vbar->setSingleStep(20); -#endif viewport->setBackgroundRole(QPalette::Base); q->setAcceptDrops(true); |