Allow colorizing CrossLineAnimation.

This commit is contained in:
John Preston 2020-12-02 15:25:02 +03:00
parent 87ee83bc73
commit ab4ad89c4c
3 changed files with 64 additions and 21 deletions

View file

@ -18,56 +18,82 @@ CrossLineAnimation::CrossLineAnimation(
, _reversed(reversed) , _reversed(reversed)
, _transparentPen(Qt::transparent, st.stroke, Qt::SolidLine, Qt::RoundCap) , _transparentPen(Qt::transparent, st.stroke, Qt::SolidLine, Qt::RoundCap)
, _strokePen(st.fg, st.stroke, Qt::SolidLine, Qt::RoundCap) , _strokePen(st.fg, st.stroke, Qt::SolidLine, Qt::RoundCap)
, _line(st.startPosition, st.endPosition) , _line(st.startPosition, st.endPosition) {
, _completeCross(image(1.)) {
_line.setAngle(angle); _line.setAngle(angle);
} }
void CrossLineAnimation::paint( void CrossLineAnimation::paint(
Painter &p, Painter &p,
QPoint position, QPoint position,
float64 progress) { float64 progress,
paint(p, position.x(), position.y(), progress); std::optional<QColor> colorOverride) {
paint(p, position.x(), position.y(), progress, colorOverride);
} }
void CrossLineAnimation::paint( void CrossLineAnimation::paint(
Painter &p, Painter &p,
int left, int left,
int top, int top,
float64 progress) { float64 progress,
std::optional<QColor> colorOverride) {
if (progress == 0.) { 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.) { } else if (progress == 1.) {
if (_completeCross.isNull()) {
fillFrame(progress, colorOverride);
_completeCross = _frame;
}
p.drawImage(left, top, _completeCross); p.drawImage(left, top, _completeCross);
} else { } 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<QColor> colorOverride) {
const auto ratio = style::DevicePixelRatio(); const auto ratio = style::DevicePixelRatio();
auto frame = QImage( if (_frame.isNull()) {
QSize(_st.icon.width() * ratio, _st.icon.height() * ratio), _frame = QImage(
QImage::Format_ARGB32_Premultiplied); _st.icon.size() * ratio,
frame.setDevicePixelRatio(ratio); QImage::Format_ARGB32_Premultiplied);
frame.fill(Qt::transparent); _frame.setDevicePixelRatio(ratio);
}
_frame.fill(Qt::transparent);
auto topLine = _line; auto topLine = _line;
topLine.setLength(topLine.length() * progress); topLine.setLength(topLine.length() * progress);
auto bottomLine = topLine.translated(0, _strokePen.widthF() + 1); auto bottomLine = topLine.translated(0, _strokePen.widthF() + 1);
Painter q(&frame); Painter q(&_frame);
PainterHighQualityEnabler hq(q); 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.drawLine(_reversed ? topLine : bottomLine);
q.setCompositionMode(QPainter::CompositionMode_Source); q.setCompositionMode(QPainter::CompositionMode_Source);
q.setPen(_transparentPen); q.setPen(_transparentPen);
q.drawLine(_reversed ? bottomLine : topLine); q.drawLine(_reversed ? bottomLine : topLine);
}
return frame; void CrossLineAnimation::invalidate() {
_completeCross = QImage();
} }
} // namespace Ui } // namespace Ui

View file

@ -19,18 +19,30 @@ public:
bool reversed = false, bool reversed = false,
float angle = 315); float angle = 315);
void paint(Painter &p, QPoint position, float64 progress); void paint(
void paint(Painter &p, int left, int top, float64 progress); Painter &p,
QPoint position,
float64 progress,
std::optional<QColor> colorOverride = std::nullopt);
void paint(
Painter &p,
int left,
int top,
float64 progress,
std::optional<QColor> colorOverride = std::nullopt);
void invalidate();
private: private:
QImage image(float64 progress) const; void fillFrame(float64 progress, std::optional<QColor> colorOverride);
const style::CrossLineAnimation &_st; const style::CrossLineAnimation &_st;
const bool _reversed; const bool _reversed;
const QPen _transparentPen; const QPen _transparentPen;
const QPen _strokePen; const QPen _strokePen;
QLineF _line; QLineF _line;
const QImage _completeCross; QImage _frame;
QImage _completeCross;
}; };

View file

@ -258,6 +258,11 @@ CallMuteButton::CallMuteButton(
, _colors(Colors()) , _colors(Colors())
, _crossLineMuteAnimation(st::callMuteCrossLine) { , _crossLineMuteAnimation(st::callMuteCrossLine) {
init(); init();
style::PaletteChanged(
) | rpl::start_with_next([=] {
_crossLineMuteAnimation.invalidate();
}, lifetime());
} }
void CallMuteButton::init() { void CallMuteButton::init() {