view src/gui/widgets/poster.cc @ 348:6b0768158dcd

text: redesign almost every widget i.e. Paragraph is now a QLabel, etc etc, some things will probably break, idc
author Paper <paper@paper.us.eu.org>
date Tue, 25 Jun 2024 11:19:54 -0400
parents b1f625b0227c
children
line wrap: on
line source

#include "gui/widgets/poster.h"
#include "core/anime_db.h"
#include "core/http.h"
#include "core/session.h"
#include "core/strings.h"
#include "gui/widgets/clickable_label.h"

#include <QByteArray>
#include <QDebug>
#include <QDesktopServices>
#include <QFrame>
#include <QHBoxLayout>
#include <QLabel>
#include <QMessageBox>
#include <QPixmap>
#include <QThread>
#include <QUrl>

#include <iostream>

Poster::Poster(QWidget* parent) : QFrame(parent) {
	QHBoxLayout* layout = new QHBoxLayout(this);
	layout->setContentsMargins(1, 1, 1, 1);

	setCursor(Qt::PointingHandCursor);
	setFixedSize(150, 225); // FIXME need to kill this
	setFrameShape(QFrame::Box);
	setFrameShadow(QFrame::Plain);

	label_.setAlignment(Qt::AlignCenter);
	layout->addWidget(&label_);

	get_thread_ = new HTTP::RequestThread(HTTP::Type::Get);
	connect(get_thread_, &HTTP::RequestThread::ReceivedData, this, &Poster::ImageDownloadFinished);
}

Poster::Poster(const Anime::Anime& anime, QWidget* parent) : Poster(parent) {
	SetAnime(anime);
}

Poster::~Poster() {
	/* schedule deletion of the thread */
	get_thread_->deleteLater();
}

void Poster::DownloadPoster() {
	if (get_thread_->isRunning())
		get_thread_->Stop();
	get_thread_->wait();

	get_thread_->SetUrl(poster_url_);
	get_thread_->start();
}

void Poster::SetAnime(const Anime::Anime& anime) {
	label_.clear();

	poster_url_ = anime.GetPosterUrl();
	if (isVisible())
		DownloadPoster();
	else
		need_refresh_ = true;

	std::optional<std::string> url = anime.GetServiceUrl(session.config.service);
	if (url)
		service_url_ = Strings::ToQString(url.value());

	if (clickable_) {
		label_.disconnect();
		connect(&label_, &ClickableLabel::clicked, this, [this] { QDesktopServices::openUrl(service_url_); });
	}
}

void Poster::showEvent(QShowEvent* event) {
	if (need_refresh_) {
		DownloadPoster();
		need_refresh_ = false;
	}
}

void Poster::SetClickable(bool enabled) {
	clickable_ = enabled;

	if (clickable_ && !service_url_.isEmpty()) {
		setCursor(Qt::PointingHandCursor);
		label_.disconnect();
		connect(&label_, &ClickableLabel::clicked, this, [this] { QDesktopServices::openUrl(service_url_); });
	} else {
		setCursor(Qt::ArrowCursor);
		label_.disconnect();
	}
}

void Poster::ImageDownloadFinished(const QByteArray& arr) {
	img_.loadFromData(arr);
	RenderToLabel();
}

void Poster::RenderToLabel() {
	const QPixmap pixmap = QPixmap::fromImage(img_);
	if (pixmap.isNull())
		return;
	label_.setPixmap(pixmap.scaled(label_.size(), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
}

bool Poster::hasHeightForWidth(void) const {
	return true;
}

int Poster::heightForWidth(int w) const {
	return static_cast<int>(static_cast<double>(w) * 225 / 150);
}

void Poster::resizeEvent(QResizeEvent*) {
	RenderToLabel();
}

QSize Poster::minimumSizeHint() const {
	return QSize(120, heightForWidth(120));
}

QSize Poster::sizeHint() const {
	return QSize(150, heightForWidth(150));
}