From 4612305bd65e1948d9c676cee2b9e58c1a7eba21 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Wed, 15 Mar 2023 08:41:27 +0200 Subject: [PATCH] more work on game_list --- shadPS4/gui/game_list_frame.cpp | 310 +++++++++++++++++--------------- shadPS4/gui/game_list_frame.h | 2 + 2 files changed, 167 insertions(+), 145 deletions(-) diff --git a/shadPS4/gui/game_list_frame.cpp b/shadPS4/gui/game_list_frame.cpp index 1344fb44..d5c5d25e 100644 --- a/shadPS4/gui/game_list_frame.cpp +++ b/shadPS4/gui/game_list_frame.cpp @@ -76,29 +76,29 @@ game_list_frame::game_list_frame(std::shared_ptr gui_settings, QWi m_columnActs[col]->setCheckable(true); connect(m_columnActs[col], &QAction::triggered, this, [this, col](bool checked) + { + if (!checked) // be sure to have at least one column left so you can call the context menu at all time { - if (!checked) // be sure to have at least one column left so you can call the context menu at all time + int c = 0; + for (int i = 0; i < m_columnActs.count(); ++i) { - int c = 0; - for (int i = 0; i < m_columnActs.count(); ++i) - { - if (m_gui_settings->GetGamelistColVisibility(i) && ++c > 1) - break; - } - if (c < 2) - { - m_columnActs[col]->setChecked(true); // re-enable the checkbox if we don't change the actual state - return; - } + if (m_gui_settings->GetGamelistColVisibility(i) && ++c > 1) + break; } - m_game_list->setColumnHidden(col, !checked); // Negate because it's a set col hidden and we have menu say show. - m_gui_settings->SetGamelistColVisibility(col, checked); + if (c < 2) + { + m_columnActs[col]->setChecked(true); // re-enable the checkbox if we don't change the actual state + return; + } + } + m_game_list->setColumnHidden(col, !checked); // Negate because it's a set col hidden and we have menu say show. + m_gui_settings->SetGamelistColVisibility(col, checked); - if (checked) // handle hidden columns that have zero width after showing them (stuck between others) - { - FixNarrowColumns(); - } - }); + if (checked) // handle hidden columns that have zero width after showing them (stuck between others) + { + FixNarrowColumns(); + } + }); } //events @@ -119,139 +119,27 @@ game_list_frame::game_list_frame(std::shared_ptr gui_settings, QWi }); connect(&m_repaint_watcher, &QFutureWatcher::finished, this, &game_list_frame::OnRepaintFinished); + connect(&m_refresh_watcher, &QFutureWatcher::finished, this, &game_list_frame::OnRefreshFinished); + connect(&m_refresh_watcher, &QFutureWatcher::canceled, this, [this]() + { + gui::utils::stop_future_watcher(m_repaint_watcher, true); + + m_path_list.clear(); + m_game_data.clear(); + m_games.clear(); + }); + Refresh();//TODO remove when watchers added } game_list_frame::~game_list_frame() { gui::utils::stop_future_watcher(m_repaint_watcher, true); + gui::utils::stop_future_watcher(m_refresh_watcher, true); SaveSettings(); } -void game_list_frame::FixNarrowColumns() const + +void game_list_frame::OnRefreshFinished() { - qApp->processEvents(); - // handle columns (other than the icon column) that have zero width after showing them (stuck between others) - for (int col = 1; col < m_columnActs.count(); ++col) - { - if (m_game_list->isColumnHidden(col)) - { - continue; - } - - if (m_game_list->columnWidth(col) <= m_game_list->horizontalHeader()->minimumSectionSize()) - { - m_game_list->setColumnWidth(col, m_game_list->horizontalHeader()->minimumSectionSize()); - } - } -} - -void game_list_frame::ResizeColumnsToContents(int spacing) const -{ - if (!m_game_list) - { - return; - } - - m_game_list->verticalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents); - m_game_list->horizontalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents); - - // Make non-icon columns slighty bigger for better visuals - for (int i = 1; i < m_game_list->columnCount(); i++) - { - if (m_game_list->isColumnHidden(i)) - { - continue; - } - - const int size = m_game_list->horizontalHeader()->sectionSize(i) + spacing; - m_game_list->horizontalHeader()->resizeSection(i, size); - } -} - -void game_list_frame::SortGameList() const -{ - // Back-up old header sizes to handle unwanted column resize in case of zero search results - QList column_widths; - const int old_row_count = m_game_list->rowCount(); - const int old_game_count = m_game_data.count(); - - for (int i = 0; i < m_game_list->columnCount(); i++) - { - column_widths.append(m_game_list->columnWidth(i)); - } - - // Sorting resizes hidden columns, so unhide them as a workaround - QList columns_to_hide; - - for (int i = 0; i < m_game_list->columnCount(); i++) - { - if (m_game_list->isColumnHidden(i)) - { - m_game_list->setColumnHidden(i, false); - columns_to_hide << i; - } - } - - // Sort the list by column and sort order - m_game_list->sortByColumn(m_sort_column, m_col_sort_order); - - // Hide columns again - for (auto i : columns_to_hide) - { - m_game_list->setColumnHidden(i, true); - } - - // Don't resize the columns if no game is shown to preserve the header settings - if (!m_game_list->rowCount()) - { - for (int i = 0; i < m_game_list->columnCount(); i++) - { - m_game_list->setColumnWidth(i, column_widths[i]); - } - - m_game_list->horizontalHeader()->setSectionResizeMode(gui::column_icon, QHeaderView::Fixed); - return; - } - - // Fixate vertical header and row height - m_game_list->verticalHeader()->setMinimumSectionSize(m_icon_size.height()); - m_game_list->verticalHeader()->setMaximumSectionSize(m_icon_size.height()); - m_game_list->resizeRowsToContents(); - - // Resize columns if the game list was empty before - if (!old_row_count && !old_game_count) - { - ResizeColumnsToContents(); - } - else - { - m_game_list->resizeColumnToContents(gui::column_icon); - } - - // Fixate icon column - m_game_list->horizontalHeader()->setSectionResizeMode(gui::column_icon, QHeaderView::Fixed); - - // Shorten the last section to remove horizontal scrollbar if possible - m_game_list->resizeColumnToContents(gui::column_count - 1); -} - -void game_list_frame::OnHeaderColumnClicked(int col) -{ - if (col == 0) return; // Don't "sort" icons. - - if (col == m_sort_column) - { - m_col_sort_order = (m_col_sort_order == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder; - } - else - { - m_col_sort_order = Qt::AscendingOrder; - } - m_sort_column = col; - - m_gui_settings->SetValue(gui::game_list_sortAsc, m_col_sort_order == Qt::AscendingOrder); - m_gui_settings->SetValue(gui::game_list_sortCol, col); - - SortGameList(); } void game_list_frame::LoadSettings() @@ -314,6 +202,9 @@ void game_list_frame::SaveSettings() } void game_list_frame::Refresh(const bool from_drive, const bool scroll_after) { + gui::utils::stop_future_watcher(m_repaint_watcher, true); + gui::utils::stop_future_watcher(m_refresh_watcher, from_drive); + if (from_drive) { m_path_list.clear(); @@ -527,6 +418,135 @@ void game_list_frame::RepaintIcons(const bool& from_settings) m_repaint_watcher.setFuture(QtConcurrent::mapped(m_game_data, func)); } +void game_list_frame::FixNarrowColumns() const +{ + qApp->processEvents(); + + // handle columns (other than the icon column) that have zero width after showing them (stuck between others) + for (int col = 1; col < m_columnActs.count(); ++col) + { + if (m_game_list->isColumnHidden(col)) + { + continue; + } + + if (m_game_list->columnWidth(col) <= m_game_list->horizontalHeader()->minimumSectionSize()) + { + m_game_list->setColumnWidth(col, m_game_list->horizontalHeader()->minimumSectionSize()); + } + } +} + +void game_list_frame::ResizeColumnsToContents(int spacing) const +{ + if (!m_game_list) + { + return; + } + + m_game_list->verticalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents); + m_game_list->horizontalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents); + + // Make non-icon columns slighty bigger for better visuals + for (int i = 1; i < m_game_list->columnCount(); i++) + { + if (m_game_list->isColumnHidden(i)) + { + continue; + } + + const int size = m_game_list->horizontalHeader()->sectionSize(i) + spacing; + m_game_list->horizontalHeader()->resizeSection(i, size); + } +} + +void game_list_frame::OnHeaderColumnClicked(int col) +{ + if (col == 0) return; // Don't "sort" icons. + + if (col == m_sort_column) + { + m_col_sort_order = (m_col_sort_order == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder; + } + else + { + m_col_sort_order = Qt::AscendingOrder; + } + m_sort_column = col; + + m_gui_settings->SetValue(gui::game_list_sortAsc, m_col_sort_order == Qt::AscendingOrder); + m_gui_settings->SetValue(gui::game_list_sortCol, col); + + SortGameList(); +} + +void game_list_frame::SortGameList() const +{ + // Back-up old header sizes to handle unwanted column resize in case of zero search results + QList column_widths; + const int old_row_count = m_game_list->rowCount(); + const int old_game_count = m_game_data.count(); + + for (int i = 0; i < m_game_list->columnCount(); i++) + { + column_widths.append(m_game_list->columnWidth(i)); + } + + // Sorting resizes hidden columns, so unhide them as a workaround + QList columns_to_hide; + + for (int i = 0; i < m_game_list->columnCount(); i++) + { + if (m_game_list->isColumnHidden(i)) + { + m_game_list->setColumnHidden(i, false); + columns_to_hide << i; + } + } + + // Sort the list by column and sort order + m_game_list->sortByColumn(m_sort_column, m_col_sort_order); + + // Hide columns again + for (auto i : columns_to_hide) + { + m_game_list->setColumnHidden(i, true); + } + + // Don't resize the columns if no game is shown to preserve the header settings + if (!m_game_list->rowCount()) + { + for (int i = 0; i < m_game_list->columnCount(); i++) + { + m_game_list->setColumnWidth(i, column_widths[i]); + } + + m_game_list->horizontalHeader()->setSectionResizeMode(gui::column_icon, QHeaderView::Fixed); + return; + } + + // Fixate vertical header and row height + m_game_list->verticalHeader()->setMinimumSectionSize(m_icon_size.height()); + m_game_list->verticalHeader()->setMaximumSectionSize(m_icon_size.height()); + m_game_list->resizeRowsToContents(); + + // Resize columns if the game list was empty before + if (!old_row_count && !old_game_count) + { + ResizeColumnsToContents(); + } + else + { + m_game_list->resizeColumnToContents(gui::column_icon); + } + + // Fixate icon column + m_game_list->horizontalHeader()->setSectionResizeMode(gui::column_icon, QHeaderView::Fixed); + + // Shorten the last section to remove horizontal scrollbar if possible + m_game_list->resizeColumnToContents(gui::column_count - 1); +} + QPixmap game_list_frame::PaintedPixmap(const QPixmap& icon) const { const qreal device_pixel_ratio = devicePixelRatioF(); @@ -583,4 +603,4 @@ QPixmap game_list_frame::PaintedPixmap(const QPixmap& icon) const // Scale and return our final image return canvas.scaled(m_icon_size * device_pixel_ratio, Qt::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation); -} \ No newline at end of file +} diff --git a/shadPS4/gui/game_list_frame.h b/shadPS4/gui/game_list_frame.h index e5b399b8..75e4a17a 100644 --- a/shadPS4/gui/game_list_frame.h +++ b/shadPS4/gui/game_list_frame.h @@ -39,6 +39,7 @@ public : private Q_SLOTS: void OnHeaderColumnClicked(int col); void OnRepaintFinished(); + void OnRefreshFinished(); private: QPixmap PaintedPixmap(const QPixmap& icon) const; void SortGameList() const; @@ -64,6 +65,7 @@ private: std::vector m_path_list; std::deque m_games; QFutureWatcher m_repaint_watcher; + QFutureWatcher m_refresh_watcher; // Icons QSize m_icon_size;