Added background analysis in main menu for better readability.

This commit is contained in:
23rd 2019-05-24 21:46:52 +03:00 committed by John Preston
parent 08a3a5747a
commit 159f90a42c
6 changed files with 86 additions and 11 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -128,6 +128,7 @@ mainMenu: Menu(defaultMenu) {
}
itemToggleShift: 11px;
}
mainMenuShadow: icon {{ "menu_shadow", windowShadowFg }};
mainMenuNewGroup: icon {{ "menu_new_group", menuIconFg }};
mainMenuNewGroupOver: icon {{ "menu_new_group", menuIconFgOver }};
mainMenuNewChannel: icon {{ "menu_new_channel", menuIconFg }};

View File

@ -33,6 +33,30 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_settings.h"
#include "styles/style_boxes.h"
namespace {
constexpr auto kMinDiffIntensity = 0.25;
float64 IntensityOfColor(QColor color) {
return (0.299 * color.red()
+ 0.587 * color.green()
+ 0.114 * color.blue()) / 255.0;
}
bool IsShadowShown(const QImage &img, const QRect r, float64 intensityText) {
for (auto x = r.x(); x < r.x() + r.width(); x++) {
for (auto y = r.y(); y < r.y() + r.height(); y++) {
const auto intensity = IntensityOfColor(QColor(img.pixel(x, y)));
if ((std::abs(intensity - intensityText)) < kMinDiffIntensity) {
return true;
}
}
}
return false;
}
}
namespace Window {
class MainMenu::ResetScaleButton : public Ui::AbstractButton {
@ -122,6 +146,7 @@ MainMenu::MainMenu(
Window::Theme::ToggleNightMode();
Window::Theme::KeepApplied();
}
refreshBackground();
}
});
@ -130,6 +155,7 @@ MainMenu::MainMenu(
emit action->triggered();
});
refreshMenu();
refreshBackground();
_telegram->setRichText(textcmdLink(1, qsl("Telegram Desktop")));
_telegram->setLink(1, std::make_shared<UrlClickHandler>(qsl("https://desktop.telegram.org")));
@ -148,6 +174,7 @@ MainMenu::MainMenu(
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) {
if (update.type == Window::Theme::BackgroundUpdate::Type::ApplyingTheme) {
refreshMenu();
refreshBackground();
}
});
updatePhone();
@ -220,6 +247,45 @@ void MainMenu::refreshMenu() {
updatePhone();
}
void MainMenu::refreshBackground() {
const auto fill = QRect(0, 0, width(), st::mainMenuCoverHeight);
const auto intensityText = IntensityOfColor(st::mainMenuCoverFg->c);
QImage backgroundImage(
st::mainMenuWidth * cIntRetinaFactor(),
st::mainMenuCoverHeight * cIntRetinaFactor(),
QImage::Format_ARGB32_Premultiplied);
QPainter p(&backgroundImage);
// Solid color.
if (const auto color = Window::Theme::Background()->colorForFill()) {
const auto intensity = IntensityOfColor(*color);
_isShadowShown =
(std::abs(intensity - intensityText) < kMinDiffIntensity);
p.fillRect(fill, *color);
_background = backgroundImage;
return;
}
// Background image.
const auto &pixmap = Window::Theme::Background()->pixmap();
QRect to, from;
Window::Theme::ComputeBackgroundRects(fill, pixmap.size(), to, from);
p.drawPixmap(to, pixmap, from);
_background = backgroundImage;
// Cut off the part of the background that is under text.
const QRect underText(
st::mainMenuCoverTextLeft,
st::mainMenuCoverNameTop,
std::max(
st::semiboldFont->width(Auth().user()->nameText.toString()),
st::normalFont->width(_phoneText)),
st::semiboldFont->height * 2);
_isShadowShown = IsShadowShown(backgroundImage, underText, intensityText);
}
void MainMenu::resizeEvent(QResizeEvent *e) {
_menu->setForceWidth(width());
updateControlsGeometry();
@ -248,25 +314,30 @@ void MainMenu::updatePhone() {
void MainMenu::paintEvent(QPaintEvent *e) {
Painter p(this);
const auto clip = e->rect();
const auto fill = QRect(0, 0, width(), st::mainMenuCoverHeight);
const auto cover = fill.intersected(clip);
const auto cover = QRect(0, 0, width(), st::mainMenuCoverHeight)
.intersected(e->rect());
if (const auto color = Window::Theme::Background()->colorForFill()) {
p.fillRect(fill, *color);
} else {
if (!_background.isNull()) {
PainterHighQualityEnabler hq(p);
const auto &pix = Window::Theme::Background()->pixmap();
QRect to, from;
Window::Theme::ComputeBackgroundRects(fill, pix.size(), to, from);
p.drawPixmap(to, pix, from);
p.drawImage(0, 0, _background);
}
if (!cover.isEmpty()) {
const auto widthText = _cloudButton
? _cloudButton->x() - st::mainMenuCloudSize
: width() - 2 * st::mainMenuCoverTextLeft;
p.fillRect(cover, QColor(0, 0, 0, 51)); // 20% opacity.
if (_isShadowShown) {
st::mainMenuShadow.paint(
p,
0,
st::mainMenuCoverHeight - st::mainMenuShadow.height(),
st::mainMenuWidth,
IntensityOfColor(st::mainMenuCoverFg->c) < 0.5
? Qt::white
: Qt::black);
}
p.setPen(st::mainMenuCoverFg);
p.setFont(st::semiboldFont);
Auth().user()->nameText.drawLeftElided(

View File

@ -38,6 +38,7 @@ private:
void updatePhone();
void initResetScaleButton();
void refreshMenu();
void refreshBackground();
class ResetScaleButton;
not_null<Controller*> _controller;
@ -51,6 +52,8 @@ private:
base::Timer _nightThemeSwitch;
QString _phoneText;
QImage _background;
bool _isShadowShown = false;
};