Commit 824ba007 authored by Wescoeur's avatar Wescoeur

feat(App): svg images supports color override

parent c19b1956
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<desc>Created with Sketch.</desc> <desc>Created with Sketch.</desc>
<defs></defs> <defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"> <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="settings_call_selected" stroke="#FE5E00" stroke-width="1.5"> <g id="settings_call_selected" class="color-i-stroke" stroke="#FE5E00" stroke-width="1.5">
<path d="M4.55461126,14.3889991 L4.61101441,14.4450242 C7.3002852,17.1350119 12.0969113,18.7974809 15.4512283,17.6111264 L17.995659,14.2747867 L14.5299113,10.8085083 L11.3593468,13.4904363 L8.46175774,10.5924679 L8.4061407,10.5364429 L5.50894471,7.63847454 L8.18956832,4.46588524 L4.7251964,1 L1.38876333,3.54530555 C0.202724956,6.90169626 1.8647509,11.6984217 4.55461126,14.3889991 Z" id="call_icon"></path> <path d="M4.55461126,14.3889991 L4.61101441,14.4450242 C7.3002852,17.1350119 12.0969113,18.7974809 15.4512283,17.6111264 L17.995659,14.2747867 L14.5299113,10.8085083 L11.3593468,13.4904363 L8.46175774,10.5924679 L8.4061407,10.5364429 L5.50894471,7.63847454 L8.18956832,4.46588524 L4.7251964,1 L1.38876333,3.54530555 C0.202724956,6.90169626 1.8647509,11.6984217 4.55461126,14.3889991 Z" id="call_icon"></path>
</g> </g>
</g> </g>
......
...@@ -106,9 +106,7 @@ App::~App () { ...@@ -106,9 +106,7 @@ App::~App () {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
inline QQuickWindow *createSubWindow (App *app, const char *path) { inline QQuickWindow *createSubWindow (QQmlApplicationEngine *engine, const char *path) {
QQmlEngine *engine = app->getEngine();
QQmlComponent component(engine, QUrl(path)); QQmlComponent component(engine, QUrl(path));
if (component.isError()) { if (component.isError()) {
qWarning() << component.errors(); qWarning() << component.errors();
...@@ -117,16 +115,16 @@ inline QQuickWindow *createSubWindow (App *app, const char *path) { ...@@ -117,16 +115,16 @@ inline QQuickWindow *createSubWindow (App *app, const char *path) {
QObject *object = component.create(); QObject *object = component.create();
QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
object->setParent(app->getEngine()); object->setParent(engine);
return qobject_cast<QQuickWindow *>(object); return qobject_cast<QQuickWindow *>(object);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
inline void activeSplashScreen (App *app) { inline void activeSplashScreen (QQmlApplicationEngine *engine) {
qInfo() << QStringLiteral("Open splash screen..."); qInfo() << QStringLiteral("Open splash screen...");
QQuickWindow *splashScreen = ::createSubWindow(app, QML_VIEW_SPLASH_SCREEN); QQuickWindow *splashScreen = ::createSubWindow(engine, QML_VIEW_SPLASH_SCREEN);
QObject::connect(CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::coreStarted, splashScreen, [splashScreen] { QObject::connect(CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::coreStarted, splashScreen, [splashScreen] {
splashScreen->close(); splashScreen->close();
splashScreen->deleteLater(); splashScreen->deleteLater();
...@@ -176,17 +174,20 @@ void App::initContentApp () { ...@@ -176,17 +174,20 @@ void App::initContentApp () {
mEngine->addImageProvider(ImageProvider::PROVIDER_ID, new ImageProvider()); mEngine->addImageProvider(ImageProvider::PROVIDER_ID, new ImageProvider());
mEngine->addImageProvider(ThumbnailProvider::PROVIDER_ID, new ThumbnailProvider()); mEngine->addImageProvider(ThumbnailProvider::PROVIDER_ID, new ThumbnailProvider());
mColors = new Colors(this);
registerTypes(); registerTypes();
registerSharedTypes(); registerSharedTypes();
registerToolTypes(); registerToolTypes();
registerSharedToolTypes();
// Enable notifications. // Enable notifications.
createNotifier(); mNotifier = new Notifier(mEngine);
// Load splashscreen. // Load splashscreen.
bool selfTest = mParser->isSet("self-test"); bool selfTest = mParser->isSet("self-test");
if (!selfTest) if (!selfTest)
::activeSplashScreen(this); ::activeSplashScreen(mEngine);
// Set a self test limit. // Set a self test limit.
else else
QTimer::singleShot(SELF_TEST_DELAY, this, [] { QTimer::singleShot(SELF_TEST_DELAY, this, [] {
...@@ -224,7 +225,7 @@ void App::executeCommand (const QString &command) { ...@@ -224,7 +225,7 @@ void App::executeCommand (const QString &command) {
QQuickWindow *App::getCallsWindow () { QQuickWindow *App::getCallsWindow () {
if (!mCallsWindow) if (!mCallsWindow)
mCallsWindow = ::createSubWindow(this, QML_VIEW_CALLS_WINDOW); mCallsWindow = ::createSubWindow(mEngine, QML_VIEW_CALLS_WINDOW);
return mCallsWindow; return mCallsWindow;
} }
...@@ -237,7 +238,7 @@ QQuickWindow *App::getMainWindow () const { ...@@ -237,7 +238,7 @@ QQuickWindow *App::getMainWindow () const {
QQuickWindow *App::getSettingsWindow () { QQuickWindow *App::getSettingsWindow () {
if (!mSettingsWindow) { if (!mSettingsWindow) {
mSettingsWindow = ::createSubWindow(this, QML_VIEW_SETTINGS_WINDOW); mSettingsWindow = ::createSubWindow(mEngine, QML_VIEW_SETTINGS_WINDOW);
QObject::connect(mSettingsWindow, &QWindow::visibilityChanged, this, [](QWindow::Visibility visibility) { QObject::connect(mSettingsWindow, &QWindow::visibilityChanged, this, [](QWindow::Visibility visibility) {
if (visibility == QWindow::Hidden) { if (visibility == QWindow::Hidden) {
qInfo() << QStringLiteral("Update nat policy."); qInfo() << QStringLiteral("Update nat policy.");
...@@ -338,6 +339,15 @@ void registerToolType (const char *name) { ...@@ -338,6 +339,15 @@ void registerToolType (const char *name) {
}); });
} }
#define registerSharedToolType(TYPE, NAME, METHOD) qmlRegisterSingletonType<TYPE>( \
NAME, 1, 0, NAME, \
[](QQmlEngine *, QJSEngine *) -> QObject *{ \
QObject *object = METHOD(); \
QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); \
return object; \
} \
)
void App::registerTypes () { void App::registerTypes () {
qInfo() << QStringLiteral("Registering types..."); qInfo() << QStringLiteral("Registering types...");
...@@ -387,12 +397,18 @@ void App::registerToolTypes () { ...@@ -387,12 +397,18 @@ void App::registerToolTypes () {
qInfo() << QStringLiteral("Registering tool types..."); qInfo() << QStringLiteral("Registering tool types...");
registerToolType<Clipboard>("Clipboard"); registerToolType<Clipboard>("Clipboard");
registerToolType<Colors>("Colors");
registerToolType<TextToSpeech>("TextToSpeech"); registerToolType<TextToSpeech>("TextToSpeech");
registerToolType<Units>("Units"); registerToolType<Units>("Units");
} }
void App::registerSharedToolTypes () {
qInfo() << QStringLiteral("Registering shared tool types...");
registerSharedToolType(Colors, "Colors", App::getInstance()->getColors);
}
#undef registerUncreatableType #undef registerUncreatableType
#undef registerSharedToolType
#undef registerSharedSingletonType #undef registerSharedSingletonType
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -436,13 +452,6 @@ void App::setTrayIcon () { ...@@ -436,13 +452,6 @@ void App::setTrayIcon () {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void App::createNotifier () {
if (!mNotifier)
mNotifier = new Notifier(this);
}
// -----------------------------------------------------------------------------
void App::initLocale () { void App::initLocale () {
// Try to use preferred locale. // Try to use preferred locale.
QString locale; QString locale;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <QQuickWindow> #include <QQuickWindow>
#include "../components/notifier/Notifier.hpp" #include "../components/notifier/Notifier.hpp"
#include "../components/other/colors/Colors.hpp"
#include "../externals/single-application/SingleApplication.hpp" #include "../externals/single-application/SingleApplication.hpp"
#define APP_CODE_RESTART 1000 #define APP_CODE_RESTART 1000
...@@ -63,6 +64,10 @@ public: ...@@ -63,6 +64,10 @@ public:
return mNotifier; return mNotifier;
} }
Colors *getColors () const {
return mColors;
}
QQuickWindow *getMainWindow () const; QQuickWindow *getMainWindow () const;
bool hasFocus () const; bool hasFocus () const;
...@@ -92,6 +97,7 @@ private: ...@@ -92,6 +97,7 @@ private:
void registerTypes (); void registerTypes ();
void registerSharedTypes (); void registerSharedTypes ();
void registerToolTypes (); void registerToolTypes ();
void registerSharedToolTypes ();
void setTrayIcon (); void setTrayIcon ();
void createNotifier (); void createNotifier ();
...@@ -128,6 +134,8 @@ private: ...@@ -128,6 +134,8 @@ private:
QQuickWindow *mCallsWindow = nullptr; QQuickWindow *mCallsWindow = nullptr;
QQuickWindow *mSettingsWindow = nullptr; QQuickWindow *mSettingsWindow = nullptr;
Colors *mColors = nullptr;
Cli *mCli = nullptr; Cli *mCli = nullptr;
}; };
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <QXmlStreamReader> #include <QXmlStreamReader>
#include <QtDebug> #include <QtDebug>
#include "../App.hpp"
#include "ImageProvider.hpp" #include "ImageProvider.hpp"
// Max image size in bytes. (100Kb) // Max image size in bytes. (100Kb)
...@@ -35,28 +37,73 @@ ...@@ -35,28 +37,73 @@
// ============================================================================= // =============================================================================
const QString ImageProvider::PROVIDER_ID = "internal"; static QByteArray buildByteArrayAttribute (const QByteArray &name, const QByteArray &value) {
QByteArray attribute = name;
attribute.append("=\"");
attribute.append(value);
attribute.append("\" ");
return attribute;
}
ImageProvider::ImageProvider () : QQuickImageProvider( static QByteArray fillFillAndStroke (QXmlStreamAttributes &readerAttributes, bool &fill, bool &stroke, const Colors &colors) {
QQmlImageProviderBase::Image, static QRegExp regex("^color-([^-]+)-(fill|stroke)$");
QQmlImageProviderBase::ForceAsynchronousImageLoading
) {}
// -----------------------------------------------------------------------------
static QByteArray parseAttributes (QXmlStreamReader &reader) {
QByteArray attributes; QByteArray attributes;
for (const auto &attribute : reader.attributes()) { QByteArray value = readerAttributes.value("class").toLatin1();
const QByteArray prefix = attribute.prefix().toLatin1(); if (!value.length())
return attributes;
for (const auto &subValue : value.split(' ')) {
regex.indexIn(subValue.trimmed());
const QStringList list = regex.capturedTexts();
if (list.length() != 3)
continue;
const QString colorName = list[1];
QVariant colorValue = colors.property(colorName.toStdString().c_str());
if (!colorValue.isValid()) {
qWarning() << QStringLiteral("Color name `%1` does not exist.").arg(colorName);
continue;
}
QByteArray property = list[2].toLatin1();
if (property == QStringLiteral("fill"))
fill = true;
else
stroke = true;
attributes.append(
buildByteArrayAttribute(
property,
colorValue.value<QColor>().name().toLatin1()
)
);
}
return attributes;
}
static QByteArray parseAttributes (QXmlStreamReader &reader, const Colors &colors) {
QXmlStreamAttributes readerAttributes = reader.attributes();
bool fill = false, stroke = false;
QByteArray attributes = fillFillAndStroke(readerAttributes, fill, stroke, colors);
for (const auto &attribute : readerAttributes) {
QByteArray name = attribute.name().toLatin1();
if (fill && name == QStringLiteral("fill"))
continue;
if (stroke && name == QStringLiteral("stroke"))
continue;
QByteArray prefix = attribute.prefix().toLatin1();
QByteArray value = attribute.value().toLatin1();
if (prefix.length() > 0) { if (prefix.length() > 0) {
attributes.append(prefix); attributes.append(prefix);
attributes.append(":"); attributes.append(":");
} }
attributes.append(attribute.name().toLatin1()); attributes.append(buildByteArrayAttribute(name, value));
attributes.append("=\"");
attributes.append(attribute.value().toLatin1());
attributes.append("\" ");
} }
return attributes; return attributes;
...@@ -65,7 +112,7 @@ static QByteArray parseAttributes (QXmlStreamReader &reader) { ...@@ -65,7 +112,7 @@ static QByteArray parseAttributes (QXmlStreamReader &reader) {
static QByteArray parseDeclarations (QXmlStreamReader &reader) { static QByteArray parseDeclarations (QXmlStreamReader &reader) {
QByteArray declarations; QByteArray declarations;
for (const auto &declaration : reader.namespaceDeclarations()) { for (const auto &declaration : reader.namespaceDeclarations()) {
const QByteArray prefix = declaration.prefix().toLatin1(); QByteArray prefix = declaration.prefix().toLatin1();
if (prefix.length() > 0) { if (prefix.length() > 0) {
declarations.append("xmlns:"); declarations.append("xmlns:");
declarations.append(prefix); declarations.append(prefix);
...@@ -89,11 +136,11 @@ static QByteArray parseStartDocument (QXmlStreamReader &reader) { ...@@ -89,11 +136,11 @@ static QByteArray parseStartDocument (QXmlStreamReader &reader) {
return startDocument; return startDocument;
} }
static QByteArray parseStartElement (QXmlStreamReader &reader) { static QByteArray parseStartElement (QXmlStreamReader &reader, const Colors &colors) {
QByteArray startElement = "<"; QByteArray startElement = "<";
startElement.append(reader.name().toLatin1()); startElement.append(reader.name().toLatin1());
startElement.append(" "); startElement.append(" ");
startElement.append(parseAttributes(reader)); startElement.append(parseAttributes(reader, colors));
startElement.append(" "); startElement.append(" ");
startElement.append(parseDeclarations(reader)); startElement.append(parseDeclarations(reader));
startElement.append(">"); startElement.append(">");
...@@ -110,6 +157,8 @@ static QByteArray parseEndElement (QXmlStreamReader &reader) { ...@@ -110,6 +157,8 @@ static QByteArray parseEndElement (QXmlStreamReader &reader) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
static QByteArray computeContent (QFile &file) { static QByteArray computeContent (QFile &file) {
const Colors *colors = App::getInstance()->getColors();
QByteArray content; QByteArray content;
QXmlStreamReader reader(&file); QXmlStreamReader reader(&file);
while (!reader.atEnd()) while (!reader.atEnd())
...@@ -127,7 +176,7 @@ static QByteArray computeContent (QFile &file) { ...@@ -127,7 +176,7 @@ static QByteArray computeContent (QFile &file) {
break; break;
case QXmlStreamReader::StartElement: case QXmlStreamReader::StartElement:
content.append(parseStartElement(reader)); content.append(parseStartElement(reader, *colors));
break; break;
case QXmlStreamReader::EndElement: case QXmlStreamReader::EndElement:
...@@ -148,6 +197,15 @@ static QByteArray computeContent (QFile &file) { ...@@ -148,6 +197,15 @@ static QByteArray computeContent (QFile &file) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
const QString ImageProvider::PROVIDER_ID = "internal";
ImageProvider::ImageProvider () : QQuickImageProvider(
QQmlImageProviderBase::Image,
QQmlImageProviderBase::ForceAsynchronousImageLoading
) {}
// -----------------------------------------------------------------------------
QImage ImageProvider::requestImage (const QString &id, QSize *, const QSize &) { QImage ImageProvider::requestImage (const QString &id, QSize *, const QSize &) {
const QString path = QStringLiteral(":/assets/images/%1").arg(id); const QString path = QStringLiteral(":/assets/images/%1").arg(id);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment