2010-10-08 01:13:41 +02:00
|
|
|
/* This file is part of Clementine.
|
2010-11-20 14:27:10 +01:00
|
|
|
Copyright 2010, David Sansome <me@davidsansome.com>
|
2010-10-08 01:13:41 +02:00
|
|
|
|
|
|
|
Clementine 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.
|
|
|
|
|
|
|
|
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
#include "prettyimage.h"
|
2010-10-08 01:13:41 +02:00
|
|
|
#include "prettyimageview.h"
|
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
#include <QHBoxLayout>
|
2010-10-08 01:13:41 +02:00
|
|
|
#include <QMouseEvent>
|
2010-10-09 18:07:20 +02:00
|
|
|
#include <QPropertyAnimation>
|
|
|
|
#include <QScrollBar>
|
|
|
|
#include <QTimer>
|
2010-10-08 01:13:41 +02:00
|
|
|
#include <QtDebug>
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
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) {
|
2010-10-09 18:07:20 +02:00
|
|
|
setWidget(container_);
|
|
|
|
setWidgetResizable(true);
|
|
|
|
setMinimumHeight(PrettyImage::kTotalHeight + 10);
|
2010-10-08 01:13:41 +02:00
|
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
2010-10-09 18:07:20 +02:00
|
|
|
setFrameShape(QFrame::NoFrame);
|
|
|
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
2010-10-08 01:13:41 +02:00
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
scroll_animation_->setDuration(250);
|
|
|
|
scroll_animation_->setEasingCurve(QEasingCurve::InOutCubic);
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(horizontalScrollBar(), SIGNAL(sliderReleased()),
|
|
|
|
SLOT(ScrollBarReleased()));
|
|
|
|
connect(horizontalScrollBar(), SIGNAL(actionTriggered(int)),
|
|
|
|
SLOT(ScrollBarAction(int)));
|
2010-10-08 23:09:01 +02:00
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
layout_->setSizeConstraint(QLayout::SetMinAndMaxSize);
|
|
|
|
layout_->setContentsMargins(6, 6, 6, 6);
|
|
|
|
layout_->setSpacing(6);
|
|
|
|
layout_->addSpacing(200);
|
|
|
|
layout_->addSpacing(200);
|
2010-10-08 01:13:41 +02:00
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
container_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
2010-10-08 01:13:41 +02:00
|
|
|
}
|
|
|
|
|
2010-12-21 15:41:02 +01:00
|
|
|
bool PrettyImageView::eventFilter(QObject* obj, QEvent* event) {
|
2010-12-21 15:55:42 +01:00
|
|
|
// 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;
|
2010-12-21 15:41:02 +01:00
|
|
|
}
|
|
|
|
|
2010-10-08 01:13:41 +02:00
|
|
|
void PrettyImageView::AddImage(const QUrl& url) {
|
2010-12-30 18:35:10 +01:00
|
|
|
PrettyImage* image = new PrettyImage(url, network_, container_);
|
2010-10-12 20:58:12 +02:00
|
|
|
connect(image, SIGNAL(destroyed()), SLOT(ScrollToCurrent()));
|
|
|
|
connect(image, SIGNAL(Loaded()), SLOT(ScrollToCurrent()));
|
|
|
|
|
|
|
|
layout_->insertWidget(layout_->count() - 1, image);
|
2014-02-07 16:34:20 +01:00
|
|
|
if (current_index_ == -1) ScrollTo(0);
|
2010-10-08 23:34:39 +02:00
|
|
|
}
|
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
void PrettyImageView::mouseReleaseEvent(QMouseEvent* e) {
|
|
|
|
// Find the image that was clicked on
|
|
|
|
QWidget* widget = container_->childAt(container_->mapFrom(this, e->pos()));
|
2014-02-07 16:34:20 +01:00
|
|
|
if (!widget) return;
|
2010-10-08 23:34:39 +02:00
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
// Get the index of that image
|
|
|
|
const int index = layout_->indexOf(widget) - 1;
|
2014-02-07 16:34:20 +01:00
|
|
|
if (index == -1) return;
|
2010-10-08 01:13:41 +02:00
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
if (index == current_index_) {
|
|
|
|
// Show the image fullsize
|
|
|
|
PrettyImage* pretty_image = qobject_cast<PrettyImage*>(widget);
|
|
|
|
if (pretty_image) {
|
|
|
|
pretty_image->ShowFullsize();
|
|
|
|
}
|
2010-10-08 23:34:39 +02:00
|
|
|
} else {
|
2010-10-09 18:07:20 +02:00
|
|
|
// Scroll to the image
|
|
|
|
ScrollTo(index);
|
2010-10-08 23:34:39 +02:00
|
|
|
}
|
2010-10-08 01:13:41 +02:00
|
|
|
}
|
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
void PrettyImageView::ScrollTo(int index, bool smooth) {
|
|
|
|
current_index_ = qBound(0, index, layout_->count() - 3);
|
|
|
|
const int layout_index = current_index_ + 1;
|
2010-10-08 23:34:39 +02:00
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
const QWidget* target_widget = layout_->itemAt(layout_index)->widget();
|
2014-02-07 16:34:20 +01:00
|
|
|
if (!target_widget) return;
|
2010-10-08 01:13:41 +02:00
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
const int current_x = horizontalScrollBar()->value();
|
|
|
|
const int target_x = target_widget->geometry().center().x() - width() / 2;
|
2010-10-08 01:13:41 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
if (current_x == target_x) return;
|
2010-10-12 20:58:12 +02:00
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
if (smooth) {
|
|
|
|
scroll_animation_->setStartValue(current_x);
|
|
|
|
scroll_animation_->setEndValue(target_x);
|
|
|
|
scroll_animation_->start();
|
|
|
|
} else {
|
|
|
|
scroll_animation_->stop();
|
|
|
|
horizontalScrollBar()->setValue(target_x);
|
2010-10-08 01:13:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
void PrettyImageView::ScrollToCurrent() { ScrollTo(current_index_); }
|
2010-10-12 20:58:12 +02:00
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
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;
|
2014-02-07 16:34:20 +01:00
|
|
|
for (; layout_index < layout_->count() - 1; ++layout_index) {
|
2010-10-09 18:07:20 +02:00
|
|
|
const QWidget* widget = layout_->itemAt(layout_index)->widget();
|
|
|
|
if (widget && widget->geometry().right() > current_x) {
|
|
|
|
break;
|
|
|
|
}
|
2010-10-08 23:09:01 +02:00
|
|
|
}
|
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
ScrollTo(layout_index - 1);
|
2010-10-08 23:09:01 +02:00
|
|
|
}
|
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
void PrettyImageView::ScrollBarAction(int action) {
|
|
|
|
switch (action) {
|
2014-02-07 16:34:20 +01:00
|
|
|
case QAbstractSlider::SliderSingleStepAdd:
|
|
|
|
case QAbstractSlider::SliderPageStepAdd:
|
|
|
|
ScrollTo(current_index_ + 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QAbstractSlider::SliderSingleStepSub:
|
|
|
|
case QAbstractSlider::SliderPageStepSub:
|
|
|
|
ScrollTo(current_index_ - 1);
|
|
|
|
break;
|
2010-10-08 23:09:01 +02:00
|
|
|
}
|
2010-10-09 18:07:20 +02:00
|
|
|
}
|
2010-10-08 23:09:01 +02:00
|
|
|
|
2010-10-09 18:07:20 +02:00
|
|
|
void PrettyImageView::resizeEvent(QResizeEvent* e) {
|
|
|
|
QScrollArea::resizeEvent(e);
|
|
|
|
ScrollTo(current_index_, false);
|
2010-10-08 23:09:01 +02:00
|
|
|
}
|
2011-01-02 20:17:03 +01:00
|
|
|
|
|
|
|
void PrettyImageView::wheelEvent(QWheelEvent* e) {
|
2011-01-09 20:10:15 +01:00
|
|
|
const int d = e->delta() > 0 ? -1 : 1;
|
2011-01-02 20:17:03 +01:00
|
|
|
ScrollTo(current_index_ + d, true);
|
|
|
|
}
|