mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-02-07 15:08:24 +00:00
feat(App): svg images supports color override
This commit is contained in:
parent
c19b19562f
commit
824ba007c6
4 changed files with 112 additions and 37 deletions
|
|
@ -5,7 +5,7 @@
|
|||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<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>
|
||||
</g>
|
||||
</g>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1,020 B After Width: | Height: | Size: 1 KiB |
|
|
@ -106,9 +106,7 @@ App::~App () {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
inline QQuickWindow *createSubWindow (App *app, const char *path) {
|
||||
QQmlEngine *engine = app->getEngine();
|
||||
|
||||
inline QQuickWindow *createSubWindow (QQmlApplicationEngine *engine, const char *path) {
|
||||
QQmlComponent component(engine, QUrl(path));
|
||||
if (component.isError()) {
|
||||
qWarning() << component.errors();
|
||||
|
|
@ -117,16 +115,16 @@ inline QQuickWindow *createSubWindow (App *app, const char *path) {
|
|||
|
||||
QObject *object = component.create();
|
||||
QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
|
||||
object->setParent(app->getEngine());
|
||||
object->setParent(engine);
|
||||
|
||||
return qobject_cast<QQuickWindow *>(object);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
inline void activeSplashScreen (App *app) {
|
||||
inline void activeSplashScreen (QQmlApplicationEngine *engine) {
|
||||
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] {
|
||||
splashScreen->close();
|
||||
splashScreen->deleteLater();
|
||||
|
|
@ -176,17 +174,20 @@ void App::initContentApp () {
|
|||
mEngine->addImageProvider(ImageProvider::PROVIDER_ID, new ImageProvider());
|
||||
mEngine->addImageProvider(ThumbnailProvider::PROVIDER_ID, new ThumbnailProvider());
|
||||
|
||||
mColors = new Colors(this);
|
||||
|
||||
registerTypes();
|
||||
registerSharedTypes();
|
||||
registerToolTypes();
|
||||
registerSharedToolTypes();
|
||||
|
||||
// Enable notifications.
|
||||
createNotifier();
|
||||
mNotifier = new Notifier(mEngine);
|
||||
|
||||
// Load splashscreen.
|
||||
bool selfTest = mParser->isSet("self-test");
|
||||
if (!selfTest)
|
||||
::activeSplashScreen(this);
|
||||
::activeSplashScreen(mEngine);
|
||||
// Set a self test limit.
|
||||
else
|
||||
QTimer::singleShot(SELF_TEST_DELAY, this, [] {
|
||||
|
|
@ -224,7 +225,7 @@ void App::executeCommand (const QString &command) {
|
|||
|
||||
QQuickWindow *App::getCallsWindow () {
|
||||
if (!mCallsWindow)
|
||||
mCallsWindow = ::createSubWindow(this, QML_VIEW_CALLS_WINDOW);
|
||||
mCallsWindow = ::createSubWindow(mEngine, QML_VIEW_CALLS_WINDOW);
|
||||
|
||||
return mCallsWindow;
|
||||
}
|
||||
|
|
@ -237,7 +238,7 @@ QQuickWindow *App::getMainWindow () const {
|
|||
|
||||
QQuickWindow *App::getSettingsWindow () {
|
||||
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) {
|
||||
if (visibility == QWindow::Hidden) {
|
||||
qInfo() << QStringLiteral("Update nat policy.");
|
||||
|
|
@ -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 () {
|
||||
qInfo() << QStringLiteral("Registering types...");
|
||||
|
||||
|
|
@ -387,12 +397,18 @@ void App::registerToolTypes () {
|
|||
qInfo() << QStringLiteral("Registering tool types...");
|
||||
|
||||
registerToolType<Clipboard>("Clipboard");
|
||||
registerToolType<Colors>("Colors");
|
||||
registerToolType<TextToSpeech>("TextToSpeech");
|
||||
registerToolType<Units>("Units");
|
||||
}
|
||||
|
||||
void App::registerSharedToolTypes () {
|
||||
qInfo() << QStringLiteral("Registering shared tool types...");
|
||||
|
||||
registerSharedToolType(Colors, "Colors", App::getInstance()->getColors);
|
||||
}
|
||||
|
||||
#undef registerUncreatableType
|
||||
#undef registerSharedToolType
|
||||
#undef registerSharedSingletonType
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -436,13 +452,6 @@ void App::setTrayIcon () {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void App::createNotifier () {
|
||||
if (!mNotifier)
|
||||
mNotifier = new Notifier(this);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void App::initLocale () {
|
||||
// Try to use preferred locale.
|
||||
QString locale;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <QQuickWindow>
|
||||
|
||||
#include "../components/notifier/Notifier.hpp"
|
||||
#include "../components/other/colors/Colors.hpp"
|
||||
#include "../externals/single-application/SingleApplication.hpp"
|
||||
|
||||
#define APP_CODE_RESTART 1000
|
||||
|
|
@ -63,6 +64,10 @@ public:
|
|||
return mNotifier;
|
||||
}
|
||||
|
||||
Colors *getColors () const {
|
||||
return mColors;
|
||||
}
|
||||
|
||||
QQuickWindow *getMainWindow () const;
|
||||
|
||||
bool hasFocus () const;
|
||||
|
|
@ -92,6 +97,7 @@ private:
|
|||
void registerTypes ();
|
||||
void registerSharedTypes ();
|
||||
void registerToolTypes ();
|
||||
void registerSharedToolTypes ();
|
||||
|
||||
void setTrayIcon ();
|
||||
void createNotifier ();
|
||||
|
|
@ -128,6 +134,8 @@ private:
|
|||
QQuickWindow *mCallsWindow = nullptr;
|
||||
QQuickWindow *mSettingsWindow = nullptr;
|
||||
|
||||
Colors *mColors = nullptr;
|
||||
|
||||
Cli *mCli = nullptr;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#include <QXmlStreamReader>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "../App.hpp"
|
||||
|
||||
#include "ImageProvider.hpp"
|
||||
|
||||
// Max image size in bytes. (100Kb)
|
||||
|
|
@ -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(
|
||||
QQmlImageProviderBase::Image,
|
||||
QQmlImageProviderBase::ForceAsynchronousImageLoading
|
||||
) {}
|
||||
static QByteArray fillFillAndStroke (QXmlStreamAttributes &readerAttributes, bool &fill, bool &stroke, const Colors &colors) {
|
||||
static QRegExp regex("^color-([^-]+)-(fill|stroke)$");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static QByteArray parseAttributes (QXmlStreamReader &reader) {
|
||||
QByteArray attributes;
|
||||
for (const auto &attribute : reader.attributes()) {
|
||||
const QByteArray prefix = attribute.prefix().toLatin1();
|
||||
QByteArray value = readerAttributes.value("class").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) {
|
||||
attributes.append(prefix);
|
||||
attributes.append(":");
|
||||
}
|
||||
|
||||
attributes.append(attribute.name().toLatin1());
|
||||
attributes.append("=\"");
|
||||
attributes.append(attribute.value().toLatin1());
|
||||
attributes.append("\" ");
|
||||
attributes.append(buildByteArrayAttribute(name, value));
|
||||
}
|
||||
|
||||
return attributes;
|
||||
|
|
@ -65,7 +112,7 @@ static QByteArray parseAttributes (QXmlStreamReader &reader) {
|
|||
static QByteArray parseDeclarations (QXmlStreamReader &reader) {
|
||||
QByteArray declarations;
|
||||
for (const auto &declaration : reader.namespaceDeclarations()) {
|
||||
const QByteArray prefix = declaration.prefix().toLatin1();
|
||||
QByteArray prefix = declaration.prefix().toLatin1();
|
||||
if (prefix.length() > 0) {
|
||||
declarations.append("xmlns:");
|
||||
declarations.append(prefix);
|
||||
|
|
@ -89,11 +136,11 @@ static QByteArray parseStartDocument (QXmlStreamReader &reader) {
|
|||
return startDocument;
|
||||
}
|
||||
|
||||
static QByteArray parseStartElement (QXmlStreamReader &reader) {
|
||||
static QByteArray parseStartElement (QXmlStreamReader &reader, const Colors &colors) {
|
||||
QByteArray startElement = "<";
|
||||
startElement.append(reader.name().toLatin1());
|
||||
startElement.append(" ");
|
||||
startElement.append(parseAttributes(reader));
|
||||
startElement.append(parseAttributes(reader, colors));
|
||||
startElement.append(" ");
|
||||
startElement.append(parseDeclarations(reader));
|
||||
startElement.append(">");
|
||||
|
|
@ -110,6 +157,8 @@ static QByteArray parseEndElement (QXmlStreamReader &reader) {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
static QByteArray computeContent (QFile &file) {
|
||||
const Colors *colors = App::getInstance()->getColors();
|
||||
|
||||
QByteArray content;
|
||||
QXmlStreamReader reader(&file);
|
||||
while (!reader.atEnd())
|
||||
|
|
@ -127,7 +176,7 @@ static QByteArray computeContent (QFile &file) {
|
|||
break;
|
||||
|
||||
case QXmlStreamReader::StartElement:
|
||||
content.append(parseStartElement(reader));
|
||||
content.append(parseStartElement(reader, *colors));
|
||||
break;
|
||||
|
||||
case QXmlStreamReader::EndElement:
|
||||
|
|
@ -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 &) {
|
||||
const QString path = QStringLiteral(":/assets/images/%1").arg(id);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue