diff options
-rw-r--r-- | src/corelib/widgets/mimagewidget.cpp | 45 | ||||
-rw-r--r-- | src/corelib/widgets/mimagewidget_p.h | 7 | ||||
-rw-r--r-- | src/views/mimagewidgetview.cpp | 244 | ||||
-rw-r--r-- | src/views/mimagewidgetview.h | 3 | ||||
-rw-r--r-- | src/views/mimagewidgetview_p.h | 64 |
5 files changed, 256 insertions, 107 deletions
diff --git a/src/corelib/widgets/mimagewidget.cpp b/src/corelib/widgets/mimagewidget.cpp index 9ef6edb5..7ea7eb95 100644 --- a/src/corelib/widgets/mimagewidget.cpp +++ b/src/corelib/widgets/mimagewidget.cpp @@ -50,6 +50,7 @@ void MImageWidgetPrivate::cleanUp() MTheme::releasePixmap(pixmap); pixmap = 0; } + image = QImage(); } QSizeF MImageWidgetPrivate::imageDataSize() const @@ -57,11 +58,15 @@ QSizeF MImageWidgetPrivate::imageDataSize() const Q_Q(const MImageWidget); QSizeF imageSize = QSizeF(0, 0); - if (pixmap != 0 && !pixmap->isNull()) { - if (q->model()->crop().isEmpty()) - imageSize = pixmap->size(); - else + if ((pixmap != 0 && !pixmap->isNull()) || (!image.isNull())) { + if (q->model()->crop().isEmpty()) { + if (image.isNull()) + imageSize = pixmap->size(); + else + imageSize = image.size(); + } else { imageSize = q->model()->crop().size(); + } } return imageSize; @@ -72,8 +77,12 @@ MImageWidgetPrivate &MImageWidgetPrivate::operator=(const MImageWidgetPrivate &o cleanUp(); if (other.pixmap != 0) { - if (other.deletePixmap) - pixmap = new QPixmap(*(other.pixmap)); + if (other.deletePixmap) { + if (other.pixmap) + pixmap = new QPixmap(*(other.pixmap)); + else + image = other.image; + } else setImageName(other.imageName, other.pixmap->size()); } @@ -130,7 +139,8 @@ MImageWidget::MImageWidget(const QImage *image, QGraphicsItem *parent) : MWidgetController(new MImageWidgetPrivate(), new MImageWidgetModel(), parent) { Q_D(MImageWidget); - d->pixmap = new QPixmap(QPixmap::fromImage(*image)); + d->pixmap = NULL; + d->image = *image; } MImageWidget::MImageWidget(const QPixmap *pixmap, QGraphicsItem *parent) : @@ -180,6 +190,8 @@ QSize MImageWidget::imageSize() const Q_D(const MImageWidget); if (d->pixmap != 0) return d->pixmap->size(); + else + return d->image.size(); return QSize(); } @@ -217,7 +229,8 @@ void MImageWidget::zoomFactor(qreal *fx, qreal *fy) const Q_D(const MImageWidget); QSizeF imageSize = d->imageDataSize(); - if (imageSize.isEmpty()) return; + if (imageSize.isEmpty()) + return; // if factor not equals 0, calculate it with imageSize, targetSize and widgetSize QSizeF buffer; @@ -267,7 +280,8 @@ void MImageWidget::zoomOut() void MImageWidget::setAspectRatioMode(Qt::AspectRatioMode mode) { - if (model()->aspectRatioMode() == mode) return; + if (model()->aspectRatioMode() == mode) + return; model()->setAspectRatioMode(mode); } @@ -279,10 +293,13 @@ Qt::AspectRatioMode MImageWidget::aspectRatioMode() const void MImageWidget::setCrop(const QRectF &rect) { Q_D(MImageWidget); - if (d->pixmap == 0) return; - if (rect.size().width() < 0 || rect.size().height() < 0) return; + if (d->pixmap == 0 && d->image.isNull()) + return; - QSizeF imageSize = d->pixmap->size(); + if (rect.size().width() < 0 || rect.size().height() < 0) + return; + + QSizeF imageSize = this->imageSize(); // protect the crop section size not beyond the image size QRectF r; @@ -330,8 +347,8 @@ void MImageWidget::setImage(const QImage &image) Q_D(MImageWidget); d->cleanUp(); - d->pixmap = new QPixmap(QPixmap::fromImage(image)); - d->deletePixmap = true; + d->image = image; + d->deletePixmap = false; model()->setCrop(QRect()); diff --git a/src/corelib/widgets/mimagewidget_p.h b/src/corelib/widgets/mimagewidget_p.h index 4b3bc3bc..aed5b174 100644 --- a/src/corelib/widgets/mimagewidget_p.h +++ b/src/corelib/widgets/mimagewidget_p.h @@ -40,10 +40,11 @@ public: void deepCopy(const MImageWidget &); - const QPixmap *pixmap; - QString imageName; + const QPixmap *pixmap; + QString imageName; + QImage image; - bool deletePixmap; + bool deletePixmap; }; #endif diff --git a/src/views/mimagewidgetview.cpp b/src/views/mimagewidgetview.cpp index 4ba442e6..b780ced1 100644 --- a/src/views/mimagewidgetview.cpp +++ b/src/views/mimagewidgetview.cpp @@ -18,6 +18,7 @@ ****************************************************************************/ #include "mimagewidgetview.h" +#include "mimagewidgetview_p.h" #include <QPixmap> @@ -26,17 +27,15 @@ #include "mviewcreator.h" #include "private/mwidgetview_p.h" -class MImageWidgetViewPrivate : public MWidgetViewPrivate -{ -public: - MImageWidgetViewPrivate(); - ~MImageWidgetViewPrivate(); - - MImageWidget *controller; -}; - MImageWidgetViewPrivate::MImageWidgetViewPrivate() - : controller(0) + : controller(NULL), + cachedPixmapSize(0, 0), + borderOpacity(1.0), + brush(Qt::transparent), + leftBorder(0.0), + topBorder(0.0), + rightBorder(0.0), + bottomBorder(0.0) { } @@ -44,45 +43,53 @@ MImageWidgetViewPrivate::~MImageWidgetViewPrivate() { } -MImageWidgetView::MImageWidgetView(MImageWidget *controller) : - MWidgetView(* new MImageWidgetViewPrivate, controller) +void MImageWidgetViewPrivate::calculateDrawRect(const QSizeF &imageSize) { - Q_D(MImageWidgetView); - d->controller = controller; -} + Q_Q(MImageWidgetView); -MImageWidgetView::MImageWidgetView(MImageWidgetViewPrivate &dd, MImageWidget *controller) : - MWidgetView(dd, controller) -{ - Q_D(MImageWidgetView); - d->controller = controller; -} + // no image, return + if (imageSize.isEmpty()) + return; -MImageWidgetView::~MImageWidgetView() -{ -} + // get target size, bounded by widget size + QSizeF widgetSize = q->size(); + QSizeF targetSize = widgetSize; + QSizeF t; -void MImageWidgetView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const -{ - Q_UNUSED(option); + // get the image display size + qreal fx, fy; + controller->zoomFactor(&fx, &fy); - Q_D(const MImageWidgetView); + t.setWidth(imageSize.width()*fx); + t.setHeight(imageSize.height()*fy); - // no image, return - QSizeF imageSize = d->controller->d_func()->imageDataSize(); - if (imageSize.isEmpty()) return; + // limited by target size + t = targetSize.boundedTo(t); + + // calculate the rectangle of draw + qreal dx = (widgetSize.width() - t.width()) / 2.0; + qreal dy = (widgetSize.height() - t.height()) / 2.0; - // the source image section size will be used finally + // calculate draw rect + drawRect.setRect(dx, dy, t.width(), t.height()); +} + +QSizeF MImageWidgetViewPrivate::calculateSourceSize(const QSizeF &imageSize) +{ QSizeF sourceSize = imageSize; + QSizeF targetSize = controller->size(); + + // protection codes + if (sourceSize.width() < 1.0) + sourceSize.setWidth(1.0); + if (sourceSize.height() < 1.0) + sourceSize.setHeight(1.0); - // get target size, bounded by widget size - QSizeF widgetSize = size(); - QSizeF targetSize = widgetSize; QSizeF t; // get the image display size qreal fx, fy; - d->controller->zoomFactor(&fx, &fy); + controller->zoomFactor(&fx, &fy); t.setWidth(imageSize.width()*fx); t.setHeight(imageSize.height()*fy); @@ -98,57 +105,55 @@ void MImageWidgetView::drawContents(QPainter *painter, const QStyleOptionGraphic sourceSize.setHeight(qRound(value * targetSize.height() / t.height())); } - // limited by target size - t = targetSize.boundedTo(t); - - // protection codes - if (sourceSize.width() < 1.0) - sourceSize.setWidth(1.0); - if (sourceSize.height() < 1.0) - sourceSize.setHeight(1.0); - - // get values from controller - const QPixmap *pixmap = d->controller->pixmap(); + return sourceSize; +} - qreal leftBorder = style()->borderLeft(); - qreal topBorder = style()->borderTop(); - qreal rightBorder = style()->borderRight(); - qreal bottomBorder = style()->borderBottom(); +void MImageWidgetViewPrivate::calculateSourceRect(const QSizeF &imageSize) +{ + QPointF topLeft = controller->crop().topLeft(); + QSizeF originalSize = controller->imageSize(); + QSizeF sourceSize = calculateSourceSize(imageSize); - qreal w = leftBorder + rightBorder; - qreal h = topBorder + bottomBorder; + if (topLeft == QPointF(-1.0, -1.0)) { + // calculate default crop section + qreal dx = (originalSize.width() - sourceSize.width()) / 2.0; + qreal dy = (originalSize.height() - sourceSize.height()) / 2.0; - // calculate if need draw border - // notice: no border on the cropped edge - QSizeF originSize = pixmap->size(); + sourceRect = QRectF(dx, dy, sourceSize.width(), sourceSize.height()); + } else { + // calculate crop section by given topLeft corner + qreal dx = topLeft.x(); + qreal dy = topLeft.y(); - if (originSize.width() > sourceSize.width()) - w = 0; + sourceRect = QRectF(dx, dy, qMin(dx + sourceSize.width(), originalSize.width()), + qMin(dy + sourceSize.height(), originalSize.height())); + } +} - if (originSize.height() > sourceSize.height()) - h = 0; +void MImageWidgetViewPrivate::checkPixmapSize() +{ + Q_Q(MImageWidgetView); - // calculate the rectangle of draw - qreal dx = (widgetSize.width() - t.width()) / 2.0; - qreal dy = (widgetSize.height() - t.height()) / 2.0; + const QPixmap *pixmap = controller->pixmap(); + if (pixmap->size() != cachedPixmapSize) { + cachedPixmapSize = pixmap->size(); + q->updateGeometry(); + } +} - // calculate draw rect - QRectF drawRect, sourceRect, border; - drawRect.setRect(dx, dy, t.width(), t.height()); +void MImageWidgetViewPrivate::drawBorders(QPainter *painter, const QRectF &drawRect) const +{ + qreal w = leftBorder + rightBorder; + qreal h = topBorder + bottomBorder; - // draw borders outside of target - // if both borders equals 0, do not draw border if (w > 0 || h > 0) { - - QColor borderColor = style()->borderColor(); - qreal borderOpacity = style()->borderOpacity(); - QBrush brush(borderColor); + QRectF border; qreal oldOpacity = painter->opacity(); painter->setOpacity(borderOpacity); - dx = drawRect.x() - leftBorder; - dy = drawRect.y() - topBorder; + qreal dx = drawRect.x() - leftBorder; + qreal dy = drawRect.y() - topBorder; if (w > 0 && h == 0) { // only have horizontal border @@ -165,7 +170,6 @@ void MImageWidgetView::drawContents(QPainter *painter, const QStyleOptionGraphic border = QRectF(drawRect.x(), drawRect.y() + drawRect.height(), drawRect.width(), bottomBorder); painter->fillRect(border, brush); } else { - // draw top border border = QRectF(dx, dy, drawRect.width() + w, topBorder); painter->fillRect(border, brush); @@ -185,27 +189,56 @@ void MImageWidgetView::drawContents(QPainter *painter, const QStyleOptionGraphic painter->setOpacity(oldOpacity); } - // draw image - QPointF topLeft = d->controller->crop().topLeft(); +} - if (topLeft == QPointF(-1.0, -1.0)) { +void MImageWidgetViewPrivate::applyStyle() +{ + Q_Q(MImageWidgetView); - // calculate default crop section - dx = (originSize.width() - sourceSize.width()) / 2.0; - dy = (originSize.height() - sourceSize.height()) / 2.0; + borderOpacity = q->style()->borderOpacity(); + brush.setColor(q->style()->borderColor()); - sourceRect = QRectF(dx, dy, sourceSize.width(), sourceSize.height()); - } else { + leftBorder = q->style()->borderLeft(); + topBorder = q->style()->borderTop(); + rightBorder = q->style()->borderRight(); + bottomBorder = q->style()->borderBottom(); +} - // calculate crop section by given topLeft corner - dx = topLeft.x(); - dy = topLeft.y(); +MImageWidgetView::MImageWidgetView(MImageWidget *controller) : + MWidgetView(* new MImageWidgetViewPrivate, controller) +{ + Q_D(MImageWidgetView); + d->controller = controller; +} - sourceRect = QRectF(dx, dy, qMin(dx + sourceSize.width(), originSize.width()), - qMin(dy + sourceSize.height(), originSize.height())); - } +MImageWidgetView::MImageWidgetView(MImageWidgetViewPrivate &dd, MImageWidget *controller) : + MWidgetView(dd, controller) +{ + Q_D(MImageWidgetView); + d->controller = controller; +} - painter->drawPixmap(drawRect, *pixmap, sourceRect); +MImageWidgetView::~MImageWidgetView() +{ +} + +void MImageWidgetView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const +{ + Q_UNUSED(option); + + Q_D(const MImageWidgetView); + + const QPixmap *pixmap = d->controller->pixmap(); + + d->drawBorders(painter, d->drawRect); + + if (pixmap) { + const_cast<MImageWidgetViewPrivate*>(d)->checkPixmapSize(); + painter->drawPixmap(d->drawRect, *pixmap, d->sourceRect); + } else { + QImage image = d->controller->d_func()->image; + painter->drawImage(d->drawRect, image, d->sourceRect); + } } void MImageWidgetView::resizeEvent(QGraphicsSceneResizeEvent *event) @@ -214,6 +247,37 @@ void MImageWidgetView::resizeEvent(QGraphicsSceneResizeEvent *event) update(); } +void MImageWidgetView::setGeometry(const QRectF &rect) +{ + Q_D(MImageWidgetView); + MWidgetView::setGeometry(rect); + + QSizeF imageSize = d->controller->d_func()->imageDataSize(); + d->calculateDrawRect(imageSize); + d->calculateSourceRect(imageSize); +} + +void MImageWidgetView::applyStyle() +{ + Q_D(MImageWidgetView); + MWidgetView::applyStyle(); + + d->applyStyle(); +} + +void MImageWidgetView::updateData(const QList<const char *> &modifications) +{ + MWidgetView::updateData(modifications); + + const char *member; + for (int i = 0; i < modifications.count(); i++) { + member = modifications[i]; + if (member == MImageWidgetModel::ZoomFactorX || member == MImageWidgetModel::ZoomFactorY || member == MImageWidgetModel::Crop) { + updateGeometry(); + } + } +} + QSizeF MImageWidgetView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const { Q_D(const MImageWidgetView); diff --git a/src/views/mimagewidgetview.h b/src/views/mimagewidgetview.h index 0f1d0040..fd4c80e0 100644 --- a/src/views/mimagewidgetview.h +++ b/src/views/mimagewidgetview.h @@ -72,6 +72,9 @@ protected: //! \reimp virtual void drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const; virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + virtual void setGeometry(const QRectF &rect); + virtual void applyStyle(); + virtual void updateData(const QList<const char *> &modifications); //! \reimp_end //! \internal diff --git a/src/views/mimagewidgetview_p.h b/src/views/mimagewidgetview_p.h new file mode 100644 index 00000000..569643b4 --- /dev/null +++ b/src/views/mimagewidgetview_p.h @@ -0,0 +1,64 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libmeegotouch. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it 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. +** +****************************************************************************/ + +#ifndef MIMAGEWIDGETVIEW_P_H +#define MIMAGEWIDGETVIEW_P_H + +#include "private/mwidgetview_p.h" + +class MImageWidget; + +class MImageWidgetViewPrivate : public MWidgetViewPrivate +{ +public: + MImageWidgetViewPrivate(); + ~MImageWidgetViewPrivate(); + + void calculateDrawRect(const QSizeF &imageSize); + QSizeF calculateSourceSize(const QSizeF &imageSize); + void calculateSourceRect(const QSizeF &imageSize); + + void checkPixmapSize(); + + void drawBorders(QPainter *painter, const QRectF &drawRect) const; + + void applyStyle(); + + + QRectF drawRect; + QRectF sourceRect; + +private: + Q_DECLARE_PUBLIC(MImageWidgetView) + MImageWidget *controller; + + QSize cachedPixmapSize; + + //border related + qreal borderOpacity; + QBrush brush; + + qreal leftBorder; + qreal topBorder; + qreal rightBorder; + qreal bottomBorder; +}; + + +#endif // MIMAGEWIDGETVIEW_P_H |