view src/gui/dialog/information.cpp @ 46:d0adc4aedfc8

*: update... this commit: 1. consolidates dark theme stuff to dark_theme.cpp 2. creates a new widgets folder to store all of our custom widgets 3. creates the list settings page in the information dialog, although much of it is nonfunctional: it doesn't save, and the status doesn't even get filled in... we'll fix this later!
author Paper <mrpapersonic@gmail.com>
date Sat, 23 Sep 2023 01:02:15 -0400
parents 2743011a6042
children d8eb763e6661
line wrap: on
line source

#include "gui/dialog/information.h"
#include "core/anime.h"
#include "core/array.h"
#include "core/strings.h"
#include "gui/pages/anime_list.h"
#include "gui/translate/anime.h"
#include "gui/widgets/text.h"
#include "gui/window.h"
#include <QCheckBox>
#include <QComboBox>
#include <QDebug>
#include <QDialogButtonBox>
#include <QLineEdit>
#include <QPlainTextEdit>
#include <QSpinBox>
#include <QStringList>
#include <QTextStream>
#include <QVBoxLayout>
#include <functional>

/* TODO: Taiga disables rendering of the tab widget entirely when the anime is not part of a list,
   which sucks. Think of a better way to implement this later. */
InformationDialog::InformationDialog(const Anime::Anime& anime, std::function<void()> accept, QWidget* parent)
    : QDialog(parent) {
	setFixedSize(842, 613);
	setWindowTitle(tr("Anime Information"));
	setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);

	{
		QPalette pal;
		pal.setColor(QPalette::Window, Qt::white);
		setPalette(pal);
	}

	QWidget* widget = new QWidget(this);

	/* "sidebar", includes... just the anime image :) */
	QWidget* sidebar = new QWidget(widget);
	sidebar->setFixedWidth(175);

	/* main widget */
	QWidget* main_widget = new QWidget(widget);

	{
		QPalette pal;
		pal.setColor(QPalette::Window, Qt::white);
		main_widget->setPalette(pal);
	}

	main_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

	/* anime title header text */
	TextWidgets::Paragraph* anime_title =
	    new TextWidgets::Paragraph(QString::fromUtf8(anime.GetUserPreferredTitle().c_str()), main_widget);
	anime_title->setReadOnly(true);
	anime_title->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
	anime_title->setWordWrapMode(QTextOption::NoWrap);
	anime_title->setFrameShape(QFrame::NoFrame);
	anime_title->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
	anime_title->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
	anime_title->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

	{
		QFont font(anime_title->font());
		font.setPointSize(12);
		anime_title->setFont(font);
	}

	{
		QPalette pal;
		pal.setColor(QPalette::Window, Qt::transparent);
		pal.setColor(QPalette::WindowText, Qt::blue);
	}

	/* tabbed widget */
	QTabWidget* tabbed_widget = new QTabWidget(main_widget);
	tabbed_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);

	/* main info tab */
	QWidget* main_information_widget = new QWidget(tabbed_widget);
	main_information_widget->setLayout(new QVBoxLayout);

	/* alt titles */
	main_information_widget->layout()->addWidget(new TextWidgets::SelectableTextParagraph(
	    "Alternative titles", QString::fromUtf8(Strings::Implode(anime.GetTitleSynonyms(), ", ").c_str()),
	    main_information_widget));

	/* details */
	QString details_data;
	QTextStream details_data_s(&details_data);
	details_data_s << Translate::ToString(anime.GetFormat()).c_str() << "\n"
	               << anime.GetEpisodes() << "\n"
	               << Translate::ToString(anime.GetUserStatus()).c_str() << "\n"
	               << Translate::ToString(anime.GetSeason()).c_str() << " " << anime.GetAirDate().GetYear() << "\n"
	               << Strings::Implode(anime.GetGenres(), ", ").c_str() << "\n"
	               << anime.GetAudienceScore() << "%";
	main_information_widget->layout()->addWidget(new TextWidgets::LabelledTextParagraph(
	    "Details", "Type:\nEpisodes:\nStatus:\nSeason:\nGenres:\nScore:", details_data, main_information_widget));

	/* synopsis */
	TextWidgets::SelectableTextParagraph* synopsis = new TextWidgets::SelectableTextParagraph(
	    "Synopsis", QString::fromUtf8(anime.GetSynopsis().c_str()), main_information_widget);

	synopsis->GetParagraph()->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
	main_information_widget->layout()->addWidget(synopsis);

	QWidget* settings_widget = new QWidget(tabbed_widget);
	settings_widget->setLayout(new QVBoxLayout);
	settings_widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);

	settings_widget->layout()->addWidget(new TextWidgets::Header(tr("Anime list"), settings_widget));

	QWidget* sg_anime_list_content = new QWidget(settings_widget);
	settings_widget->layout()->addWidget(sg_anime_list_content);
	sg_anime_list_content->setLayout(new QVBoxLayout);
	sg_anime_list_content->layout()->setSpacing(5);
	sg_anime_list_content->layout()->setContentsMargins(12, 0, 0, 0);

	/* Note: PLEASE find a way we can consolidate these. By ANY other means than
	   putting them in a separate function. Macros are very much preferred. */
#define LAYOUT_HORIZ_SPACING 9
#define LAYOUT_VERT_SPACING 5
	{
		/* Episodes watched section */
		QWidget* section = new QWidget(sg_anime_list_content);
		QHBoxLayout* layout = new QHBoxLayout;
		layout->setSpacing(LAYOUT_HORIZ_SPACING);
		layout->setMargin(0);
		section->setLayout(layout);
		{
			QWidget* subsection = new QWidget(section);
			subsection->setLayout(new QVBoxLayout);
			subsection->layout()->setSpacing(LAYOUT_VERT_SPACING);
			subsection->layout()->setMargin(0);

			subsection->layout()->addWidget(new QLabel(tr("Episodes watched:"), subsection));

			QSpinBox* spin_box = new QSpinBox(subsection);
			spin_box->setRange(0, anime.GetEpisodes());
			spin_box->setSingleStep(1);
			spin_box->setValue(anime.GetUserProgress());
			subsection->layout()->addWidget(spin_box);

			layout->addWidget(subsection);
		}
		{
			QWidget* subsection = new QWidget(section);
			subsection->setLayout(new QVBoxLayout);
			subsection->layout()->setSpacing(LAYOUT_VERT_SPACING);
			subsection->layout()->setMargin(0);

			subsection->layout()->addWidget(new QLabel(tr(" "), subsection));

			QCheckBox* rewatched_checkbox = new QCheckBox("Rewatching");
			subsection->layout()->addWidget(rewatched_checkbox);

			layout->addWidget(subsection);
		}
		sg_anime_list_content->layout()->addWidget(section);
	}
	{
		/* Status & score section */
		QWidget* section = new QWidget(sg_anime_list_content);
		QHBoxLayout* layout = new QHBoxLayout;
		layout->setSpacing(LAYOUT_HORIZ_SPACING);
		layout->setMargin(0);
		section->setLayout(layout);
		{
			QWidget* subsection = new QWidget(section);
			subsection->setLayout(new QVBoxLayout);
			subsection->layout()->setSpacing(LAYOUT_VERT_SPACING);
			subsection->layout()->setMargin(0);

			subsection->layout()->addWidget(new QLabel(tr("Status:"), subsection));

			QStringList string_list;
			for (unsigned int i = 0; i < ARRAYSIZE(Anime::ListStatuses); i++)
				string_list.append(QString::fromStdString(Translate::ToString(Anime::ListStatuses[i])));

			QComboBox* combo_box = new QComboBox(subsection);
			combo_box->addItems(string_list);
			subsection->layout()->addWidget(combo_box);

			layout->addWidget(subsection);
		}
		{
			QWidget* subsection = new QWidget(section);
			subsection->setLayout(new QVBoxLayout);
			subsection->layout()->setSpacing(LAYOUT_VERT_SPACING);
			subsection->layout()->setMargin(0);

			subsection->layout()->addWidget(new QLabel(tr("Score:"), subsection));

			QSpinBox* spin_box = new QSpinBox(subsection);
			spin_box->setRange(0, 100);
			spin_box->setSingleStep(5);
			spin_box->setValue(anime.GetUserScore());
			subsection->layout()->addWidget(spin_box);

			layout->addWidget(subsection);
		}
		sg_anime_list_content->layout()->addWidget(section);
	}
	{
		/* Notes section */
		QWidget* section = new QWidget(sg_anime_list_content);
		QHBoxLayout* layout = new QHBoxLayout;
		layout->setSpacing(LAYOUT_HORIZ_SPACING);
		layout->setMargin(0);
		section->setLayout(layout);
		{
			QWidget* subsection = new QWidget(section);
			subsection->setLayout(new QVBoxLayout);
			subsection->layout()->setSpacing(LAYOUT_VERT_SPACING);
			subsection->layout()->setMargin(0);

			subsection->layout()->addWidget(new QLabel(tr("Notes:"), subsection));

			QLineEdit* line_edit = new QLineEdit(QString::fromStdString(anime.GetUserNotes()), subsection);
			line_edit->setPlaceholderText(tr("Enter your notes about this anime"));
			subsection->layout()->addWidget(line_edit);

			layout->addWidget(subsection);
		}
		sg_anime_list_content->layout()->addWidget(section);
	}

	settings_widget->layout()->addWidget(new TextWidgets::Header(tr("Local settings"), settings_widget));

	QWidget* sg_local_content = new QWidget(settings_widget);
	settings_widget->layout()->addWidget(sg_local_content);
	sg_local_content->setLayout(new QVBoxLayout);
	sg_local_content->layout()->setSpacing(5);
	sg_local_content->layout()->setContentsMargins(12, 0, 0, 0);

	{
		/* Alternative titles */
		QWidget* section = new QWidget(sg_local_content);
		QHBoxLayout* layout = new QHBoxLayout;
		layout->setSpacing(LAYOUT_HORIZ_SPACING);
		layout->setMargin(0);
		section->setLayout(layout);
		{
			QWidget* subsection = new QWidget(section);
			subsection->setLayout(new QVBoxLayout);
			subsection->layout()->setSpacing(LAYOUT_VERT_SPACING);
			subsection->layout()->setMargin(0);

			subsection->layout()->addWidget(new QLabel(tr("Alternative titles:"), subsection));

			QLineEdit* line_edit = new QLineEdit(QString::fromStdString(anime.GetUserNotes()), subsection);
			line_edit->setPlaceholderText(tr("Enter alternative titles here, separated by a semicolon (i.e. Title 1; Title 2)"));
			subsection->layout()->addWidget(line_edit);

			QCheckBox* checkbox = new QCheckBox("Use the first alternative title to search for torrents");
			subsection->layout()->addWidget(checkbox);

			layout->addWidget(subsection);
		}
		sg_local_content->layout()->addWidget(section);
	}

	static_cast<QBoxLayout*>(settings_widget->layout())->addStretch();

	tabbed_widget->addTab(main_information_widget, "Main information");
	tabbed_widget->addTab(settings_widget, "My list and settings");

	QVBoxLayout* main_layout = new QVBoxLayout;
	main_layout->addWidget(anime_title);
	main_layout->addWidget(tabbed_widget);
	main_layout->setMargin(0);
	main_widget->setLayout(main_layout);

	QHBoxLayout* layout = new QHBoxLayout;
	layout->addWidget(sidebar);
	layout->addWidget(main_widget);
	widget->setLayout(layout);

	QDialogButtonBox* button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
	connect(button_box, &QDialogButtonBox::accepted, this, [this, accept] {
		accept();
		QDialog::accept();
	});
	connect(button_box, &QDialogButtonBox::rejected, this, &QDialog::reject);

	QVBoxLayout* buttons_layout = new QVBoxLayout;
	buttons_layout->addWidget(widget);
	buttons_layout->addWidget(button_box, 0, Qt::AlignBottom);
	setLayout(buttons_layout);
}

#include "gui/dialog/moc_information.cpp"