diff -r 89c329efa980 -r e48454f237ca ganeswidgets/src/hgcoverflowcontainer.cpp --- a/ganeswidgets/src/hgcoverflowcontainer.cpp Mon Apr 19 14:40:06 2010 +0300 +++ b/ganeswidgets/src/hgcoverflowcontainer.cpp Mon May 03 13:32:54 2010 +0300 @@ -16,6 +16,7 @@ */ #include +#include #include #include #include "hgcoverflowcontainer.h" @@ -34,8 +35,9 @@ mDescriptionLabel(0), mTitlePosition(HgMediawall::PositionAboveImage), mDescriptionPosition(HgMediawall::PositionNone), - mCenterIconTop(0), - mPrevPos(-1) + mPrevPos(-1), + mAspectRatio(1), + mDrawableRect(rect()) { mTitleLabel = new HbLabel(this); mTitleLabel->setZValue(zValue()+1); @@ -46,6 +48,9 @@ mDescriptionLabel->setZValue(zValue()+1); mDescriptionLabel->setAlignment(Qt::AlignCenter); mDescriptionLabel->setVisible(false); + + mUserItemSize = QSize(250,250); + mUserItemSpacing = QSize(1,1); } HgCoverflowContainer::~HgCoverflowContainer() @@ -64,24 +69,18 @@ HbWidget::resizeEvent(event); - QSizeF s(size()); - qreal side = qMin(s.height()/1.8, s.width()/1.8); - INFO("Setting image size to:" << side << "," << side); - mRenderer->setImageSize(QSizeF(side, side)); - mCenterIconTop = (s.height()-side)/2; - - positionLabels(); + updatePositions(); } // from HgContainer -HgMediaWallRenderer* HgCoverflowContainer::createRenderer() +HgMediaWallRenderer* HgCoverflowContainer::createRenderer(Qt::Orientation scrollDirection) { - HgMediaWallRenderer* renderer = new HgMediaWallRenderer(this); - renderer->setImageSize(QSizeF(200, 200)); + HgMediaWallRenderer* renderer = new HgMediaWallRenderer(this, scrollDirection, true); + renderer->setImageSize(mUserItemSize); renderer->enableCoverflowMode(true); renderer->setRowCount(1, renderer->getImageSize(), false); renderer->enableReflections(true); - renderer->setSpacing(QSizeF(1,1)); + renderer->setSpacing(mUserItemSpacing); renderer->setFrontCoverElevationFactor(0.5); return renderer; } @@ -121,12 +120,16 @@ { HgContainer::onScrollPositionChanged(pos); - if (mPrevPos != (int)pos) { - mPrevPos = (int)pos; - HgWidgetItem* item = itemByIndex((int)pos); + qreal ipos = floorf(pos); + qreal frac = pos - ipos; + qreal p = frac > 0.5 ? ipos + 1.0f : ipos; + + if (mPrevPos != (int)p) { + mPrevPos = (int)p; + HgWidgetItem* item = itemByIndex((int)p); if (item && item->modelIndex() != mSelectionModel->currentIndex()) { mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current); - } + } } } @@ -152,6 +155,15 @@ updateLabels(current); } } + + if (firstIndex == 0) { + // Take preferred aspect ratio from the first image + const HgImage *firstImage = image(0); + if (firstImage && firstImage->height() != 0) { + mAspectRatio = qMax((qreal)0.1, (qreal)firstImage->width()/firstImage->height()); // Don't let aspect ratio go to 0 + updatePositions(); + } + } } void HgCoverflowContainer::setTitlePosition(HgMediawall::LabelPosition position) @@ -160,7 +172,7 @@ if (mTitlePosition != position) { mTitlePosition = position; - positionLabels(); + updatePositions(); } } @@ -177,7 +189,7 @@ if (mDescriptionPosition != position) { mDescriptionPosition = position; - positionLabels(); + updatePositions(); } } @@ -195,7 +207,7 @@ if (!mTitleLabel) return; if (mTitleLabel->fontSpec() != fontSpec) { mTitleLabel->setFontSpec(fontSpec); - positionLabels(); + updatePositions(); } } @@ -214,7 +226,7 @@ if (!mDescriptionLabel) return; if (mDescriptionLabel->fontSpec() != fontSpec) { mDescriptionLabel->setFontSpec(fontSpec); - positionLabels(); + updatePositions(); } } @@ -226,6 +238,106 @@ return mDescriptionLabel->fontSpec(); } +void HgCoverflowContainer::calculatePositions() +{ + FUNC_LOG; + HANDLE_ERROR_NULL(mTitleLabel); + HANDLE_ERROR_NULL(mDescriptionLabel); + + int height = size().height(); + int width = size().width(); + int titleHeight = QFontMetrics(mTitleLabel->effectiveFontSpec().font()).height(); + int descriptionHeight = QFontMetrics(mDescriptionLabel->effectiveFontSpec().font()).height(); + qreal usableHeight = height-KLabelMargin; + if (mTitlePosition != HgMediawall::PositionNone) { + usableHeight -= (titleHeight+KLabelMargin); + } + if (mDescriptionPosition != HgMediawall::PositionNone) { + usableHeight -= (descriptionHeight+KLabelMargin); + } + + usableHeight *= 0.8; // Leave some space for the reflection + if (usableHeight <= 0) return; + + qreal usableWidth = width/2; + if (usableWidth <= 0) return; + + mDrawableRect = rect(); + QSizeF imageSize; + if (usableWidth/usableHeight > mAspectRatio) { + imageSize.setHeight(usableHeight); + imageSize.setWidth(mAspectRatio*usableHeight); + } + else { + imageSize.setWidth(usableWidth); + imageSize.setHeight(usableWidth/mAspectRatio); + mDrawableRect.setTop((usableHeight-imageSize.height())/2); + } + + QRectF titleGeometry(0, mDrawableRect.top()+KLabelMargin, width, titleHeight); + QRectF descriptionGeometry(0, mDrawableRect.top()+KLabelMargin, width, descriptionHeight); + + if (mTitlePosition == HgMediawall::PositionAboveImage && + mDescriptionPosition == HgMediawall::PositionAboveImage) { + // titleGeometry default is ok + descriptionGeometry.moveTop(titleGeometry.bottom()+KLabelMargin); + mDrawableRect.setTop(descriptionGeometry.bottom()+KLabelMargin); + } + else if (mTitlePosition == HgMediawall::PositionBelowImage && + mDescriptionPosition == HgMediawall::PositionBelowImage) { + titleGeometry.moveTop(mDrawableRect.top()+imageSize.height()+KLabelMargin); + descriptionGeometry.moveTop(titleGeometry.bottom()+KLabelMargin); + } + else { + if (mTitlePosition == HgMediawall::PositionAboveImage) { + // titleGeometry default is ok + mDrawableRect.setTop(titleGeometry.bottom()+KLabelMargin); + } + else if (mDescriptionPosition == HgMediawall::PositionAboveImage) { + // descriptionGeometry default is ok + mDrawableRect.setTop(descriptionGeometry.bottom()+KLabelMargin); + } + + if (mTitlePosition == HgMediawall::PositionBelowImage) { + titleGeometry.moveTop(mDrawableRect.top()+imageSize.height()+KLabelMargin); + } + else if (mDescriptionPosition == HgMediawall::PositionBelowImage) { + descriptionGeometry.moveTop(mDrawableRect.top()+imageSize.height()+KLabelMargin); + } + } + + INFO("Setting image size to:" << imageSize << "(total size:" << QSize(width, height) + << "usable size:" << QSizeF(usableWidth, usableHeight) << ", aspect ratio is:" << mAspectRatio << ")" << "Drawable rect:" << mDrawableRect); + mRenderer->setImageSize(imageSize); + mAutoSize = imageSize; + mDrawableRect.setHeight(imageSize.height()/0.8); + + if (mTitlePosition != HgMediawall::PositionNone) { + INFO("Title geometry:" << titleGeometry); + mTitleLabel->setGeometry(titleGeometry); + mTitleLabel->setVisible(true); + } + else { + mTitleLabel->setVisible(false); + } + if (mDescriptionPosition != HgMediawall::PositionNone) { + INFO("Description geometry:" << descriptionGeometry); + mDescriptionLabel->setGeometry(descriptionGeometry); + mDescriptionLabel->setVisible(true); + } + else { + mDescriptionLabel->setVisible(false); + } + + // This may be called before selection model is set. + if (mSelectionModel && mSelectionModel->currentIndex().isValid()) { + updateLabels(mSelectionModel->currentIndex().row()); + } + + mRenderer->setSpacing(QSizeF(1,1)); + +} + void HgCoverflowContainer::positionLabels() { FUNC_LOG; @@ -233,6 +345,8 @@ HANDLE_ERROR_NULL(mDescriptionLabel); HANDLE_ERROR_NULL(mSelectionModel); + int centerIconTop = (size().height() - mRenderer->getImageSize().height()) / 2; + int height = size().height(); int width = size().width(); int titleHeight = QFontMetrics(mTitleLabel->effectiveFontSpec().font()).height(); @@ -242,7 +356,7 @@ mDescriptionPosition == HgMediawall::PositionAboveImage) { mTitleLabel->setGeometry(QRectF( 0, - qMax(KLabelMargin, mCenterIconTop-2*KLabelMargin-titleHeight-descriptionHeight), + qMax(KLabelMargin, centerIconTop-2*KLabelMargin-titleHeight-descriptionHeight), width, titleHeight)); mDescriptionLabel->setGeometry(QRectF( 0, @@ -264,7 +378,7 @@ if (mTitlePosition == HgMediawall::PositionAboveImage) { mTitleLabel->setGeometry(QRectF( 0, - qMax(KLabelMargin, mCenterIconTop-KLabelMargin-titleHeight), + qMax(KLabelMargin, centerIconTop-KLabelMargin-titleHeight), width, titleHeight)); } else if (mTitlePosition == HgMediawall::PositionBelowImage) { @@ -277,7 +391,7 @@ if (mDescriptionPosition == HgMediawall::PositionAboveImage) { mDescriptionLabel->setGeometry(QRectF( 0, - qMax(KLabelMargin, mCenterIconTop-KLabelMargin-descriptionHeight), + qMax(KLabelMargin, centerIconTop-KLabelMargin-descriptionHeight), width, descriptionHeight)); } else if (mDescriptionPosition == HgMediawall::PositionBelowImage) { @@ -294,11 +408,12 @@ INFO("Title geometry:" << mTitleLabel->geometry() << "visible:" << mTitleLabel->isVisible()); INFO("Description geometry:" << mDescriptionLabel->geometry() << "visible:" << mDescriptionLabel->isVisible()); - if (mSelectionModel->currentIndex().isValid()) { + if ( mSelectionModel && mSelectionModel->currentIndex().isValid()) { updateLabels(mSelectionModel->currentIndex().row()); } } + void HgCoverflowContainer::updateLabels(int itemIndex) { FUNC_LOG; @@ -317,3 +432,75 @@ p.setX((int)pos.x()); HgContainer::scrollToPosition(p,animate); } + +QRectF HgCoverflowContainer::drawableRect() const +{ + if (mItemSizePolicy == HgWidget::ItemSizeAutomatic) + return mDrawableRect; + + return rect(); +} + +void HgCoverflowContainer::setDefaultImage(QImage defaultImage) +{ + HgContainer::setDefaultImage(defaultImage); + + if (!defaultImage.isNull()) { + mAspectRatio = qMax((qreal)0.1, (qreal)defaultImage.width()/defaultImage.height()); // Don't let aspect ratio go to 0 + updatePositions(); + } +} + +QSizeF HgCoverflowContainer::getAutoItemSize() const +{ + return mAutoSize; +} + +QSizeF HgCoverflowContainer::getAutoItemSpacing() const +{ + return QSizeF(1,1); +} + +void HgCoverflowContainer::updateItemSizeAndSpacing() +{ + HgContainer::updateItemSizeAndSpacing(); + + updatePositions(); +} + + +void HgCoverflowContainer::updatePositions() +{ + if (mItemSizePolicy == HgWidget::ItemSizeAutomatic) + calculatePositions(); + else + { + positionLabels(); + } +} + +void HgCoverflowContainer::setFrontItemPositionDelta(const QPointF& position) +{ + if (!mRenderer) + return; + + mRenderer->setFrontItemPosition(position); +} + +QPointF HgCoverflowContainer::frontItemPositionDelta() const +{ + return mRenderer ? mRenderer->frontItemPosition() : QPointF(); +} + +void HgCoverflowContainer::enableReflections(bool enabled) +{ + if (mRenderer) + mRenderer->enableReflections(enabled); +} + +bool HgCoverflowContainer::reflectionsEnabled() const +{ + return mRenderer ? mRenderer->reflectionsEnabled() : false; +} + +