Home · All Classes · Main Classes · Deprecated

mwidgetview.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002 **
00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
00004 ** All rights reserved.
00005 ** Contact: Nokia Corporation (directui@nokia.com)
00006 **
00007 ** This file is part of libmeegotouch.
00008 **
00009 ** If you have questions regarding the use of this file, please contact
00010 ** Nokia at directui@nokia.com.
00011 **
00012 ** This library is free software; you can redistribute it and/or
00013 ** modify it under the terms of the GNU Lesser General Public
00014 ** License version 2.1 as published by the Free Software Foundation
00015 ** and appearing in the file LICENSE.LGPL included in the packaging
00016 ** of this file.
00017 **
00018 ****************************************************************************/
00019 
00020 #include "mwidgetview.h"
00021 #include "mwidgetview_p.h"
00022 
00023 #include "mfeedback.h"
00024 #include "mtheme.h"
00025 #include "mwidgetcontroller.h"
00026 #include "mscalableimage.h"
00027 #include <QGraphicsSceneMouseEvent>
00028 #include <QGraphicsLayout>
00029 #include <QPainter>
00030 #include "mapplicationpage.h"
00031 #include "mwidgetmodel.h"
00032 #include "mapplication.h"
00033 #include "mapplicationwindow.h"
00034 #include "mclassfactory.h"
00035 
00036 #include <QGestureEvent>
00037 #include <QTapAndHoldGesture>
00038 #include <QPanGesture>
00039 #include <QPinchGesture>
00040 #include <QTapGesture>
00041 #include <QSwipeGesture>
00042 
00043 MWidgetViewPrivate::MWidgetViewPrivate() :
00044     q_ptr(NULL),
00045     controller(NULL),
00046     model(NULL),
00047     styleContainer(NULL)
00048 {
00049 }
00050 
00051 MWidgetViewPrivate::~MWidgetViewPrivate()
00052 {
00053 }
00054 
00055 void MWidgetViewPrivate::setActive(bool active)
00056 {
00057     if (active) {
00058         styleContainer->setModeActive();
00059     } else {
00060         styleContainer->setModeDefault();
00061     }
00062 }
00063 
00064 void MWidgetViewPrivate::setEnabled(bool enabled)
00065 {
00066     if (enabled)
00067         styleContainer->setModeDefault();
00068     else
00069         styleContainer->setModeDisabled();
00070 
00071     // Apply style mode recursively to child items
00072     foreach(QGraphicsItem *item, controller->childItems()) {
00073         MWidgetController *widget = dynamic_cast<MWidgetController*>(item);
00074         if (widget) {
00075             MWidgetViewPrivate *viewPrivate = const_cast<MWidgetViewPrivate*>(widget->view()->d_func());
00076             if (enabled && widget->isEnabled())
00077                 viewPrivate->setEnabled(true);
00078             else
00079                 viewPrivate->setEnabled(false);
00080         }
00081     }
00082 }
00083 
00084 void MWidgetViewPrivate::setSelected(bool selected)
00085 {
00086     if (selected)
00087         styleContainer->setModeSelected();
00088     else
00089         styleContainer->setModeDefault();
00090 
00091     // Apply style mode recursively to child items
00092     foreach(QGraphicsItem *item, controller->childItems()) {
00093         MWidgetController *widget = dynamic_cast<MWidgetController*>(item);
00094         if (widget) {
00095             MWidgetViewPrivate *viewPrivate = const_cast<MWidgetViewPrivate*>(widget->view()->d_func());
00096             if (selected || widget->isSelected())
00097                 viewPrivate->setSelected(true);
00098             else
00099                 viewPrivate->setSelected(false);
00100         }
00101     }
00102 }
00103 
00104 MWidgetView::MWidgetView() :
00105     d_ptr(new MWidgetViewPrivate)
00106 {
00107     Q_D(MWidgetView);
00108     d->q_ptr = this;
00109 }
00110 
00111 MWidgetView::MWidgetView(MWidgetViewPrivate *dd) :
00112     d_ptr(dd)
00113 {
00114     Q_D(MWidgetView);
00115     d->q_ptr = this;
00116 }
00117 
00118 MWidgetView::MWidgetView(MWidgetController *controller) :
00119     d_ptr(new MWidgetViewPrivate)
00120 {
00121     // old way, we shouldn't need controller in the view side.
00122     Q_D(MWidgetView);
00123     d->q_ptr = this;
00124     d->controller = controller;
00125 }
00126 
00127 MWidgetView::MWidgetView(MWidgetViewPrivate &dd, MWidgetController *controller) :
00128     d_ptr(&dd)
00129 {
00130     // old way, we shouldn't need controller in the view side.
00131     Q_D(MWidgetView);
00132     d->q_ptr = this;
00133     d->controller = controller;
00134 }
00135 
00136 MWidgetView::~MWidgetView()
00137 {
00138     Q_D(MWidgetView);
00139 
00140     d->model->decreaseReferenceCount();
00141     d->model = 0;
00142     delete d->styleContainer;
00143     delete d_ptr;
00144 }
00145 
00146 void MWidgetView::destroy()
00147 {
00148     // TODO: animate away
00149     /*
00150         deleteLater(); // Use deleteLater() for QObjects instead of "delete this"
00151     */
00152     // TODO: replace this with something when there's a better solution available.
00153     // deleteLater() breaks theme change.
00154     delete this;
00155 }
00156 
00157 void MWidgetView::setActive(bool active)
00158 {
00159     Q_D(MWidgetView);
00160 
00161     d->setActive(active);
00162 }
00163 
00164 void MWidgetView::setModel(MWidgetModel *model)
00165 {
00166     Q_ASSERT(model);
00167 
00168     Q_D(MWidgetView);
00169 
00170     if (model == d->model)
00171         return;
00172 
00173     if (d->model) {
00174         disconnect(d->model, 0, this, 0);
00175         d->model->decreaseReferenceCount();
00176     }
00177 
00178     d->model = model;
00179     d->model->increaseReferenceCount();
00180 
00181     if (!d->styleContainer) {
00182         d->styleContainer = createStyleContainer();
00183     }
00184 
00185     MWidgetController *parent = NULL;
00186     QGraphicsItem *p = d->controller->parentItem();
00187     while (p && !(parent = dynamic_cast<MWidgetController *>(p))) {
00188         p = p->parentItem();
00189     }
00190 
00191     //The default style type is "", not "default".
00192     QString styleType = d->model->viewType();
00193     if (styleType == MWidgetController::defaultType)
00194         styleType.clear();
00195 
00196     QString styleName;
00197     if (d->model->styleName().isNull())
00198         styleName = d->model->objectName(); // fallback to old behavior
00199     else
00200         styleName = d->model->styleName();
00201     d->styleContainer->initialize(styleName, styleType, parent);
00202 
00203     if (d->controller->isActive()) {
00204         setActive(true);
00205     } else if (!d->controller->isEnabled()) {
00206         notifyItemChange(QGraphicsItem::ItemEnabledHasChanged, false);
00207     } else if (d->controller->isSelected()) {
00208         notifyItemChange(QGraphicsItem::ItemSelectedHasChanged, true);
00209     }
00210 
00211     // TODO: to be removed when scalable image is ready
00212     applyStyle();
00213 
00214     // notify derived classes
00215     setupModel();
00216 }
00217 
00218 void MWidgetView::updateData(const QList<const char *>& modifications)
00219 {
00220     const char *member;
00221     foreach(member, modifications) {
00222         if (member == MWidgetModel::ObjectName ||
00223             member == MWidgetModel::StyleName) {
00224             // style name has changed, we need to update the style
00225             QString styleName(QString::null);
00226             if (model()->styleName().isNull())
00227                 styleName = model()->objectName(); // fallback to old behavior
00228             else
00229                 styleName = model()->styleName();
00230             style().setObjectName(styleName);
00231             // TODO: to be removed
00232             applyStyle();
00233         } else if (member == MWidgetModel::ViewType) {
00234             style().setType(model()->viewType());
00235         } else if (member == MWidgetModel::Position) {
00236         }
00237     }
00238 }
00239 
00240 
00241 void MWidgetView::updateMicroFocus()
00242 {
00243     Q_D(MWidgetView);
00244 
00245     d->controller->updateMicroFocus();
00246 }
00247 
00248 
00249 void MWidgetView::setupModel()
00250 {
00251     Q_D(MWidgetView);
00252     connect(d->model, SIGNAL(modified(QList<const char *>)),
00253             this, SLOT(updateData(QList<const char *>)));
00254 
00255     update();
00256 }
00257 
00258 void MWidgetView::applyStyle()
00259 {
00260     Q_D(MWidgetView);
00261 
00262     if (d->controller->layoutDirection() == Qt::RightToLeft)
00263         d->controller->setContentsMargins(
00264             style()->paddingRight() + style()->marginRight(),
00265             style()->paddingTop() + style()->marginTop(),
00266             style()->paddingLeft() + style()->marginLeft(),
00267             style()->paddingBottom() + style()->marginBottom());
00268     else
00269         d->controller->setContentsMargins(
00270             style()->paddingLeft() + style()->marginLeft(),
00271             style()->paddingTop() + style()->marginTop(),
00272             style()->paddingRight() + style()->marginRight(),
00273             style()->paddingBottom() + style()->marginBottom());
00274 
00275     updateGeometry();
00276     update();
00277 }
00278 
00279 MWidgetModel *MWidgetView::model()
00280 {
00281     Q_D(MWidgetView);
00282     return d->model;
00283 }
00284 
00285 const MWidgetModel *MWidgetView::model() const
00286 {
00287     Q_D(const MWidgetView);
00288     return d->model;
00289 }
00290 
00291 MWidgetStyleContainer &MWidgetView::style()
00292 {
00293     Q_D(MWidgetView);
00294     return *d->styleContainer;
00295 }
00296 
00297 const MWidgetStyleContainer &MWidgetView::style() const
00298 {
00299     Q_D(const MWidgetView);
00300     return *d->styleContainer;
00301 }
00302 
00303 QRect MWidgetView::margins() const
00304 {
00305     const MWidgetStyle *s = static_cast<const MWidgetStyle*>(style().operator->());
00306     return QRect(s->marginLeft(),
00307                  s->marginTop(),
00308                  s->marginRight(),
00309                  s->marginBottom());
00310 }
00311 
00312 int MWidgetView::marginLeft() const
00313 {
00314     return style()->marginLeft();
00315 }
00316 
00317 int MWidgetView::marginTop() const
00318 {
00319     return style()->marginTop();
00320 }
00321 
00322 int MWidgetView::marginRight() const
00323 {
00324     return style()->marginRight();
00325 }
00326 
00327 int MWidgetView::marginBottom() const
00328 {
00329     return style()->marginBottom();
00330 }
00331 
00332 QRect MWidgetView::reactiveMargins() const
00333 {
00334     const MWidgetStyle *s = static_cast<const MWidgetStyle*>(style().operator->());
00335     return QRect(s->reactiveMarginLeft(),
00336                  s->reactiveMarginTop(),
00337                  s->reactiveMarginRight(),
00338                  s->reactiveMarginBottom());
00339 }
00340 
00341 int MWidgetView::reactiveMarginLeft() const
00342 {
00343     return style()->reactiveMarginLeft();
00344 }
00345 
00346 int MWidgetView::reactiveMarginTop() const
00347 {
00348     return style()->reactiveMarginTop();
00349 }
00350 
00351 int MWidgetView::reactiveMarginRight() const
00352 {
00353     return style()->reactiveMarginRight();
00354 }
00355 
00356 int MWidgetView::reactiveMarginBottom() const
00357 {
00358     return style()->reactiveMarginBottom();
00359 }
00360 
00361 QRectF MWidgetView::boundingRect() const
00362 {
00363     return QRectF(QPointF(), size());
00364 }
00365 
00366 QPainterPath MWidgetView::shape() const
00367 {
00368     QPainterPath path;
00369     QRectF br = boundingRect();
00370     br.setRect(br.x() - reactiveMarginLeft(),
00371                br.y() - reactiveMarginTop(),
00372                br.width()  + marginLeft() + marginRight() + reactiveMarginLeft() +  reactiveMarginRight(),
00373                br.height() + marginTop() + marginBottom() + reactiveMarginTop() + reactiveMarginBottom());
00374     path.addRect(br);
00375     return path;
00376 }
00377 
00378 void MWidgetView::mousePressEvent(QGraphicsSceneMouseEvent *event)
00379 {
00380     style()->pressFeedback().play();
00381 
00382     // Ignore the event by default so it will propagate to widgets below
00383     event->ignore();
00384 }
00385 
00386 void MWidgetView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
00387 {
00388     style()->releaseFeedback().play();
00389 
00390     // Ignore the event by default so it will propagate to widgets below
00391     event->ignore();
00392 }
00393 
00394 void MWidgetViewPrivate::reloadChildItemsStyles(QGraphicsItem* item)
00395 {
00396     foreach(QGraphicsItem* child, item->childItems()) {
00397         reloadChildItemsStyles(child);
00398 
00399         if (!child->isWidget()) {
00400             continue;
00401         }
00402         QGraphicsWidget *graphicsWidget = static_cast<QGraphicsWidget*>(child);
00403         MWidgetController *widget = qobject_cast<MWidgetController*>(graphicsWidget);
00404 
00405         MWidgetView *view = widget ? const_cast<MWidgetView*>(widget->view()) : NULL;
00406         if (view) {
00407             MWidgetStyleContainer& style = view->style();
00408             style.reloadStyles();
00409             view->applyStyle();
00410         }
00411     }
00412 }
00413 
00414 void MWidgetView::notifyItemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
00415 {
00416     Q_D(MWidgetView);
00417     if (change == QGraphicsItem::ItemEnabledHasChanged) {
00418         d->setEnabled(d->controller->isEnabled());
00419     } else if (change == QGraphicsItem::ItemSelectedHasChanged) {
00420         if (d->controller->isEnabled()) {
00421             d->setSelected(d->controller->isSelected());
00422         }
00423     } else if (change == QGraphicsItem::ItemParentHasChanged) {
00424         MWidgetController *parent = NULL;
00425         QGraphicsItem *p = d->controller->parentItem();
00426         while (p && !(parent = dynamic_cast<MWidgetController *>(p))) {
00427             p = p->parentItem();
00428         }
00429 
00430         style().setParent(parent);
00431         if (value.value<QGraphicsItem*>() != NULL) {
00432             d->reloadChildItemsStyles(d->controller);
00433             applyStyle();
00434         }
00435     }
00436 }
00437 void MWidgetView::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
00438 {
00439     Q_UNUSED(event);
00440 }
00441 
00442 void MWidgetView::cancelEvent(MCancelEvent *event)
00443 {
00444     style()->cancelFeedback().play();
00445 
00446     Q_UNUSED(event);
00447 }
00448 
00449 void MWidgetView::orientationChangeEvent(MOrientationChangeEvent *event)
00450 {
00451     Q_UNUSED(event);
00452     applyStyle();
00453 }
00454 
00455 void MWidgetView::tapAndHoldGestureEvent(QGestureEvent *event, QTapAndHoldGesture *gesture)
00456 {
00457     event->ignore(gesture);
00458 }
00459 
00460 void MWidgetView::panGestureEvent(QGestureEvent *event, QPanGesture *gesture)
00461 {
00462     event->ignore(gesture);
00463 }
00464 
00465 void MWidgetView::pinchGestureEvent(QGestureEvent *event, QPinchGesture* gesture)
00466 {
00467     event->ignore(gesture);
00468 }
00469 
00470 void MWidgetView::tapGestureEvent(QGestureEvent *event, QTapGesture* gesture)
00471 {
00472     event->ignore(gesture);
00473 }
00474 
00475 void MWidgetView::swipeGestureEvent(QGestureEvent *event, QSwipeGesture* gesture)
00476 {
00477     event->ignore(gesture);
00478 }
00479 
00480 void MWidgetView::setGeometry(const QRectF &rect)
00481 {
00482     Q_UNUSED(rect);
00483 }
00484 
00485 void MWidgetView::update(const QRectF &rect)
00486 {
00487     Q_D(MWidgetView);
00488     d->controller->update(rect);
00489 }
00490 
00491 void MWidgetView::update(qreal x, qreal y, qreal width, qreal height)
00492 {
00493     Q_D(MWidgetView);
00494     d->controller->update(x, y, width, height);
00495 }
00496 
00497 void MWidgetView::updateGeometry()
00498 {
00499     Q_D(MWidgetView);
00500     d->controller->updateGeometry();
00501 }
00502 
00503 QRectF MWidgetView::geometry() const
00504 {
00505     Q_D(const MWidgetView);
00506     QRectF controllerGeom = d->controller->geometry();
00507     return QRectF(controllerGeom.topLeft() + QPointF(marginLeft(), marginTop()),
00508                   controllerGeom.bottomRight() - QPointF(marginRight(), marginBottom()));
00509 }
00510 
00511 QSizeF MWidgetView::size() const
00512 {
00513     Q_D(const MWidgetView);
00514     return d->controller->size() - QSizeF(marginLeft() + marginRight(), marginTop() + marginBottom());
00515 }
00516 
00517 QPointF MWidgetView::pos() const
00518 {
00519     Q_D(const MWidgetView);
00520     return d->controller->pos() + QPointF(marginLeft(), marginTop());
00521 }
00522 
00523 QRectF MWidgetView::rect() const
00524 {
00525     return QRectF(QPointF(0, 0), size());
00526 }
00527 
00528 QVariant MWidgetView::inputMethodQuery(Qt::InputMethodQuery query) const
00529 {
00530     Q_UNUSED(query);
00531     return QVariant();
00532 }
00533 
00534 void MWidgetView::resizeEvent(QGraphicsSceneResizeEvent *event)
00535 {
00536     Q_UNUSED(event);
00537 }
00538 
00539 
00540 void MWidgetView::changeEvent(QEvent *event)
00541 {
00542     // styles can depend on right-to-left e.g. left and right margins
00543     // get switched.
00544     if (event->type() == QEvent::LayoutDirectionChange)
00545         applyStyle();
00546 }
00547 
00548 void MWidgetView::show()
00549 {
00550     Q_D(MWidgetView);
00551     d->controller->show();
00552 }
00553 
00554 void MWidgetView::hide()
00555 {
00556     Q_D(MWidgetView);
00557     d->controller->hide();
00558 }
00559 
00560 qreal MWidgetView::effectiveOpacity() const
00561 {
00562     Q_D(const MWidgetView);
00563     return d->controller->effectiveOpacity();
00564 }
00565 
00566 qreal MWidgetView::opacity() const
00567 {
00568     Q_D(const MWidgetView);
00569     return d->controller->opacity();
00570 }
00571 
00572 qreal MWidgetView::scale() const
00573 {
00574     Q_D(const MWidgetView);
00575     return d->controller->scale();
00576 }
00577 
00578 
00579 QFont MWidgetView::font() const
00580 {
00581     return QFont();
00582 }
00583 
00584 void MWidgetView::setOpacity(qreal opacity)
00585 {
00586     Q_D(MWidgetView);
00587     d->controller->setOpacity(opacity);
00588 }
00589 
00590 void MWidgetView::setScale(qreal scale)
00591 {
00592     Q_D(MWidgetView);
00593     d->controller->setScale(scale);
00594 }
00595 
00596 bool MWidgetView::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
00597 {
00598     Q_UNUSED(watched);
00599     Q_UNUSED(event);
00600     return false;  //by default, don't catch the event.  Allow it to continue to propagate
00601 }
00602 
00603 QSizeF MWidgetView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
00604 {
00605     Q_UNUSED(which);
00606     Q_UNUSED(constraint);
00607     return QSizeF(-1,-1);
00608 }
00609 
00610 void MWidgetView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
00611 {
00612     Q_D(MWidgetView);
00613     Q_UNUSED(widget);
00614 
00615     int horizontalMargin = 0;
00616     if (d->controller->layoutDirection() == Qt::LeftToRight)
00617         horizontalMargin = marginLeft();
00618     else
00619         horizontalMargin = marginRight();
00620 
00621     painter->translate(horizontalMargin, marginTop());
00622     drawBackground(painter, option);
00623     drawContents(painter, option);
00624     painter->translate(-horizontalMargin, -marginTop());
00625     drawForeground(painter, option);
00626 }
00627 
00628 void MWidgetView::drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option) const
00629 {
00630     Q_UNUSED(option);
00631     QSizeF currentSize = size();
00632 
00633     if (currentSize.width() == 0 || currentSize.height() == 0)
00634         return;
00635 
00636     qreal oldOpacity = painter->opacity();
00637     painter->setOpacity(style()->backgroundOpacity() * effectiveOpacity());
00638 
00639     if (style()->backgroundTiles().isValid()) {
00640         style()->backgroundTiles()[model()->layoutPosition()]->draw(0,0, currentSize.width(), currentSize.height(), painter);
00641     }
00642     else if (style()->backgroundImage()) {
00643         style()->backgroundImage()->draw(0, 0, currentSize.width(), currentSize.height(), painter);
00644     } else if (style()->backgroundColor().isValid()) {
00645         painter->fillRect(boundingRect(), QBrush(style()->backgroundColor()));
00646     }
00647     painter->setOpacity(oldOpacity);
00648 }
00649 
00650 void MWidgetView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const
00651 {
00652     Q_UNUSED(painter);
00653     Q_UNUSED(option);
00654 }
00655 
00656 void MWidgetView::drawForeground(QPainter *painter, const QStyleOptionGraphicsItem *option) const
00657 {
00658     Q_UNUSED(painter);
00659     Q_UNUSED(option);
00660 }
00661 
00662 M_REGISTER_VIEW(MWidgetView, MApplicationPage)
00663 #include "moc_mwidgetview.cpp"

Copyright © 2010 Nokia Corporation Generated on Thu Nov 4 2010 18:14:22 (PDT)
Doxygen 1.7.1
MeeGo Touch