resources popout refresh + new components & reskinned old components
This commit is contained in:
@@ -1,20 +1,22 @@
|
||||
qml_module(ZShell-internal
|
||||
URI ZShell.Internal
|
||||
SOURCES
|
||||
hyprextras.hpp hyprextras.cpp
|
||||
hyprdevices.hpp hyprdevices.cpp
|
||||
cachingimagemanager.hpp cachingimagemanager.cpp
|
||||
URI ZShell.Internal
|
||||
SOURCES
|
||||
hyprextras.hpp hyprextras.cpp
|
||||
hyprdevices.hpp hyprdevices.cpp
|
||||
cachingimagemanager.hpp cachingimagemanager.cpp
|
||||
circularindicatormanager.hpp circularindicatormanager.cpp
|
||||
circularbuffer.hpp circularbuffer.cpp
|
||||
sparklineitem.hpp sparklineitem.cpp
|
||||
arcgauge.hpp arcgauge.cpp
|
||||
wallpaperimage.hpp wallpaperimage.cpp
|
||||
lidwatcher.hpp lidwatcher.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Quick
|
||||
Qt::Concurrent
|
||||
Qt::Core
|
||||
visualizerbars.hpp visualizerbars.cpp
|
||||
linearindicatormanager.hpp linearindicatormanager.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Quick
|
||||
Qt::Concurrent
|
||||
Qt::Core
|
||||
Qt::Network
|
||||
Qt::DBus
|
||||
)
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
#include "linearindicatormanager.hpp"
|
||||
|
||||
#include <qpoint.h>
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int TOTAL_DURATION_IN_MS = 1800;
|
||||
constexpr std::array DURATION_TO_MOVE_SEGMENT_ENDS = { 533, 567, 850, 750 };
|
||||
constexpr std::array DELAY_TO_MOVE_SEGMENT_ENDS = { 1267, 1000, 333, 0 };
|
||||
|
||||
QEasingCurve curve(const QPointF& c1, const QPointF& c2) {
|
||||
QEasingCurve curve(QEasingCurve::BezierSpline);
|
||||
curve.addCubicBezierSegment(c1, c2, { 1.0, 1.0 });
|
||||
return curve;
|
||||
}
|
||||
|
||||
qreal getFractionInRange(qreal playtime, int start, int duration) {
|
||||
const auto fraction = static_cast<qreal>(playtime - start) / duration;
|
||||
return std::clamp(fraction, 0.0, 1.0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace ZShell::controls {
|
||||
|
||||
LinearIndicatorSegment::LinearIndicatorSegment(int gap, QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_startFraction(0)
|
||||
, m_endFraction(0)
|
||||
, m_gapSize(gap) {
|
||||
}
|
||||
|
||||
qreal LinearIndicatorSegment::startFraction() const {
|
||||
return m_startFraction;
|
||||
}
|
||||
|
||||
qreal LinearIndicatorSegment::endFraction() const {
|
||||
return m_endFraction;
|
||||
}
|
||||
|
||||
int LinearIndicatorSegment::gapSize() const {
|
||||
return m_gapSize;
|
||||
}
|
||||
|
||||
LinearIndicatorManager::LinearIndicatorManager(QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_interpolators({
|
||||
curve({ 0.2, 0.0 }, { 0.8, 1.0 }),
|
||||
curve({ 0.4, 0.0 }, { 1.0, 1.0 }),
|
||||
curve({ 0.0, 0.0 }, { 0.65, 1.0 }),
|
||||
curve({ 0.1, 0.0 }, { 0.45, 1.0 }),
|
||||
})
|
||||
, m_progress(0)
|
||||
, m_completeEndProgress(0)
|
||||
, m_gap(4)
|
||||
, m_activeIndicators({
|
||||
new LinearIndicatorSegment(m_gap, this),
|
||||
new LinearIndicatorSegment(m_gap, this),
|
||||
}) {
|
||||
for (auto el : m_activeIndicators)
|
||||
QObject::connect(this, &LinearIndicatorManager::updated, el, &LinearIndicatorSegment::updated);
|
||||
}
|
||||
|
||||
QList<LinearIndicatorSegment*> LinearIndicatorManager::activeIndicators() const {
|
||||
return { m_activeIndicators.cbegin(), m_activeIndicators.cend() };
|
||||
}
|
||||
|
||||
qreal LinearIndicatorManager::progress() const {
|
||||
return m_progress;
|
||||
}
|
||||
|
||||
qreal LinearIndicatorManager::completeEndProgress() const {
|
||||
return m_completeEndProgress;
|
||||
}
|
||||
|
||||
int LinearIndicatorManager::gap() const {
|
||||
return m_gap;
|
||||
}
|
||||
|
||||
void LinearIndicatorManager::setGap(int gap) {
|
||||
m_gap = gap;
|
||||
for (auto el : m_activeIndicators)
|
||||
el->m_gapSize = m_gap;
|
||||
update(m_progress);
|
||||
}
|
||||
|
||||
int LinearIndicatorManager::duration() const {
|
||||
return TOTAL_DURATION_IN_MS;
|
||||
}
|
||||
|
||||
int LinearIndicatorManager::completeEndDuration() const {
|
||||
return TOTAL_DURATION_IN_MS;
|
||||
}
|
||||
|
||||
void LinearIndicatorManager::update(qreal progress) {
|
||||
const auto playtime = progress * TOTAL_DURATION_IN_MS;
|
||||
for (size_t i = 0; i < SEGMENTS; i++) {
|
||||
const auto di = i * 2;
|
||||
auto* const indicator = m_activeIndicators[i];
|
||||
|
||||
auto fraction = getFractionInRange(playtime, DELAY_TO_MOVE_SEGMENT_ENDS[di], DURATION_TO_MOVE_SEGMENT_ENDS[di]);
|
||||
indicator->m_startFraction = std::clamp(m_interpolators[di].valueForProgress(fraction), 0.0, 1.0);
|
||||
|
||||
fraction =
|
||||
getFractionInRange(playtime, DELAY_TO_MOVE_SEGMENT_ENDS[di + 1], DURATION_TO_MOVE_SEGMENT_ENDS[di + 1]);
|
||||
indicator->m_endFraction = std::clamp(m_interpolators[di + 1].valueForProgress(fraction), 0.0, 1.0);
|
||||
}
|
||||
|
||||
m_progress = progress;
|
||||
emit updated();
|
||||
}
|
||||
|
||||
void LinearIndicatorManager::updateCompleteEndProgress(qreal progress) {
|
||||
m_completeEndProgress = progress;
|
||||
update(m_progress);
|
||||
}
|
||||
|
||||
} // namespace ZShell::controls
|
||||
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include <qcolor.h>
|
||||
#include <qeasingcurve.h>
|
||||
#include <qobject.h>
|
||||
#include <qqmlengine.h>
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace ZShell::controls {
|
||||
|
||||
class LinearIndicatorManager;
|
||||
|
||||
class LinearIndicatorSegment : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("LinearIndicatorSegments can only be retrieved from a "
|
||||
"LinearIndicatorManager.")
|
||||
|
||||
Q_PROPERTY(qreal startFraction READ startFraction NOTIFY updated FINAL)
|
||||
Q_PROPERTY(qreal endFraction READ endFraction NOTIFY updated FINAL)
|
||||
Q_PROPERTY(int gapSize READ gapSize NOTIFY updated FINAL)
|
||||
|
||||
public:
|
||||
explicit LinearIndicatorSegment(int gap, QObject* parent = nullptr);
|
||||
|
||||
qreal startFraction() const;
|
||||
qreal endFraction() const;
|
||||
int gapSize() const;
|
||||
|
||||
signals:
|
||||
void updated();
|
||||
|
||||
private:
|
||||
qreal m_startFraction;
|
||||
qreal m_endFraction;
|
||||
int m_gapSize;
|
||||
|
||||
friend LinearIndicatorManager;
|
||||
};
|
||||
|
||||
class LinearIndicatorManager : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
Q_PROPERTY(
|
||||
QList<ZShell::controls::LinearIndicatorSegment*> activeIndicators READ activeIndicators CONSTANT FINAL)
|
||||
|
||||
Q_PROPERTY(qreal progress READ progress WRITE update NOTIFY updated FINAL)
|
||||
Q_PROPERTY(qreal completeEndProgress READ completeEndProgress WRITE updateCompleteEndProgress NOTIFY updated FINAL)
|
||||
Q_PROPERTY(int gap READ gap WRITE setGap NOTIFY updated FINAL)
|
||||
|
||||
Q_PROPERTY(qreal duration READ duration CONSTANT FINAL)
|
||||
Q_PROPERTY(qreal completeEndDuration READ completeEndDuration CONSTANT FINAL)
|
||||
|
||||
public:
|
||||
explicit LinearIndicatorManager(QObject* parent = nullptr);
|
||||
|
||||
QList<LinearIndicatorSegment*> activeIndicators() const;
|
||||
|
||||
qreal progress() const;
|
||||
qreal completeEndProgress() const;
|
||||
|
||||
int gap() const;
|
||||
void setGap(int gap);
|
||||
|
||||
int duration() const;
|
||||
int completeEndDuration() const;
|
||||
|
||||
void update(qreal progress);
|
||||
void updateCompleteEndProgress(qreal progress);
|
||||
|
||||
signals:
|
||||
void updated();
|
||||
|
||||
private:
|
||||
static constexpr int SEGMENTS = 2;
|
||||
|
||||
std::array<QEasingCurve, 4> m_interpolators;
|
||||
qreal m_progress;
|
||||
qreal m_completeEndProgress;
|
||||
int m_gap;
|
||||
|
||||
std::array<LinearIndicatorSegment*, SEGMENTS> m_activeIndicators;
|
||||
};
|
||||
|
||||
} // namespace ZShell::controls
|
||||
@@ -0,0 +1,198 @@
|
||||
#include "visualizerbars.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <qbrush.h>
|
||||
#include <qpainter.h>
|
||||
#include <qpainterpath.h>
|
||||
#include <qpen.h>
|
||||
|
||||
namespace ZShell::internal {
|
||||
|
||||
VisualizerBars::VisualizerBars(QQuickItem* parent)
|
||||
: QQuickPaintedItem(parent) {
|
||||
setAntialiasing(true);
|
||||
}
|
||||
|
||||
void VisualizerBars::advance(qreal dt) {
|
||||
if (m_displayValues.isEmpty() || m_settled)
|
||||
return;
|
||||
|
||||
// dt is in seconds (from FrameAnimation.frameTime), convert to ms
|
||||
const qreal dtMs = dt * 1000.0;
|
||||
const qreal tau = m_animationDuration / 3.0;
|
||||
const qreal alpha = 1.0 - std::exp(-dtMs / tau);
|
||||
|
||||
bool allSettled = true;
|
||||
|
||||
for (qsizetype i = 0; i < m_displayValues.size(); ++i) {
|
||||
const double diff = m_targetValues[i] - m_displayValues[i];
|
||||
|
||||
if (std::abs(diff) > 0.001) {
|
||||
m_displayValues[i] += diff * alpha;
|
||||
allSettled = false;
|
||||
} else {
|
||||
m_displayValues[i] = m_targetValues[i];
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
|
||||
if (allSettled && !m_settled) {
|
||||
m_settled = true;
|
||||
emit settledChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void VisualizerBars::paint(QPainter* painter) {
|
||||
if (m_displayValues.isEmpty())
|
||||
return;
|
||||
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
painter->setPen(Qt::NoPen);
|
||||
|
||||
const qreal h = height();
|
||||
const qreal maxBarHeight = h * 0.4;
|
||||
|
||||
QLinearGradient gradient(0, h - maxBarHeight, 0, h);
|
||||
gradient.setColorAt(0, m_primaryColor);
|
||||
gradient.setColorAt(1, m_secondaryColor);
|
||||
painter->setBrush(gradient);
|
||||
|
||||
drawSide(painter, false);
|
||||
drawSide(painter, true);
|
||||
}
|
||||
|
||||
void VisualizerBars::drawSide(QPainter* painter, bool rightSide) {
|
||||
const qreal w = width();
|
||||
const qreal h = height();
|
||||
const auto count = m_displayValues.size();
|
||||
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
const qreal sideWidth = w * 0.4;
|
||||
const qreal slotWidth = sideWidth / static_cast<qreal>(count);
|
||||
const qreal barWidth = slotWidth - m_spacing;
|
||||
|
||||
if (barWidth <= 0)
|
||||
return;
|
||||
|
||||
const qreal sideOffset = rightSide ? w * 0.6 : 0;
|
||||
const qreal maxBarHeight = h * 0.4;
|
||||
|
||||
for (qsizetype i = 0; i < count; ++i) {
|
||||
const qsizetype valueIndex = rightSide ? i : (count - i - 1);
|
||||
const qreal value = std::clamp(m_displayValues[valueIndex], 0.0, 1.0);
|
||||
const qreal barHeight = value * maxBarHeight;
|
||||
|
||||
if (barHeight <= 0)
|
||||
continue;
|
||||
|
||||
const qreal x = static_cast<qreal>(i) * slotWidth + sideOffset;
|
||||
const qreal y = h - barHeight;
|
||||
const qreal r = std::min({ m_rounding, barWidth / 2.0, barHeight });
|
||||
|
||||
QPainterPath path;
|
||||
path.moveTo(x, h);
|
||||
path.lineTo(x, y + r);
|
||||
|
||||
if (r > 0) {
|
||||
path.arcTo(x, y, r * 2, r * 2, 180, -90);
|
||||
path.lineTo(x + barWidth - r, y);
|
||||
path.arcTo(x + barWidth - r * 2, y, r * 2, r * 2, 90, -90);
|
||||
} else {
|
||||
path.lineTo(x, y);
|
||||
path.lineTo(x + barWidth, y);
|
||||
}
|
||||
|
||||
path.lineTo(x + barWidth, h);
|
||||
path.closeSubpath();
|
||||
|
||||
painter->drawPath(path);
|
||||
}
|
||||
}
|
||||
|
||||
QVector<double> VisualizerBars::values() const {
|
||||
return m_targetValues;
|
||||
}
|
||||
|
||||
void VisualizerBars::setValues(const QVector<double>& values) {
|
||||
m_targetValues = values;
|
||||
|
||||
if (m_displayValues.size() != values.size()) {
|
||||
m_displayValues.resize(values.size(), 0.0);
|
||||
}
|
||||
|
||||
if (m_settled) {
|
||||
m_settled = false;
|
||||
emit settledChanged();
|
||||
}
|
||||
|
||||
emit valuesChanged();
|
||||
}
|
||||
|
||||
bool VisualizerBars::settled() const {
|
||||
return m_settled;
|
||||
}
|
||||
|
||||
QColor VisualizerBars::primaryColor() const {
|
||||
return m_primaryColor;
|
||||
}
|
||||
|
||||
void VisualizerBars::setPrimaryColor(const QColor& color) {
|
||||
if (m_primaryColor == color)
|
||||
return;
|
||||
m_primaryColor = color;
|
||||
emit primaryColorChanged();
|
||||
update();
|
||||
}
|
||||
|
||||
QColor VisualizerBars::secondaryColor() const {
|
||||
return m_secondaryColor;
|
||||
}
|
||||
|
||||
void VisualizerBars::setSecondaryColor(const QColor& color) {
|
||||
if (m_secondaryColor == color)
|
||||
return;
|
||||
m_secondaryColor = color;
|
||||
emit secondaryColorChanged();
|
||||
update();
|
||||
}
|
||||
|
||||
qreal VisualizerBars::rounding() const {
|
||||
return m_rounding;
|
||||
}
|
||||
|
||||
void VisualizerBars::setRounding(qreal rounding) {
|
||||
if (qFuzzyCompare(m_rounding, rounding))
|
||||
return;
|
||||
m_rounding = rounding;
|
||||
emit roundingChanged();
|
||||
update();
|
||||
}
|
||||
|
||||
qreal VisualizerBars::spacing() const {
|
||||
return m_spacing;
|
||||
}
|
||||
|
||||
void VisualizerBars::setSpacing(qreal spacing) {
|
||||
if (qFuzzyCompare(m_spacing, spacing))
|
||||
return;
|
||||
m_spacing = spacing;
|
||||
emit spacingChanged();
|
||||
update();
|
||||
}
|
||||
|
||||
int VisualizerBars::animationDuration() const {
|
||||
return m_animationDuration;
|
||||
}
|
||||
|
||||
void VisualizerBars::setAnimationDuration(int duration) {
|
||||
if (m_animationDuration == duration)
|
||||
return;
|
||||
m_animationDuration = duration;
|
||||
emit animationDurationChanged();
|
||||
}
|
||||
|
||||
} // namespace ZShell::internal
|
||||
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <qcolor.h>
|
||||
#include <qobject.h>
|
||||
#include <qqmlintegration.h>
|
||||
#include <qquickpainteditem.h>
|
||||
#include <qvector.h>
|
||||
|
||||
namespace ZShell::internal {
|
||||
|
||||
class VisualizerBars : public QQuickPaintedItem {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
Q_PROPERTY(QVector<double> values READ values WRITE setValues NOTIFY valuesChanged)
|
||||
Q_PROPERTY(QColor primaryColor READ primaryColor WRITE setPrimaryColor NOTIFY primaryColorChanged)
|
||||
Q_PROPERTY(QColor secondaryColor READ secondaryColor WRITE setSecondaryColor NOTIFY secondaryColorChanged)
|
||||
Q_PROPERTY(qreal rounding READ rounding WRITE setRounding NOTIFY roundingChanged)
|
||||
Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
|
||||
Q_PROPERTY(int animationDuration READ animationDuration WRITE setAnimationDuration NOTIFY animationDurationChanged)
|
||||
Q_PROPERTY(bool settled READ settled NOTIFY settledChanged)
|
||||
|
||||
public:
|
||||
explicit VisualizerBars(QQuickItem* parent = nullptr);
|
||||
|
||||
void paint(QPainter* painter) override;
|
||||
|
||||
Q_INVOKABLE void advance(qreal dt);
|
||||
|
||||
[[nodiscard]] QVector<double> values() const;
|
||||
void setValues(const QVector<double>& values);
|
||||
|
||||
[[nodiscard]] QColor primaryColor() const;
|
||||
void setPrimaryColor(const QColor& color);
|
||||
|
||||
[[nodiscard]] QColor secondaryColor() const;
|
||||
void setSecondaryColor(const QColor& color);
|
||||
|
||||
[[nodiscard]] qreal rounding() const;
|
||||
void setRounding(qreal rounding);
|
||||
|
||||
[[nodiscard]] qreal spacing() const;
|
||||
void setSpacing(qreal spacing);
|
||||
|
||||
[[nodiscard]] int animationDuration() const;
|
||||
void setAnimationDuration(int duration);
|
||||
|
||||
[[nodiscard]] bool settled() const;
|
||||
|
||||
signals:
|
||||
void valuesChanged();
|
||||
void primaryColorChanged();
|
||||
void secondaryColorChanged();
|
||||
void roundingChanged();
|
||||
void spacingChanged();
|
||||
void animationDurationChanged();
|
||||
void settledChanged();
|
||||
|
||||
private:
|
||||
void drawSide(QPainter* painter, bool rightSide);
|
||||
|
||||
QVector<double> m_targetValues;
|
||||
QVector<double> m_displayValues;
|
||||
QColor m_primaryColor;
|
||||
QColor m_secondaryColor;
|
||||
qreal m_rounding = 0.0;
|
||||
qreal m_spacing = 0.0;
|
||||
int m_animationDuration = 200;
|
||||
bool m_settled = true;
|
||||
};
|
||||
|
||||
} // namespace ZShell::internal
|
||||
Reference in New Issue
Block a user