| Home · All Classes · Main Classes · Deprecated |
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 |