Calculate icon size dynamically based on resolution, aspect ratio and DPI scaling

Co-authored-by: jonaski <10343810+jonaski@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-12-28 00:08:01 +00:00
parent eaced733bb
commit 350d907e8b
3 changed files with 60 additions and 14 deletions

View File

@@ -22,6 +22,7 @@
#include "config.h"
#include <utility>
#include <algorithm>
#include <QWidget>
#include <QVariant>
@@ -33,12 +34,12 @@
#include <QAction>
#include <QActionGroup>
#include <QToolButton>
#include <QSettings>
#include <QScreen>
#include <QGuiApplication>
#include "core/iconloader.h"
#include "core/settings.h"
#include "core/settingsprovider.h"
#include "constants/appearancesettings.h"
#include "utilities/screenutils.h"
#include "playlistsequence.h"
#include "ui_playlistsequence.h"
@@ -46,7 +47,14 @@ using namespace Qt::Literals::StringLiterals;
namespace {
constexpr char kSettingsGroup[] = "PlaylistSequence";
}
// Base icon size for reference resolution (1920x1080 at 1.0 scale)
constexpr int kBaseIconSize = 20;
constexpr int kReferenceWidth = 1920;
constexpr int kReferenceHeight = 1080;
constexpr qreal kReferenceDevicePixelRatio = 1.0;
} // namespace
PlaylistSequence::PlaylistSequence(QWidget *parent, SettingsProvider *settings)
: QWidget(parent),
@@ -63,12 +71,9 @@ PlaylistSequence::PlaylistSequence(QWidget *parent, SettingsProvider *settings)
// Icons
ui_->repeat->setIcon(AddDesaturatedIcon(IconLoader::Load(u"media-playlist-repeat"_s)));
ui_->shuffle->setIcon(AddDesaturatedIcon(IconLoader::Load(u"media-playlist-shuffle"_s)));
// Read icon size from settings
Settings s;
s.beginGroup(AppearanceSettings::kSettingsGroup);
const int icon_size = s.value(AppearanceSettings::kIconSizePlaylistButtons, 20).toInt();
s.endGroup();
// Calculate icon size dynamically based on screen resolution, aspect ratio, and scaling
const int icon_size = CalculateIconSize();
ui_->repeat->setIconSize(QSize(icon_size, icon_size));
ui_->shuffle->setIconSize(QSize(icon_size, icon_size));
@@ -107,6 +112,46 @@ PlaylistSequence::~PlaylistSequence() {
delete ui_;
}
int PlaylistSequence::CalculateIconSize() const {
// Get screen information for the widget
QScreen *screen = Utilities::GetScreen(const_cast<PlaylistSequence*>(this));
if (!screen) {
screen = QGuiApplication::primaryScreen();
}
if (!screen) {
// Fallback to a reasonable default if no screen is available
return kBaseIconSize;
}
// Get screen properties
const QSize screen_size = screen->size();
const qreal device_pixel_ratio = screen->devicePixelRatio();
const int screen_width = screen_size.width();
const int screen_height = screen_size.height();
// Calculate scaling factors based on resolution
// Use the smaller dimension to handle both landscape and portrait orientations
const int min_dimension = std::min(screen_width, screen_height);
const int ref_min_dimension = std::min(kReferenceWidth, kReferenceHeight);
const qreal resolution_factor = static_cast<qreal>(min_dimension) / static_cast<qreal>(ref_min_dimension);
// Apply device pixel ratio (for high-DPI displays)
const qreal dpi_factor = device_pixel_ratio / kReferenceDevicePixelRatio;
// Calculate final icon size with combined scaling
// Use a balanced approach: resolution contributes 50%, DPI contributes 50%
const qreal combined_factor = (resolution_factor * 0.5) + (dpi_factor * 0.5) + 0.5;
int calculated_size = static_cast<int>(kBaseIconSize * combined_factor);
// Clamp to reasonable bounds (minimum 16px, maximum 48px)
calculated_size = std::max(16, std::min(48, calculated_size));
return calculated_size;
}
void PlaylistSequence::Load() {
loading_ = true; // Stops these setter functions calling Save()

View File

@@ -83,6 +83,7 @@ class PlaylistSequence : public QWidget {
private:
void Load();
void Save();
int CalculateIconSize() const;
static QIcon AddDesaturatedIcon(const QIcon &icon);
static QPixmap DesaturatedPixmap(const QPixmap &pixmap);

View File

@@ -40,8 +40,8 @@
</property>
<property name="iconSize">
<size>
<width>20</width>
<height>20</height>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="checkable">
@@ -59,8 +59,8 @@
</property>
<property name="iconSize">
<size>
<width>20</width>
<height>20</height>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="checkable">