RetroArch/ui/drivers/qt/viewoptionsdialog.cpp

488 lines
17 KiB
C++
Raw Normal View History

#include <QSettings>
#include <QComboBox>
#include <QCheckBox>
#include <QPushButton>
#include <QColor>
#include <QLabel>
#include <QSpinBox>
#include <QFormLayout>
#include <QDialogButtonBox>
#include <QFileDialog>
#include <QApplication>
#include <QColorDialog>
#include "viewoptionsdialog.h"
2019-03-27 02:37:34 +01:00
#ifdef HAVE_MENU
#include <QBitmap>
#include <QStackedLayout>
#include <QScrollBar>
#include "options/options.h"
#endif
#include "../ui_qt.h"
2019-01-13 21:56:16 -08:00
#ifndef CXX_BUILD
extern "C" {
2019-01-13 21:56:16 -08:00
#endif
#include "../../../msg_hash.h"
2019-01-13 21:56:16 -08:00
#ifndef CXX_BUILD
}
2019-01-13 21:56:16 -08:00
#endif
2019-03-27 02:37:34 +01:00
#ifdef HAVE_MENU
2019-04-15 22:29:16 +02:00
static const int MAX_MIN_WIDTH = 250;
static const int MAX_MIN_HEIGHT = 250;
2019-03-27 02:37:34 +01:00
QPixmap getColorizedPixmap(const QPixmap& oldPixmap, const QColor& color)
{
QPixmap pixmap = oldPixmap;
2019-04-21 03:28:23 +02:00
QBitmap mask = pixmap.createMaskFromColor(Qt::transparent, Qt::MaskInColor);
2019-03-27 02:37:34 +01:00
pixmap.fill(color);
pixmap.setMask(mask);
return pixmap;
}
QColor getLabelColor(const QString& objectName)
{
QLabel dummyColor;
dummyColor.setObjectName(objectName);
dummyColor.ensurePolished();
return dummyColor.palette().color(QPalette::Foreground);
}
2019-04-15 22:29:16 +02:00
/* stolen from Qt Creator */
class SmartScrollArea : public QScrollArea
{
public:
explicit SmartScrollArea(QWidget *parent) :
QScrollArea(parent)
{
setFrameStyle(QFrame::NoFrame | QFrame::Plain);
viewport()->setAutoFillBackground(false);
setWidgetResizable(true);
}
private:
void resizeEvent(QResizeEvent *event) final
{
QWidget *inner = widget();
2019-04-21 03:28:23 +02:00
2019-04-15 22:29:16 +02:00
if (inner)
{
2019-04-21 03:28:23 +02:00
int fw = frameWidth() * 2;
QSize innerSize = event->size() - QSize(fw, fw);
2019-04-15 22:29:16 +02:00
QSize innerSizeHint = inner->minimumSizeHint();
2019-04-21 03:28:23 +02:00
/* Widget wants to be bigger than available space */
2019-04-15 22:29:16 +02:00
if (innerSizeHint.height() > innerSize.height())
2019-04-21 03:28:23 +02:00
{
2019-04-15 22:29:16 +02:00
innerSize.setWidth(innerSize.width() - scrollBarWidth());
innerSize.setHeight(innerSizeHint.height());
}
inner->resize(innerSize);
}
QScrollArea::resizeEvent(event);
}
QSize minimumSizeHint() const final
{
QWidget *inner = widget();
2019-04-21 03:28:23 +02:00
if (inner)
{
int fw = frameWidth() * 2;
2019-04-15 22:29:16 +02:00
QSize minSize = inner->minimumSizeHint();
2019-04-21 03:28:23 +02:00
2019-04-15 22:29:16 +02:00
minSize += QSize(fw, fw);
minSize += QSize(scrollBarWidth(), 0);
minSize.setWidth(qMin(minSize.width(), MAX_MIN_WIDTH));
minSize.setHeight(qMin(minSize.height(), MAX_MIN_HEIGHT));
return minSize;
}
return QSize(0, 0);
}
bool event(QEvent *event) final
{
if (event->type() == QEvent::LayoutRequest)
updateGeometry();
return QScrollArea::event(event);
}
int scrollBarWidth() const
{
SmartScrollArea *that = const_cast<SmartScrollArea *>(this);
QWidgetList list = that->scrollBarWidgets(Qt::AlignRight);
if (list.isEmpty())
return 0;
return list.first()->sizeHint().width();
}
};
ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) :
QDialog(mainwindow)
2019-04-15 22:29:16 +02:00
,m_optionsList(new QListWidget(this))
,m_optionsStack(new QStackedLayout)
2019-03-27 02:37:34 +01:00
{
int width;
2019-04-21 03:28:23 +02:00
QGridLayout *layout = new QGridLayout(this);
QLabel *m_headerLabel = new QLabel(this);
/* Header label with large font and a bit of spacing
* (align with group boxes) */
QFont headerLabelFont = m_headerLabel->font();
const int pointSize = headerLabelFont.pointSize();
QHBoxLayout *headerHLayout = new QHBoxLayout;
const int leftMargin = QApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin);
2019-03-27 02:37:34 +01:00
2019-04-15 22:29:16 +02:00
m_optionsStack->setMargin(0);
2019-03-27 02:37:34 +01:00
headerLabelFont.setBold(true);
2019-04-21 03:28:23 +02:00
/* Paranoia: Should a font be set in pixels... */
2019-03-27 02:37:34 +01:00
if (pointSize > 0)
headerLabelFont.setPointSize(pointSize + 2);
m_headerLabel->setFont(headerLabelFont);
headerHLayout->addSpacerItem(new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored));
headerHLayout->addWidget(m_headerLabel);
addCategory(new DriversCategory(this));
addCategory(new VideoCategory(this));
addCategory(new AudioCategory(this));
addCategory(new InputCategory(this));
addCategory(new LatencyCategory(this));
addCategory(new CoreCategory(this));
addCategory(new ConfigurationCategory(this));
addCategory(new SavingCategory(this));
addCategory(new LoggingCategory(this));
addCategory(new FrameThrottleCategory(this));
addCategory(new RecordingCategory(this));
addCategory(new OnscreenDisplayCategory(this));
addCategory(new UserInterfaceCategory(mainwindow, this));
addCategory(new AchievementsCategory(this));
addCategory(new NetworkCategory(this));
addCategory(new PlaylistsCategory(this));
addCategory(new UserCategory(this));
addCategory(new DirectoryCategory(this));
width = m_optionsList->sizeHintForColumn(0) + m_optionsList->frameWidth() * 2 + 5;
width += m_optionsList->verticalScrollBar()->sizeHint().width();
m_optionsList->setMaximumWidth(width);
m_optionsList->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE));
layout->addWidget(m_optionsList, 0, 0, 2, 1);
layout->addLayout(headerHLayout, 0, 1);
2019-04-15 22:29:16 +02:00
layout->addLayout(m_optionsStack, 1, 1);
2019-03-27 02:37:34 +01:00
connect(m_optionsList, SIGNAL(currentRowChanged(int)), m_optionsStack, SLOT(setCurrentIndex(int)));
connect(m_optionsList, SIGNAL(currentTextChanged(const QString&)), m_headerLabel, SLOT(setText(const QString&)));
connect(this, SIGNAL(rejected()), this, SLOT(onRejected()));
}
QIcon getIcon(OptionsCategory *category) {
QPixmap pixmap = QPixmap(QString(config_get_ptr()->paths.directory_assets) + "/xmb/monochrome/png/" + category->categoryIconName() + ".png");
return QIcon(getColorizedPixmap(pixmap, getLabelColor("iconColor")));
}
void ViewOptionsDialog::addCategory(OptionsCategory *category)
{
QTabWidget *tabWidget = new QTabWidget();
m_categoryList.append(category);
for (OptionsPage* page : category->pages())
{
2019-04-15 22:29:16 +02:00
SmartScrollArea *scrollArea = new SmartScrollArea(this);
2019-03-27 02:37:34 +01:00
QWidget *widget = page->widget();
2019-04-15 22:29:16 +02:00
scrollArea->setWidget(widget);
2019-03-27 02:37:34 +01:00
widget->setAutoFillBackground(false);
2019-04-15 22:29:16 +02:00
tabWidget->addTab(scrollArea, page->displayName());
2019-03-27 02:37:34 +01:00
}
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
tabWidget->setTabBarAutoHide(true);
#else
/* TODO remove the tabBar's space */
if (tabWidget->count() < 2)
tabWidget->tabBar()->hide();
#endif
m_optionsList->addItem(new QListWidgetItem(getIcon(category), category->displayName()));
m_optionsStack->addWidget(tabWidget);
}
void ViewOptionsDialog::repaintIcons()
{
2019-04-21 03:28:23 +02:00
unsigned i;
2019-03-27 02:37:34 +01:00
for (i = 0; i < m_categoryList.size(); i++)
m_optionsList->item(i)->setIcon(getIcon(m_categoryList.at(i)));
}
#else
ViewOptionsDialog::ViewOptionsDialog(MainWindow *mainwindow, QWidget *parent) :
QDialog(mainwindow)
, m_viewOptionsWidget(new ViewOptionsWidget(mainwindow))
{
2019-04-21 03:28:23 +02:00
QVBoxLayout *layout = new QVBoxLayout;
2019-03-27 02:37:34 +01:00
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
connect(this, SIGNAL(accepted()), m_viewOptionsWidget, SLOT(onAccepted()));
connect(this, SIGNAL(rejected()), m_viewOptionsWidget, SLOT(onRejected()));
setWindowTitle(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_TITLE));
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_viewOptionsWidget);
layout->addWidget(buttonBox);
setLayout(layout);
}
#endif
void ViewOptionsDialog::showDialog()
{
#ifndef HAVE_MENU
m_viewOptionsWidget->loadViewOptions();
#else
2019-04-21 03:28:23 +02:00
unsigned i;
2019-03-27 02:37:34 +01:00
for (i = 0; i < m_categoryList.size(); i++)
m_categoryList.at(i)->load();
#endif
show();
activateWindow();
}
void ViewOptionsDialog::hideDialog()
{
reject();
}
void ViewOptionsDialog::onRejected()
{
#ifdef HAVE_MENU
int i;
for (i = 0; i < m_categoryList.size(); i++)
m_categoryList.at(i)->apply();
#endif
}
ViewOptionsWidget::ViewOptionsWidget(MainWindow *mainwindow, QWidget *parent) :
QWidget(parent)
,m_mainwindow(mainwindow)
,m_settings(mainwindow->settings())
,m_saveGeometryCheckBox(new QCheckBox(this))
,m_saveDockPositionsCheckBox(new QCheckBox(this))
,m_saveLastTabCheckBox(new QCheckBox(this))
,m_showHiddenFilesCheckBox(new QCheckBox(this))
,m_themeComboBox(new QComboBox(this))
,m_thumbnailCacheSpinBox(new QSpinBox(this))
,m_startupPlaylistComboBox(new QComboBox(this))
,m_highlightColorPushButton(new QPushButton(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CHOOSE), this))
,m_highlightColor()
,m_highlightColorLabel(new QLabel(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_HIGHLIGHT_COLOR), this))
,m_customThemePath()
,m_suggestLoadedCoreFirstCheckBox(new QCheckBox(this))
2019-01-31 23:54:25 +01:00
/* ,m_allPlaylistsListMaxCountSpinBox(new QSpinBox(this)) */
/* ,m_allPlaylistsGridMaxCountSpinBox(new QSpinBox(this)) */
{
2019-03-27 02:37:34 +01:00
QVBoxLayout *layout = new QVBoxLayout;
QFormLayout *form = new QFormLayout;
m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_SYSTEM_DEFAULT), MainWindow::THEME_SYSTEM_DEFAULT);
m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_DARK), MainWindow::THEME_DARK);
m_themeComboBox->addItem(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME_CUSTOM), MainWindow::THEME_CUSTOM);
m_thumbnailCacheSpinBox->setSuffix(" MB");
m_thumbnailCacheSpinBox->setRange(0, 99999);
2019-01-31 23:54:25 +01:00
/* m_allPlaylistsListMaxCountSpinBox->setRange(0, 99999); */
/* m_allPlaylistsGridMaxCountSpinBox->setRange(0, 99999); */
form->setFormAlignment(Qt::AlignCenter);
form->setLabelAlignment(Qt::AlignCenter);
form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_GEOMETRY), m_saveGeometryCheckBox);
form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_DOCK_POSITIONS), m_saveDockPositionsCheckBox);
form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SAVE_LAST_TAB), m_saveLastTabCheckBox);
form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SHOW_HIDDEN_FILES), m_showHiddenFilesCheckBox);
form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_SUGGEST_LOADED_CORE_FIRST), m_suggestLoadedCoreFirstCheckBox);
2019-01-31 23:54:25 +01:00
/* form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_LIST_MAX_COUNT), m_allPlaylistsListMaxCountSpinBox); */
/* form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_ALL_PLAYLISTS_GRID_MAX_COUNT), m_allPlaylistsGridMaxCountSpinBox); */
form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_STARTUP_PLAYLIST), m_startupPlaylistComboBox);
form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THUMBNAIL_CACHE_LIMIT), m_thumbnailCacheSpinBox);
form->addRow(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_MENU_VIEW_OPTIONS_THEME), m_themeComboBox);
form->addRow(m_highlightColorLabel, m_highlightColorPushButton);
2019-03-27 02:37:34 +01:00
layout->addLayout(form);
layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));
setLayout(layout);
loadViewOptions();
connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThemeComboBoxIndexChanged(int)));
connect(m_highlightColorPushButton, SIGNAL(clicked()), this, SLOT(onHighlightColorChoose()));
}
2019-03-27 02:37:34 +01:00
void ViewOptionsWidget::onThemeComboBoxIndexChanged(int)
{
MainWindow::Theme theme = static_cast<MainWindow::Theme>(m_themeComboBox->currentData(Qt::UserRole).toInt());
if (theme == MainWindow::THEME_CUSTOM)
{
QString filePath = QFileDialog::getOpenFileName(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SELECT_THEME));
if (filePath.isEmpty())
{
int oldThemeIndex = m_themeComboBox->findData(m_mainwindow->getThemeFromString(m_settings->value("theme", "default").toString()));
if (m_themeComboBox->count() > oldThemeIndex)
{
disconnect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThemeComboBoxIndexChanged(int)));
m_themeComboBox->setCurrentIndex(oldThemeIndex);
connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onThemeComboBoxIndexChanged(int)));
}
}
else
{
m_customThemePath = filePath;
if (m_mainwindow->setCustomThemeFile(filePath))
m_mainwindow->setTheme(theme);
}
}
else
m_mainwindow->setTheme(theme);
showOrHideHighlightColor();
}
2019-03-27 02:37:34 +01:00
void ViewOptionsWidget::onHighlightColorChoose()
{
QPixmap highlightPixmap(m_highlightColorPushButton->iconSize());
QColor currentHighlightColor = m_settings->value("highlight_color", QApplication::palette().highlight().color()).value<QColor>();
QColor newHighlightColor = QColorDialog::getColor(currentHighlightColor, this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_SELECT_COLOR));
if (newHighlightColor.isValid())
{
MainWindow::Theme theme = static_cast<MainWindow::Theme>(m_themeComboBox->currentData(Qt::UserRole).toInt());
m_highlightColor = newHighlightColor;
m_settings->setValue("highlight_color", m_highlightColor);
highlightPixmap.fill(m_highlightColor);
m_highlightColorPushButton->setIcon(highlightPixmap);
m_mainwindow->setTheme(theme);
}
}
2019-03-27 02:37:34 +01:00
void ViewOptionsWidget::loadViewOptions()
{
2019-04-21 03:28:23 +02:00
int i;
int themeIndex = 0;
int playlistIndex = 0;
QColor highlightColor = m_settings->value("highlight_color", QApplication::palette().highlight().color()).value<QColor>();
QPixmap highlightPixmap(m_highlightColorPushButton->iconSize());
QVector<QPair<QString, QString> > playlists = m_mainwindow->getPlaylists();
QString initialPlaylist = m_settings->value("initial_playlist", m_mainwindow->getSpecialPlaylistPath(SPECIAL_PLAYLIST_HISTORY)).toString();
m_saveGeometryCheckBox->setChecked(m_settings->value("save_geometry", false).toBool());
m_saveDockPositionsCheckBox->setChecked(m_settings->value("save_dock_positions", false).toBool());
m_saveLastTabCheckBox->setChecked(m_settings->value("save_last_tab", false).toBool());
m_showHiddenFilesCheckBox->setChecked(m_settings->value("show_hidden_files", true).toBool());
m_suggestLoadedCoreFirstCheckBox->setChecked(m_settings->value("suggest_loaded_core_first", false).toBool());
2019-01-31 23:54:25 +01:00
/* m_allPlaylistsListMaxCountSpinBox->setValue(m_settings->value("all_playlists_list_max_count", 0).toInt()); */
/* m_allPlaylistsGridMaxCountSpinBox->setValue(m_settings->value("all_playlists_grid_max_count", 5000).toInt()); */
m_thumbnailCacheSpinBox->setValue(m_settings->value("thumbnail_cache_limit", 512).toInt());
themeIndex = m_themeComboBox->findData(m_mainwindow->getThemeFromString(m_settings->value("theme", "default").toString()));
if (m_themeComboBox->count() > themeIndex)
m_themeComboBox->setCurrentIndex(themeIndex);
if (highlightColor.isValid())
{
m_highlightColor = highlightColor;
highlightPixmap.fill(m_highlightColor);
m_highlightColorPushButton->setIcon(highlightPixmap);
}
showOrHideHighlightColor();
m_startupPlaylistComboBox->clear();
for (i = 0; i < playlists.count(); i++)
{
const QPair<QString, QString> &pair = playlists.at(i);
m_startupPlaylistComboBox->addItem(pair.first, pair.second);
}
playlistIndex = m_startupPlaylistComboBox->findData(initialPlaylist, Qt::UserRole, Qt::MatchFixedString);
if (playlistIndex >= 0)
m_startupPlaylistComboBox->setCurrentIndex(playlistIndex);
}
2019-03-27 02:37:34 +01:00
void ViewOptionsWidget::showOrHideHighlightColor()
{
if (m_mainwindow->theme() == MainWindow::THEME_DARK)
{
m_highlightColorLabel->show();
m_highlightColorPushButton->show();
}
else
{
m_highlightColorLabel->hide();
m_highlightColorPushButton->hide();
}
}
2019-03-27 02:37:34 +01:00
void ViewOptionsWidget::saveViewOptions()
{
m_settings->setValue("save_geometry", m_saveGeometryCheckBox->isChecked());
m_settings->setValue("save_dock_positions", m_saveDockPositionsCheckBox->isChecked());
m_settings->setValue("save_last_tab", m_saveLastTabCheckBox->isChecked());
m_settings->setValue("theme", m_mainwindow->getThemeString(static_cast<MainWindow::Theme>(m_themeComboBox->currentData(Qt::UserRole).toInt())));
m_settings->setValue("show_hidden_files", m_showHiddenFilesCheckBox->isChecked());
m_settings->setValue("highlight_color", m_highlightColor);
m_settings->setValue("suggest_loaded_core_first", m_suggestLoadedCoreFirstCheckBox->isChecked());
2019-01-31 23:54:25 +01:00
/* m_settings->setValue("all_playlists_list_max_count", m_allPlaylistsListMaxCountSpinBox->value()); */
/* m_settings->setValue("all_playlists_grid_max_count", m_allPlaylistsGridMaxCountSpinBox->value()); */
m_settings->setValue("initial_playlist", m_startupPlaylistComboBox->currentData(Qt::UserRole).toString());
m_settings->setValue("thumbnail_cache_limit", m_thumbnailCacheSpinBox->value());
if (!m_mainwindow->customThemeString().isEmpty())
m_settings->setValue("custom_theme", m_customThemePath);
2019-01-31 23:54:25 +01:00
/* m_mainwindow->setAllPlaylistsListMaxCount(m_allPlaylistsListMaxCountSpinBox->value()); */
/* m_mainwindow->setAllPlaylistsGridMaxCount(m_allPlaylistsGridMaxCountSpinBox->value()); */
m_mainwindow->setThumbnailCacheLimit(m_thumbnailCacheSpinBox->value());
}
2019-03-27 02:37:34 +01:00
void ViewOptionsWidget::onAccepted()
{
saveViewOptions();
}
2019-03-27 02:37:34 +01:00
void ViewOptionsWidget::onRejected()
{
loadViewOptions();
}