Allow duplicating icons with different palettes.

This commit is contained in:
John Preston 2021-08-27 23:43:50 +03:00
parent 15ffd051d6
commit 3c95a91871
2 changed files with 51 additions and 6 deletions

View file

@ -8,6 +8,7 @@
#include "ui/style/style_core.h"
#include "base/basic_types.h"
#include "styles/palette.h"
#include <QtGui/QPainter>
@ -21,7 +22,7 @@ uint32 colorKey(QColor c) {
base::flat_map<const IconMask*, QImage> iconMasks;
base::flat_map<QPair<const IconMask*, uint32>, QPixmap> iconPixmaps;
OrderedSet<IconData*> iconData;
base::flat_set<IconData*> iconData;
QImage createIconMask(const IconMask *mask, int scale) {
auto maskImage = QImage::fromData(mask->data(), mask->size(), "PNG");
@ -86,6 +87,14 @@ QSize readGeneratedSize(const IconMask *mask, int scale) {
} // namespace
MonoIcon::MonoIcon(const MonoIcon &other, const style::palette &palette)
: _mask(other._mask)
, _color(
palette.colorAtIndex(
style::main_palette::indexOfColor(other._color)))
, _offset(other._offset) {
}
MonoIcon::MonoIcon(const IconMask *mask, Color color, QPoint offset)
: _mask(mask)
, _color(std::move(color))
@ -279,8 +288,20 @@ void MonoIcon::createCachedPixmap() const {
_size = _pixmap.size() / DevicePixelRatio();
}
IconData::IconData(const IconData &other, const style::palette &palette) {
created();
_parts.reserve(other._parts.size());
for (const auto &part : other._parts) {
_parts.push_back(MonoIcon(part, palette));
}
}
void IconData::created() {
iconData.insert(this);
iconData.emplace(this);
}
IconData::~IconData() {
iconData.remove(this);
}
void IconData::fill(QPainter &p, const QRect &rect) const {
@ -306,7 +327,8 @@ void IconData::fill(QPainter &p, const QRect &rect, QColor colorOverride) const
}
QImage IconData::instance(QColor colorOverride, int scale) const {
Assert(_parts.size() == 1);
Expects(_parts.size() == 1);
auto &part = _parts[0];
Assert(part.offset() == QPoint(0, 0));
return part.instance(colorOverride, scale);
@ -332,6 +354,15 @@ int IconData::height() const {
return _height;
}
Icon Icon::withPalette(const style::palette &palette) const {
Expects(_data != nullptr);
auto result = Icon(Qt::Uninitialized);
result._data = new IconData(*_data, palette);
result._owner = true;
return result;
}
void resetIcons() {
iconPixmaps.clear();
for (const auto data : iconData) {

View file

@ -43,6 +43,7 @@ public:
MonoIcon &operator=(const MonoIcon &other) = delete;
MonoIcon(MonoIcon &&other) = default;
MonoIcon &operator=(MonoIcon &&other) = default;
MonoIcon(const MonoIcon &other, const style::palette &palette);
MonoIcon(const IconMask *mask, Color color, QPoint offset);
void reset() const;
@ -82,13 +83,18 @@ private:
class IconData {
public:
struct FromIcons {
};
template <typename ...MonoIcons>
IconData(MonoIcons &&...icons) {
IconData(FromIcons, MonoIcons &&...icons) {
created();
_parts.reserve(sizeof...(MonoIcons));
addIcons(std::forward<MonoIcons>(icons)...);
}
IconData(const IconData &other, const style::palette &palette);
~IconData();
void reset() {
for (const auto &part : _parts) {
part.reset();
@ -149,11 +155,17 @@ public:
}
template <typename ... MonoIcons>
Icon(MonoIcons&&... icons) : _data(new IconData(std::forward<MonoIcons>(icons)...)), _owner(true) {
Icon(MonoIcons&&... icons)
: _data(new IconData(
IconData::FromIcons{},
std::forward<MonoIcons>(icons)...))
, _owner(true) {
}
Icon(const Icon &other) : _data(other._data) {
}
Icon(Icon &&other) : _data(base::take(other._data)), _owner(base::take(other._owner)) {
Icon(Icon &&other)
: _data(base::take(other._data))
, _owner(base::take(other._owner)) {
}
Icon &operator=(const Icon &other) {
Expects(!_owner);
@ -247,6 +259,8 @@ public:
return Proxy(*this, paletteOverride);
}
Icon withPalette(const style::palette &palette) const;
~Icon() {
if (auto data = base::take(_data)) {
if (_owner) {