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

View file

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