Closed beta 10019001: style::color copy is denied, only const refs.

This commit is contained in:
John Preston 2016-11-03 13:33:57 +03:00
parent 5d10c02b5b
commit 2a3fd0066d
44 changed files with 344 additions and 381 deletions

View File

@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,10,20,0
PRODUCTVERSION 0,10,20,0
FILEVERSION 0,10,19,1
PRODUCTVERSION 0,10,19,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -51,10 +51,10 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileVersion", "0.10.20.0"
VALUE "FileVersion", "0.10.19.1"
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "0.10.20.0"
VALUE "ProductVersion", "0.10.19.1"
END
END
BLOCK "VarFileInfo"

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,10,20,0
PRODUCTVERSION 0,10,20,0
FILEVERSION 0,10,19,1
PRODUCTVERSION 0,10,19,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -43,10 +43,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileDescription", "Telegram Updater"
VALUE "FileVersion", "0.10.20.0"
VALUE "FileVersion", "0.10.19.1"
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "0.10.20.0"
VALUE "ProductVersion", "0.10.19.1"
END
END
BLOCK "VarFileInfo"

View File

@ -127,13 +127,6 @@ namespace {
LastPhotosList lastPhotos;
using LastPhotosMap = QHash<PhotoData*, LastPhotosList::iterator>;
LastPhotosMap lastPhotosMap;
style::color _msgServiceBg;
style::color _msgServiceSelectBg;
style::color _historyScrollBarColor;
style::color _historyScrollBgColor;
style::color _historyScrollBarOverColor;
style::color _historyScrollBgOverColor;
}
namespace App {
@ -2270,6 +2263,23 @@ namespace {
prepareCorners(MessageInSelectedCorners, msgRadius(), st::msgInBgSelected, &st::msgInShadowSelected);
prepareCorners(MessageOutCorners, msgRadius(), st::msgOutBg, &st::msgOutShadow);
prepareCorners(MessageOutSelectedCorners, msgRadius(), st::msgOutBgSelected, &st::msgOutShadowSelected);
static auto subscription = Window::Theme::Background()->add_subscription([](const Window::Theme::BackgroundUpdate &update) {
if (update.type != Window::Theme::BackgroundUpdate::Type::New) {
return;
}
for (int i = 0; i < 4; ++i) {
delete ::corners[StickerCorners].p[i]; ::corners[StickerCorners].p[i] = nullptr;
delete ::corners[StickerSelectedCorners].p[i]; ::corners[StickerSelectedCorners].p[i] = nullptr;
}
prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg);
prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceSelectBg);
if (App::main()) {
App::main()->updateScrollColors();
}
HistoryLayout::serviceColorsUpdated();
});
}
void clearHistories() {
@ -2774,125 +2784,6 @@ namespace {
roundRect(p, x, y, w, h, bg, i.value(), 0);
}
void initColorsFromBackground(const QImage &img) {
uint64 components[3] = { 0 }, componentsScroll[3] = { 0 };
auto w = img.width();
auto h = img.height();
auto size = w * h;
if (auto pix = img.constBits()) {
for (int i = 0, l = size * 4; i != l; i += 4) {
components[2] += pix[i + 0];
components[1] += pix[i + 1];
components[0] += pix[i + 2];
}
}
if (size) {
for (int i = 0; i != 3; ++i) {
components[i] /= size;
}
}
int maxtomin[3] = { 0, 1, 2 };
if (components[maxtomin[0]] < components[maxtomin[1]]) {
qSwap(maxtomin[0], maxtomin[1]);
}
if (components[maxtomin[1]] < components[maxtomin[2]]) {
qSwap(maxtomin[1], maxtomin[2]);
if (components[maxtomin[0]] < components[maxtomin[1]]) {
qSwap(maxtomin[0], maxtomin[1]);
}
}
uint64 max = qMax(1ULL, components[maxtomin[0]]), mid = qMax(1ULL, components[maxtomin[1]]), min = qMax(1ULL, components[maxtomin[2]]);
memcpy(componentsScroll, components, sizeof(components));
if (max != min) {
if (min > uint64(qRound(0.77 * max))) {
uint64 newmin = qRound(0.77 * max); // min saturation 23%
uint64 newmid = max - ((max - mid) * (max - newmin)) / (max - min);
components[maxtomin[1]] = newmid;
components[maxtomin[2]] = newmin;
}
uint64 newmin = qRound(0.77 * max); // saturation 23% for scroll
uint64 newmid = max - ((max - mid) * (max - newmin)) / (max - min);
componentsScroll[maxtomin[1]] = newmid;
componentsScroll[maxtomin[2]] = newmin;
}
float64 luminance = 0.299 * componentsScroll[0] + 0.587 * componentsScroll[1] + 0.114 * componentsScroll[2];
uint64 maxScroll = max;
if (luminance < 0.5 * 0xFF) {
maxScroll += qRound(0.2 * 0xFF);
} else {
maxScroll -= qRound(0.2 * 0xFF);
}
componentsScroll[maxtomin[2]] = qMin(uint64(float64(componentsScroll[maxtomin[2]]) * maxScroll / float64(componentsScroll[maxtomin[0]])), 0xFFULL);
componentsScroll[maxtomin[1]] = qMin(uint64(float64(componentsScroll[maxtomin[1]]) * maxScroll / float64(componentsScroll[maxtomin[0]])), 0xFFULL);
componentsScroll[maxtomin[0]] = qMin(maxScroll, 0xFFULL);
if (max > uint64(qRound(0.2 * 0xFF))) { // brightness greater than 20%
max -= qRound(0.2 * 0xFF);
} else {
max = 0;
}
components[maxtomin[2]] = uint64(float64(components[maxtomin[2]]) * max / float64(components[maxtomin[0]]));
components[maxtomin[1]] = uint64(float64(components[maxtomin[1]]) * max / float64(components[maxtomin[0]]));
components[maxtomin[0]] = max;
uchar r = uchar(components[0]), g = uchar(components[1]), b = uchar(components[2]);
float64 alpha = st::msgServiceBg->c.alphaF();
_msgServiceBg = style::color(r, g, b, qRound(alpha * 0xFF));
float64 alphaSel = st::msgServiceSelectBg->c.alphaF(), addSel = (1. - ((1. - alphaSel) / (1. - alpha))) * 0xFF;
uchar rsel = snap(qRound(((1. - alphaSel) * r + addSel) / alphaSel), 0, 0xFF);
uchar gsel = snap(qRound(((1. - alphaSel) * g + addSel) / alphaSel), 0, 0xFF);
uchar bsel = snap(qRound(((1. - alphaSel) * b + addSel) / alphaSel), 0, 0xFF);
_msgServiceSelectBg = style::color(r, g, b, qRound(alphaSel * 0xFF));
for (int i = 0; i < 4; ++i) {
delete ::corners[StickerCorners].p[i]; ::corners[StickerCorners].p[i] = nullptr;
delete ::corners[StickerSelectedCorners].p[i]; ::corners[StickerSelectedCorners].p[i] = nullptr;
}
prepareCorners(StickerCorners, st::dateRadius, _msgServiceBg);
prepareCorners(StickerSelectedCorners, st::dateRadius, _msgServiceSelectBg);
uchar rScroll = uchar(componentsScroll[0]), gScroll = uchar(componentsScroll[1]), bScroll = uchar(componentsScroll[2]);
_historyScrollBarColor = style::color(rScroll, gScroll, bScroll, st::historyScroll.barColor->c.alpha());
_historyScrollBgColor = style::color(rScroll, gScroll, bScroll, st::historyScroll.bgColor->c.alpha());
_historyScrollBarOverColor = style::color(rScroll, gScroll, bScroll, st::historyScroll.barOverColor->c.alpha());
_historyScrollBgOverColor = style::color(rScroll, gScroll, bScroll, st::historyScroll.bgOverColor->c.alpha());
if (App::main()) {
App::main()->updateScrollColors();
}
HistoryLayout::serviceColorsUpdated();
}
const style::color &msgServiceBg() {
return _msgServiceBg;
}
const style::color &msgServiceSelectBg() {
return _msgServiceSelectBg;
}
const style::color &historyScrollBarColor() {
return _historyScrollBarColor;
}
const style::color &historyScrollBgColor() {
return _historyScrollBgColor;
}
const style::color &historyScrollBarOverColor() {
return _historyScrollBarOverColor;
}
const style::color &historyScrollBgOverColor() {
return _historyScrollBgOverColor;
}
WallPapers gServerBackgrounds;
}

View File

@ -293,15 +293,6 @@ namespace App {
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius);
}
void initColorsFromBackground(const QImage &image);
const style::color &msgServiceBg();
const style::color &msgServiceSelectBg();
const style::color &historyScrollBarColor();
const style::color &historyScrollBgColor();
const style::color &historyScrollBarOverColor();
const style::color &historyScrollBgOverColor();
struct WallPaper {
WallPaper(int32 id, ImagePtr thumb, ImagePtr full) : id(id), thumb(thumb), full(full) {
}

View File

@ -284,7 +284,7 @@ void PhotoSendBox::paintEvent(QPaintEvent *e) {
p.setPen(st::historyFileNameOutFg);
_name.drawLeftElided(p, x + nameleft, y + nametop, namewidth, width());
style::color status(st::mediaOutFg);
auto &status = st::mediaOutFg;
p.setFont(st::normalFont);
p.setPen(status);
p.drawTextLeft(x + nameleft, y + statustop, width(), _status);
@ -602,7 +602,7 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) {
p.setPen(st::historyFileNameInFg);
_name.drawLeftElided(p, x + nameleft, y + nametop, namewidth, width());
style::color status(st::mediaInFg);
auto &status = st::mediaInFg;
p.setFont(st::normalFont);
p.setPen(status);
p.drawTextLeft(x + nameleft, y + statustop, width(), _status);

View File

@ -484,7 +484,7 @@ ShareBox::Inner::Chat *ShareBox::Inner::getChat(Dialogs::Row *row) {
void ShareBox::Inner::setActive(int active) {
if (active != _active) {
auto changeNameFg = [this](int index, style::color from, style::color to) {
auto changeNameFg = [this](int index, const style::color &from, const style::color &to) {
if (auto chat = getChatAtIndex(index)) {
chat->nameFg.start([this, peer = chat->peer] {
repaintChat(peer);

View File

@ -646,7 +646,7 @@ void StickersBox::Inner::paintRow(Painter &p, int32 index) {
int addy = st::contactsPadding.top() + (st::contactsPhotoSize - st::stickersAddSize.height()) / 2;
QRect add(myrtlrect(addx, addy, addw, st::stickersAddSize.height()));
auto textBg = (_actionSel == index) ? st::defaultActiveButton.textBgOver : st::defaultActiveButton.textBg;
auto &textBg = (_actionSel == index) ? st::defaultActiveButton.textBgOver : st::defaultActiveButton.textBg;
App::roundRect(p, add, textBg, ImageRoundRadius::Small);
int iconx = addx + (st::stickersAddSize.width() - st::stickersAddIcon.width()) / 2;
int icony = addy + (st::stickersAddSize.height() - st::stickersAddIcon.height()) / 2;

View File

@ -330,7 +330,13 @@ QString Generator::typeToDefaultValue(structure::Type type) const {
QString Generator::valueAssignmentCode(structure::Value value) const {
auto copy = value.copyOf();
if (!copy.isEmpty()) {
return "st::" + copy.back();
auto result = "st::" + copy.back();
// Copy is disabled for colors.
if (value.type().tag == Tag::Color || value.type().tag == Tag::Struct) {
result += ".clone()";
}
return result;
}
switch (value.type().tag) {
@ -590,15 +596,30 @@ bool Generator::writeStructsDefinitions() {
}
bool result = module_.enumStructs([this](const Struct &value) -> bool {
header_->stream() << "struct " << value.name.back() << " {\n";
for (const auto &field : value.fields) {
QStringList fields;
for (auto field : value.fields) {
auto clone = field.name.back();
if (field.type.tag == Tag::Color || field.type.tag == Tag::Struct) {
clone += ".clone()";
}
fields.push_back(clone);
}
header_->stream() << "\
struct " << value.name.back() << " {\n\
" << value.name.back() << " clone() const {\n\
return { " << fields.join(", ") << " };\n\
}\n";
if (!fields.empty()) header_->newline();
for (auto &field : value.fields) {
auto type = typeToString(field.type);
if (type.isEmpty()) {
return false;
}
header_->stream() << "\t" << type << " " << field.name.back() << ";\n";
}
header_->stream() << "};\n\n";
header_->stream() << "\
};\n\n";
return true;
});

View File

@ -119,7 +119,7 @@ public:
return insertAt;
}
inline void push_back(T &&value) {
insert(end(), std_::forward<T>(value));
insert(end(), std_::move(value));
}
inline void pop_back() {
erase(end() - 1);

View File

@ -22,7 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "core/utils.h"
#define BETA_VERSION_MACRO (0ULL)
#define BETA_VERSION_MACRO (10019001ULL)
constexpr int AppVersion = 10020;
constexpr str_const AppVersionStr = "0.10.20";

View File

@ -144,7 +144,12 @@ struct UnreadBadgeSizeData {
class UnreadBadgeStyleData : public Data::AbstractStructure {
public:
UnreadBadgeSizeData sizes[UnreadBadgeSizesCount];
style::color bg[4] = { st::dialogsUnreadBg, st::dialogsUnreadBgActive, st::dialogsUnreadBgMuted, st::dialogsUnreadBgMutedActive };
const style::color *bg[4] = {
&st::dialogsUnreadBg,
&st::dialogsUnreadBgActive,
&st::dialogsUnreadBgMuted,
&st::dialogsUnreadBgMutedActive
};
};
Data::GlobalStructurePointer<UnreadBadgeStyleData> unreadBadgeStyle;
@ -154,7 +159,7 @@ void createCircleMask(UnreadBadgeSizeData *data, int size) {
data->circle = style::createCircleMask(size);
}
QImage colorizeCircleHalf(UnreadBadgeSizeData *data, int size, int half, int xoffset, style::color color) {
QImage colorizeCircleHalf(UnreadBadgeSizeData *data, int size, int half, int xoffset, const style::color &color) {
auto result = style::colorizeImage(data->circle, color, QRect(xoffset, 0, half, size));
result.setDevicePixelRatio(cRetinaFactor());
return result;
@ -183,18 +188,18 @@ void paintUnreadBadge(Painter &p, const QRect &rect, const UnreadBadgeStyle &st)
t_assert(st.sizeId < UnreadBadgeSizesCount);
badgeData = &unreadBadgeStyle->sizes[st.sizeId];
}
auto &bg = unreadBadgeStyle->bg[index];
auto bg = unreadBadgeStyle->bg[index];
if (badgeData->left[index].isNull()) {
int imgsize = size * cIntRetinaFactor(), imgsizehalf = sizehalf * cIntRetinaFactor();
createCircleMask(badgeData, size);
badgeData->left[index] = App::pixmapFromImageInPlace(colorizeCircleHalf(badgeData, imgsize, imgsizehalf, 0, bg));
badgeData->right[index] = App::pixmapFromImageInPlace(colorizeCircleHalf(badgeData, imgsize, imgsizehalf, imgsize - imgsizehalf, bg));
badgeData->left[index] = App::pixmapFromImageInPlace(colorizeCircleHalf(badgeData, imgsize, imgsizehalf, 0, *bg));
badgeData->right[index] = App::pixmapFromImageInPlace(colorizeCircleHalf(badgeData, imgsize, imgsizehalf, imgsize - imgsizehalf, *bg));
}
int bar = rect.width() - 2 * sizehalf;
p.drawPixmap(rect.x(), rect.y(), badgeData->left[index]);
if (bar) {
p.fillRect(rect.x() + sizehalf, rect.y(), bar, rect.height(), bg);
p.fillRect(rect.x() + sizehalf, rect.y(), bar, rect.height(), *bg);
}
p.drawPixmap(rect.x() + sizehalf + bar, rect.y(), badgeData->right[index]);
}

View File

@ -1211,8 +1211,8 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
float64 prg = voice->_playback ? voice->_playback->a_progress.current() : 0;
// rescale waveform by going in waveform.size * bar_count 1D grid
style::color active(outbg ? (selected ? st::msgWaveformOutActiveSelected : st::msgWaveformOutActive) : (selected ? st::msgWaveformInActiveSelected : st::msgWaveformInActive));
style::color inactive(outbg ? (selected ? st::msgWaveformOutInactiveSelected : st::msgWaveformOutInactive) : (selected ? st::msgWaveformInInactiveSelected : st::msgWaveformInInactive));
auto &active = outbg ? (selected ? st::msgWaveformOutActiveSelected : st::msgWaveformOutActive) : (selected ? st::msgWaveformInActiveSelected : st::msgWaveformInActive);
auto &inactive = outbg ? (selected ? st::msgWaveformOutInactiveSelected : st::msgWaveformOutInactive) : (selected ? st::msgWaveformInInactiveSelected : st::msgWaveformInInactive);
int32 wf_size = wf ? wf->size() : WaveformSamplesCount, availw = int32(namewidth + st::msgWaveformSkip), activew = qRound(availw * prg);
if (!outbg && !voice->_playback && _parent->isMediaUnread()) {
activew = availw;
@ -1261,7 +1261,7 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
}
}
style::color status(outbg ? (selected ? st::mediaOutFgSelected : st::mediaOutFg) : (selected ? st::mediaInFgSelected : st::mediaInFg));
auto &status = outbg ? (selected ? st::mediaOutFgSelected : st::mediaOutFg) : (selected ? st::mediaInFgSelected : st::mediaInFg);
p.setFont(st::normalFont);
p.setPen(status);
p.drawTextLeft(nameleft, statustop, _width, _statusText);
@ -2066,7 +2066,7 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, u
// Make the bottom of the rect at the same level as the bottom of the info rect.
recty -= st::msgDateImgDelta;
App::roundRect(p, rectx, recty, rectw, recth, selected ? App::msgServiceSelectBg() : App::msgServiceBg(), selected ? StickerSelectedCorners : StickerCorners);
App::roundRect(p, rectx, recty, rectw, recth, selected ? st::msgServiceSelectBg : st::msgServiceBg, selected ? StickerSelectedCorners : StickerCorners);
rectx += st::msgReplyPadding.left();
rectw -= st::msgReplyPadding.left() + st::msgReplyPadding.right();
if (via) {
@ -2317,7 +2317,7 @@ void HistoryContact::draw(Painter &p, const QRect &r, TextSelection selection, u
p.setPen(outbg ? st::historyFileNameOutFg : st::historyFileNameInFg);
_name.drawLeftElided(p, nameleft, nametop, namewidth, width);
style::color status(outbg ? (selected ? st::mediaOutFgSelected : st::mediaOutFg) : (selected ? st::mediaInFgSelected : st::mediaInFg));
auto &status = outbg ? (selected ? st::mediaOutFgSelected : st::mediaOutFg) : (selected ? st::mediaInFgSelected : st::mediaInFg);
p.setFont(st::normalFont);
p.setPen(status);
p.drawTextLeft(nameleft, statustop, width, _phone);
@ -2649,9 +2649,9 @@ void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, u
bool out = _parent->out(), isPost = _parent->isPost(), outbg = out && !isPost;
bool selected = (selection == FullSelection);
style::color barfg = (selected ? (outbg ? st::historyOutSelectedFg : st::msgInReplyBarSelColor) : (outbg ? st::historyOutFg : st::msgInReplyBarColor));
style::color semibold = (selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg));
style::color regular = (selected ? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected) : (outbg ? st::msgOutDateFg : st::msgInDateFg));
auto &barfg = selected ? (outbg ? st::historyOutSelectedFg : st::msgInReplyBarSelColor) : (outbg ? st::historyOutFg : st::msgInReplyBarColor);
auto &semibold = selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg);
auto &regular = selected ? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected) : (outbg ? st::msgOutDateFg : st::msgInDateFg);
QMargins bubble(_attach ? _attach->bubbleMargins() : QMargins());
auto padding = inBubblePadding();
@ -3048,9 +3048,9 @@ void HistoryGame::draw(Painter &p, const QRect &r, TextSelection selection, uint
bool out = _parent->out(), isPost = _parent->isPost(), outbg = out && !isPost;
bool selected = (selection == FullSelection);
style::color barfg = (selected ? (outbg ? st::historyOutSelectedFg : st::msgInReplyBarSelColor) : (outbg ? st::historyOutFg : st::msgInReplyBarColor));
style::color semibold = (selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg));
style::color regular = (selected ? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected) : (outbg ? st::msgOutDateFg : st::msgInDateFg));
auto &barfg = selected ? (outbg ? st::historyOutSelectedFg : st::msgInReplyBarSelColor) : (outbg ? st::historyOutFg : st::msgInReplyBarColor);
auto &semibold = selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg);
auto &regular = selected ? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected) : (outbg ? st::msgOutDateFg : st::msgInDateFg);
QMargins bubble(_attach ? _attach->bubbleMargins() : QMargins());
auto padding = inBubblePadding();

View File

@ -243,14 +243,12 @@ void HistoryMessageReply::itemRemoved(HistoryMessage *holder, HistoryItem *remov
void HistoryMessageReply::paint(Painter &p, const HistoryItem *holder, int x, int y, int w, PaintFlags flags) const {
bool selected = (flags & PaintSelected), outbg = holder->hasOutLayout();
style::color bar;
const style::color *bar = &st::msgImgReplyBarColor;
if (flags & PaintInBubble) {
bar = ((flags & PaintSelected) ? (outbg ? st::historyOutSelectedFg : st::msgInReplyBarSelColor) : (outbg ? st::historyOutFg : st::msgInReplyBarColor));
} else {
bar = st::msgImgReplyBarColor;
bar = &((flags & PaintSelected) ? (outbg ? st::historyOutSelectedFg : st::msgInReplyBarSelColor) : (outbg ? st::historyOutFg : st::msgInReplyBarColor));
}
QRect rbar(rtlrect(x + st::msgReplyBarPos.x(), y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height(), w + 2 * x));
p.fillRect(rbar, bar);
p.fillRect(rbar, *bar);
if (w > st::msgReplyBarSkip) {
if (replyToMsg) {
@ -282,7 +280,7 @@ void HistoryMessageReply::paint(Painter &p, const HistoryItem *holder, int x, in
HistoryMessage *replyToAsMsg = replyToMsg->toHistoryMessage();
if (!(flags & PaintInBubble)) {
} else if ((replyToAsMsg && replyToAsMsg->emptyText()) || replyToMsg->serviceMsg()) {
style::color date(outbg ? (selected ? st::msgOutDateFgSelected : st::msgOutDateFg) : (selected ? st::msgInDateFgSelected : st::msgInDateFg));
auto &date = outbg ? (selected ? st::msgOutDateFgSelected : st::msgOutDateFg) : (selected ? st::msgInDateFgSelected : st::msgInDateFg);
p.setPen(date);
} else {
p.setPen(st::msgColor);
@ -291,7 +289,7 @@ void HistoryMessageReply::paint(Painter &p, const HistoryItem *holder, int x, in
}
} else {
p.setFont(st::msgDateFont);
style::color date(outbg ? (selected ? st::msgOutDateFgSelected : st::msgOutDateFg) : (selected ? st::msgInDateFgSelected : st::msgInDateFg));
auto &date = outbg ? (selected ? st::msgOutDateFgSelected : st::msgOutDateFg) : (selected ? st::msgInDateFgSelected : st::msgInDateFg);
p.setPen((flags & PaintInBubble) ? date : st::msgDateImgColor);
p.drawTextLeft(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2, w + 2 * x, st::msgDateFont->elided(lang(replyToMsgId ? lng_profile_loading : lng_deleted_message), w - st::msgReplyBarSkip));
}
@ -311,7 +309,7 @@ void HistoryMessage::KeyboardStyle::repaint(const HistoryItem *item) const {
}
void HistoryMessage::KeyboardStyle::paintButtonBg(Painter &p, const QRect &rect, bool down, float64 howMuchOver) const {
App::roundRect(p, rect, App::msgServiceBg(), StickerCorners);
App::roundRect(p, rect, st::msgServiceBg, StickerCorners);
if (down) {
howMuchOver = 1.;
}
@ -1153,7 +1151,7 @@ void HistoryMessage::drawInfo(Painter &p, int32 right, int32 bottom, int32 width
App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
} else if (type == InfoDisplayOverBackground) {
int32 dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y();
App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? App::msgServiceSelectBg() : App::msgServiceBg(), selected ? StickerSelectedCorners : StickerCorners);
App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgServiceSelectBg : st::msgServiceBg, selected ? StickerSelectedCorners : StickerCorners);
}
dateX += HistoryMessage::timeLeft();

View File

@ -102,7 +102,7 @@ QPixmap circleCorner(int corner) {
yoffset = size;
}
auto part = QRect(xoffset, yoffset, size, size);
auto result = style::colorizeImage(serviceMessageStyle->circle[maskType], App::msgServiceBg(), part);
auto result = style::colorizeImage(serviceMessageStyle->circle[maskType], st::msgServiceBg, part);
result.setDevicePixelRatio(cRetinaFactor());
serviceMessageStyle->corners[corner] = App::pixmapFromImageInPlace(std_::move(result));
}
@ -127,7 +127,7 @@ int paintBubbleSide(Painter &p, int x, int y, int width, SideStyle style, Corner
p.drawPixmap(x + width - rightWidth, y, right);
int cornerHeight = left.height() / cIntRetinaFactor();
p.fillRect(x + leftWidth, y, width - leftWidth - rightWidth, cornerHeight, App::msgServiceBg());
p.fillRect(x + leftWidth, y, width - leftWidth - rightWidth, cornerHeight, st::msgServiceBg);
return cornerHeight;
} else if (style == SideStyle::Inverted) {
// CornerLeft and CornerRight are inverted for SideStyle::Inverted sprites.
@ -161,7 +161,7 @@ void paintBubblePart(Painter &p, int x, int y, int width, int height, SideStyle
height -= skip;
}
p.fillRect(x, y, width, height, App::msgServiceBg());
p.fillRect(x, y, width, height, st::msgServiceBg);
}
void paintPreparedDate(Painter &p, const QString &dateText, int dateTextWidth, int y, int w) {
@ -337,7 +337,7 @@ QVector<int> ServiceMessagePainter::countLineWidths(const Text &text, const QRec
void paintEmpty(Painter &p, int width, int height) {
auto position = QPoint((width - st::historyEmptySize) / 2, ((height - st::historyEmptySize) * 4) / 9);
p.setPen(Qt::NoPen);
p.setBrush(App::msgServiceBg());
p.setBrush(st::msgServiceBg);
p.setRenderHint(QPainter::HighQualityAntialiasing);
p.drawEllipse(rtlrect(position.x(), position.y(), st::historyEmptySize, st::historyEmptySize, width));
p.setRenderHint(QPainter::HighQualityAntialiasing, false);

View File

@ -7090,8 +7090,7 @@ void HistoryWidget::itemEdited(HistoryItem *item) {
}
void HistoryWidget::updateScrollColors() {
if (!App::historyScrollBarColor()) return;
_scroll.updateColors(App::historyScrollBarColor(), App::historyScrollBgColor(), App::historyScrollBarOverColor(), App::historyScrollBgOverColor());
_scroll.updateBars();
}
MsgId HistoryWidget::replyToId() const {

View File

@ -1047,9 +1047,14 @@ void Article::paint(Painter &p, const QRect &clip, const PaintContext *context)
ImagePtr thumb = getResultThumb();
if (thumb->isNull() && !_thumbLetter.isEmpty()) {
int32 index = (_thumbLetter.at(0).unicode() % 4);
style::color colors[] = { st::msgFileRedColor, st::msgFileYellowColor, st::msgFileGreenColor, st::msgFileBlueColor };
const style::color *colors[] = {
&st::msgFileRedColor,
&st::msgFileYellowColor,
&st::msgFileGreenColor,
&st::msgFileBlueColor
};
p.fillRect(rthumb, colors[index]);
p.fillRect(rthumb, *colors[index]);
if (!_thumbLetter.isEmpty()) {
p.setFont(st::linksLetterFont);
p.setPen(st::linksLetterFg);

View File

@ -210,24 +210,44 @@ int32 documentColorIndex(DocumentData *document, QString &ext) {
return colorIndex;
}
style::color documentColor(int32 colorIndex) {
static style::color colors[] = { st::msgFileBlueColor, st::msgFileGreenColor, st::msgFileRedColor, st::msgFileYellowColor };
return colors[colorIndex & 3];
const style::color &documentColor(int32 colorIndex) {
static const style::color *colors[] = {
&st::msgFileBlueColor,
&st::msgFileGreenColor,
&st::msgFileRedColor,
&st::msgFileYellowColor
};
return *colors[colorIndex & 3];
}
style::color documentDarkColor(int32 colorIndex) {
static style::color colors[] = { st::msgFileBlueDark, st::msgFileGreenDark, st::msgFileRedDark, st::msgFileYellowDark };
return colors[colorIndex & 3];
const style::color &documentDarkColor(int32 colorIndex) {
static const style::color *colors[] = {
&st::msgFileBlueDark,
&st::msgFileGreenDark,
&st::msgFileRedDark,
&st::msgFileYellowDark
};
return *colors[colorIndex & 3];
}
style::color documentOverColor(int32 colorIndex) {
static style::color colors[] = { st::msgFileBlueOver, st::msgFileGreenOver, st::msgFileRedOver, st::msgFileYellowOver };
return colors[colorIndex & 3];
const style::color &documentOverColor(int32 colorIndex) {
static const style::color *colors[] = {
&st::msgFileBlueOver,
&st::msgFileGreenOver,
&st::msgFileRedOver,
&st::msgFileYellowOver
};
return *colors[colorIndex & 3];
}
style::color documentSelectedColor(int32 colorIndex) {
static style::color colors[] = { st::msgFileBlueSelected, st::msgFileGreenSelected, st::msgFileRedSelected, st::msgFileYellowSelected };
return colors[colorIndex & 3];
const style::color &documentSelectedColor(int32 colorIndex) {
static const style::color *colors[] = {
&st::msgFileBlueSelected,
&st::msgFileGreenSelected,
&st::msgFileRedSelected,
&st::msgFileYellowSelected
};
return *colors[colorIndex & 3];
}
RoundCorners documentCorners(int32 colorIndex) {

View File

@ -82,11 +82,11 @@ QString formatPlayedText(qint64 played, qint64 duration);
QString documentName(DocumentData *document);
TextWithEntities documentNameWithEntities(DocumentData *document);
int32 documentColorIndex(DocumentData *document, QString &ext);
style::color documentColor(int32 colorIndex);
style::color documentDarkColor(int32 colorIndex);
style::color documentOverColor(int32 colorIndex);
style::color documentSelectedColor(int32 colorIndex);
RoundCorners documentCorners(int32 colorIndex);
const style::color &documentColor(int colorIndex);
const style::color &documentDarkColor(int colorIndex);
const style::color &documentOverColor(int colorIndex);
const style::color &documentSelectedColor(int colorIndex);
RoundCorners documentCorners(int colorIndex);
bool documentIsValidMediaFile(const QString &filepath);
class PaintContextBase {

View File

@ -1228,7 +1228,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
if (!fileShown()) {
if (!_doc || _doc->thumb->isNull()) {
int32 colorIndex = documentColorIndex(_doc, _docExt);
_docIconColor = documentColor(colorIndex);
_docIconColor = &documentColor(colorIndex);
const style::icon *(thumbs[]) = { &st::mediaviewFileBlue, &st::mediaviewFileGreen, &st::mediaviewFileRed, &st::mediaviewFileYellow };
_docIcon = thumbs[colorIndex];
@ -1660,7 +1660,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
radialOpacity = _radial.opacity();
}
if (!_doc || _doc->thumb->isNull()) {
p.fillRect(_docIconRect, _docIconColor->b);
p.fillRect(_docIconRect, (*_docIconColor)->b);
if ((!_doc || _doc->loaded()) && (!radial || radialOpacity < 1) && _docIcon) {
_docIcon->paint(p, _docIconRect.x() + (_docIconRect.width() - _docIcon->width()), _docIconRect.y(), width());
p.setPen(st::mediaviewFileExtFg);

View File

@ -238,7 +238,7 @@ private:
void stopGif();
const style::icon *_docIcon = nullptr;
style::color _docIconColor;
const style::color *_docIconColor = nullptr;
QString _docName, _docSize, _docExt;
int _docNameWidth = 0, _docSizeWidth = 0, _docExtWidth = 0;
QRect _docRect, _docIconRect;

View File

@ -1020,7 +1020,7 @@ void StickerPanInner::paintStickers(Painter &p, const QRect &r) {
if (featuredHasAddButton(c)) {
auto add = featuredAddRect(c);
auto selected = (_selectedFeaturedSetAdd == c);
auto textBg = selected ? st::stickersTrendingAdd.textBgOver : st::stickersTrendingAdd.textBg;
auto &textBg = selected ? st::stickersTrendingAdd.textBgOver : st::stickersTrendingAdd.textBg;
auto textTop = (selected && _selectedFeaturedSetAdd == _pressedFeaturedSetAdd) ? st::stickersTrendingAdd.downTextTop : st::stickersTrendingAdd.textTop;
App::roundRect(p, myrtlrect(add), textBg, ImageRoundRadius::Small);

View File

@ -48,12 +48,6 @@ int peerColorIndex(const PeerId &peer) {
return (md5[peerId & 0x0F] & (peerIsUser(peer) ? 0x07 : 0x03));
}
struct ColorReferenceWrap {
ColorReferenceWrap(const style::color &data) : data(data) {
}
const style::color &data;
};
ImagePtr generateUserpicImage(const style::icon &icon) {
auto data = QImage(icon.size() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
data.setDevicePixelRatio(cRetinaFactor());
@ -67,17 +61,17 @@ ImagePtr generateUserpicImage(const style::icon &icon) {
} // namespace
const style::color &peerColor(int index) {
static const ColorReferenceWrap peerColors[kUserColorsCount] = {
st::historyPeer1NameFg,
st::historyPeer2NameFg,
st::historyPeer3NameFg,
st::historyPeer4NameFg,
st::historyPeer5NameFg,
st::historyPeer6NameFg,
st::historyPeer7NameFg,
st::historyPeer8NameFg,
static const style::color *peerColors[kUserColorsCount] = {
&st::historyPeer1NameFg,
&st::historyPeer2NameFg,
&st::historyPeer3NameFg,
&st::historyPeer4NameFg,
&st::historyPeer5NameFg,
&st::historyPeer6NameFg,
&st::historyPeer7NameFg,
&st::historyPeer8NameFg,
};
return peerColors[index].data;
return *peerColors[index];
}
ImagePtr userDefPhoto(int index) {

View File

@ -304,7 +304,7 @@ public:
MTPinputPeer input;
int colorIndex;
style::color color;
const style::color &color;
void setUserpic(ImagePtr userpic);
void paintUserpic(Painter &p, int size, int x, int y) const;

View File

@ -27,19 +27,19 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "autoupdater.h"
SysBtn::SysBtn(QWidget *parent, const style::sysButton &st, const QString &text) : Button(parent)
, _st(st)
, a_color(_st.color->c)
, _st(&st)
, a_color(_st->color->c)
, _a_color(animation(this, &SysBtn::step_color))
, _text(text) {
int32 w = _st.size.width() + (_text.isEmpty() ? 0 : ((_st.size.width() - _st.icon.width()) / 2 + st::titleTextButton.font->width(_text)));
resize(w, _st.size.height());
int32 w = _st->size.width() + (_text.isEmpty() ? 0 : ((_st->size.width() - _st->icon.width()) / 2 + st::titleTextButton.font->width(_text)));
resize(w, _st->size.height());
setCursor(style::cur_default);
}
void SysBtn::setText(const QString &text) {
_text = text;
int32 w = _st.size.width() + (_text.isEmpty() ? 0 : ((_st.size.width() - _st.icon.width()) / 2 + st::titleTextButton.font->width(_text)));
resize(w, _st.size.height());
int32 w = _st->size.width() + (_text.isEmpty() ? 0 : ((_st->size.width() - _st->icon.width()) / 2 + st::titleTextButton.font->width(_text)));
resize(w, _st->size.height());
}
void SysBtn::setOverLevel(float64 level) {
@ -48,7 +48,7 @@ void SysBtn::setOverLevel(float64 level) {
}
void SysBtn::onStateChanged(int oldState, ButtonStateChangeSource source) {
a_color.start((_state & StateOver ? _st.overColor : _st.color)->c);
a_color.start((_state & StateOver ? _st->overColor : _st->color)->c);
if (source == ButtonByUser || source == ButtonByPress) {
_a_color.stop();
@ -62,29 +62,29 @@ void SysBtn::onStateChanged(int oldState, ButtonStateChangeSource source) {
void SysBtn::paintEvent(QPaintEvent *e) {
Painter p(this);
int x = width() - ((_st.size.width() + _st.icon.width()) / 2), y = (height() - _st.icon.height()) / 2;
int x = width() - ((_st->size.width() + _st->icon.width()) / 2), y = (height() - _st->icon.height()) / 2;
QColor c = a_color.current();
if (_overLevel > 0) {
if (_overLevel >= 1) {
c = _st.overColor->c;
c = _st->overColor->c;
} else {
c.setRedF(c.redF() * (1 - _overLevel) + _st.overColor->c.redF() * _overLevel);
c.setGreenF(c.greenF() * (1 - _overLevel) + _st.overColor->c.greenF() * _overLevel);
c.setBlueF(c.blueF() * (1 - _overLevel) + _st.overColor->c.blueF() * _overLevel);
c.setRedF(c.redF() * (1 - _overLevel) + _st->overColor->c.redF() * _overLevel);
c.setGreenF(c.greenF() * (1 - _overLevel) + _st->overColor->c.greenF() * _overLevel);
c.setBlueF(c.blueF() * (1 - _overLevel) + _st->overColor->c.blueF() * _overLevel);
}
}
p.fillRect(x, y, _st.icon.width(), _st.icon.height(), c);
_st.icon.paint(p, x, y, width());
p.fillRect(x, y, _st->icon.width(), _st->icon.height(), c);
_st->icon.paint(p, x, y, width());
if (!_text.isEmpty()) {
p.setFont(st::titleTextButton.font->f);
p.setPen(c);
p.drawText((_st.size.width() - _st.icon.width()) / 2, st::titleTextButton.textTop + st::titleTextButton.font->ascent, _text);
p.drawText((_st->size.width() - _st->icon.width()) / 2, st::titleTextButton.textTop + st::titleTextButton.font->ascent, _text);
}
}
void SysBtn::setSysBtnStyle(const style::sysButton &st) {
_st = st;
_st = &st;
update();
}
@ -97,7 +97,7 @@ HitTestType SysBtn::hitTest(const QPoint &p) const {
}
void SysBtn::step_color(float64 ms, bool timer) {
float64 dt = ms / _st.duration;
float64 dt = ms / _st->duration;
if (dt >= 1) {
_a_color.stop();
a_color.finish();

View File

@ -56,7 +56,7 @@ protected:
void onStateChanged(int oldState, ButtonStateChangeSource source) override;
void paintEvent(QPaintEvent *e) override;
style::sysButton _st;
const style::sysButton *_st;
anim::cvalue a_color;
Animation _a_color;

View File

@ -58,7 +58,7 @@ private:
QPixmap _arrow;
QRect _inner, _arrowRect;
style::countryInput _st;
const style::countryInput &_st;
bool _active;
QString _text;

View File

@ -31,12 +31,14 @@ FlatButton::FlatButton(QWidget *parent, const QString &text, const style::flatBu
, _a_appearance(animation(this, &FlatButton::step_appearance))
, _opacity(1) {
if (_st.width < 0) {
_st.width = textWidth() - _st.width;
_width = textWidth() - _st.width;
} else if (!_st.width) {
_st.width = textWidth() + _st.height - _st.font->height;
_width = textWidth() + _st.height - _st.font->height;
} else {
_width = _st.width;
}
connect(this, SIGNAL(stateChanged(int, ButtonStateChangeSource)), this, SLOT(onStateChange(int, ButtonStateChangeSource)));
resize(_st.width, _st.height);
resize(_width, _st.height);
setCursor(_st.cursor);
}
@ -55,13 +57,13 @@ void FlatButton::setText(const QString &text) {
}
void FlatButton::setWidth(int32 w) {
_st.width = w;
if (_st.width < 0) {
_st.width = textWidth() - _st.width;
} else if (!_st.width) {
_st.width = textWidth() + _st.height - _st.font->height;
_width = w;
if (_width < 0) {
_width = textWidth() - _st.width;
} else if (!_width) {
_width = textWidth() + _st.height - _st.font->height;
}
resize(_st.width, height());
resize(_width, height());
}
int32 FlatButton::textWidth() const {

View File

@ -47,9 +47,9 @@ public slots:
private:
QString _text, _textForAutoSize;
int32 _textWidth;
int _width, _textWidth;
style::flatButton _st;
const style::flatButton &_st;
anim::cvalue a_bg, a_text;
Animation _a_appearance;
@ -79,7 +79,7 @@ public slots:
private:
QString _text;
int _textWidth = 0;
style::linkButton _st;
const style::linkButton &_st;
};

View File

@ -111,10 +111,6 @@ void FlatInput::customUpDown(bool custom) {
_customUpDown = custom;
}
void FlatInput::setTextMargins(const QMargins &mrg) {
_st.textMrg = mrg;
}
void FlatInput::onTouchTimer() {
_touchRightButton = true;
}

View File

@ -49,8 +49,6 @@ public:
return _oldtext;
}
void setTextMargins(const QMargins &mrg);
public slots:
void onTextChange(const QString &text);
void onTextEdited();
@ -104,9 +102,7 @@ private:
Animation _a_appearance;
int _notingBene;
style::flatInput _st;
style::font _font;
const style::flatInput &_st;
QTimer _touchTimer;
bool _touchPress, _touchRightButton, _touchMove;

View File

@ -109,8 +109,8 @@ private:
void showContextMenu(QContextMenuEvent *e, ContextMenuReason reason);
Text _text;
style::flatLabel _st;
style::textStyle _tst;
const style::flatLabel &_st;
const style::textStyle &_tst;
float64 _opacity = 1.;
int _allowedWidth = 0;

View File

@ -212,7 +212,7 @@ private:
std_::unique_ptr<TagMimeProcessor> _tagMimeProcessor;
style::flatTextarea _st;
const style::flatTextarea &_st;
bool _undoAvailable = false;
bool _redoAvailable = false;

View File

@ -780,11 +780,7 @@ void ScrollArea::onVerticalScroll() {
void ScrollArea::rangeChanged(int oldMax, int newMax, bool vertical) {
}
void ScrollArea::updateColors(const style::color &bar, const style::color &bg, const style::color &barOver, const style::color &bgOver) {
_st.barColor = bar;
_st.bgColor = bg;
_st.barOverColor = barOver;
_st.bgOverColor = bgOver;
void ScrollArea::updateBars() {
_horizontalBar->update();
_verticalBar->update();
}

View File

@ -179,7 +179,7 @@ public:
void rangeChanged(int oldMax, int newMax, bool vertical);
void updateColors(const style::color &bar, const style::color &bg, const style::color &barOver, const style::color &bgOver);
void updateBars();
bool focusNextPrevChild(bool next) override;
void setMovingByScrollBar(bool movingByScrollBar);
@ -239,7 +239,7 @@ private:
bool _ownsWidget = false; // if true, the widget is deleted in destructor.
bool _movingByScrollBar = false;
style::flatScroll _st;
const style::flatScroll &_st;
ChildWidget<ScrollBar> _horizontalBar, _verticalBar;
ChildWidget<ScrollShadow> _topShadow, _bottomShadow;
int _horizontalValue, _verticalValue;

View File

@ -41,9 +41,6 @@ void destroyColors() {
colorsMap.clear();
}
Color::Color(const Color &c) : ptr(c.ptr) {
}
Color::Color(ColorData *data) : ptr(data) {
}
@ -51,6 +48,14 @@ Color::Color(uchar r, uchar g, uchar b, uchar a) {
init(r, g, b, a);
}
Color::Color(Color &&other) : ptr(other.ptr) {
}
Color &Color::operator=(Color &&other) {
ptr = other.ptr;
return *this;
}
void Color::set(uchar r, uchar g, uchar b, uchar a) const {
ptr->set(r, g, b, a);
}

View File

@ -28,18 +28,50 @@ namespace internal {
void destroyColors();
class ColorData;
class Color;
class ColorData {
public:
QColor c;
QPen p;
QBrush b;
QColor transparent() const {
return QColor(c.red(), c.green(), c.blue(), 0);
}
private:
ColorData();
ColorData(uchar r, uchar g, uchar b, uchar a);
void set(uchar r, uchar g, uchar b, uchar a);
friend class Color;
friend class style::palette;
};
class Color {
public:
Color(Qt::Initialization = Qt::Uninitialized) {
}
Color(const Color &c);
Color(uchar r, uchar g, uchar b, uchar a);
Color(const Color &other) = delete;
Color &operator=(const Color &other) = delete;
Color(Color &&other);
Color &operator=(Color &&other);
Color clone() const {
return Color(ptr);
}
void set(uchar r, uchar g, uchar b, uchar a) const;
operator const QBrush &() const;
operator const QPen &() const;
operator const QBrush &() const {
return ptr->b;
}
operator const QPen &() const {
return ptr->p;
}
ColorData *operator->() const {
return ptr;
@ -62,26 +94,6 @@ private:
};
class ColorData {
public:
QColor c;
QPen p;
QBrush b;
QColor transparent() const {
return QColor(c.red(), c.green(), c.blue(), 0);
}
private:
ColorData();
ColorData(uchar r, uchar g, uchar b, uchar a);
void set(uchar r, uchar g, uchar b, uchar a);
friend class Color;
friend class style::palette;
};
inline bool operator==(const Color &a, const Color &b) {
return a->c == b->c;
}
@ -90,13 +102,6 @@ inline bool operator!=(const Color &a, const Color &b) {
return a->c != b->c;
}
inline Color::operator const QBrush &() const {
return ptr->b;
}
inline Color::operator const QPen &() const {
return ptr->p;
}
} // namespace internal
inline QColor interpolate(QColor a, QColor b, float64 opacity_b) {

View File

@ -74,9 +74,9 @@ QImage createIconMask(const IconMask *mask) {
} // namespace
MonoIcon::MonoIcon(const IconMask *mask, const Color &color, QPoint offset)
MonoIcon::MonoIcon(const IconMask *mask, Color &&color, QPoint offset)
: _mask(mask)
, _color(color)
, _color(std_::move(color))
, _offset(offset) {
}

View File

@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#pragma once
#include "ui/style/style_core_color.h"
#include "core/vector_of_moveable.h"
namespace style {
namespace internal {
@ -48,7 +49,11 @@ private:
class MonoIcon {
public:
MonoIcon() = default;
MonoIcon(const IconMask *mask, const Color &color, QPoint offset);
MonoIcon(const MonoIcon &other) = delete;
MonoIcon &operator=(const MonoIcon &other) = delete;
MonoIcon(MonoIcon &&other) = default;
MonoIcon &operator=(MonoIcon &&other) = default;
MonoIcon(const IconMask *mask, Color &&color, QPoint offset);
void reset() const;
int width() const;
@ -82,10 +87,10 @@ private:
class IconData {
public:
template <typename ...MonoIcons>
IconData(const MonoIcons &...icons) {
IconData(MonoIcons &&...icons) {
created();
_parts.reserve(sizeof...(MonoIcons));
addIcons(icons...);
addIcons(std_::forward<MonoIcons>(icons)...);
}
void reset() {
@ -122,12 +127,12 @@ private:
}
template <typename ... MonoIcons>
void addIcons(const MonoIcon &icon, const MonoIcons&... icons) {
_parts.push_back(icon);
addIcons(icons...);
void addIcons(MonoIcon &&icon, MonoIcons&&... icons) {
_parts.push_back(std_::move(icon));
addIcons(std_::forward<MonoIcons>(icons)...);
}
QVector<MonoIcon> _parts;
std_::vector_of_moveable<MonoIcon> _parts;
mutable int _width = -1;
mutable int _height = -1;
@ -139,7 +144,7 @@ public:
}
template <typename ... MonoIcons>
Icon(const MonoIcons&... icons) : _data(new IconData(icons...)), _owner(true) {
Icon(MonoIcons&&... icons) : _data(new IconData(std_::forward<MonoIcons>(icons)...)), _owner(true) {
}
Icon(const Icon &other) : _data(other._data) {
}

View File

@ -91,18 +91,6 @@ QString textcmdLink(const QString &url, const QString &text) {
return result.append(textcmdStartLink(url)).append(text).append(textcmdStopLink());
}
QString textcmdStartColor(const style::color &color) {
QString result;
result.reserve(7);
return result.append(TextCommand).append(QChar(TextCommandColor)).append(QChar(color->c.red())).append(QChar(color->c.green())).append(QChar(color->c.blue())).append(QChar(color->c.alpha())).append(TextCommand);
}
QString textcmdStopColor() {
QString result;
result.reserve(3);
return result.append(TextCommand).append(QChar(TextCommandNoColor)).append(TextCommand);
}
QString textcmdStartSemibold() {
QString result;
result.reserve(3);
@ -132,7 +120,6 @@ const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink)
case TextCommandNoItalic:
case TextCommandUnderline:
case TextCommandNoUnderline:
case TextCommandNoColor:
break;
case TextCommandLinkIndex:
@ -146,15 +133,6 @@ const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink)
result += len + 1;
} break;
case TextCommandColor: {
const QChar *e = result + 4;
if (e >= end) return from;
for (; result < e; ++result) {
if (result->unicode() >= 256) return from;
}
} break;
case TextCommandSkipBlock:
result += 2;
break;
@ -216,13 +194,13 @@ public:
}
lastSkipped = false;
if (emoji) {
_t->_blocks.push_back(new EmojiBlock(_t->_font, _t->_text, blockStart, len, flags, color, lnkIndex, emoji));
_t->_blocks.push_back(new EmojiBlock(_t->_font, _t->_text, blockStart, len, flags, lnkIndex, emoji));
emoji = 0;
lastSkipped = true;
} else if (newline) {
_t->_blocks.push_back(new NewlineBlock(_t->_font, _t->_text, blockStart, len));
} else {
_t->_blocks.push_back(new TextBlock(_t->_font, _t->_text, _t->_minResizeWidth, blockStart, len, flags, color, lnkIndex));
_t->_blocks.push_back(new TextBlock(_t->_font, _t->_text, _t->_minResizeWidth, blockStart, len, flags, lnkIndex));
}
blockStart += len;
blockCreated();
@ -451,24 +429,9 @@ public:
lnkIndex = 0x8000 + links.size();
} break;
case TextCommandColor: {
style::color c(ptr->unicode(), (ptr + 1)->unicode(), (ptr + 2)->unicode(), (ptr + 3)->unicode());
if (color != c) {
createBlock();
color = c;
}
} break;
case TextCommandSkipBlock:
createSkipBlock(ptr->unicode(), (ptr + 1)->unicode());
break;
case TextCommandNoColor:
if (color) {
createBlock();
color = style::color();
}
break;
}
ptr = afterCmd;
@ -747,7 +710,6 @@ private:
int32 diacs; // diac chars skipped without good char
QFixed sumWidth, stopAfterWidth; // summary width of all added words
bool sumFinished, newlineAwaited;
style::color color; // current color, could be invalid
// current char data
QChar ch; // current char (low surrogate, if current char is surrogate pair)
@ -1177,9 +1139,6 @@ public:
}
const QPen &blockPen(ITextBlock *block) {
if (block->color()) {
return block->color()->p;
}
if (block->lnkIndex()) {
if (ClickHandler::showAsPressed(_t->_links.at(block->lnkIndex() - 1))) {
return _textStyle->linkFgDown->p;
@ -1581,7 +1540,7 @@ public:
_elideSavedIndex = blockIndex;
_elideSavedBlock = _t->_blocks[blockIndex];
const_cast<Text*>(_t)->_blocks[blockIndex] = new TextBlock(_t->_font, _t->_text, QFIXED_MAX, elideStart, 0, _elideSavedBlock->flags(), _elideSavedBlock->color(), _elideSavedBlock->lnkIndex());
const_cast<Text*>(_t)->_blocks[blockIndex] = new TextBlock(_t->_font, _t->_text, QFIXED_MAX, elideStart, 0, _elideSavedBlock->flags(), _elideSavedBlock->lnkIndex());
_blocksSize = blockIndex + 1;
_endBlock = (blockIndex + 1 < _t->_blocks.size() ? _t->_blocks[blockIndex + 1] : 0);
}

View File

@ -38,8 +38,6 @@ enum TextCommands {
TextCommandNoSemibold = 0x08,
TextCommandLinkIndex = 0x09, // 0 - NoLink
TextCommandLinkText = 0x0A,
TextCommandColor = 0x0B,
TextCommandNoColor = 0x0C,
TextCommandSkipBlock = 0x0D,
TextCommandLangTag = 0x20,
@ -279,8 +277,6 @@ QString textcmdStartLink(const QString &url);
QString textcmdStopLink();
QString textcmdLink(ushort lnkIndex, const QString &text);
QString textcmdLink(const QString &url, const QString &text);
QString textcmdStartColor(const style::color &color);
QString textcmdStopColor();
QString textcmdStartSemibold();
QString textcmdStopSemibold();
const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink = true);

View File

@ -300,7 +300,7 @@ QFixed ITextBlock::f_rbearing() const {
return (type() == TextBlockTText) ? static_cast<const TextBlock*>(this)->real_f_rbearing() : 0;
}
TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, const style::color &color, uint16 lnkIndex) : ITextBlock(font, str, from, length, flags, color, lnkIndex) {
TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, uint16 lnkIndex) : ITextBlock(font, str, from, length, flags, lnkIndex) {
_flags |= ((TextBlockTText & 0x0F) << 8);
if (length) {
style::font blockFont = font;
@ -343,12 +343,12 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi
}
}
EmojiBlock::EmojiBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, const style::color &color, uint16 lnkIndex, const EmojiData *emoji) : ITextBlock(font, str, from, length, flags, color, lnkIndex), emoji(emoji) {
EmojiBlock::EmojiBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex, const EmojiData *emoji) : ITextBlock(font, str, from, length, flags, lnkIndex), emoji(emoji) {
_flags |= ((TextBlockTEmoji & 0x0F) << 8);
_width = int(st::emojiSize + 2 * st::emojiPadding);
}
SkipBlock::SkipBlock(const style::font &font, const QString &str, uint16 from, int32 w, int32 h, uint16 lnkIndex) : ITextBlock(font, str, from, 1, 0, style::color(), lnkIndex), _height(h) {
SkipBlock::SkipBlock(const style::font &font, const QString &str, uint16 from, int32 w, int32 h, uint16 lnkIndex) : ITextBlock(font, str, from, 1, 0, lnkIndex), _height(h) {
_flags |= ((TextBlockTSkip & 0x0F) << 8);
_width = w;
}

View File

@ -41,8 +41,7 @@ enum TextBlockFlags {
class ITextBlock {
public:
ITextBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, const style::color &color, uint16 lnkIndex) : _from(from), _flags((flags & 0xFF) | ((lnkIndex & 0xFFFF) << 12))/*, _color(color)*/, _lpadding(0) {
ITextBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex) : _from(from), _flags((flags & 0xFF) | ((lnkIndex & 0xFFFF) << 12)), _lpadding(0) {
if (length) {
if (str.at(_from + length - 1).unicode() == QChar::Space) {
_rpadding = font->spacew;
@ -91,10 +90,6 @@ public:
int32 flags() const {
return (_flags & 0xFF);
}
const style::color &color() const {
static style::color tmp;
return tmp;//_color;
}
virtual ITextBlock *clone() const = 0;
virtual ~ITextBlock() {
@ -121,7 +116,7 @@ public:
}
private:
NewlineBlock(const style::font &font, const QString &str, uint16 from, uint16 length) : ITextBlock(font, str, from, length, 0, st::windowTextFg, 0), _nextDir(Qt::LayoutDirectionAuto) {
NewlineBlock(const style::font &font, const QString &str, uint16 from, uint16 length) : ITextBlock(font, str, from, length, 0, 0), _nextDir(Qt::LayoutDirectionAuto) {
_flags |= ((TextBlockTNewline & 0x0F) << 8);
}
@ -175,7 +170,7 @@ public:
private:
TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, const style::color &color, uint16 lnkIndex);
TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, uint16 lnkIndex);
friend class ITextBlock;
QFixed real_f_rbearing() const {
@ -201,7 +196,7 @@ public:
private:
EmojiBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, const style::color &color, uint16 lnkIndex, const EmojiData *emoji);
EmojiBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex, const EmojiData *emoji);
const EmojiData *emoji;

View File

@ -307,6 +307,90 @@ QImage prepareBackgroundImage(QImage &&image) {
return std_::move(image);
}
void initColorsFromBackground(const QImage &img) {
uint64 components[3] = { 0 }, componentsScroll[3] = { 0 };
auto w = img.width();
auto h = img.height();
auto size = w * h;
if (auto pix = img.constBits()) {
for (int i = 0, l = size * 4; i != l; i += 4) {
components[2] += pix[i + 0];
components[1] += pix[i + 1];
components[0] += pix[i + 2];
}
}
if (size) {
for (int i = 0; i != 3; ++i) {
components[i] /= size;
}
}
int maxtomin[3] = { 0, 1, 2 };
if (components[maxtomin[0]] < components[maxtomin[1]]) {
qSwap(maxtomin[0], maxtomin[1]);
}
if (components[maxtomin[1]] < components[maxtomin[2]]) {
qSwap(maxtomin[1], maxtomin[2]);
if (components[maxtomin[0]] < components[maxtomin[1]]) {
qSwap(maxtomin[0], maxtomin[1]);
}
}
uint64 max = qMax(1ULL, components[maxtomin[0]]), mid = qMax(1ULL, components[maxtomin[1]]), min = qMax(1ULL, components[maxtomin[2]]);
memcpy(componentsScroll, components, sizeof(components));
if (max != min) {
if (min > uint64(qRound(0.77 * max))) {
uint64 newmin = qRound(0.77 * max); // min saturation 23%
uint64 newmid = max - ((max - mid) * (max - newmin)) / (max - min);
components[maxtomin[1]] = newmid;
components[maxtomin[2]] = newmin;
}
uint64 newmin = qRound(0.77 * max); // saturation 23% for scroll
uint64 newmid = max - ((max - mid) * (max - newmin)) / (max - min);
componentsScroll[maxtomin[1]] = newmid;
componentsScroll[maxtomin[2]] = newmin;
}
float64 luminance = 0.299 * componentsScroll[0] + 0.587 * componentsScroll[1] + 0.114 * componentsScroll[2];
uint64 maxScroll = max;
if (luminance < 0.5 * 0xFF) {
maxScroll += qRound(0.2 * 0xFF);
} else {
maxScroll -= qRound(0.2 * 0xFF);
}
componentsScroll[maxtomin[2]] = qMin(uint64(float64(componentsScroll[maxtomin[2]]) * maxScroll / float64(componentsScroll[maxtomin[0]])), 0xFFULL);
componentsScroll[maxtomin[1]] = qMin(uint64(float64(componentsScroll[maxtomin[1]]) * maxScroll / float64(componentsScroll[maxtomin[0]])), 0xFFULL);
componentsScroll[maxtomin[0]] = qMin(maxScroll, 0xFFULL);
if (max > uint64(qRound(0.2 * 0xFF))) { // brightness greater than 20%
max -= qRound(0.2 * 0xFF);
} else {
max = 0;
}
components[maxtomin[2]] = uint64(float64(components[maxtomin[2]]) * max / float64(components[maxtomin[0]]));
components[maxtomin[1]] = uint64(float64(components[maxtomin[1]]) * max / float64(components[maxtomin[0]]));
components[maxtomin[0]] = max;
uchar r = uchar(components[0]);
uchar g = uchar(components[1]);
uchar b = uchar(components[2]);
st::msgServiceBg.set(r, g, b, st::msgServiceBg->c.alpha());
float64 alphaSel = st::msgServiceSelectBg->c.alphaF(), addSel = (1. - ((1. - alphaSel) / (1. - st::msgServiceBg->c.alphaF()))) * 0xFF;
uchar rsel = snap(qRound(((1. - alphaSel) * r + addSel) / alphaSel), 0, 0xFF);
uchar gsel = snap(qRound(((1. - alphaSel) * g + addSel) / alphaSel), 0, 0xFF);
uchar bsel = snap(qRound(((1. - alphaSel) * b + addSel) / alphaSel), 0, 0xFF);
st::msgServiceSelectBg.set(r, g, b, qRound(alphaSel * 0xFF));
uchar rScroll = uchar(componentsScroll[0]), gScroll = uchar(componentsScroll[1]), bScroll = uchar(componentsScroll[2]);
st::historyScroll.barColor.set(rScroll, gScroll, bScroll, st::historyScroll.barColor->c.alpha());
st::historyScroll.bgColor.set(rScroll, gScroll, bScroll, st::historyScroll.bgColor->c.alpha());
st::historyScroll.barOverColor.set(rScroll, gScroll, bScroll, st::historyScroll.barOverColor->c.alpha());
st::historyScroll.bgOverColor.set(rScroll, gScroll, bScroll, st::historyScroll.bgOverColor->c.alpha());
}
} // namespace
void ChatBackground::setThemeData(QImage &&themeImage, bool themeTile) {
@ -354,7 +438,7 @@ void ChatBackground::setImage(int32 id, QImage &&image) {
}
void ChatBackground::setPreparedImage(QImage &&image) {
App::initColorsFromBackground(image);
initColorsFromBackground(image);
_image = App::pixmapFromImageInPlace(std_::move(image));
}

View File

@ -3,4 +3,4 @@ AppVersionStrMajor 0.10
AppVersionStrSmall 0.10.20
AppVersionStr 0.10.20
AlphaChannel 0
BetaVersion 0
BetaVersion 10019001