From 21eb3509bcf6f2fe1c99f444dcdda82d8767e3c4 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 29 Nov 2020 09:34:19 +0300 Subject: [PATCH] Added icon cross line animation. --- CMakeLists.txt | 2 ++ ui/effects/cross_line.cpp | 64 +++++++++++++++++++++++++++++++++++++++ ui/effects/cross_line.h | 34 +++++++++++++++++++++ ui/widgets/widgets.style | 8 +++++ 4 files changed, 108 insertions(+) create mode 100644 ui/effects/cross_line.cpp create mode 100644 ui/effects/cross_line.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 47285df..8bd2451 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,8 @@ PRIVATE ui/effects/animations.h ui/effects/cross_animation.cpp ui/effects/cross_animation.h + ui/effects/cross_line.cpp + ui/effects/cross_line.h ui/effects/fade_animation.cpp ui/effects/fade_animation.h ui/effects/numbers_animation.cpp diff --git a/ui/effects/cross_line.cpp b/ui/effects/cross_line.cpp new file mode 100644 index 0000000..5bede5b --- /dev/null +++ b/ui/effects/cross_line.cpp @@ -0,0 +1,64 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#include "ui/effects/cross_line.h" + +#include "ui/painter.h" + +namespace Ui { + +CrossLineAnimation::CrossLineAnimation( + const style::CrossLineAnimation &st, + float angle) +: _st(st) +, _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.setAngle(angle); +} + +void CrossLineAnimation::paint( + Painter &p, + int left, + int top, + float64 progress) { + if (progress == 0.) { + _st.icon.paint(p, left, top, _st.icon.width()); + } else if (progress == 1.) { + p.drawImage(left, top, _completeCross); + } else { + p.drawImage(left, top, image(progress)); + } +} + +QImage CrossLineAnimation::image(float64 progress) const { + 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); + + auto topLine = _line; + topLine.setLength(topLine.length() * progress); + auto bottomLine = topLine.translated(0, _strokePen.widthF() + 1); + + Painter q(&frame); + PainterHighQualityEnabler hq(q); + _st.icon.paint(q, 0, 0, _st.icon.width()); + + q.setPen(_strokePen); + q.drawLine(bottomLine); + + q.setCompositionMode(QPainter::CompositionMode_Source); + q.setPen(_transparentPen); + q.drawLine(topLine); + + return frame; +} + +} // namespace Ui diff --git a/ui/effects/cross_line.h b/ui/effects/cross_line.h new file mode 100644 index 0000000..eb6edb5 --- /dev/null +++ b/ui/effects/cross_line.h @@ -0,0 +1,34 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#pragma once + +#include "styles/style_widgets.h" + +class Painter; + +namespace Ui { + +class CrossLineAnimation { +public: + CrossLineAnimation( + const style::CrossLineAnimation &st, + float angle = 315); + + void paint(Painter &p, int left, int top, float64 progress); + +private: + QImage image(float64 progress) const; + + const style::CrossLineAnimation &_st; + const QPen _transparentPen; + const QPen _strokePen; + QLineF _line; + const QImage _completeCross; + +}; + +} // namespace Ui diff --git a/ui/widgets/widgets.style b/ui/widgets/widgets.style index aa57e61..0d2ffcd 100644 --- a/ui/widgets/widgets.style +++ b/ui/widgets/widgets.style @@ -400,6 +400,14 @@ CrossButton { ripple: RippleAnimation; } +CrossLineAnimation { + fg: color; + icon: icon; + startPosition: point; + endPosition: point; + stroke: pixels; +} + MultiSelectItem { padding: margins; maxWidth: pixels;