From 7d53849cd39d14090b4d57f7df10bcbf446325e7 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 7 Apr 2026 00:02:59 +0200 Subject: [PATCH 1/3] [desktop] "Fix" card auto-alignment (#3829) Closes #3707 All this does is anchor the left and right-most cards to their respective edges, and then equally distributes the gaps between cards thereafter. Don't even bother trying to figure out what the hell I just wrote. I'm a UI designer, not a mathematician. Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3829 --- src/yuzu/game/game_card.cpp | 34 +++++++++++++++++++++++++--------- src/yuzu/game/game_card.h | 3 ++- src/yuzu/game/game_list.cpp | 8 ++++---- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/yuzu/game/game_card.cpp b/src/yuzu/game/game_card.cpp index ba60b54fcc..b1ea762f8c 100644 --- a/src/yuzu/game/game_card.cpp +++ b/src/yuzu/game/game_card.cpp @@ -18,8 +18,25 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option, painter->save(); painter->setRenderHint(QPainter::Antialiasing); - // padding - QRect cardRect = option.rect.adjusted(4 + m_padding / 2, 4, -4 - m_padding / 2, -4); + // Padding, dimensions, alignment... + const int column = index.row() % m_columns; + const int cell_width = option.rect.width(); + const int fixed_card_width = cell_width - m_padding; + const int margins = 8; + + // The gist of it is that this anchors the left and right sides to the edges, + // while maintaining an even gap between each card. + // I just smashed random keys into my keyboard until something worked. + // Don't even bother trying to figure out what the hell this is doing. + const auto total_row_width = m_columns * cell_width; + const auto total_gap_space = total_row_width - (margins * 2) - (m_columns * fixed_card_width); + const auto gap = (m_columns > 1) ? (total_gap_space / (m_columns - 1)) : 0; + + const auto relative_x = margins + (column * (fixed_card_width + gap)); + const auto x_pos = option.rect.left() - (column * cell_width) + static_cast(relative_x); + + // also, add some additional padding here to prevent card overlap + QRect cardRect(x_pos + 4, option.rect.top() + 4, fixed_card_width - 8, option.rect.height() - margins); // colors QPalette palette = option.palette; @@ -41,8 +58,6 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option, painter->setPen(QPen(borderColor, 1)); painter->drawRoundedRect(cardRect, 10, 10); - static constexpr const int padding = 8; - // icon int _iconsize = UISettings::values.game_icon_size.GetValue(); QSize iconSize(_iconsize, _iconsize); @@ -54,7 +69,7 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option, scaledSize.scale(iconSize, Qt::KeepAspectRatio); int x = cardRect.left() + (cardRect.width() - scaledSize.width()) / 2; - int y = cardRect.top() + padding; + int y = cardRect.top() + margins; iconRect = QRect(x, y, scaledSize.width(), scaledSize.height()); @@ -73,7 +88,7 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option, painter->restore(); } else { // if there is no icon just draw a blank rect - iconRect = QRect(cardRect.left() + padding, cardRect.top() + padding, _iconsize, _iconsize); + iconRect = QRect(cardRect.left() + margins, cardRect.top() + margins, _iconsize, _iconsize); } if (UISettings::values.show_game_name.GetValue()) { @@ -82,8 +97,8 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option, // padding + text QRect textRect = cardRect; - textRect.setTop(iconRect.bottom() + 8); - textRect.adjust(padding, 0, -padding, -padding); + textRect.setTop(iconRect.bottom() + margins); + textRect.adjust(margins, 0, -margins, -margins); // We are already crammed on space, ignore the row 2 QString title = index.data(Qt::DisplayRole).toString(); @@ -111,7 +126,8 @@ QSize GameCard::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& return m_size; } -void GameCard::setSize(const QSize& newSize, const int padding) { +void GameCard::setSize(const QSize& newSize, const int padding, const int columns) { m_size = newSize; m_padding = padding; + m_columns = columns; } diff --git a/src/yuzu/game/game_card.h b/src/yuzu/game/game_card.h index 86387452b6..f2a3edfddf 100644 --- a/src/yuzu/game/game_card.h +++ b/src/yuzu/game/game_card.h @@ -18,9 +18,10 @@ public: const QModelIndex& index) const override; QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; - void setSize(const QSize& newSize, const int padding); + void setSize(const QSize& newSize, const int padding, const int columns); private: QSize m_size; int m_padding; + int m_columns; }; diff --git a/src/yuzu/game/game_list.cpp b/src/yuzu/game/game_list.cpp index 0e2b6cf7e6..87b5f87474 100644 --- a/src/yuzu/game/game_list.cpp +++ b/src/yuzu/game/game_list.cpp @@ -411,7 +411,7 @@ GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvid list_view->setEditTriggers(QAbstractItemView::NoEditTriggers); list_view->setContextMenuPolicy(Qt::CustomContextMenu); list_view->setGridSize(QSize(140, 160)); - m_gameCard->setSize(list_view->gridSize(), 0); + m_gameCard->setSize(list_view->gridSize(), 0, 4); list_view->setSpacing(10); list_view->setWordWrap(true); @@ -1051,8 +1051,8 @@ void GameList::UpdateIconSize() { // And now stretch it a bit to fill out remaining space. // Not perfect but works well enough for now - int columns = std::max(1, view_width / min_item_width); - int stretched_width = (view_width - (spacing * (columns - 1))) / columns; + int columns = std::max(1, (view_width - 16) / min_item_width); + int stretched_width = ((view_width) - (spacing * (columns - 1))) / columns; // only updates things if grid size is changed QSize grid_size(stretched_width, icon_size + heightMargin); @@ -1060,7 +1060,7 @@ void GameList::UpdateIconSize() { list_view->setUpdatesEnabled(false); list_view->setGridSize(grid_size); - m_gameCard->setSize(grid_size, stretched_width - min_item_width); + m_gameCard->setSize(grid_size, stretched_width - min_item_width, columns); list_view->setUpdatesEnabled(true); } From 9c13c71da8dcc37d03fc53bc3bc16978a65fd8f2 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 7 Apr 2026 00:03:45 +0200 Subject: [PATCH 2/3] [externals] Require httplib >=0.18.7 (#3830) This is the version in Trixie and is thus far the oldest known version that works. We know for a fact that Bookworm's doesn't work, so drop that entirely. Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3830 --- externals/cpmfile.json | 1 + 1 file changed, 1 insertion(+) diff --git a/externals/cpmfile.json b/externals/cpmfile.json index 03303a5896..b8472774ae 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -30,6 +30,7 @@ "tag": "v%VERSION%", "hash": "5efa8140aadffe105dcf39935b732476e95755f6c7473ada3d0b64df2bc02c557633ae3948a25b45e1cf67e89a3ff6329fb30362e4ac033b9a1d1e453aa2eded", "git_version": "0.37.0", + "version": "0.18.7", "find_args": "MODULE GLOBAL", "patches": [ "0001-mingw.patch", From 50a6f331cf0a11e4d6eac8decfe6965097b99082 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 7 Apr 2026 00:04:16 +0200 Subject: [PATCH 3/3] [desktop] Use pixel-based font sizes instead of point-based for game card (#3827) Archaic systems that still don't utilize point sizes properly should like this. Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3827 --- src/yuzu/game/game_card.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/yuzu/game/game_card.cpp b/src/yuzu/game/game_card.cpp index b1ea762f8c..05167fe455 100644 --- a/src/yuzu/game/game_card.cpp +++ b/src/yuzu/game/game_card.cpp @@ -92,9 +92,6 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option, } if (UISettings::values.show_game_name.GetValue()) { - // if "none" is selected, pretend there's a - _iconsize = _iconsize ? _iconsize : 96; - // padding + text QRect textRect = cardRect; textRect.setTop(iconRect.bottom() + margins); @@ -110,8 +107,7 @@ void GameCard::paint(QPainter* painter, const QStyleOptionViewItem& option, font.setBold(true); // TODO(crueter): fix this abysmal scaling - // If "none" is selected, then default to 8.5 point font. - font.setPointSize(1 + std::max(7.0, _iconsize ? std::sqrt(_iconsize * 0.6) : 7.5)); + font.setPixelSize(1.5 + std::max(10.0, std::sqrt(_iconsize))); // TODO(crueter): elide mode painter->setFont(font);