Add interface scale (100%..150%) for Retina.

Fixes #69, fixes #3126, fixes #3789.
This commit is contained in:
John Preston 2018-10-15 22:42:10 +03:00
parent f2866442d2
commit 5b4abe69aa
19 changed files with 111 additions and 106 deletions

View File

@ -461,14 +461,18 @@ void launch() {
const auto dpi = Application::primaryScreen()->logicalDotsPerInch();
LOG(("Primary screen DPI: %1").arg(dpi));
if (dpi <= 108) { // 0-96-108
cSetScreenScale(100);
} else if (dpi <= 132) { // 108-120-132
cSetScreenScale(125);
} else if (dpi <= 168) { // 132-144-168
cSetScreenScale(150);
} else { // 168-192-inf
cSetScreenScale(200);
if (dpi <= 108) {
cSetScreenScale(100); // 100%: 96 DPI (0-108)
} else if (dpi <= 132) {
cSetScreenScale(125); // 125%: 120 DPI (108-132)
} else if (dpi <= 168) {
cSetScreenScale(150); // 150%: 144 DPI (132-168)
} else if (dpi <= 216) {
cSetScreenScale(200); // 200%: 192 DPI (168-216)
} else if (dpi <= 264) {
cSetScreenScale(250); // 250%: 240 DPI (216-264)
} else {
cSetScreenScale(300); // 300%: 288 DPI (264-inf)
}
auto devicePixelRatio = application()->devicePixelRatio();
@ -480,11 +484,9 @@ void launch() {
LOG(("Environmental variables: QT_AUTO_SCREEN_SCALE_FACTOR='%1'").arg(QString::fromLatin1(qgetenv("QT_AUTO_SCREEN_SCALE_FACTOR"))));
LOG(("Environmental variables: QT_SCREEN_SCALE_FACTORS='%1'").arg(QString::fromLatin1(qgetenv("QT_SCREEN_SCALE_FACTORS"))));
}
cSetRetina(true);
cSetRetinaFactor(devicePixelRatio);
cSetIntRetinaFactor(int32(cRetinaFactor()));
cSetConfigScale(100);
cSetRealScale(100);
cSetScreenScale(kInterfaceScaleDefault);
}
application()->createMessenger();

View File

@ -548,7 +548,7 @@ void Panel::createUserpicCache(ImagePtr image) {
options,
st::callWidth,
st::callWidth);
if (cRetina()) _userPhoto.setDevicePixelRatio(cRetinaFactor());
_userPhoto.setDevicePixelRatio(cRetinaFactor());
} else {
auto filled = QImage(QSize(st::callWidth, st::callWidth) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
filled.setDevicePixelRatio(cRetinaFactor());

View File

@ -1121,8 +1121,6 @@ bool Generator::writePxValuesInit() {
}
source_->stream() << "\
void initPxValues() {\n\
if (cRetina()) return;\n\
\n\
const auto scale = cScale();\n";
for (auto it = pxValues_.cbegin(), e = pxValues_.cend(); it != e; ++it) {
auto value = it.key();

View File

@ -1701,7 +1701,7 @@ void MediaView::initAnimation() {
auto w = _doc->dimensions.width();
auto h = _doc->dimensions.height();
_current = _doc->thumb->pixNoCache(fileOrigin(), w, h, videoThumbOptions(), w / cIntRetinaFactor(), h / cIntRetinaFactor());
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
_current.setDevicePixelRatio(cRetinaFactor());
} else {
_current = _doc->thumb->pixNoCache(fileOrigin(), _doc->thumb->width(), _doc->thumb->height(), videoThumbOptions(), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
}
@ -1717,7 +1717,7 @@ void MediaView::createClipReader() {
int w = _doc->dimensions.width();
int h = _doc->dimensions.height();
_current = _doc->thumb->pixNoCache(fileOrigin(), w, h, videoThumbOptions(), w / cIntRetinaFactor(), h / cIntRetinaFactor());
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
_current.setDevicePixelRatio(cRetinaFactor());
} else {
_current = _doc->thumb->pixNoCache(fileOrigin(), _doc->thumb->width(), _doc->thumb->height(), videoThumbOptions(), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
}
@ -1985,17 +1985,17 @@ void MediaView::paintEvent(QPaintEvent *e) {
if (_full <= 0 && _photo->loaded()) {
int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999);
_current = _photo->full->pixNoCache(fileOrigin(), w, h, Images::Option::Smooth);
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
_current.setDevicePixelRatio(cRetinaFactor());
_full = 1;
} else if (_full < 0 && _photo->medium->loaded()) {
int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999);
_current = _photo->medium->pixNoCache(fileOrigin(), w, h, Images::Option::Smooth | Images::Option::Blurred);
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
_current.setDevicePixelRatio(cRetinaFactor());
_full = 0;
} else if (_current.isNull() && _photo->thumb->loaded()) {
int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999);
_current = _photo->thumb->pixNoCache(fileOrigin(), w, h, Images::Option::Smooth | Images::Option::Blurred);
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
_current.setDevicePixelRatio(cRetinaFactor());
} else if (_current.isNull()) {
_current = _photo->thumb->pix(fileOrigin());
}

View File

@ -108,11 +108,6 @@ Messenger::Messenger(not_null<Core::Launcher*> launcher)
return;
}
if (cRetina()) {
cSetConfigScale(100);
cSetRealScale(100);
}
_translator = std::make_unique<Lang::Translator>();
QCoreApplication::instance()->installTranslator(_translator.get());

View File

@ -536,7 +536,7 @@ void MainWindow::updateIconCounters() {
QImage img(psTrayIcon(dm)), imgsel(psTrayIcon(true));
img.detach();
imgsel.detach();
int32 size = cRetina() ? 44 : 22;
int32 size = 22 * cIntRetinaFactor();
_placeCounter(img, size, counter, bg, (dm && muted) ? st::trayCounterFgMacInvert : st::trayCounterFg);
_placeCounter(imgsel, size, counter, st::trayCounterBgMacInvert, st::trayCounterFgMacInvert);
icon.addPixmap(App::pixmapFromImageInPlace(std::move(img)));

View File

@ -65,7 +65,6 @@ bool gPasswordRecovered = false;
int32 gPasscodeBadTries = 0;
TimeMs gPasscodeLastTry = 0;
bool gRetina = false;
float64 gRetinaFactor = 1.;
int32 gIntRetinaFactor = 1;

View File

@ -95,28 +95,6 @@ DeclareSetting(int, ScreenScale);
DeclareSetting(int, ConfigScale);
DeclareSetting(QString, TimeFormat);
constexpr auto kInterfaceScaleAuto = 0;
inline int cEvalScale(int scale) {
return (scale == kInterfaceScaleAuto) ? cScreenScale() : scale;
}
inline int cScale() {
return cEvalScale(cRealScale());
}
template <typename T>
inline T ConvertScale(T value, int scale) {
return (value < 0.)
? (-ConvertScale(-value, scale))
: T(std::round((float64(value) * scale / 100.) - 0.01));
}
template <typename T>
inline T ConvertScale(T value) {
return ConvertScale(value, cScale());
}
inline void cChangeTimeFormat(const QString &newFormat) {
if (!newFormat.isEmpty()) cSetTimeFormat(newFormat);
}
@ -177,7 +155,6 @@ inline bool passcodeCanTry() {
DeclareSetting(QStringList, SendPaths);
DeclareSetting(QString, StartUrl);
DeclareSetting(bool, Retina);
DeclareSetting(float64, RetinaFactor);
DeclareSetting(int32, IntRetinaFactor);
@ -206,3 +183,36 @@ DeclareSetting(int32, AutoDownloadPhoto);
DeclareSetting(int32, AutoDownloadAudio);
DeclareSetting(int32, AutoDownloadGif);
DeclareSetting(bool, AutoPlayGif);
constexpr auto kInterfaceScaleAuto = 0;
constexpr auto kInterfaceScaleMin = 100;
constexpr auto kInterfaceScaleDefault = 100;
constexpr auto kInterfaceScaleMax = 300;
inline int cEvalScale(int scale) {
return (scale == kInterfaceScaleAuto) ? cScreenScale() : scale;
}
inline int cScale() {
return cEvalScale(cRealScale());
}
template <typename T>
inline T ConvertScale(T value, int scale) {
return (value < 0.)
? (-ConvertScale(-value, scale))
: T(std::round((float64(value) * scale / 100.) - 0.01));
}
template <typename T>
inline T ConvertScale(T value) {
return ConvertScale(value, cScale());
}
inline void SetScaleChecked(int scale) {
const auto checked = (scale == kInterfaceScaleAuto)
? kInterfaceScaleAuto
: snap(scale, kInterfaceScaleMin, kInterfaceScaleMax / cIntRetinaFactor());
cSetConfigScale(checked);
cSetRealScale(checked);
}

View File

@ -98,7 +98,7 @@ void SetupSections(
}
bool HasInterfaceScale() {
return !cRetina();
return true;
}
void SetupInterfaceScale(
@ -125,7 +125,9 @@ void SetupInterfaceScale(
object_ptr<Ui::SettingsSlider>(container, st::settingsSlider),
icon ? st::settingsScalePadding : st::settingsBigScalePadding);
static const auto ScaleValues = { 100, 125, 150, 200, 300 };
static const auto ScaleValues = (cIntRetinaFactor() > 1)
? std::vector<int>{ 100, 110, 120, 130, 140, 150 }
: std::vector<int>{ 100, 125, 150, 200, 250, 300 };
const auto sectionFromScale = [](int scale) {
auto result = 0;
for (const auto value : ScaleValues) {
@ -182,10 +184,22 @@ void SetupInterfaceScale(
if (scale != cScale()) {
scale = cScale();
} else {
scale -= 25;
if (scale < 100) {
scale = 125;
auto selected = 0;
for (const auto possible : ScaleValues) {
if (possible == scale) {
if (selected) {
break;
} else {
selected = -1;
}
} else if (selected == -1) {
selected = possible;
break;
} else {
selected = possible;
}
}
scale = selected;
}
}
(*setScale)(scale);

View File

@ -1370,11 +1370,7 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
stream >> v;
if (!_checkStreamStatus(stream)) return false;
const auto s = [&] {
if (cRetina()) {
return 100;
}
SetScaleChecked([&] {
constexpr auto kAuto = 0;
constexpr auto kOne = 1;
constexpr auto kOneAndQuarter = 2;
@ -1388,9 +1384,7 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
case kTwo: return 200;
}
return cRealScale();
}();
cSetConfigScale(s);
cSetRealScale(s);
}());
} break;
case dbiScalePercent: {
@ -1398,10 +1392,7 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
stream >> v;
if (!_checkStreamStatus(stream)) return false;
if (!v || (v >= 100 && v <= (cRetina() ? 150 : 300) && !(v % 25))) {
cSetConfigScale(v);
cSetRealScale(v);
}
SetScaleChecked(v);
} break;
case dbiLangOld: {

View File

@ -291,8 +291,8 @@ void ClearUniversalChecked() {
void Init() {
internal::Init();
SizeNormal = ConvertScale(18) * cIntRetinaFactor();
SizeLarge = int(ConvertScale(18 * 4 / 3.)) * cIntRetinaFactor();
SizeNormal = ConvertScale(18, cScale() * cIntRetinaFactor());
SizeLarge = int(ConvertScale(18 * 4 / 3., cScale() * cIntRetinaFactor()));
const auto count = internal::FullCount();
const auto persprite = kImagesPerRow * kImageRowsPerSprite;
SpritesCount = (count / persprite) + ((count % persprite) ? 1 : 0);
@ -553,9 +553,7 @@ const QPixmap &SinglePixmap(EmojiPtr emoji, int fontHeight) {
SizeNormal + st::emojiPadding * cIntRetinaFactor() * 2,
fontHeight * cIntRetinaFactor(),
QImage::Format_ARGB32_Premultiplied);
if (cRetina()) {
image.setDevicePixelRatio(cRetinaFactor());
}
image.setDevicePixelRatio(cRetinaFactor());
image.fill(Qt::transparent);
{
QPainter p(&image);
@ -643,9 +641,7 @@ void Instance::generateCache() {
void Instance::pushSprite(QImage &&data) {
_sprites.push_back(App::pixmapFromImageInPlace(std::move(data)));
if (cRetina()) {
_sprites.back().setDevicePixelRatio(cRetinaFactor());
}
_sprites.back().setDevicePixelRatio(cRetinaFactor());
}
} // namespace Emoji

View File

@ -490,7 +490,7 @@ const QPixmap &Image::pix(
if (w <= 0 || !width() || !height()) {
w = width();
} else if (cRetina()) {
} else {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
@ -499,7 +499,7 @@ const QPixmap &Image::pix(
auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
globalAcquiredSize += int64(p.width()) * p.height() * 4;
@ -518,7 +518,7 @@ const QPixmap &Image::pixRounded(
if (w <= 0 || !width() || !height()) {
w = width();
} else if (cRetina()) {
} else {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
@ -540,7 +540,7 @@ const QPixmap &Image::pixRounded(
auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
globalAcquiredSize += int64(p.width()) * p.height() * 4;
@ -557,7 +557,7 @@ const QPixmap &Image::pixCircled(
if (w <= 0 || !width() || !height()) {
w = width();
} else if (cRetina()) {
} else {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
@ -566,7 +566,7 @@ const QPixmap &Image::pixCircled(
auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
globalAcquiredSize += int64(p.width()) * p.height() * 4;
@ -583,7 +583,7 @@ const QPixmap &Image::pixBlurredCircled(
if (w <= 0 || !width() || !height()) {
w = width();
} else if (cRetina()) {
} else {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
@ -592,7 +592,7 @@ const QPixmap &Image::pixBlurredCircled(
auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
globalAcquiredSize += int64(p.width()) * p.height() * 4;
@ -609,7 +609,7 @@ const QPixmap &Image::pixBlurred(
if (w <= 0 || !width() || !height()) {
w = width() * cIntRetinaFactor();
} else if (cRetina()) {
} else {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
@ -618,7 +618,7 @@ const QPixmap &Image::pixBlurred(
auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
globalAcquiredSize += int64(p.width()) * p.height() * 4;
@ -636,7 +636,7 @@ const QPixmap &Image::pixColored(
if (w <= 0 || !width() || !height()) {
w = width() * cIntRetinaFactor();
} else if (cRetina()) {
} else {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
@ -645,7 +645,7 @@ const QPixmap &Image::pixColored(
auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixColoredNoCache(origin, add, w, h, true);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
globalAcquiredSize += int64(p.width()) * p.height() * 4;
@ -663,7 +663,7 @@ const QPixmap &Image::pixBlurredColored(
if (w <= 0 || !width() || !height()) {
w = width() * cIntRetinaFactor();
} else if (cRetina()) {
} else {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
@ -672,7 +672,7 @@ const QPixmap &Image::pixBlurredColored(
auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixBlurredColoredNoCache(origin, add, w, h);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
globalAcquiredSize += int64(p.width()) * p.height() * 4;
@ -694,7 +694,7 @@ const QPixmap &Image::pixSingle(
if (w <= 0 || !width() || !height()) {
w = width() * cIntRetinaFactor();
} else if (cRetina()) {
} else {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
@ -724,7 +724,7 @@ const QPixmap &Image::pixSingle(
globalAcquiredSize -= int64(i->width()) * i->height() * 4;
}
auto p = pixNoCache(origin, w, h, options, outerw, outerh, colored);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
globalAcquiredSize += int64(p.width()) * p.height() * 4;
@ -745,7 +745,7 @@ const QPixmap &Image::pixBlurredSingle(
if (w <= 0 || !width() || !height()) {
w = width() * cIntRetinaFactor();
} else if (cRetina()) {
} else {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
@ -772,7 +772,7 @@ const QPixmap &Image::pixBlurredSingle(
globalAcquiredSize -= int64(i->width()) * i->height() * 4;
}
auto p = pixNoCache(origin, w, h, options, outerw, outerh);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
globalAcquiredSize += int64(p.width()) * p.height() * 4;

View File

@ -47,8 +47,10 @@ void unregisterModule(ModuleBase *module) {
} // namespace internal
void startManager() {
if (cRetina()) {
cSetRealScale(100);
if ((cIntRetinaFactor() * cConfigScale() > kInterfaceScaleMax)
|| (cIntRetinaFactor() * cRealScale() > kInterfaceScaleMax)) {
cSetConfigScale(kInterfaceScaleDefault);
cSetRealScale(kInterfaceScaleDefault);
}
internal::registerFontFamily(qsl("Open Sans"));

View File

@ -30,9 +30,7 @@ QImage createIconMask(const IconMask *mask, int scale) {
// images are layouted like this:
// 100x 200x
// 300x
if (cRetina()) {
scale *= 2;
}
scale *= cIntRetinaFactor();
const auto width = maskImage.width() / 3;
const auto height = maskImage.height() / 5;
const auto one = QRect(0, 0, width, height);

View File

@ -603,7 +603,9 @@ public:
ch = emojiLookback = 0;
lastSkipped = false;
checkTilde = !cRetina() && (_t->_st->font->size() == 13) && (_t->_st->font->flags() == 0) && (_t->_st->font->f.family() == qstr("Open Sans")); // tilde Open Sans fix
checkTilde = (_t->_st->font->size() * cIntRetinaFactor() == 13)
&& (_t->_st->font->flags() == 0)
&& (_t->_st->font->f.family() == qstr("Open Sans")); // tilde Open Sans fix
for (; ptr <= end; ++ptr) {
while (checkEntities() || (rich && checkCommand())) {
}

View File

@ -1849,8 +1849,7 @@ bool InputField::isRedoAvailable() const {
void InputField::processFormatting(int insertPosition, int insertEnd) {
// Tilde formatting.
const auto tildeFormatting = !cRetina()
&& (_st.font->f.pixelSize() == 13)
const auto tildeFormatting = (_st.font->f.pixelSize() * cIntRetinaFactor() == 13)
&& (_st.font->f.family() == qstr("Open Sans"));
auto isTildeFragment = false;
const auto tildeFixedFont = AdjustFont(st::semiboldFont, _st.font);

View File

@ -645,7 +645,7 @@ void Notification::updateNotifyDisplay() {
int32 w = width(), h = height();
QImage img(w * cIntRetinaFactor(), h * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
if (cRetina()) img.setDevicePixelRatio(cRetinaFactor());
img.setDevicePixelRatio(cRetinaFactor());
img.fill(st::notificationBg->c);
{

View File

@ -409,10 +409,9 @@ void ChatBackground::setImage(int32 id, QImage &&image) {
} else {
if (_id == kInitialBackground) {
image.load(qsl(":/gui/art/bg_initial.jpg"));
if (cRetina()) {
image = image.scaledToWidth(image.width() * 2, Qt::SmoothTransformation);
} else if (cScale() != 100) {
image = image.scaledToWidth(ConvertScale(image.width()), Qt::SmoothTransformation);
const auto scale = cScale() * cIntRetinaFactor();
if (scale != 100) {
image = image.scaledToWidth(ConvertScale(image.width(), scale), Qt::SmoothTransformation);
}
} else if (_id == kDefaultBackground || image.isNull()) {
_id = kDefaultBackground;

View File

@ -948,7 +948,7 @@ void DefaultPreviewWindowFramePaint(QImage &preview, const style::palette &palet
currentInt = *lastLineInts;
++maxSize;
}
if (cRetina() && (maxSize % cIntRetinaFactor())) {
if (maxSize % cIntRetinaFactor()) {
maxSize -= (maxSize % cIntRetinaFactor());
}
auto size = maxSize / cIntRetinaFactor();