view src/gui/dialog/settings/application.cc @ 198:bc1ae1810855

dep/animia: switch from using classes to global functions the old idea was ok, but sort of hackish; this method doesn't use classes at all, and this way (especially important!) we can do wayland stuff AND x11 at the same time, which wasn't really possible without stupid workarounds in the other method
author Paper <mrpapersonic@gmail.com>
date Sun, 24 Dec 2023 02:59:42 -0500
parents 975a3f0965e2
children ff0061e75f0f
line wrap: on
line source

#include "core/session.h"
#include "core/strings.h"
#include "gui/dialog/settings.h"
#include "gui/theme.h"
#include "gui/locale.h"
#include "gui/translate/anime.h"

#include <QCheckBox>
#include <QComboBox>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QSizePolicy>
#include <QVBoxLayout>

#include <algorithm>

QWidget* SettingsPageApplication::CreateAnimeListWidget() {
	QWidget* result = new QWidget(this);
	result->setAutoFillBackground(true);
	result->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

	QVBoxLayout* full_layout = new QVBoxLayout(result);

	{
		/* Actions */
		QGroupBox* actions_group_box = new QGroupBox(tr("Actions"), result);
		actions_group_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

		QHBoxLayout* actions_layout = new QHBoxLayout(actions_group_box);

		{
			/* Actions/Double click */
			QWidget* double_click_widget = new QWidget(actions_group_box);
			QLabel* dc_combo_box_label = new QLabel(tr("Double click:"), double_click_widget);
			QComboBox* dc_combo_box = new QComboBox(double_click_widget);
			dc_combo_box->addItem(tr("View anime info"));

			QVBoxLayout* double_click_layout = new QVBoxLayout(double_click_widget);
			double_click_layout->addWidget(dc_combo_box_label);
			double_click_layout->addWidget(dc_combo_box);
			double_click_layout->setContentsMargins(0, 0, 0, 0);

			actions_layout->addWidget(double_click_widget);
		}

		{
			/* Actions/Middle click */
			QWidget* middle_click_widget = new QWidget(actions_group_box);
			QLabel* mc_combo_box_label = new QLabel(tr("Middle click:"), middle_click_widget);
			QComboBox* mc_combo_box = new QComboBox(middle_click_widget);
			mc_combo_box->addItem(tr("Play next episode"));

			QVBoxLayout* middle_click_layout = new QVBoxLayout(middle_click_widget);
			middle_click_layout->addWidget(mc_combo_box_label);
			middle_click_layout->addWidget(mc_combo_box);
			middle_click_layout->setContentsMargins(0, 0, 0, 0);
			
			actions_layout->addWidget(middle_click_widget);
		}

		full_layout->addWidget(actions_group_box);
	}

	{
		/* Appearance */
		QGroupBox* appearance_group_box = new QGroupBox(tr("Appearance"), result);
		appearance_group_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

		QVBoxLayout* appearance_layout = new QVBoxLayout(appearance_group_box);

		{
			/* Title language */
			{
				QLabel* lang_combo_box_label = new QLabel(tr("Title language preference:"), appearance_group_box);
				appearance_layout->addWidget(lang_combo_box_label);
			}
			{
				QComboBox* lang_combo_box = new QComboBox(appearance_group_box);
				lang_combo_box->addItem(tr("Romaji"));
				lang_combo_box->addItem(tr("Native"));
				lang_combo_box->addItem(tr("English"));
				connect(lang_combo_box, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
				        [this](int index) { language = static_cast<Anime::TitleLanguage>(index); });
				lang_combo_box->setCurrentIndex(static_cast<int>(language));
				appearance_layout->addWidget(lang_combo_box);
			}
		}

		{
			/* Application theme */
			{
				QLabel* rating_combo_box_label = new QLabel(tr("Rating system:"), appearance_group_box);
				appearance_layout->addWidget(rating_combo_box_label);
			}

			{
				QComboBox* rating_combo_box = new QComboBox(appearance_group_box);

				for (const auto& score_format : Anime::ScoreFormats)
					rating_combo_box->addItem(Strings::ToQString(Translate::ToLocalString(score_format)), static_cast<int>(score_format));

				connect(rating_combo_box, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
					    [this, rating_combo_box](int index) { format = static_cast<Anime::ScoreFormat>(rating_combo_box->itemData(index).toInt()); });

				rating_combo_box->setCurrentIndex(static_cast<int>(format));
				appearance_layout->addWidget(rating_combo_box);
			}
		}

		{
			/* Hopefully I made this easy to parse... */
			QCheckBox* hl_above_anime_box = new QCheckBox(tr("Display highlighted anime above others"), appearance_group_box);
			hl_above_anime_box->setCheckState(highlighted_anime_above_others ? Qt::Checked : Qt::Unchecked);
			hl_above_anime_box->setEnabled(highlight_anime_if_available);
			hl_above_anime_box->setContentsMargins(10, 0, 0, 0);

			connect(hl_above_anime_box, &QCheckBox::stateChanged, this,
			        [this](int state) { highlight_anime_if_available = !(state == Qt::Unchecked); });

			{
				/* This is here because the above checkbox actually depends on it to be checked. */
				QCheckBox* hl_anime_box = new QCheckBox(tr("Highlight anime if next episode is available in library folders"), appearance_group_box);
				hl_anime_box->setCheckState(highlight_anime_if_available ? Qt::Checked : Qt::Unchecked);

				connect(hl_anime_box, &QCheckBox::stateChanged, this, [this, hl_above_anime_box](int state) {
					highlight_anime_if_available = !(state == Qt::Unchecked);
					hl_above_anime_box->setEnabled(state);
				});

				appearance_layout->addWidget(hl_anime_box);
			}

			appearance_layout->addWidget(hl_above_anime_box);
		}

		full_layout->addWidget(appearance_group_box);
	}

	{
		/* Progress */
		QGroupBox* progress_group_box = new QGroupBox(tr("Progress"), result);
		progress_group_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

		QVBoxLayout* progress_layout = new QVBoxLayout(progress_group_box);

		{
			QCheckBox* progress_display_aired_episodes =
			    new QCheckBox(tr("Display aired episodes (estimated)"), progress_group_box);
			connect(progress_display_aired_episodes, &QCheckBox::stateChanged, this,
			        [this](int state) { display_aired_episodes = !(state == Qt::Unchecked); });
			progress_display_aired_episodes->setCheckState(display_aired_episodes ? Qt::Checked : Qt::Unchecked);
			progress_layout->addWidget(progress_display_aired_episodes);
		}
		{
			QCheckBox* progress_display_available_episodes =
			    new QCheckBox(tr("Display available episodes in library folders"), progress_group_box);
			connect(progress_display_available_episodes, &QCheckBox::stateChanged, this,
			        [this](int state) { display_available_episodes = !(state == Qt::Unchecked); });
			progress_display_available_episodes->setCheckState(display_available_episodes ? Qt::Checked : Qt::Unchecked);
			progress_layout->addWidget(progress_display_available_episodes);
		}

		full_layout->addWidget(progress_group_box);
	}

	full_layout->setSpacing(10);
	full_layout->addStretch();

	return result;
}

QWidget* SettingsPageApplication::CreateGeneralWidget() {
	QWidget* result = new QWidget(this);
	result->setAutoFillBackground(true);
	result->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

	QVBoxLayout* full_layout = new QVBoxLayout(result);

	{
		/* Appearance */
		QGroupBox* appearance_group_box = new QGroupBox(tr("Appearance"), result);
		appearance_group_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

		QVBoxLayout* appearance_layout = new QVBoxLayout(appearance_group_box);

		{
			/* Application theme */
			{
				QLabel* theme_combo_box_label = new QLabel(tr("Application theme:"), appearance_group_box);
				appearance_layout->addWidget(theme_combo_box_label);
			}

			{
				QComboBox* theme_combo_box = new QComboBox(appearance_group_box);
				theme_combo_box->addItem(tr("Default"));
				theme_combo_box->addItem(tr("Light"));
				theme_combo_box->addItem(tr("Dark"));
				connect(theme_combo_box, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
					    [this](int index) { theme = static_cast<Themes>(index); });
				theme_combo_box->setCurrentIndex(static_cast<int>(theme));
				appearance_layout->addWidget(theme_combo_box);
			}
		}

		{
			/* Application locale */
			{
				QLabel* locale_combo_box_label = new QLabel(tr("Application locale:"), appearance_group_box);
				appearance_layout->addWidget(locale_combo_box_label);
			}

			{
				QComboBox* locale_combo_box = new QComboBox(appearance_group_box);
				const auto& available_locales = session.config.locale.GetAvailableLocales();
				for (const auto& l : available_locales)
					locale_combo_box->addItem(Strings::ToQString(Locale::GetLocaleFullName(l)), l);

				connect(locale_combo_box, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
					    [this, locale_combo_box](int) { locale = locale_combo_box->currentData().toLocale(); });

				for (size_t i = 0; i < available_locales.size(); i++)
					if (available_locales[i] == locale)
						locale_combo_box->setCurrentIndex(i);

				appearance_layout->addWidget(locale_combo_box);
			}
		}

		full_layout->addWidget(appearance_group_box);
	}

	full_layout->setSpacing(10);
	full_layout->addStretch();

	return result;
}


void SettingsPageApplication::SaveInfo() {
	session.config.anime_list.language = language;
	session.config.anime_list.highlighted_anime_above_others = highlighted_anime_above_others;
	session.config.anime_list.highlight_anime_if_available = highlight_anime_if_available;
	session.config.anime_list.display_aired_episodes = display_aired_episodes;
	session.config.anime_list.display_available_episodes = display_available_episodes;
	session.config.theme.SetTheme(theme);
	session.config.locale.SetActiveLocale(locale);
}

SettingsPageApplication::SettingsPageApplication(QWidget* parent) : SettingsPage(parent, tr("Application")) {
	language = session.config.anime_list.language;
	format = session.config.anime_list.score_format;
	theme = session.config.theme.GetTheme();
	locale = session.config.locale.GetLocale();
	highlighted_anime_above_others = session.config.anime_list.highlighted_anime_above_others;
	highlight_anime_if_available = session.config.anime_list.highlight_anime_if_available;
	display_aired_episodes = session.config.anime_list.display_aired_episodes;
	display_available_episodes = session.config.anime_list.display_available_episodes;
	AddTab(CreateGeneralWidget(), tr("General"));
	AddTab(CreateAnimeListWidget(), tr("Anime list"));
}