diff --git a/ui/effects/cross_line.cpp b/ui/effects/cross_line.cpp index 2241fe1..4c70455 100644 --- a/ui/effects/cross_line.cpp +++ b/ui/effects/cross_line.cpp @@ -18,56 +18,82 @@ CrossLineAnimation::CrossLineAnimation( , _reversed(reversed) , _transparentPen(Qt::transparent, st.stroke, Qt::SolidLine, Qt::RoundCap) , _strokePen(st.fg, st.stroke, Qt::SolidLine, Qt::RoundCap) -, _line(st.startPosition, st.endPosition) -, _completeCross(image(1.)) { +, _line(st.startPosition, st.endPosition) { _line.setAngle(angle); } void CrossLineAnimation::paint( Painter &p, QPoint position, - float64 progress) { - paint(p, position.x(), position.y(), progress); + float64 progress, + std::optional colorOverride) { + paint(p, position.x(), position.y(), progress, colorOverride); } void CrossLineAnimation::paint( Painter &p, int left, int top, - float64 progress) { + float64 progress, + std::optional colorOverride) { if (progress == 0.) { - _st.icon.paint(p, left, top, _st.icon.width()); + if (colorOverride) { + _st.icon.paint(p, left, top, _st.icon.width(), *colorOverride); + } else { + _st.icon.paint(p, left, top, _st.icon.width()); + } } else if (progress == 1.) { + if (_completeCross.isNull()) { + fillFrame(progress, colorOverride); + _completeCross = _frame; + } p.drawImage(left, top, _completeCross); } else { - p.drawImage(left, top, image(progress)); + fillFrame(progress, colorOverride); + p.drawImage(left, top, _frame); } } -QImage CrossLineAnimation::image(float64 progress) const { +void CrossLineAnimation::fillFrame( + float64 progress, + std::optional colorOverride) { const auto ratio = style::DevicePixelRatio(); - auto frame = QImage( - QSize(_st.icon.width() * ratio, _st.icon.height() * ratio), - QImage::Format_ARGB32_Premultiplied); - frame.setDevicePixelRatio(ratio); - frame.fill(Qt::transparent); + if (_frame.isNull()) { + _frame = QImage( + _st.icon.size() * ratio, + QImage::Format_ARGB32_Premultiplied); + _frame.setDevicePixelRatio(ratio); + } + _frame.fill(Qt::transparent); auto topLine = _line; topLine.setLength(topLine.length() * progress); auto bottomLine = topLine.translated(0, _strokePen.widthF() + 1); - Painter q(&frame); + Painter q(&_frame); PainterHighQualityEnabler hq(q); - _st.icon.paint(q, 0, 0, _st.icon.width()); + if (colorOverride) { + _st.icon.paint(q, 0, 0, _st.icon.width(), *colorOverride); + } else { + _st.icon.paint(q, 0, 0, _st.icon.width()); + } - q.setPen(_strokePen); + if (colorOverride) { + auto pen = _strokePen; + pen.setColor(*colorOverride); + q.setPen(pen); + } else { + q.setPen(_strokePen); + } q.drawLine(_reversed ? topLine : bottomLine); q.setCompositionMode(QPainter::CompositionMode_Source); q.setPen(_transparentPen); q.drawLine(_reversed ? bottomLine : topLine); +} - return frame; +void CrossLineAnimation::invalidate() { + _completeCross = QImage(); } } // namespace Ui diff --git a/ui/effects/cross_line.h b/ui/effects/cross_line.h index 0f21e51..d1336c7 100644 --- a/ui/effects/cross_line.h +++ b/ui/effects/cross_line.h @@ -19,18 +19,30 @@ public: bool reversed = false, float angle = 315); - void paint(Painter &p, QPoint position, float64 progress); - void paint(Painter &p, int left, int top, float64 progress); + void paint( + Painter &p, + QPoint position, + float64 progress, + std::optional colorOverride = std::nullopt); + void paint( + Painter &p, + int left, + int top, + float64 progress, + std::optional colorOverride = std::nullopt); + + void invalidate(); private: - QImage image(float64 progress) const; + void fillFrame(float64 progress, std::optional colorOverride); const style::CrossLineAnimation &_st; const bool _reversed; const QPen _transparentPen; const QPen _strokePen; QLineF _line; - const QImage _completeCross; + QImage _frame; + QImage _completeCross; }; diff --git a/ui/widgets/call_mute_button.cpp b/ui/widgets/call_mute_button.cpp index ac08ca9..3892154 100644 --- a/ui/widgets/call_mute_button.cpp +++ b/ui/widgets/call_mute_button.cpp @@ -258,6 +258,11 @@ CallMuteButton::CallMuteButton( , _colors(Colors()) , _crossLineMuteAnimation(st::callMuteCrossLine) { init(); + + style::PaletteChanged( + ) | rpl::start_with_next([=] { + _crossLineMuteAnimation.invalidate(); + }, lifetime()); } void CallMuteButton::init() {