mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
Qt: use gifs as icons on hover if available.
This commit is contained in:
parent
0a7df9d02e
commit
53f317e076
@ -1043,6 +1043,7 @@
|
|||||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent"</Command>
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl" "-I.\..\3rdparty\curl\include" "-I.\..\3rdparty\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent"</Command>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
<ClInclude Include="rpcs3qt\movie_item.h" />
|
||||||
<ClInclude Include="rpcs3qt\numbered_widget_item.h" />
|
<ClInclude Include="rpcs3qt\numbered_widget_item.h" />
|
||||||
<ClInclude Include="rpcs3qt\richtext_item_delegate.h" />
|
<ClInclude Include="rpcs3qt\richtext_item_delegate.h" />
|
||||||
<ClInclude Include="rpcs3qt\stylesheets.h" />
|
<ClInclude Include="rpcs3qt\stylesheets.h" />
|
||||||
|
@ -872,6 +872,9 @@
|
|||||||
<ClInclude Include="Input\hid_pad_handler.h">
|
<ClInclude Include="Input\hid_pad_handler.h">
|
||||||
<Filter>Io</Filter>
|
<Filter>Io</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="rpcs3qt\movie_item.h">
|
||||||
|
<Filter>Gui\custom items</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="debug\moc_predefs.h.cbt">
|
<CustomBuild Include="debug\moc_predefs.h.cbt">
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
custom_table_widget_item::custom_table_widget_item(const std::string& text, int sort_role, const QVariant& sort_value)
|
custom_table_widget_item::custom_table_widget_item(const std::string& text, int sort_role, const QVariant& sort_value)
|
||||||
: QTableWidgetItem(QString::fromStdString(text).simplified()) // simplified() forces single line text
|
: movie_item(QString::fromStdString(text).simplified()) // simplified() forces single line text
|
||||||
{
|
{
|
||||||
if (sort_role != Qt::DisplayRole)
|
if (sort_role != Qt::DisplayRole)
|
||||||
{
|
{
|
||||||
@ -13,7 +13,7 @@ custom_table_widget_item::custom_table_widget_item(const std::string& text, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
custom_table_widget_item::custom_table_widget_item(const QString& text, int sort_role, const QVariant& sort_value)
|
custom_table_widget_item::custom_table_widget_item(const QString& text, int sort_role, const QVariant& sort_value)
|
||||||
: QTableWidgetItem(text.simplified()) // simplified() forces single line text
|
: movie_item(text.simplified()) // simplified() forces single line text
|
||||||
{
|
{
|
||||||
if (sort_role != Qt::DisplayRole)
|
if (sort_role != Qt::DisplayRole)
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QTableWidgetItem>
|
#include "movie_item.h"
|
||||||
|
|
||||||
class custom_table_widget_item : public QTableWidgetItem
|
class custom_table_widget_item : public movie_item
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int m_sort_role = Qt::DisplayRole;
|
int m_sort_role = Qt::DisplayRole;
|
||||||
|
@ -2,6 +2,26 @@
|
|||||||
|
|
||||||
#include <QTableWidget>
|
#include <QTableWidget>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QPixmap>
|
||||||
|
|
||||||
|
#include "game_compatibility.h"
|
||||||
|
#include "Emu/GameInfo.h"
|
||||||
|
|
||||||
|
/* Having the icons associated with the game info simplifies logic internally */
|
||||||
|
struct gui_game_info
|
||||||
|
{
|
||||||
|
GameInfo info;
|
||||||
|
QString localized_category;
|
||||||
|
compat::status compat;
|
||||||
|
QPixmap icon;
|
||||||
|
QPixmap pxmap;
|
||||||
|
bool hasCustomConfig;
|
||||||
|
bool hasCustomPadConfig;
|
||||||
|
bool has_hover_gif;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<gui_game_info> game_info;
|
||||||
|
Q_DECLARE_METATYPE(game_info)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
class used in order to get deselection
|
class used in order to get deselection
|
||||||
@ -9,6 +29,10 @@
|
|||||||
*/
|
*/
|
||||||
class game_list : public QTableWidget
|
class game_list : public QTableWidget
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
int m_last_entered_row = -1;
|
||||||
|
int m_last_entered_col = -1;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void mousePressEvent(QMouseEvent *event) override
|
void mousePressEvent(QMouseEvent *event) override
|
||||||
{
|
{
|
||||||
|
@ -96,6 +96,7 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> gui_settings, std
|
|||||||
m_game_list->setAlternatingRowColors(true);
|
m_game_list->setAlternatingRowColors(true);
|
||||||
m_game_list->installEventFilter(this);
|
m_game_list->installEventFilter(this);
|
||||||
m_game_list->setColumnCount(gui::column_count);
|
m_game_list->setColumnCount(gui::column_count);
|
||||||
|
m_game_list->setMouseTracking(true);
|
||||||
|
|
||||||
m_game_compat = new game_compatibility(m_gui_settings, this);
|
m_game_compat = new game_compatibility(m_gui_settings, this);
|
||||||
|
|
||||||
@ -132,6 +133,19 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> gui_settings, std
|
|||||||
connect(m_game_list, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu);
|
connect(m_game_list, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu);
|
||||||
connect(m_game_list, &QTableWidget::itemSelectionChanged, this, &game_list_frame::itemSelectionChangedSlot);
|
connect(m_game_list, &QTableWidget::itemSelectionChanged, this, &game_list_frame::itemSelectionChangedSlot);
|
||||||
connect(m_game_list, &QTableWidget::itemDoubleClicked, this, &game_list_frame::doubleClickedSlot);
|
connect(m_game_list, &QTableWidget::itemDoubleClicked, this, &game_list_frame::doubleClickedSlot);
|
||||||
|
connect(m_game_list, &QTableWidget::cellEntered, this, [this](int row, int column)
|
||||||
|
{
|
||||||
|
if (auto old_item = static_cast<movie_item*>(m_game_list->item(m_game_list->m_last_entered_row, m_game_list->m_last_entered_col)))
|
||||||
|
{
|
||||||
|
old_item->set_active(false);
|
||||||
|
}
|
||||||
|
if (auto new_item = static_cast<movie_item*>(m_game_list->item(row, column)))
|
||||||
|
{
|
||||||
|
new_item->set_active(true);
|
||||||
|
}
|
||||||
|
m_game_list->m_last_entered_row = row;
|
||||||
|
m_game_list->m_last_entered_col = column;
|
||||||
|
});
|
||||||
|
|
||||||
connect(m_game_list->horizontalHeader(), &QHeaderView::sectionClicked, this, &game_list_frame::OnColClicked);
|
connect(m_game_list->horizontalHeader(), &QHeaderView::sectionClicked, this, &game_list_frame::OnColClicked);
|
||||||
connect(m_game_list->horizontalHeader(), &QHeaderView::customContextMenuRequested, [this](const QPoint& pos)
|
connect(m_game_list->horizontalHeader(), &QHeaderView::customContextMenuRequested, [this](const QPoint& pos)
|
||||||
@ -209,6 +223,7 @@ void game_list_frame::LoadSettings()
|
|||||||
m_category_filters = m_gui_settings->GetGameListCategoryFilters();
|
m_category_filters = m_gui_settings->GetGameListCategoryFilters();
|
||||||
m_draw_compat_status_to_grid = m_gui_settings->GetValue(gui::gl_draw_compat).toBool();
|
m_draw_compat_status_to_grid = m_gui_settings->GetValue(gui::gl_draw_compat).toBool();
|
||||||
m_show_custom_icons = m_gui_settings->GetValue(gui::gl_custom_icon).toBool();
|
m_show_custom_icons = m_gui_settings->GetValue(gui::gl_custom_icon).toBool();
|
||||||
|
m_play_hover_movies = m_gui_settings->GetValue(gui::gl_hover_gifs).toBool();
|
||||||
|
|
||||||
Refresh(true);
|
Refresh(true);
|
||||||
|
|
||||||
@ -531,10 +546,9 @@ void game_list_frame::Refresh(const bool from_drive, const bool scroll_after)
|
|||||||
path_list.erase(unique(path_list.begin(), path_list.end()), path_list.end());
|
path_list.erase(unique(path_list.begin(), path_list.end()), path_list.end());
|
||||||
|
|
||||||
QSet<QString> serials;
|
QSet<QString> serials;
|
||||||
|
|
||||||
QMutex mutex_cat;
|
QMutex mutex_cat;
|
||||||
|
|
||||||
lf_queue<game_info> games;
|
lf_queue<game_info> games;
|
||||||
|
const std::string game_icon_path = m_play_hover_movies ? fs::get_config_dir() + "/Icons/game_icons/" : "";
|
||||||
|
|
||||||
QtConcurrent::blockingMap(path_list, [&](const std::string& dir)
|
QtConcurrent::blockingMap(path_list, [&](const std::string& dir)
|
||||||
{
|
{
|
||||||
@ -678,11 +692,12 @@ void game_list_frame::Refresh(const bool from_drive, const bool scroll_after)
|
|||||||
|
|
||||||
const bool hasCustomConfig = fs::is_file(Emulator::GetCustomConfigPath(game.serial)) || fs::is_file(Emulator::GetCustomConfigPath(game.serial, true));
|
const bool hasCustomConfig = fs::is_file(Emulator::GetCustomConfigPath(game.serial)) || fs::is_file(Emulator::GetCustomConfigPath(game.serial, true));
|
||||||
const bool hasCustomPadConfig = fs::is_file(Emulator::GetCustomInputConfigPath(game.serial));
|
const bool hasCustomPadConfig = fs::is_file(Emulator::GetCustomInputConfigPath(game.serial));
|
||||||
|
const bool has_hover_gif = fs::is_file(game_icon_path + game.serial + "/hover.gif");
|
||||||
|
|
||||||
const QColor color = getGridCompatibilityColor(compat.color);
|
const QColor color = getGridCompatibilityColor(compat.color);
|
||||||
const QPixmap pxmap = PaintedPixmap(icon, hasCustomConfig, hasCustomPadConfig, color);
|
const QPixmap pxmap = PaintedPixmap(icon, hasCustomConfig, hasCustomPadConfig, color);
|
||||||
|
|
||||||
games.push(std::make_shared<gui_game_info>(gui_game_info{game, qt_cat, compat, icon, pxmap, hasCustomConfig, hasCustomPadConfig}));
|
games.push(std::make_shared<gui_game_info>(gui_game_info{game, qt_cat, compat, icon, pxmap, hasCustomConfig, hasCustomPadConfig, has_hover_gif}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1025,6 +1040,13 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
|||||||
icon_menu->addAction(tr("&Remove Custom Icon"))
|
icon_menu->addAction(tr("&Remove Custom Icon"))
|
||||||
};
|
};
|
||||||
icon_menu->addSeparator();
|
icon_menu->addSeparator();
|
||||||
|
const std::array<QAction*, 3> custom_gif_actions =
|
||||||
|
{
|
||||||
|
icon_menu->addAction(tr("&Import Hover Gif")),
|
||||||
|
icon_menu->addAction(tr("&Replace Hover Gif")),
|
||||||
|
icon_menu->addAction(tr("&Remove Hover Gif"))
|
||||||
|
};
|
||||||
|
icon_menu->addSeparator();
|
||||||
const std::array<QAction*, 3> custom_shader_icon_actions =
|
const std::array<QAction*, 3> custom_shader_icon_actions =
|
||||||
{
|
{
|
||||||
icon_menu->addAction(tr("&Import Custom Shader Loading Background")),
|
icon_menu->addAction(tr("&Import Custom Shader Loading Background")),
|
||||||
@ -1044,36 +1066,60 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
|||||||
enum class icon_type
|
enum class icon_type
|
||||||
{
|
{
|
||||||
game_list,
|
game_list,
|
||||||
|
hover_gif,
|
||||||
shader_load
|
shader_load
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto handle_icon = [this, serial](const QString& game_icon_path, icon_action action, icon_type type)
|
const auto handle_icon = [this, serial](const QString& game_icon_path, const QString& suffix, icon_action action, icon_type type)
|
||||||
{
|
{
|
||||||
QString icon_path;
|
QString icon_path;
|
||||||
|
|
||||||
if (action != icon_action::remove)
|
if (action != icon_action::remove)
|
||||||
{
|
{
|
||||||
icon_path = QFileDialog::getOpenFileName(this, type == icon_type::game_list
|
QString msg;
|
||||||
? tr("Select Custom Icon")
|
switch (type)
|
||||||
: tr("Select Custom Shader Loading Background"), "", tr("png (*.png);;All files (*.*)"));
|
{
|
||||||
|
case icon_type::game_list:
|
||||||
|
msg = tr("Select Custom Icon");
|
||||||
|
break;
|
||||||
|
case icon_type::hover_gif:
|
||||||
|
msg = tr("Select Custom Hover Gif");
|
||||||
|
break;
|
||||||
|
case icon_type::shader_load:
|
||||||
|
msg = tr("Select Custom Shader Loading Background");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
icon_path = QFileDialog::getOpenFileName(this, msg, "", tr("%0 (*.%0);;All files (*.*)").arg(suffix));
|
||||||
}
|
}
|
||||||
if (action == icon_action::remove || !icon_path.isEmpty())
|
if (action == icon_action::remove || !icon_path.isEmpty())
|
||||||
{
|
{
|
||||||
bool refresh = false;
|
bool refresh = false;
|
||||||
|
|
||||||
|
QString msg;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case icon_type::game_list:
|
||||||
|
msg = tr("Remove Custom Icon of %0?").arg(serial);
|
||||||
|
break;
|
||||||
|
case icon_type::hover_gif:
|
||||||
|
msg = tr("Remove Custom Hover Gif of %0?").arg(serial);
|
||||||
|
break;
|
||||||
|
case icon_type::shader_load:
|
||||||
|
msg = tr("Remove Custom Shader Loading Background of %0?").arg(serial);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (action == icon_action::replace || (action == icon_action::remove &&
|
if (action == icon_action::replace || (action == icon_action::remove &&
|
||||||
QMessageBox::question(this, tr("Confirm Removal"), type == icon_type::game_list
|
QMessageBox::question(this, tr("Confirm Removal"), msg) == QMessageBox::Yes))
|
||||||
? tr("Remove custom icon of %0?").arg(serial)
|
|
||||||
: tr("Remove Custom Shader Loading Background of %0?").arg(serial)) == QMessageBox::Yes))
|
|
||||||
{
|
{
|
||||||
if (QFile file(game_icon_path); file.exists() && !file.remove())
|
if (QFile file(game_icon_path); file.exists() && !file.remove())
|
||||||
{
|
{
|
||||||
game_list_log.error("Could not remove old image: '%s'", sstr(game_icon_path), sstr(file.errorString()));
|
game_list_log.error("Could not remove old file: '%s'", sstr(game_icon_path), sstr(file.errorString()));
|
||||||
QMessageBox::warning(this, tr("Warning!"), tr("Failed to remove the old image!"));
|
QMessageBox::warning(this, tr("Warning!"), tr("Failed to remove the old file!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
game_list_log.success("Removed image: '%s'", sstr(game_icon_path));
|
game_list_log.success("Removed file: '%s'", sstr(game_icon_path));
|
||||||
if (action == icon_action::remove)
|
if (action == icon_action::remove)
|
||||||
{
|
{
|
||||||
refresh = true;
|
refresh = true;
|
||||||
@ -1084,12 +1130,12 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
|||||||
{
|
{
|
||||||
if (!QFile::copy(icon_path, game_icon_path))
|
if (!QFile::copy(icon_path, game_icon_path))
|
||||||
{
|
{
|
||||||
game_list_log.error("Could not import image '%s' to '%s'.", sstr(icon_path), sstr(game_icon_path));
|
game_list_log.error("Could not import file '%s' to '%s'.", sstr(icon_path), sstr(game_icon_path));
|
||||||
QMessageBox::warning(this, tr("Warning!"), tr("Failed to import the new image!"));
|
QMessageBox::warning(this, tr("Warning!"), tr("Failed to import the new file!"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
game_list_log.success("Imported image '%s' to '%s'", sstr(icon_path), sstr(game_icon_path));
|
game_list_log.success("Imported file '%s' to '%s'", sstr(icon_path), sstr(game_icon_path));
|
||||||
refresh = true;
|
refresh = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1101,25 +1147,26 @@ void game_list_frame::ShowContextMenu(const QPoint &pos)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<std::tuple<icon_type, QString, const std::array<QAction*, 3>&>> icon_map =
|
const std::vector<std::tuple<icon_type, QString, QString, const std::array<QAction*, 3>&>> icon_map =
|
||||||
{
|
{
|
||||||
{icon_type::game_list, "/ICON0.PNG", custom_icon_actions},
|
{icon_type::game_list, "/ICON0.PNG", "png", custom_icon_actions},
|
||||||
{icon_type::shader_load, "/PIC1.PNG", custom_shader_icon_actions},
|
{icon_type::hover_gif, "/hover.gif", "gif", custom_gif_actions},
|
||||||
|
{icon_type::shader_load, "/PIC1.PNG", "png", custom_shader_icon_actions},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto& [type, icon_name, actions] : icon_map)
|
for (const auto& [type, icon_name, suffix, actions] : icon_map)
|
||||||
{
|
{
|
||||||
const QString icon_path = qstr(custom_icon_dir_path) + icon_name;
|
const QString icon_path = qstr(custom_icon_dir_path) + icon_name;
|
||||||
|
|
||||||
if (QFile::exists(icon_path))
|
if (QFile::exists(icon_path))
|
||||||
{
|
{
|
||||||
actions[static_cast<int>(icon_action::add)]->setVisible(false);
|
actions[static_cast<int>(icon_action::add)]->setVisible(false);
|
||||||
connect(actions[static_cast<int>(icon_action::replace)], &QAction::triggered, this, [handle_icon, icon_path, t = type] { handle_icon(icon_path, icon_action::replace, t); });
|
connect(actions[static_cast<int>(icon_action::replace)], &QAction::triggered, this, [handle_icon, icon_path, t = type, s = suffix] { handle_icon(icon_path, s, icon_action::replace, t); });
|
||||||
connect(actions[static_cast<int>(icon_action::remove)], &QAction::triggered, this, [handle_icon, icon_path, t = type] { handle_icon(icon_path, icon_action::remove, t); });
|
connect(actions[static_cast<int>(icon_action::remove)], &QAction::triggered, this, [handle_icon, icon_path, t = type, s = suffix] { handle_icon(icon_path, s, icon_action::remove, t); });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
connect(actions[static_cast<int>(icon_action::add)], &QAction::triggered, this, [handle_icon, icon_path, t = type] { handle_icon(icon_path, icon_action::add, t); });
|
connect(actions[static_cast<int>(icon_action::add)], &QAction::triggered, this, [handle_icon, icon_path, t = type, s = suffix] { handle_icon(icon_path, s, icon_action::add, t); });
|
||||||
actions[static_cast<int>(icon_action::replace)]->setVisible(false);
|
actions[static_cast<int>(icon_action::replace)]->setVisible(false);
|
||||||
actions[static_cast<int>(icon_action::remove)]->setEnabled(false);
|
actions[static_cast<int>(icon_action::remove)]->setEnabled(false);
|
||||||
}
|
}
|
||||||
@ -2011,7 +2058,7 @@ bool game_list_frame::eventFilter(QObject *object, QEvent *event)
|
|||||||
Q_EMIT RequestIconSizeChange(1);
|
Q_EMIT RequestIconSizeChange(1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (key_event->key() == Qt::Key_Minus)
|
if (key_event->key() == Qt::Key_Minus)
|
||||||
{
|
{
|
||||||
Q_EMIT RequestIconSizeChange(-1);
|
Q_EMIT RequestIconSizeChange(-1);
|
||||||
return true;
|
return true;
|
||||||
@ -2064,7 +2111,14 @@ void game_list_frame::PopulateGameList()
|
|||||||
const QLocale locale{};
|
const QLocale locale{};
|
||||||
const Localized localized;
|
const Localized localized;
|
||||||
|
|
||||||
int row = 0, index = -1;
|
const QString game_icon_path = m_play_hover_movies ? qstr(fs::get_config_dir() + "/Icons/game_icons/") : "";
|
||||||
|
|
||||||
|
static QIcon icon_combo_config_bordered(":/Icons/combo_config_bordered.png");
|
||||||
|
static QIcon icon_custom_config(":/Icons/custom_config.png");
|
||||||
|
static QIcon icon_controllers(":/Icons/controllers.png");
|
||||||
|
|
||||||
|
int row = 0;
|
||||||
|
int index = -1;
|
||||||
for (const auto& game : m_game_data)
|
for (const auto& game : m_game_data)
|
||||||
{
|
{
|
||||||
index++;
|
index++;
|
||||||
@ -2078,23 +2132,46 @@ void game_list_frame::PopulateGameList()
|
|||||||
|
|
||||||
// Icon
|
// Icon
|
||||||
custom_table_widget_item* icon_item = new custom_table_widget_item;
|
custom_table_widget_item* icon_item = new custom_table_widget_item;
|
||||||
icon_item->setData(Qt::DecorationRole, game->pxmap);
|
|
||||||
|
icon_item->set_icon_func([this, icon_item, game](int)
|
||||||
|
{
|
||||||
|
ensure(icon_item);
|
||||||
|
|
||||||
|
if (QMovie* movie = icon_item->movie(); movie && icon_item->get_active())
|
||||||
|
{
|
||||||
|
icon_item->setData(Qt::DecorationRole, movie->currentPixmap().scaled(m_icon_size, Qt::KeepAspectRatio));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
icon_item->setData(Qt::DecorationRole, game->pxmap);
|
||||||
|
if (movie)
|
||||||
|
{
|
||||||
|
movie->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (m_play_hover_movies && game->has_hover_gif)
|
||||||
|
{
|
||||||
|
icon_item->init_movie(game_icon_path % serial % "/hover.gif");
|
||||||
|
}
|
||||||
|
|
||||||
icon_item->setData(Qt::UserRole, index, true);
|
icon_item->setData(Qt::UserRole, index, true);
|
||||||
icon_item->setData(gui::game_role, QVariant::fromValue(game));
|
icon_item->setData(gui::custom_roles::game_role, QVariant::fromValue(game));
|
||||||
|
|
||||||
// Title
|
// Title
|
||||||
custom_table_widget_item* title_item = new custom_table_widget_item(title);
|
custom_table_widget_item* title_item = new custom_table_widget_item(title);
|
||||||
if (game->hasCustomConfig && game->hasCustomPadConfig)
|
if (game->hasCustomConfig && game->hasCustomPadConfig)
|
||||||
{
|
{
|
||||||
title_item->setIcon(QIcon(":/Icons/combo_config_bordered.png"));
|
title_item->setIcon(icon_combo_config_bordered);
|
||||||
}
|
}
|
||||||
else if (game->hasCustomConfig)
|
else if (game->hasCustomConfig)
|
||||||
{
|
{
|
||||||
title_item->setIcon(QIcon(":/Icons/custom_config.png"));
|
title_item->setIcon(icon_custom_config);
|
||||||
}
|
}
|
||||||
else if (game->hasCustomPadConfig)
|
else if (game->hasCustomPadConfig)
|
||||||
{
|
{
|
||||||
title_item->setIcon(QIcon(":/Icons/controllers.png"));
|
title_item->setIcon(icon_controllers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serial
|
// Serial
|
||||||
@ -2112,7 +2189,7 @@ void game_list_frame::PopulateGameList()
|
|||||||
|
|
||||||
// Compatibility
|
// Compatibility
|
||||||
custom_table_widget_item* compat_item = new custom_table_widget_item;
|
custom_table_widget_item* compat_item = new custom_table_widget_item;
|
||||||
compat_item->setText(game->compat.text + (game->compat.date.isEmpty() ? "" : " (" + game->compat.date + ")"));
|
compat_item->setText(game->compat.text % (game->compat.date.isEmpty() ? QStringLiteral("") : " (" % game->compat.date % ")"));
|
||||||
compat_item->setData(Qt::UserRole, game->compat.index, true);
|
compat_item->setData(Qt::UserRole, game->compat.index, true);
|
||||||
compat_item->setToolTip(game->compat.tooltip);
|
compat_item->setToolTip(game->compat.tooltip);
|
||||||
if (!game->compat.color.isEmpty())
|
if (!game->compat.color.isEmpty())
|
||||||
@ -2223,13 +2300,15 @@ void game_list_frame::PopulateGameGrid(int maxCols, const QSize& image_size, con
|
|||||||
m_game_grid->setRowCount(max_rows);
|
m_game_grid->setRowCount(max_rows);
|
||||||
m_game_grid->setColumnCount(maxCols);
|
m_game_grid->setColumnCount(maxCols);
|
||||||
|
|
||||||
|
const QString game_icon_path = m_play_hover_movies ? qstr(fs::get_config_dir() + "/Icons/game_icons/") : "";
|
||||||
|
|
||||||
for (const auto& app : matching_apps)
|
for (const auto& app : matching_apps)
|
||||||
{
|
{
|
||||||
const QString serial = qstr(app->info.serial);
|
const QString serial = qstr(app->info.serial);
|
||||||
const QString title = m_titles.value(serial, qstr(app->info.name));
|
const QString title = m_titles.value(serial, qstr(app->info.name));
|
||||||
const QString notes = m_notes.value(serial);
|
const QString notes = m_notes.value(serial);
|
||||||
|
|
||||||
m_game_grid->addItem(app->pxmap, title, r, c);
|
m_game_grid->addItem(app, title, (m_play_hover_movies && app->has_hover_gif) ? (game_icon_path % serial % "/hover.gif") : QStringLiteral(""), r, c);
|
||||||
m_game_grid->item(r, c)->setData(gui::game_role, QVariant::fromValue(app));
|
m_game_grid->item(r, c)->setData(gui::game_role, QVariant::fromValue(app));
|
||||||
|
|
||||||
if (!notes.isEmpty())
|
if (!notes.isEmpty())
|
||||||
@ -2305,9 +2384,7 @@ std::string game_list_frame::CurrentSelectionPath()
|
|||||||
|
|
||||||
if (item)
|
if (item)
|
||||||
{
|
{
|
||||||
const QVariant var = item->data(gui::game_role);
|
if (const QVariant var = item->data(gui::game_role); var.canConvert<game_info>())
|
||||||
|
|
||||||
if (var.canConvert<game_info>())
|
|
||||||
{
|
{
|
||||||
if (const game_info game = var.value<game_info>())
|
if (const game_info game = var.value<game_info>())
|
||||||
{
|
{
|
||||||
@ -2408,6 +2485,16 @@ void game_list_frame::SetShowCustomIcons(bool show)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void game_list_frame::SetPlayHoverGifs(bool play)
|
||||||
|
{
|
||||||
|
if (m_play_hover_movies != play)
|
||||||
|
{
|
||||||
|
m_play_hover_movies = play;
|
||||||
|
m_gui_settings->SetValue(gui::gl_hover_gifs, play);
|
||||||
|
Refresh(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QList<game_info> game_list_frame::GetGameInfo() const
|
QList<game_info> game_list_frame::GetGameInfo() const
|
||||||
{
|
{
|
||||||
return m_game_data;
|
return m_game_data;
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Emu/GameInfo.h"
|
#include "game_list.h"
|
||||||
|
|
||||||
#include "custom_dock_widget.h"
|
#include "custom_dock_widget.h"
|
||||||
#include "game_compatibility.h"
|
|
||||||
#include "gui_save.h"
|
#include "gui_save.h"
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
@ -14,27 +12,11 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class game_list;
|
|
||||||
class game_list_grid;
|
class game_list_grid;
|
||||||
class gui_settings;
|
class gui_settings;
|
||||||
class emu_settings;
|
class emu_settings;
|
||||||
class persistent_settings;
|
class persistent_settings;
|
||||||
|
|
||||||
/* Having the icons associated with the game info simplifies logic internally */
|
|
||||||
struct gui_game_info
|
|
||||||
{
|
|
||||||
GameInfo info;
|
|
||||||
QString localized_category;
|
|
||||||
compat::status compat;
|
|
||||||
QPixmap icon;
|
|
||||||
QPixmap pxmap;
|
|
||||||
bool hasCustomConfig;
|
|
||||||
bool hasCustomPadConfig;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::shared_ptr<gui_game_info> game_info;
|
|
||||||
Q_DECLARE_METATYPE(game_info)
|
|
||||||
|
|
||||||
class game_list_frame : public custom_dock_widget
|
class game_list_frame : public custom_dock_widget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -87,6 +69,7 @@ public Q_SLOTS:
|
|||||||
void SetSearchText(const QString& text);
|
void SetSearchText(const QString& text);
|
||||||
void SetShowCompatibilityInGrid(bool show);
|
void SetShowCompatibilityInGrid(bool show);
|
||||||
void SetShowCustomIcons(bool show);
|
void SetShowCustomIcons(bool show);
|
||||||
|
void SetPlayHoverGifs(bool play);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void OnColClicked(int col);
|
void OnColClicked(int col);
|
||||||
@ -174,4 +157,5 @@ private:
|
|||||||
qreal m_text_factor;
|
qreal m_text_factor;
|
||||||
bool m_draw_compat_status_to_grid = false;
|
bool m_draw_compat_status_to_grid = false;
|
||||||
bool m_show_custom_icons = true;
|
bool m_show_custom_icons = true;
|
||||||
|
bool m_play_hover_movies = true;
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "game_list_grid.h"
|
#include "game_list_grid.h"
|
||||||
#include "game_list_grid_delegate.h"
|
#include "game_list_grid_delegate.h"
|
||||||
|
#include "movie_item.h"
|
||||||
#include "qt_utils.h"
|
#include "qt_utils.h"
|
||||||
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
@ -38,6 +39,21 @@ game_list_grid::game_list_grid(const QSize& icon_size, QColor icon_color, const
|
|||||||
verticalHeader()->setVisible(false);
|
verticalHeader()->setVisible(false);
|
||||||
horizontalHeader()->setVisible(false);
|
horizontalHeader()->setVisible(false);
|
||||||
setShowGrid(false);
|
setShowGrid(false);
|
||||||
|
setMouseTracking(true);
|
||||||
|
|
||||||
|
connect(this, &QTableWidget::cellEntered, this, [this](int row, int column)
|
||||||
|
{
|
||||||
|
if (auto old_item = dynamic_cast<movie_item*>(item(m_last_entered_row, m_last_entered_col)))
|
||||||
|
{
|
||||||
|
old_item->set_active(false);
|
||||||
|
}
|
||||||
|
if (auto new_item = dynamic_cast<movie_item*>(item(row, column)))
|
||||||
|
{
|
||||||
|
new_item->set_active(true);
|
||||||
|
}
|
||||||
|
m_last_entered_row = row;
|
||||||
|
m_last_entered_col = column;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_list_grid::enableText(const bool& enabled)
|
void game_list_grid::enableText(const bool& enabled)
|
||||||
@ -57,44 +73,77 @@ void game_list_grid::setIconSize(const QSize& size) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_list_grid::addItem(const QPixmap& img, const QString& name, const int& row, const int& col)
|
void game_list_grid::addItem(const game_info& app, const QString& name, const QString& movie_path, const int& row, const int& col)
|
||||||
{
|
{
|
||||||
const qreal device_pixel_ratio = devicePixelRatioF();
|
|
||||||
|
|
||||||
// define size of expanded image, which is raw image size + margins
|
|
||||||
QSizeF exp_size;
|
|
||||||
if (m_text_enabled)
|
|
||||||
{
|
|
||||||
exp_size = m_icon_size + QSizeF(m_icon_size.width() * m_margin_factor * 2, m_icon_size.height() * m_margin_factor * (m_text_factor + 1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
exp_size = m_icon_size + m_icon_size * m_margin_factor * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// define offset for raw image placement
|
|
||||||
const QPoint offset = QPoint(m_icon_size.width() * m_margin_factor, m_icon_size.height() * m_margin_factor);
|
|
||||||
|
|
||||||
// create empty canvas for expanded image
|
|
||||||
QImage exp_img = QImage((exp_size * device_pixel_ratio).toSize(), QImage::Format_ARGB32);
|
|
||||||
exp_img.setDevicePixelRatio(device_pixel_ratio);
|
|
||||||
exp_img.fill(Qt::transparent);
|
|
||||||
|
|
||||||
// create background for image
|
|
||||||
QImage bg_img = QImage(img.size(), QImage::Format_ARGB32);
|
|
||||||
bg_img.setDevicePixelRatio(device_pixel_ratio);
|
|
||||||
bg_img.fill(m_icon_color);
|
|
||||||
|
|
||||||
// place raw image inside expanded image
|
|
||||||
QPainter painter(&exp_img);
|
|
||||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
|
||||||
painter.drawImage(offset, bg_img);
|
|
||||||
painter.drawPixmap(offset, img);
|
|
||||||
painter.end();
|
|
||||||
|
|
||||||
// create item with expanded image, title and position
|
// create item with expanded image, title and position
|
||||||
QTableWidgetItem* item = new QTableWidgetItem();
|
movie_item* item = new movie_item;
|
||||||
item->setData(Qt::ItemDataRole::DecorationRole, QPixmap::fromImage(exp_img));
|
|
||||||
|
item->set_icon_func([this, app, item](int)
|
||||||
|
{
|
||||||
|
ensure(item);
|
||||||
|
|
||||||
|
const qreal device_pixel_ratio = devicePixelRatioF();
|
||||||
|
|
||||||
|
// define size of expanded image, which is raw image size + margins
|
||||||
|
QSizeF exp_size_f;
|
||||||
|
if (m_text_enabled)
|
||||||
|
{
|
||||||
|
exp_size_f = m_icon_size + QSizeF(m_icon_size.width() * m_margin_factor * 2, m_icon_size.height() * m_margin_factor * (m_text_factor + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
exp_size_f = m_icon_size + m_icon_size * m_margin_factor * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMovie* movie = item->movie();
|
||||||
|
const bool draw_movie_frame = movie && movie->isValid() && item->get_active();
|
||||||
|
const QSize exp_size = (exp_size_f * device_pixel_ratio).toSize();
|
||||||
|
|
||||||
|
// create empty canvas for expanded image
|
||||||
|
QImage exp_img(exp_size, QImage::Format_ARGB32);
|
||||||
|
exp_img.setDevicePixelRatio(device_pixel_ratio);
|
||||||
|
exp_img.fill(Qt::transparent);
|
||||||
|
|
||||||
|
// define offset for raw image placement
|
||||||
|
QPoint offset(m_icon_size.width() * m_margin_factor, m_icon_size.height() * m_margin_factor);
|
||||||
|
|
||||||
|
// place raw image inside expanded image
|
||||||
|
QPainter painter(&exp_img);
|
||||||
|
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||||
|
|
||||||
|
if (draw_movie_frame)
|
||||||
|
{
|
||||||
|
const QPixmap scaled_movie_frame = movie->currentPixmap().scaled(m_icon_size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
|
offset += QPoint(m_icon_size.width() / 2 - scaled_movie_frame.width() / 2,
|
||||||
|
m_icon_size.height() / 2 - scaled_movie_frame.height() / 2);
|
||||||
|
painter.drawPixmap(offset, scaled_movie_frame);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// create background for image
|
||||||
|
QImage bg_img(app->pxmap.size(), QImage::Format_ARGB32);
|
||||||
|
bg_img.setDevicePixelRatio(device_pixel_ratio);
|
||||||
|
bg_img.fill(m_icon_color);
|
||||||
|
|
||||||
|
painter.drawImage(offset, bg_img);
|
||||||
|
painter.drawPixmap(offset, app->pxmap);
|
||||||
|
|
||||||
|
if (movie)
|
||||||
|
{
|
||||||
|
movie->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
painter.end();
|
||||||
|
|
||||||
|
// create item with expanded image, title and position
|
||||||
|
item->setData(Qt::ItemDataRole::DecorationRole, QPixmap::fromImage(exp_img));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!movie_path.isEmpty())
|
||||||
|
{
|
||||||
|
item->init_movie(movie_path);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_text_enabled)
|
if (m_text_enabled)
|
||||||
{
|
{
|
||||||
|
@ -19,9 +19,9 @@ public:
|
|||||||
|
|
||||||
void enableText(const bool& enabled);
|
void enableText(const bool& enabled);
|
||||||
void setIconSize(const QSize& size) const;
|
void setIconSize(const QSize& size) const;
|
||||||
void addItem(const QPixmap& img, const QString& name, const int& row, const int& col);
|
void addItem(const game_info& app, const QString& name, const QString& movie_path, const int& row, const int& col);
|
||||||
|
|
||||||
qreal getMarginFactor() const;
|
[[nodiscard]] qreal getMarginFactor() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
game_list_grid_delegate* grid_item_delegate;
|
game_list_grid_delegate* grid_item_delegate;
|
||||||
|
@ -5,7 +5,7 @@ game_list_grid_delegate::game_list_grid_delegate(const QSize& size, const qreal&
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_list_grid_delegate::initStyleOption(QStyleOptionViewItem * option, const QModelIndex & index) const
|
void game_list_grid_delegate::initStyleOption(QStyleOptionViewItem* option, const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(index)
|
Q_UNUSED(index)
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ void game_list_grid_delegate::initStyleOption(QStyleOptionViewItem * option, con
|
|||||||
QStyledItemDelegate::initStyleOption(option, QModelIndex());
|
QStyledItemDelegate::initStyleOption(option, QModelIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_list_grid_delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
void game_list_grid_delegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
const QRect r = option.rect;
|
const QRect r = option.rect;
|
||||||
|
|
||||||
@ -54,14 +54,14 @@ void game_list_grid_delegate::paint(QPainter *painter, const QStyleOptionViewIte
|
|||||||
painter->drawText(QRect(r.left(), top, r.width(), height), +Qt::TextWordWrap | +Qt::AlignCenter, title);
|
painter->drawText(QRect(r.left(), top, r.width(), height), +Qt::TextWordWrap | +Qt::AlignCenter, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize game_list_grid_delegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
|
QSize game_list_grid_delegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(option)
|
Q_UNUSED(option)
|
||||||
Q_UNUSED(index)
|
Q_UNUSED(index)
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_list_grid_delegate::setItemSize(const QSize & size)
|
void game_list_grid_delegate::setItemSize(const QSize& size)
|
||||||
{
|
{
|
||||||
m_size = size;
|
m_size = size;
|
||||||
}
|
}
|
||||||
|
@ -167,6 +167,7 @@ namespace gui
|
|||||||
const gui_save gl_hidden_list = gui_save(game_list, "hidden_list", QStringList());
|
const gui_save gl_hidden_list = gui_save(game_list, "hidden_list", QStringList());
|
||||||
const gui_save gl_draw_compat = gui_save(game_list, "draw_compat", false);
|
const gui_save gl_draw_compat = gui_save(game_list, "draw_compat", false);
|
||||||
const gui_save gl_custom_icon = gui_save(game_list, "custom_icon", true);
|
const gui_save gl_custom_icon = gui_save(game_list, "custom_icon", true);
|
||||||
|
const gui_save gl_hover_gifs = gui_save(game_list, "hover_gifs", true);
|
||||||
|
|
||||||
const gui_save fs_emulator_dir_list = gui_save(fs, "emulator_dir_list", QStringList());
|
const gui_save fs_emulator_dir_list = gui_save(fs, "emulator_dir_list", QStringList());
|
||||||
const gui_save fs_dev_hdd0_list = gui_save(fs, "dev_hdd0_list", QStringList());
|
const gui_save fs_dev_hdd0_list = gui_save(fs, "dev_hdd0_list", QStringList());
|
||||||
|
@ -2259,6 +2259,7 @@ void main_window::CreateConnects()
|
|||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->showCustomIconsAct, &QAction::triggered, m_game_list_frame, &game_list_frame::SetShowCustomIcons);
|
connect(ui->showCustomIconsAct, &QAction::triggered, m_game_list_frame, &game_list_frame::SetShowCustomIcons);
|
||||||
|
connect(ui->playHoverGifsAct, &QAction::triggered, m_game_list_frame, &game_list_frame::SetPlayHoverGifs);
|
||||||
|
|
||||||
connect(m_game_list_frame, &game_list_frame::RequestIconSizeChange, this, [this](const int& val)
|
connect(m_game_list_frame, &game_list_frame::RequestIconSizeChange, this, [this](const int& val)
|
||||||
{
|
{
|
||||||
@ -2517,6 +2518,7 @@ void main_window::ConfigureGuiFromSettings(bool configure_all)
|
|||||||
|
|
||||||
ui->showCompatibilityInGridAct->setChecked(m_gui_settings->GetValue(gui::gl_draw_compat).toBool());
|
ui->showCompatibilityInGridAct->setChecked(m_gui_settings->GetValue(gui::gl_draw_compat).toBool());
|
||||||
ui->showCustomIconsAct->setChecked(m_gui_settings->GetValue(gui::gl_custom_icon).toBool());
|
ui->showCustomIconsAct->setChecked(m_gui_settings->GetValue(gui::gl_custom_icon).toBool());
|
||||||
|
ui->playHoverGifsAct->setChecked(m_gui_settings->GetValue(gui::gl_hover_gifs).toBool());
|
||||||
|
|
||||||
ui->showCatHDDGameAct->setChecked(m_gui_settings->GetCategoryVisibility(Category::HDD_Game));
|
ui->showCatHDDGameAct->setChecked(m_gui_settings->GetCategoryVisibility(Category::HDD_Game));
|
||||||
ui->showCatDiscGameAct->setChecked(m_gui_settings->GetCategoryVisibility(Category::Disc_Game));
|
ui->showCatDiscGameAct->setChecked(m_gui_settings->GetCategoryVisibility(Category::Disc_Game));
|
||||||
|
@ -141,7 +141,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1058</width>
|
<width>1058</width>
|
||||||
<height>30</height>
|
<height>25</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="contextMenuPolicy">
|
<property name="contextMenuPolicy">
|
||||||
@ -279,6 +279,7 @@
|
|||||||
<addaction name="setIconSizeLargeAct"/>
|
<addaction name="setIconSizeLargeAct"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="showCustomIconsAct"/>
|
<addaction name="showCustomIconsAct"/>
|
||||||
|
<addaction name="playHoverGifsAct"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuGame_List_Mode">
|
<widget class="QMenu" name="menuGame_List_Mode">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@ -1151,6 +1152,17 @@
|
|||||||
<string>Show Custom Icons</string>
|
<string>Show Custom Icons</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="playHoverGifsAct">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Play Hover Gifs</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources>
|
<resources>
|
||||||
|
83
rpcs3/rpcs3qt/movie_item.h
Normal file
83
rpcs3/rpcs3qt/movie_item.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QTableWidgetItem>
|
||||||
|
#include <QMovie>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
using icon_callback_t = std::function<void(int)>;
|
||||||
|
|
||||||
|
class movie_item : public QTableWidgetItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
movie_item() : QTableWidgetItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
movie_item(const QString& text, int type = Type) : QTableWidgetItem(text, type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
movie_item(const QIcon& icon, const QString& text, int type = Type) : QTableWidgetItem(icon, text, type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~movie_item()
|
||||||
|
{
|
||||||
|
if (m_movie)
|
||||||
|
{
|
||||||
|
m_movie->stop();
|
||||||
|
delete m_movie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_active(bool active)
|
||||||
|
{
|
||||||
|
if (!std::exchange(m_active, active) && active && m_movie)
|
||||||
|
{
|
||||||
|
m_movie->jumpToFrame(1);
|
||||||
|
m_movie->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool get_active() const
|
||||||
|
{
|
||||||
|
return m_active;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] QMovie* movie() const
|
||||||
|
{
|
||||||
|
return m_movie;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_movie(const QString& path)
|
||||||
|
{
|
||||||
|
if (path.isEmpty() || !m_icon_callback) return;
|
||||||
|
|
||||||
|
if (QMovie* movie = new QMovie(path); movie && movie->isValid())
|
||||||
|
{
|
||||||
|
m_movie = movie;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete movie;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject::connect(m_movie, &QMovie::frameChanged, m_movie, m_icon_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_icon_func(const icon_callback_t& func)
|
||||||
|
{
|
||||||
|
m_icon_callback = func;
|
||||||
|
|
||||||
|
if (m_icon_callback)
|
||||||
|
{
|
||||||
|
m_icon_callback(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMovie* m_movie = nullptr;
|
||||||
|
bool m_active = false;
|
||||||
|
icon_callback_t m_icon_callback = nullptr;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user