From 3c95a9187194c07fda409f1ad1e142232bb82cbc Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 27 Aug 2021 23:43:50 +0300 Subject: [PATCH] Allow duplicating icons with different palettes. --- ui/style/style_core_icon.cpp | 37 +++++++++++++++++++++++++++++++++--- ui/style/style_core_icon.h | 20 ++++++++++++++++--- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/ui/style/style_core_icon.cpp b/ui/style/style_core_icon.cpp index 246da6c..09b7c21 100644 --- a/ui/style/style_core_icon.cpp +++ b/ui/style/style_core_icon.cpp @@ -8,6 +8,7 @@ #include "ui/style/style_core.h" #include "base/basic_types.h" +#include "styles/palette.h" #include @@ -21,7 +22,7 @@ uint32 colorKey(QColor c) { base::flat_map iconMasks; base::flat_map, QPixmap> iconPixmaps; -OrderedSet iconData; +base::flat_set 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) { diff --git a/ui/style/style_core_icon.h b/ui/style/style_core_icon.h index f5c3f59..a9707ca 100644 --- a/ui/style/style_core_icon.h +++ b/ui/style/style_core_icon.h @@ -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 - IconData(MonoIcons &&...icons) { + IconData(FromIcons, MonoIcons &&...icons) { created(); _parts.reserve(sizeof...(MonoIcons)); addIcons(std::forward(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 - Icon(MonoIcons&&... icons) : _data(new IconData(std::forward(icons)...)), _owner(true) { + Icon(MonoIcons&&... icons) + : _data(new IconData( + IconData::FromIcons{}, + std::forward(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) {