From 39be450fa3a7248f7dde73dfe91d2f0447a155dd Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 22 Jun 2026 21:04:47 +0200 Subject: [PATCH] [desktop] Add basic carousel view (#4112) Adds a basic carousel view, or essentially a horizontal list a la Android/Qt Quick. Lacks a lot of niceties like autoscroll, smooth shifts, etc. Will work on those later Also fixed a bug introduced recently that capped game icon size to 8 at the low end, breaking the None option Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4112 Reviewed-by: MaranBr Reviewed-by: Shinmegumi Reviewed-by: Lizzie --- src/common/settings_enums.h | 2 +- src/qt_common/config/uisettings.h | 2 +- src/qt_common/game_list/game_list_p.h | 1 + src/yuzu/CMakeLists.txt | 4 +- src/yuzu/game/carousel.cpp | 107 ++++++++++++++++++++++++++ src/yuzu/game/carousel.h | 27 +++++++ src/yuzu/game/game_card.cpp | 69 +++++++++++++---- src/yuzu/game/game_card.h | 10 ++- src/yuzu/game/game_grid.cpp | 13 +++- src/yuzu/game/game_grid.h | 4 +- src/yuzu/game/game_list.cpp | 71 +++++++++++++---- src/yuzu/game/game_list.h | 7 +- src/yuzu/game/game_tree.h | 2 - src/yuzu/main.ui | 11 ++- src/yuzu/main_window.cpp | 14 +++- src/yuzu/main_window.h | 1 + 16 files changed, 300 insertions(+), 45 deletions(-) create mode 100644 src/yuzu/game/carousel.cpp create mode 100644 src/yuzu/game/carousel.h diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index a71cf2141c..b14ed9bc67 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -158,7 +158,7 @@ ENUM(GpuUnswizzleChunk, VeryLow, Low, Normal, Medium, High) ENUM(TemperatureUnits, Celsius, Fahrenheit) ENUM(ExtendedDynamicState, Disabled, EDS1, EDS2, EDS3); ENUM(GpuLogLevel, Off, Errors, Standard, Verbose, All) -ENUM(GameListMode, TreeView, GridView); +ENUM(GameListMode, TreeView, GridView, CarouselView); ENUM(SpeedMode, Standard, Turbo, Slow); template diff --git a/src/qt_common/config/uisettings.h b/src/qt_common/config/uisettings.h index d1e365553d..fd79d2299f 100644 --- a/src/qt_common/config/uisettings.h +++ b/src/qt_common/config/uisettings.h @@ -207,7 +207,7 @@ struct Values { // Game List Setting show_add_ons{linkage, true, "show_add_ons", Category::UiGameList}; - Setting game_icon_size{linkage, 64, 8, 512, "game_icon_size", Category::UiGameList}; + Setting game_icon_size{linkage, 64, 0, 512, "game_icon_size", Category::UiGameList}; Setting folder_icon_size{linkage, 48, 8, 512, "folder_icon_size", Category::UiGameList}; Setting row_1_text_id{linkage, 3, "row_1_text_id", Category::UiGameList}; Setting row_2_text_id{linkage, 2, "row_2_text_id", Category::UiGameList}; diff --git a/src/qt_common/game_list/game_list_p.h b/src/qt_common/game_list/game_list_p.h index a5297d0db3..d3d46771aa 100644 --- a/src/qt_common/game_list/game_list_p.h +++ b/src/qt_common/game_list/game_list_p.h @@ -165,6 +165,7 @@ public: return QStringLiteral("%1\n %2").arg(row1, row2); } case Settings::GameListMode::GridView: + case Settings::GameListMode::CarouselView: return row1; default: break; diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 1e8030947c..f806ebf515 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -240,7 +240,9 @@ add_executable(yuzu render/performance_overlay.h render/performance_overlay.cpp render/performance_overlay.ui updater/update_dialog.h updater/update_dialog.cpp updater/update_dialog.ui - game/common.h) + game/common.h + game/carousel.h game/carousel.cpp +) set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden") diff --git a/src/yuzu/game/carousel.cpp b/src/yuzu/game/carousel.cpp new file mode 100644 index 0000000000..ac9c9947b5 --- /dev/null +++ b/src/yuzu/game/carousel.cpp @@ -0,0 +1,107 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "qt_common/config/uisettings.h" +#include "qt_common/game_list/model.h" +#include "yuzu/game/common.h" +#include "yuzu/game/game_card.h" +#include "yuzu/game/carousel.h" + +GameCarousel::GameCarousel(QWidget* parent) : QListView{parent} { + m_gameCard = new GameCard(this); + setItemDelegate(m_gameCard); + + setViewMode(QListView::IconMode); + setMovement(QListView::Static); + setUniformItemSizes(true); + setSelectionMode(QAbstractItemView::SingleSelection); + + setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); + + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + setEditTriggers(QAbstractItemView::NoEditTriggers); + setContextMenuPolicy(Qt::CustomContextMenu); + + setSpacing(10); + setWordWrap(true); + setTextElideMode(Qt::ElideRight); + setFlow(QListView::LeftToRight); + setWrapping(false); +} + +void GameCarousel::SetModel(GameListModel* model) { + QListView::setModel(model); + UpdateIconSize(); +} + +void GameCarousel::ApplyFilter(const QString& edit_filter_text, GameListModel* model) { + int row_count = model->rowCount(); + + for (int i = 0; i < row_count; ++i) { + QStandardItem* item = model->item(i, 0); + if (!item) + continue; + + if (Yuzu::FilterMatches(edit_filter_text, item)) { + setRowHidden(i, false); + } else { + setRowHidden(i, true); + } + } +} + +void GameCarousel::UpdateIconSize() { + const u32 icon_size = UISettings::values.game_icon_size.GetValue(); + + int heightMargin = 0; + int widthMargin = 80; + + // TODO(crueter): get rid of this nonsense + if (UISettings::values.show_game_name) { + switch (icon_size) { + case 128: + heightMargin = 65; + break; + case 0: + widthMargin = 120; + heightMargin = 120; + break; + case 64: + heightMargin = 77; + break; + case 32: + case 256: + heightMargin = 81; + break; + } + } else { + widthMargin = 24; + heightMargin = 24; + } + + const int min_item_width = icon_size + widthMargin; + const int min_item_height = icon_size + heightMargin; + const int grid_height = std::max(min_item_height, viewport()->height()); + + QSize content_size(min_item_width, min_item_height); + QSize grid_size(min_item_width, grid_height); + if (gridSize() != grid_size) { + setUpdatesEnabled(false); + + setGridSize(grid_size); + m_gameCard->setSize(grid_size, content_size, 0, 0); + + setUpdatesEnabled(true); + } +} + +QModelIndex GameCarousel::indexAt(const QPoint& point) const { + QModelIndex index = QListView::indexAt(point); + if (!index.isValid()) + return {}; + if (m_gameCard && !m_gameCard->hitTest(point, index, this, visualRect(index))) + return {}; + return index; +} diff --git a/src/yuzu/game/carousel.h b/src/yuzu/game/carousel.h new file mode 100644 index 0000000000..c03884c8c2 --- /dev/null +++ b/src/yuzu/game/carousel.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include + +class GameCard; +class GameListModel; +class QResizeEvent; + +class GameCarousel : public QListView { + Q_OBJECT + +public: + explicit GameCarousel(QWidget* parent = nullptr); + + void SetModel(GameListModel* model); + void ApplyFilter(const QString& edit_filter_text, GameListModel* model); + void UpdateIconSize(); + + QModelIndex indexAt(const QPoint& point) const override; + +private: + GameCard* m_gameCard = nullptr; +}; diff --git a/src/yuzu/game/game_card.cpp b/src/yuzu/game/game_card.cpp index e1cd92652e..12ad482c88 100644 --- a/src/yuzu/game/game_card.cpp +++ b/src/yuzu/game/game_card.cpp @@ -18,27 +18,16 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option, painter->save(); painter->setRenderHint(QPainter::Antialiasing); - constexpr int cardMargin = 8; constexpr int cardCornerRadius = 10; - const int column = index.row() % m_columns; - const int cell_width = option.rect.width(); - const int card_width = cell_width - m_padding; - - const int row_width = m_columns * cell_width; - const int total_gap = row_width - cardMargin * 2 - m_columns * card_width; - const int gap = (m_columns > 1) ? (total_gap / (m_columns - 1)) : 0; - - const int card_left = option.rect.left() - column * cell_width + cardMargin + column * (card_width + gap) + 4; - const QRect cardRect(card_left, option.rect.top() + 4, card_width - 8, - option.rect.height() - cardMargin); + const QRect cardRect = getCardRect(option, index); QPalette palette = option.palette; QColor backgroundColor = palette.window().color(); QColor borderColor = palette.dark().color(); QColor textColor = palette.text().color(); - // highlight blue on select + // highlight on select or hover if (option.state & QStyle::State_Selected) { backgroundColor = palette.highlight().color(); borderColor = palette.highlight().color().lighter(150); @@ -60,7 +49,7 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option, scaled.scale(icon_size, icon_size, Qt::KeepAspectRatio); iconRect = {cardRect.left() + (cardRect.width() - scaled.width()) / 2, - cardRect.top() + cardMargin, scaled.width(), scaled.height()}; + cardRect.top() + cardMargin - 1, scaled.width(), scaled.height()}; painter->setRenderHint(QPainter::SmoothPixmapTransform, true); @@ -94,12 +83,62 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option, painter->restore(); } +QRect GameCard::getCardRect(const QStyleOptionViewItem& option, const QModelIndex& index) const { + const int cell_width = option.rect.width(); + + const int card_width = cell_width - m_padding; + + int card_left, card_top, card_height; + + if (m_columns >= 1) { + // grid mode + + // center everything in-line, such that the leftmost and rightmost cards + // have ~ equal padding to the edge of the viewport + // spacing between each card is larger, but equal to each other + const int column = index.row() % m_columns; + + const int row_width = m_columns * cell_width; + const int total_gap = row_width - cardMargin * 2 - m_columns * card_width; + const int gap = (m_columns > 1) ? (total_gap / (m_columns - 1)) : 0; + card_left = + option.rect.left() - column * cell_width + cardMargin + column * (card_width + gap) + 4; + + // fill cell vertically + card_top = option.rect.top() + cardMargin; + card_height = option.rect.height() - cardMargin - 1; + } else { + // carousel mode + card_left = option.rect.left() + cardMargin + 4; + + // the delegate itself takes up the full height, but the card itself + // gets centered + const int content_height = m_contentSize.height() - cardMargin; + const int cell_height = option.rect.height(); + + card_height = std::min(content_height, cell_height - cardMargin * 2) - 1; + card_top = option.rect.top() + (cell_height - card_height) / 2; + } + + return QRect(card_left, card_top, card_width - cardMargin, card_height); +} + +bool GameCard::hitTest(const QPoint& point, const QModelIndex& index, const QWidget* widget, + const QRect& cellRect) const { + QStyleOptionViewItem option; + option.initFrom(widget); + option.rect = cellRect; + return getCardRect(option, index).contains(point); +} + QSize GameCard::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { return m_size; } -void GameCard::setSize(const QSize& newSize, const int padding, const int columns) { +void GameCard::setSize(const QSize& newSize, const QSize& contentSize, const int padding, + const int columns) { m_size = newSize; + m_contentSize = contentSize; m_padding = padding; m_columns = columns; } diff --git a/src/yuzu/game/game_card.h b/src/yuzu/game/game_card.h index f2a3edfddf..1d522c0ed8 100644 --- a/src/yuzu/game/game_card.h +++ b/src/yuzu/game/game_card.h @@ -17,11 +17,19 @@ public: void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; + QRect getCardRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; + + bool hitTest(const QPoint& point, const QModelIndex& index, + const QWidget* widget, const QRect& cellRect) const; + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; - void setSize(const QSize& newSize, const int padding, const int columns); + void setSize(const QSize& newSize, const QSize& contentSize, const int padding, const int columns); private: + static constexpr int cardMargin = 8; + QSize m_size; + QSize m_contentSize; int m_padding; int m_columns; }; diff --git a/src/yuzu/game/game_grid.cpp b/src/yuzu/game/game_grid.cpp index ab8a3d8bfe..c5f77cf897 100644 --- a/src/yuzu/game/game_grid.cpp +++ b/src/yuzu/game/game_grid.cpp @@ -25,8 +25,6 @@ GameGrid::GameGrid(QWidget* parent) : QListView{parent} { setEditTriggers(QAbstractItemView::NoEditTriggers); setContextMenuPolicy(Qt::CustomContextMenu); - setGridSize(QSize(140, 160)); - m_gameCard->setSize(gridSize(), 0, 4); setSpacing(10); setWordWrap(true); @@ -97,8 +95,17 @@ void GameGrid::UpdateIconSize() { setUpdatesEnabled(false); setGridSize(grid_size); - m_gameCard->setSize(grid_size, stretched_width - min_item_width, columns); + m_gameCard->setSize(grid_size, grid_size, stretched_width - min_item_width, columns); setUpdatesEnabled(true); } } + +QModelIndex GameGrid::indexAt(const QPoint& point) const { + QModelIndex index = QListView::indexAt(point); + if (!index.isValid()) + return {}; + if (m_gameCard && !m_gameCard->hitTest(point, index, this, visualRect(index))) + return {}; + return index; +} diff --git a/src/yuzu/game/game_grid.h b/src/yuzu/game/game_grid.h index b670bfc3cb..3b5d6da1d4 100644 --- a/src/yuzu/game/game_grid.h +++ b/src/yuzu/game/game_grid.h @@ -6,8 +6,6 @@ #include #include -#include "common/common_types.h" - class GameCard; class GameListModel; @@ -21,6 +19,8 @@ public: void ApplyFilter(const QString& edit_filter_text, GameListModel* model); void UpdateIconSize(); + QModelIndex indexAt(const QPoint& point) const override; + private: GameCard* m_gameCard = nullptr; }; diff --git a/src/yuzu/game/game_list.cpp b/src/yuzu/game/game_list.cpp index a1304b4343..86fd3c1b4f 100644 --- a/src/yuzu/game/game_list.cpp +++ b/src/yuzu/game/game_list.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "common/common_types.h" #include "core/core.h" @@ -31,6 +32,7 @@ #include "qt_common/qt_common.h" #include "qt_common/util/game.h" #include "yuzu/compatibility_list.h" +#include "yuzu/game/carousel.h" #include "yuzu/game/game_grid.h" #include "yuzu/game/game_list.h" #include "yuzu/game/game_tree.h" @@ -67,6 +69,9 @@ GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvid connect(grid_view, &QListView::activated, this, &GameList::ValidateEntry); connect(grid_view, &QListView::customContextMenuRequested, this, &GameList::PopupContextMenu); + connect(carousel_view, &QListView::activated, this, &GameList::ValidateEntry); + connect(carousel_view, &QListView::customContextMenuRequested, this, &GameList::PopupContextMenu); + connect(controller_navigation, &ControllerNavigation::TriggerKeyboardEvent, this, [this](Qt::Key key) { if (system.IsPoweredOn()) { @@ -86,6 +91,7 @@ GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvid connect(item_model, &GameListModel::SaveConfig, this, &GameList::SaveConfig); connect(item_model, &GameListModel::PopulatingStarted, this, &GameList::OnPopulate); + // TODO: impl on grid/carousel connect(tree_view, &GameTree::FilterResultReady, search_field, [this](int visible, int total) { search_field->setFilterResult(visible, total); }); @@ -101,12 +107,11 @@ GameList::~GameList() { void GameList::SetupViews() { tree_view = new GameTree(this); grid_view = new GameGrid(this); + carousel_view = new GameCarousel(this); tree_view->SetModel(item_model); grid_view->SetModel(item_model); - - layout->addWidget(tree_view); - layout->addWidget(grid_view); + carousel_view->SetModel(item_model); } QString GameList::GetLastFilterResultItem() const { @@ -138,10 +143,16 @@ void GameList::LoadCompatibilityList() { void GameList::OnPopulate() { m_currentView->setEnabled(false); - if (m_isTreeMode) { - grid_view->UpdateIconSize(); - } else { + switch (game_list_mode) { + case Settings::GameListMode::TreeView: tree_view->UpdateColumnVisibility(item_model); + break; + case Settings::GameListMode::GridView: + grid_view->UpdateIconSize(); + break; + case Settings::GameListMode::CarouselView: + carousel_view->UpdateIconSize(); + break; } } @@ -166,26 +177,46 @@ void GameList::UnloadController() { } void GameList::ResetViewMode() { - auto& setting = UISettings::values.game_list_mode; + const auto mode = UISettings::values.game_list_mode.GetValue(); + game_list_mode = mode; + + if (m_currentView) + layout->removeWidget(m_currentView); + bool newTreeMode = false; - switch (setting.GetValue()) { + switch (mode) { case Settings::GameListMode::TreeView: m_currentView = tree_view; newTreeMode = true; - tree_view->setVisible(true); - grid_view->setVisible(false); + break; case Settings::GameListMode::GridView: m_currentView = grid_view; newTreeMode = false; - grid_view->setVisible(true); - tree_view->setVisible(false); + + break; + case Settings::GameListMode::CarouselView: + m_currentView = carousel_view; + newTreeMode = false; + break; default: UNREACHABLE(); } + tree_view->setVisible(false); + grid_view->setVisible(false); + carousel_view->setVisible(false); + + tree_view->setEnabled(false); + grid_view->setEnabled(false); + carousel_view->setEnabled(false); + + m_currentView->setVisible(true); + m_currentView->setEnabled(true); + layout->insertWidget(0, m_currentView); + auto view = m_currentView->viewport(); view->installEventFilter(this); @@ -297,11 +328,13 @@ void GameList::OnPopulatingCompleted(const QStringList& watch_list) { for (int i = 1; i < item_model->rowCount() - 1; ++i) { children_total += item_model->item(i, 0)->rowCount(); } + search_field->setFilterResult(children_total, children_total); if (children_total > 0) { search_field->setFocus(); } + // TODO: carousel/grid impl. item_model->sort(tree_view->header()->sortIndicatorSection(), tree_view->header()->sortIndicatorOrder()); @@ -317,8 +350,15 @@ void GameList::RefreshExternalContent() { } void GameList::UpdateIconSizes() { - if (!m_isTreeMode) { + switch (game_list_mode) { + case Settings::GameListMode::GridView: grid_view->UpdateIconSize(); + break; + case Settings::GameListMode::CarouselView: + carousel_view->UpdateIconSize(); + break; + case Settings::GameListMode::TreeView: + break; } } @@ -712,6 +752,11 @@ bool GameList::eventFilter(QObject* obj, QEvent* event) { return true; } + if (obj == carousel_view->viewport() && event->type() == QEvent::Resize) { + carousel_view->UpdateIconSize(); + return true; + } + return QWidget::eventFilter(obj, event); } diff --git a/src/yuzu/game/game_list.h b/src/yuzu/game/game_list.h index 4c4c5150fe..027e58df3a 100644 --- a/src/yuzu/game/game_list.h +++ b/src/yuzu/game/game_list.h @@ -15,12 +15,12 @@ #include #include #include -#include #include "common/common_types.h" #include "core/core.h" #include "frontend_common/play_time_manager.h" #include "qt_common/config/uisettings.h" +#include "qt_common/game_list/model.h" #include "qt_common/util/game.h" #include "yuzu/compatibility_list.h" @@ -38,6 +38,9 @@ class MainWindow; enum class AmLaunchType; enum class StartGameType; +class GameCarousel; + +class QAbstractItemView; namespace Core { class System; } @@ -151,7 +154,9 @@ private: GameTree* tree_view = nullptr; GameGrid* grid_view = nullptr; + GameCarousel* carousel_view = nullptr; GameListModel* item_model = nullptr; + Settings::GameListMode game_list_mode; ControllerNavigation* controller_navigation = nullptr; diff --git a/src/yuzu/game/game_tree.h b/src/yuzu/game/game_tree.h index b5eebdb9dd..e4417803aa 100644 --- a/src/yuzu/game/game_tree.h +++ b/src/yuzu/game/game_tree.h @@ -3,8 +3,6 @@ #pragma once -#include -#include #include class GameListModel; diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index 59aab0ef93..deb7774d25 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui @@ -45,7 +45,7 @@ 0 0 1280 - 22 + 23 @@ -111,6 +111,7 @@ + @@ -620,6 +621,14 @@ Show &Performance Overlay + + + true + + + &Carousel View + + diff --git a/src/yuzu/main_window.cpp b/src/yuzu/main_window.cpp index 00b9e65c67..bc74f5da79 100644 --- a/src/yuzu/main_window.cpp +++ b/src/yuzu/main_window.cpp @@ -1529,6 +1529,7 @@ void MainWindow::ConnectMenuEvents() { connect_menu(ui->action_Grid_View, &MainWindow::SetGridView); connect_menu(ui->action_Tree_View, &MainWindow::SetTreeView); + connect_menu(ui->action_Carousel_View, &MainWindow::SetCarouselView); game_size_actions = new QActionGroup(this); game_size_actions->setExclusive(true); @@ -3317,9 +3318,10 @@ void MainWindow::ResetWindowSize1080() { void MainWindow::SetGameListMode(Settings::GameListMode mode) { ui->action_Grid_View->setChecked(mode == Settings::GameListMode::GridView); ui->action_Tree_View->setChecked(mode == Settings::GameListMode::TreeView); + ui->action_Carousel_View->setChecked(mode == Settings::GameListMode::CarouselView); UISettings::values.game_list_mode = mode; - ui->action_Show_Game_Name->setEnabled(mode == Settings::GameListMode::GridView); + ui->action_Show_Game_Name->setEnabled(mode != Settings::GameListMode::TreeView); CheckIconSize(); game_list->ResetViewMode(); @@ -3333,11 +3335,15 @@ void MainWindow::SetTreeView() { SetGameListMode(Settings::GameListMode::TreeView); } +void MainWindow::SetCarouselView() { + SetGameListMode(Settings::GameListMode::CarouselView); +} + void MainWindow::CheckIconSize() { - // When in grid view mode, with text off - // there is no point in having icons turned off.. + // When in grid/carousel view mode, with text off + // there is no point in having icons turned off auto actions = game_size_actions->actions(); - if (UISettings::values.game_list_mode.GetValue() == Settings::GameListMode::GridView && + if (UISettings::values.game_list_mode.GetValue() != Settings::GameListMode::TreeView && !UISettings::values.show_game_name.GetValue()) { u32 newSize = UISettings::values.game_icon_size.GetValue(); if (newSize == 0) { diff --git a/src/yuzu/main_window.h b/src/yuzu/main_window.h index 65da01e9ca..40253aa52f 100644 --- a/src/yuzu/main_window.h +++ b/src/yuzu/main_window.h @@ -410,6 +410,7 @@ private slots: void SetGameListMode(Settings::GameListMode mode); void SetGridView(); void SetTreeView(); + void SetCarouselView(); void CheckIconSize(); void ToggleShowGameName();