Skip to content

Commit

Permalink
Support theming of dynamic calendar icon
Browse files Browse the repository at this point in the history
  • Loading branch information
dseight committed Jul 21, 2020
1 parent e510d83 commit 6c574a2
Showing 1 changed file with 92 additions and 17 deletions.
109 changes: 92 additions & 17 deletions dynamic-icons/calendar.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
#include "dynamicicon.h"
#include "iconpack.h"
#include "iconpackfactory.h"
#include "iconprovider.h"
#include "svgiconrender.h"
#include <MGConfItem>
#include <QDate>
#include <QDebug>
#include <QFile>
#include <QTimer>

class CalendarIconProvider : public IconProvider
namespace {

class CalendarIconRenderer
{
Q_OBJECT
public:
virtual ~CalendarIconRenderer() = default;
virtual QImage requestImage(const QDate &date, const QSize &requestedSize) = 0;
};

class DefaultCalendarIconRenderer : public CalendarIconRenderer
{
public:
explicit CalendarIconProvider(QObject *parent)
: IconProvider(parent)
DefaultCalendarIconRenderer()
{
connect(&m_timer, &QTimer::timeout, this, &IconProvider::imageUpdated);

// Update icon each hour
m_timer.start(60 * 60 * 1000);

QFile file(QStringLiteral(ASSETS_PATH "/icon-launcher-calendar.svg"));

if (!file.open(QIODevice::ReadOnly)) {
Expand All @@ -29,20 +33,15 @@ class CalendarIconProvider : public IconProvider
m_asset = file.readAll();
}

QImage requestImage(const QSize &requestedSize) override
QImage requestImage(const QDate &date, const QSize &requestedSize) override
{
return renderSvgIcon(getSvgData(), requestedSize);
return renderSvgIcon(getSvgData(date), requestedSize);
}

private:
QByteArray getSvgData()
QByteArray getSvgData(const QDate &date)
{
// It might be better to parse DOM when more features will be added.
// But at current state it is just unnecessarily increases complexity.

QByteArray asset(m_asset);

const auto date = QDate::currentDate();
const auto day = ">" + QString::number(date.day()) + "<";

asset.replace(">31<", day.toLatin1());
Expand All @@ -52,9 +51,85 @@ class CalendarIconProvider : public IconProvider

private:
QByteArray m_asset;
};

class IconpackCalendarIconRenderer : public CalendarIconRenderer
{
public:
explicit IconpackCalendarIconRenderer(const QString &name)
{
const auto iconPacks = IconPackFactory::loadIconPacks();
for (auto iconPack : iconPacks) {
if (iconPack->name() == name) {
m_iconPack = iconPack;
}
}

if (m_iconPack == nullptr)
qDebug() << "No icon pack with name" << name
<< "found. Dynamic calendar icon will not work.";
}

QImage requestImage(const QDate &date, const QSize &requestedSize) override
{
if (!m_iconPack)
return {};

return m_iconPack->requestCalendarIcon(date, requestedSize);
}

private:
IconPack *m_iconPack;
};

class CalendarIconProvider : public IconProvider
{
Q_OBJECT

public:
explicit CalendarIconProvider(QObject *parent)
: IconProvider(parent)
// TODO: move currentIconPackConf to some common place
, m_currentIconPackConf(QStringLiteral("/com/dseight/clockwork/icon-pack"))
{
updateRenderer();

connect(&m_currentIconPackConf, &MGConfItem::valueChanged,
this, &CalendarIconProvider::updateRenderer);
connect(&m_currentIconPackConf, &MGConfItem::valueChanged,
this, &IconProvider::imageUpdated);
connect(&m_timer, &QTimer::timeout, this, &IconProvider::imageUpdated);

// Update icon each hour
m_timer.start(60 * 60 * 1000);
}

QImage requestImage(const QSize &requestedSize) override
{
const auto date = QDate::currentDate();
return m_renderer->requestImage(date, requestedSize);
}

private slots:
void updateRenderer()
{
const auto iconPackName = m_currentIconPackConf.value().toString();

if (iconPackName.isEmpty()) {
m_renderer.reset(new DefaultCalendarIconRenderer);
} else {
m_renderer.reset(new IconpackCalendarIconRenderer(iconPackName));
}
}

private:
QTimer m_timer;
MGConfItem m_currentIconPackConf;
QScopedPointer<CalendarIconRenderer> m_renderer;
};

} // namespace

class CalendarDynamicIcon : public DynamicIcon
{
Q_OBJECT
Expand Down

0 comments on commit 6c574a2

Please sign in to comment.