/* * Strawberry Music Player * This file was part of Clementine. * Copyright 2010, David Sansome * * Strawberry is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Strawberry is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Strawberry. If not, see . * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "core/networkaccessmanager.h" #include "prettyimage.h" #include "prettyimageview.h" PrettyImageView::PrettyImageView(QNetworkAccessManager *network, QWidget* parent) : QScrollArea(parent), network_(network), container_(new QWidget(this)), layout_(new QHBoxLayout(container_)), current_index_(-1), scroll_animation_(new QPropertyAnimation(horizontalScrollBar(), "value", this)), recursion_filter_(false) { setWidget(container_); setWidgetResizable(true); setMinimumHeight(PrettyImage::kTotalHeight + 10); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); setFrameShape(QFrame::NoFrame); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scroll_animation_->setDuration(250); scroll_animation_->setEasingCurve(QEasingCurve::InOutCubic); connect(horizontalScrollBar(), SIGNAL(sliderReleased()), SLOT(ScrollBarReleased())); connect(horizontalScrollBar(), SIGNAL(actionTriggered(int)), SLOT(ScrollBarAction(int))); layout_->setSizeConstraint(QLayout::SetMinAndMaxSize); layout_->setContentsMargins(6, 6, 6, 6); layout_->setSpacing(6); layout_->addSpacing(200); layout_->addSpacing(200); container_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); } bool PrettyImageView::eventFilter(QObject *obj, QEvent *event) { // Work around infinite recursion in QScrollArea resizes. if (recursion_filter_) { return false; } recursion_filter_ = true; bool ret = QScrollArea::eventFilter(obj, event); recursion_filter_ = false; return ret; } void PrettyImageView::AddImage(const QUrl &url) { PrettyImage *image = new PrettyImage(url, network_, container_); connect(image, SIGNAL(destroyed()), SLOT(ScrollToCurrent())); connect(image, SIGNAL(Loaded()), SLOT(ScrollToCurrent())); layout_->insertWidget(layout_->count() - 1, image); if (current_index_ == -1) ScrollTo(0); } void PrettyImageView::mouseReleaseEvent(QMouseEvent *e) { // Find the image that was clicked on QWidget *widget = container_->childAt(container_->mapFrom(this, e->pos())); if (!widget) return; // Get the index of that image const int index = layout_->indexOf(widget) - 1; if (index == -1) return; if (index == current_index_) { // Show the image fullsize PrettyImage* pretty_image = qobject_cast(widget); if (pretty_image) { pretty_image->ShowFullsize(); } } else { // Scroll to the image ScrollTo(index); } } void PrettyImageView::ScrollTo(const int index, const bool smooth) { current_index_ = qBound(0, index, layout_->count() - 3); const int layout_index = current_index_ + 1; const QWidget *target_widget = layout_->itemAt(layout_index)->widget(); if (!target_widget) return; const int current_x = horizontalScrollBar()->value(); const int target_x = target_widget->geometry().center().x() - width() / 2; if (current_x == target_x) return; if (smooth) { scroll_animation_->setStartValue(current_x); scroll_animation_->setEndValue(target_x); scroll_animation_->start(); } else { scroll_animation_->stop(); horizontalScrollBar()->setValue(target_x); } } void PrettyImageView::ScrollToCurrent() { ScrollTo(current_index_); } void PrettyImageView::ScrollBarReleased() { // Find the nearest widget to where the scroll bar was released const int current_x = horizontalScrollBar()->value() + width() / 2; int layout_index = 1; for (; layout_index < layout_->count() - 1; ++layout_index) { const QWidget *widget = layout_->itemAt(layout_index)->widget(); if (widget && widget->geometry().right() > current_x) { break; } } ScrollTo(layout_index - 1); } void PrettyImageView::ScrollBarAction(const int action) { switch (action) { case QAbstractSlider::SliderSingleStepAdd: case QAbstractSlider::SliderPageStepAdd: ScrollTo(current_index_ + 1); break; case QAbstractSlider::SliderSingleStepSub: case QAbstractSlider::SliderPageStepSub: ScrollTo(current_index_ - 1); break; } } void PrettyImageView::resizeEvent(QResizeEvent *e) { QScrollArea::resizeEvent(e); ScrollTo(current_index_, false); } void PrettyImageView::wheelEvent(QWheelEvent *e) { const int d = e->angleDelta().x() > 0 ? -1 : 1; ScrollTo(current_index_ + d, true); }