view src/gui/widgets/poster.cc @ 376:5d716acb2774

gui/dialog/dialog: fix win32 build
author Paper <paper@tflc.us>
date Fri, 25 Jul 2025 12:28:38 -0400
parents ea3a74ed2ef9
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));
}