Commit 99c67307 authored by Lucien XU's avatar Lucien XU

[qtquickcontrols-nemo] Initial import of a C++ based theme

This commit imports work done for having C++ based
theming, exporting a C++ Theme singleton object,
and C++ object for each component, starting with
the button.

It also includes the new theming system, using JSON,
and a tool to generate new components based on a
description file.
parent 5a1e772b
*.pro.user
*.pyc
......@@ -51,11 +51,15 @@ Item {
anchors.centerIn: parent
Button {
property bool isGlacier: Theme.name == "Glacier"
anchors.margins: 20
text: (Theme.themeName == NemoControls.themes[0]) ? "Set Ugly Theme"
: "Set Nice Theme"
onClicked: NemoControls.setTheme((Theme.themeName == NemoControls.themes[0]) ? NemoControls.themes[1]
: NemoControls.themes[0])
text: isGlacier ? "Set Ugly Theme" : "Set Nice Theme"
onClicked: isGlacier ? Theme.loadFromFile("ugly.json")
: Theme.loadFromFile("glacier.json")
// NemoControls.setTheme((Theme.themeName == NemoControls.themes[0]) ? NemoControls.themes[1]
// : NemoControls.themes[0])
}
Button {
......
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>content/AndroidDelegate.qml</file>
<file>content/ButtonPage.qml</file>
......@@ -15,5 +15,5 @@
<file>images/tabs_standard.png</file>
<file>images/textinput.png</file>
<file>images/toolbar.png</file>
</qresource>
</qresource>
</RCC>
......@@ -3,17 +3,13 @@ CONFIG += qt plugin
QT += qml quick
TARGET=nemocontrolsplugin
PLUGIN_IMPORT_PATH = QtQuick/Controls/Nemo
THEME_IMPORT_PATH = QtQuick/Controls/Styles/Nemo/themes
# Added/Reimplemented Controls
QML_FILES += \
Button.qml
# Private files
QML_FILES += \
private/NemoControls.qml
OTHER_FILES += qmldir \
$$QML_FILES
OTHER_FILES += qmldir
HEADERS += \
qquicknemocontrolsextensionplugin.h \
......@@ -29,10 +25,4 @@ qmlfiles.files = $$_PRO_FILE_PWD_/*.qml
qmlfiles.files += $$_PRO_FILE_PWD_/qmldir
qmlfiles.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH
privatefiles.files = $$_PRO_FILE_PWD_/private/*.qml
privatefiles.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH/private
INSTALLS += target privatefiles qmlfiles
#RESOURCES += \
# internal_resources.qrc
INSTALLS += target qmlfiles
<RCC>
<qresource prefix="/QtQuick/Controls/Nemo">
<file>private/NemoControls.qml</file>
</qresource>
</RCC>
......@@ -27,24 +27,6 @@ QQuickNemoControlsExtensionPlugin::QQuickNemoControlsExtensionPlugin(QObject *pa
{
}
static QObject *nemo_controls_singletontype_provider(QQmlEngine *engine, QJSEngine */*scriptEngine*/)
{
QObject *ret = 0;
QQmlComponent c(engine,QUrl("/usr/lib/qt5/qml/QtQuick/Controls/Nemo/private/NemoControls.qml"),QQmlComponent::PreferSynchronous);
if (c.status() == QQmlComponent::Ready) {
ret = c.create();
if (!ret) {
qWarning() << "Can't create NemoControls Singleton Object:"<<c.errorString();
}
} else {
qWarning() << "NemoControls Singleton Component not Ready:"<<c.errorString();
}
return ret;
}
static QObject *nemo_hacks_singletontype_provider(QQmlEngine *engine, QJSEngine */*scriptEngine*/)
{
QObject *ret = new Hacks(engine);
......@@ -54,7 +36,6 @@ static QObject *nemo_hacks_singletontype_provider(QQmlEngine *engine, QJSEngine
void QQuickNemoControlsExtensionPlugin::registerTypes(const char *uri)
{
Q_ASSERT(uri == QLatin1String("QtQuick.Controls.Nemo"));
qmlRegisterSingletonType<QObject>(uri, 1, 0, "NemoControls", nemo_controls_singletontype_provider);
qmlRegisterSingletonType<QObject>(uri, 1, 0, "NemoHacks", nemo_hacks_singletontype_provider);
}
......
......@@ -33,8 +33,8 @@ ButtonStyle {
implicitWidth: 240
implicitHeight: 50
clip: true
color: control.primary ? Theme.primaryButton.backgroundColor
: Theme.button.backgroundColor
color: control.primary ? Theme.primaryButton.background
: Theme.button.background
Image {
id: disabledImg
anchors.fill: parent
......
/*
* Copyright (C) 2013 Lucien Xu <sfietkonstantin@free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// This class is autogenerated using themehelper.py
// Any modification done in this file will be overridden
#include "nemotheme.h"
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonValue>
#include <QtGui/QFontDatabase>
static const char *GLACIER_THEME = "glacier.json";
static const char *THEME_NAME_KEY = "name";
static const char *THEME_DESCRIPTION_KEY = "description";
static const char *THEME_DEFINES_KEY = "defines";
static const char *THEME_STYLES_KEY = "styles";
NemoTheme::NemoTheme(QObject *parent)
: QObject(parent)
, m_button(new NemoThemeButton(this))
, m_primaryButton(new NemoThemeButton(this))
{
loadFromFile(GLACIER_THEME);
int id = QFontDatabase::addApplicationFont("/usr/share/fonts/google-opensans/OpenSans-Regular.ttf");
QStringList families = QFontDatabase::applicationFontFamilies(id);
if (families.isEmpty()) {
qWarning() << "W" << "Failed to load font" << QString("/usr/share/fonts/google-opensans/OpenSans-Regular.ttf");
return;
}
m_fontFamily = families.first();
}
QString NemoTheme::name() const
{
return m_name;
}
void NemoTheme::setName(QString name)
{
if (m_name != name) {
m_name = name;
emit nameChanged();
}
}
QString NemoTheme::description() const
{
return m_description;
}
void NemoTheme::setDescription(QString description)
{
if (m_description != description) {
m_description = description;
emit descriptionChanged();
}
}
NemoThemeButton * NemoTheme::button() const
{
return m_button;
}
NemoThemeButton * NemoTheme::primaryButton() const
{
return m_primaryButton;
}
QString NemoTheme::fontFamily() const
{
return m_fontFamily;
}
static inline QJsonValue jsonValue(const QJsonObject &object, const QString &key,
const QString &objectName = QString())
{
if (!object.contains(key)) {
if (objectName.isEmpty()) {
qWarning() << "W" << "Root JSON object do not have value" << key;
} else {
qWarning() << "W" << "JSON Object" << objectName << "do not have value" << key;
}
return QJsonValue();
}
return object.value(key);
}
static inline QString jsonToString(const QJsonValue &value,
const QMap<QString, QJsonValue> &defines)
{
QString valueString = value.toString();
if (defines.contains(valueString)) {
return defines.value(valueString).toString();
}
return value.toString();
}
static inline QColor jsonToColor(const QJsonValue &value,
const QMap<QString, QJsonValue> &defines)
{
QString color = value.toString();
if (defines.contains(color)) {
color = defines.value(color).toString();
}
if (!QColor::isValidColor(color)) {
qWarning() << "W" << color << "is not a valid color";
return QColor();
}
return QColor(color);
}
static inline int jsonToInt(const QJsonValue &value,
const QMap<QString, QJsonValue> &defines)
{
QJsonValue trueValue = value;
if (value.isString()) {
QString valueString = value.toString();
if (defines.contains(valueString)) {
trueValue = defines.value(valueString);
}
}
double doubleValue = trueValue.toDouble();
return (int) doubleValue;
}
static inline int jsonToDouble(const QJsonValue &value,
const QMap<QString, QJsonValue> &defines)
{
QJsonValue trueValue = value;
if (value.isString()) {
QString valueString = value.toString();
if (defines.contains(valueString)) {
trueValue = defines.value(valueString);
}
}
return trueValue.toDouble();
}
void NemoTheme::loadFromFile(const QString &fileName)
{
QDir dir (THEME_DIR);
if (!dir.exists(fileName)) {
qWarning() << "E" << Q_FUNC_INFO << "Theme file" << fileName << "does not exists.";
return;
}
QFile themeFile (dir.absoluteFilePath(fileName));
if (!themeFile.open(QIODevice::ReadOnly)) {
qWarning() << "E" << Q_FUNC_INFO << "Theme file" << fileName << "could not be read.";
return;
}
QJsonParseError error;
QJsonDocument themeDocument = QJsonDocument::fromJson(themeFile.readAll(), &error);
themeFile.close();
if (error.error != QJsonParseError::NoError) {
qWarning() << "E" << Q_FUNC_INFO << "Cannot parse theme file:" << error.errorString();
return;
}
// Fetch all the defines
QMap<QString, QJsonValue> defines;
if (!themeDocument.isObject()) {
qWarning() << "E" << Q_FUNC_INFO << "Theme file has an invalid format";
return;
}
QJsonObject themeObject = themeDocument.object();
if (themeObject.contains(THEME_DEFINES_KEY)) {
QJsonValue definesJson = themeObject.value(THEME_DEFINES_KEY);
if (!definesJson.isObject()) {
qWarning() << "W" << Q_FUNC_INFO << "\"defines\" is not defined as an object";
} else {
QJsonObject definesObject = definesJson.toObject();
foreach (const QString key, definesObject.keys()) {
defines.insert(key, definesObject.value(key));
}
}
} else {
qWarning() << "W" << Q_FUNC_INFO
<< "Theme file does not contain a \"defines\" object. "\
"Please add an empty \"defines\" object instead";
}
// Set the global values (name, description etc.)
setName(jsonValue(themeObject, THEME_NAME_KEY).toString());
setDescription(jsonValue(themeObject, THEME_DESCRIPTION_KEY).toString());
// Parse the defined objects
QJsonObject styles = jsonValue(themeObject, THEME_STYLES_KEY).toObject();
if (styles.isEmpty()) {
return;
}
// Setting properties for button
QJsonObject stylesButton = styles.value("button").toObject();
m_button->setBackground(jsonToColor(jsonValue(stylesButton, "background", "button"), defines));
// Setting properties for text
QJsonObject stylesButtonText = stylesButton.value("text").toObject();
m_button->text()->setColor(jsonToColor(jsonValue(stylesButtonText, "color", "text"), defines));
// Setting properties for font
QJsonObject stylesButtonTextFont = stylesButtonText.value("font").toObject();
if (stylesButtonTextFont.contains("pointSize")) {
m_button->text()->font()->setPointSize(jsonToInt(stylesButtonText.value("font"), defines));
}
if (stylesButtonTextFont.contains("weight")) {
m_button->text()->font()->setWeight(jsonToInt(stylesButtonText.value("font"), defines));
}
// Setting properties for pressedGradient
QJsonObject stylesButtonPressedGradient = stylesButton.value("pressedGradient").toObject();
m_button->pressedGradient()->setCenterColor(jsonToColor(jsonValue(stylesButtonPressedGradient, "centerColor", "pressedGradient"), defines));
m_button->pressedGradient()->setEdgeColor(jsonToColor(jsonValue(stylesButtonPressedGradient, "edgeColor", "pressedGradient"), defines));
if (stylesButtonPressedGradient.contains("width")) {
m_button->pressedGradient()->setWidth(jsonToInt(stylesButton.value("pressedGradient"), defines));
}
if (stylesButtonPressedGradient.contains("height")) {
m_button->pressedGradient()->setHeight(jsonToInt(stylesButton.value("pressedGradient"), defines));
}
if (stylesButtonPressedGradient.contains("center")) {
m_button->pressedGradient()->setCenter(jsonToDouble(stylesButton.value("pressedGradient"), defines));
}
if (stylesButtonPressedGradient.contains("edge")) {
m_button->pressedGradient()->setEdge(jsonToDouble(stylesButton.value("pressedGradient"), defines));
}
// Setting properties for primaryButton
QJsonObject stylesPrimaryButton = styles.value("primaryButton").toObject();
m_primaryButton->setBackground(jsonToColor(jsonValue(stylesPrimaryButton, "background", "primaryButton"), defines));
// Setting properties for text
QJsonObject stylesPrimaryButtonText = stylesPrimaryButton.value("text").toObject();
m_primaryButton->text()->setColor(jsonToColor(jsonValue(stylesPrimaryButtonText, "color", "text"), defines));
// Setting properties for font
QJsonObject stylesPrimaryButtonTextFont = stylesPrimaryButtonText.value("font").toObject();
if (stylesPrimaryButtonTextFont.contains("pointSize")) {
m_primaryButton->text()->font()->setPointSize(jsonToInt(stylesPrimaryButtonText.value("font"), defines));
}
if (stylesPrimaryButtonTextFont.contains("weight")) {
m_primaryButton->text()->font()->setWeight(jsonToInt(stylesPrimaryButtonText.value("font"), defines));
}
// Setting properties for pressedGradient
QJsonObject stylesPrimaryButtonPressedGradient = stylesPrimaryButton.value("pressedGradient").toObject();
m_primaryButton->pressedGradient()->setCenterColor(jsonToColor(jsonValue(stylesPrimaryButtonPressedGradient, "centerColor", "pressedGradient"), defines));
m_primaryButton->pressedGradient()->setEdgeColor(jsonToColor(jsonValue(stylesPrimaryButtonPressedGradient, "edgeColor", "pressedGradient"), defines));
if (stylesPrimaryButtonPressedGradient.contains("width")) {
m_primaryButton->pressedGradient()->setWidth(jsonToInt(stylesPrimaryButton.value("pressedGradient"), defines));
}
if (stylesPrimaryButtonPressedGradient.contains("height")) {
m_primaryButton->pressedGradient()->setHeight(jsonToInt(stylesPrimaryButton.value("pressedGradient"), defines));
}
if (stylesPrimaryButtonPressedGradient.contains("center")) {
m_primaryButton->pressedGradient()->setCenter(jsonToDouble(stylesPrimaryButton.value("pressedGradient"), defines));
}
if (stylesPrimaryButtonPressedGradient.contains("edge")) {
m_primaryButton->pressedGradient()->setEdge(jsonToDouble(stylesPrimaryButton.value("pressedGradient"), defines));
}
}
/*
* Copyright (C) 2013 Lucien Xu <sfietkonstantin@free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// This class is autogenerated using themehelper.py
// Any modification done in this file will be overridden
#ifndef NEMOTHEME_H
#define NEMOTHEME_H
#include <QtCore/QObject>
#include <QtCore/QString>
#include "nemothemebutton.h"
class NemoTheme: public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
Q_PROPERTY(NemoThemeButton * button READ button CONSTANT)
Q_PROPERTY(NemoThemeButton * primaryButton READ primaryButton CONSTANT)
Q_PROPERTY(QString fontFamily READ fontFamily CONSTANT)
public:
explicit NemoTheme(QObject *parent = 0);
QString name() const;
void setName(QString name);
QString description() const;
void setDescription(QString description);
NemoThemeButton * button() const;
NemoThemeButton * primaryButton() const;
QString fontFamily() const;
public Q_SLOTS:
void loadFromFile(const QString &fileName);
Q_SIGNALS:
void nameChanged();
void descriptionChanged();
private:
QString m_name;
QString m_description;
NemoThemeButton * m_button;
NemoThemeButton * m_primaryButton;
QString m_fontFamily;
};
#endif //NEMOTHEME_H
/*
* Copyright (C) 2013 Lucien Xu <sfietkonstantin@free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// This class is autogenerated using themehelper.py
// Any modification done in this file will be overridden
#include "nemothemebutton.h"
NemoThemeButton::NemoThemeButton(QObject *parent)
: QObject(parent)
, m_text(new NemoThemeButtonText(this))
, m_pressedGradient(new NemoThemeButtonPressedGradient(this))
{
}
QColor NemoThemeButton::background() const
{
return m_background;
}
void NemoThemeButton::setBackground(QColor background)
{
if (m_background != background) {
m_background = background;
emit backgroundChanged();
}
}
NemoThemeButtonText * NemoThemeButton::text() const
{
return m_text;
}
NemoThemeButtonPressedGradient * NemoThemeButton::pressedGradient() const
{
return m_pressedGradient;
}
/*
* Copyright (C) 2013 Lucien Xu <sfietkonstantin@free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// This class is autogenerated using themehelper.py
// Any modification done in this file will be overridden
#ifndef NEMOTHEMEBUTTON_H
#define NEMOTHEMEBUTTON_H
#include <QtCore/QObject>
#include <QtGui/QColor>
#include "nemothemebuttontext.h"
#include "nemothemebuttonpressedgradient.h"
class NemoThemeButton: public QObject
{
Q_OBJECT
Q_PROPERTY(QColor background READ background NOTIFY backgroundChanged)
Q_PROPERTY(NemoThemeButtonText * text READ text CONSTANT)
Q_PROPERTY(NemoThemeButtonPressedGradient * pressedGradient READ pressedGradient CONSTANT)
public:
explicit NemoThemeButton(QObject *parent = 0);
QColor background() const;
void setBackground(QColor background);
NemoThemeButtonText * text() const;
NemoThemeButtonPressedGradient * pressedGradient() const;
Q_SIGNALS:
void backgroundChanged();
private:
QColor m_background;
NemoThemeButtonText * m_text;
NemoThemeButtonPressedGradient * m_pressedGradient;
};
#endif //NEMOTHEMEBUTTON_H
/*
* Copyright (C) 2013 Lucien Xu <sfietkonstantin@free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// This class is autogenerated using themehelper.py
// Any modification done in this file will be overridden
#include "nemothemebuttonpressedgradient.h"
NemoThemeButtonPressedGradient::NemoThemeButtonPressedGradient(QObject *parent)
: QObject(parent)
, m_width(240)
, m_height(240)
, m_center(0.29)
, m_edge(0.5)
{
}
QColor NemoThemeButtonPressedGradient::centerColor() const
{
return m_centerColor;
}
void NemoThemeButtonPressedGradient::setCenterColor(QColor centerColor)
{
if (m_centerColor != centerColor) {
m_centerColor = centerColor;
emit centerColorChanged();
}
}
QColor NemoThemeButtonPressedGradient::edgeColor() const
{
return m_edgeColor;
}
void NemoThemeButtonPressedGradient::setEdgeColor(QColor edgeColor)
{
if (m_edgeColor != edgeColor) {
m_edgeColor = edgeColor;
emit edgeColorChanged();
}
}
int NemoThemeButtonPressedGradient::width() const
{
return m_width;
}
void NemoThemeButtonPressedGradient::setWidth(const int &width)
{
if (m_width != width) {
m_width = width;
emit widthChanged();
}
}
int NemoThemeButtonPressedGradient::height() const
{
return m_height;
}
void NemoThemeButtonPressedGradient::setHeight(const int &height)
{
if (m_height != height) {
m_height = height;
emit heightChanged();
}
}
double NemoThemeButtonPressedGradient::center() const
{
return m_center;
}
void NemoThemeButtonPressedGradient::setCenter(const double &center)
{
if (m_center != center) {
m_center = center;
emit centerChanged();
}
}
double NemoThemeButtonPressedGradient::edge() const
{
return m_edge;
}
void NemoThemeButtonPressedGradient::setEdge(const double &edge)
{
if (m_edge != edge) {
m_edge = edge;
emit edgeChanged();
}
}
/*
* Copyright (C) 2013 Lucien Xu <sfietkonstantin@free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// This class is autogenerated using themehelper.py
// Any modification done in this file will be overridden
#ifndef NEMOTHEMEBUTTONPRESSEDGRADIENT_H
#define NEMOTHEMEBUTTONPRESSEDGRADIENT_H
#include <QtCore/QObject>
#include <QtGui/QColor>
class NemoThemeButtonPressedGradient: public QObject
{
Q_OBJECT
Q_PROPERTY(QColor centerColor READ centerColor NOTIFY centerColorChanged)
Q_PROPERTY(QColor edgeColor READ edgeColor NOTIFY edgeColorChanged)
Q_PROPERTY(int width READ width NOTIFY widthChanged)
Q_PROPERTY(int height READ height NOTIFY heightChanged)
Q_PROPERTY(double center READ center NOTIFY centerChanged)
Q_PROPERTY(double edge READ edge NOTIFY edgeChanged)
public:
explicit NemoThemeButtonPressedGradient(QObject *parent = 0);
QColor centerColor() const;
void setCenterColor(QColor centerColor);
QColor edgeColor() const;
void setEdgeColor(QColor edgeColor);
int width() const;
void setWidth(const int &width);
int height() const;
void setHeight(const int &height);
double center() const;
void setCenter(const double &center);
double edge() const;
void setEdge(const double &edge);
Q_SIGNALS:
void centerColorChanged();
void edgeColorChanged();
void widthChanged();
void heightChanged();
void centerChanged();
void edgeChanged();
private:
QColor m_centerColor;
QColor m_edgeColor;
int m_width;
int m_height;
double m_center;
double m_edge;
};
#endif //NEMOTHEMEBUTTONPRESSEDGRADIENT_H
/*
* Copyright (C) 2013 Lucien Xu <sfietkonstantin@free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// This class is autogenerated using themehelper.py
// Any modification done in this file will be overridden
#include "nemothemebuttontext.h"
NemoThemeButtonText::NemoThemeButtonText(QObject *parent)
: QObject(parent)
, m_font(new NemoThemeFont(this))
{
}
QColor NemoThemeButtonText::color() const
{
return m_color;
}
void NemoThemeButtonText::setColor(QColor color)
{
if (m_color != color) {
m_color = color;
emit colorChanged();
}
}
NemoThemeFont * NemoThemeButtonText::font() const
{
return m_font;
}
/*
* Copyright (C) 2013 Lucien Xu <sfietkonstantin@free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// This class is autogenerated using themehelper.py
// Any modification done in this file will be overridden
#ifndef NEMOTHEMEBUTTONTEXT_H
#define NEMOTHEMEBUTTONTEXT_H
#include <QtCore/QObject>
#include <QtGui/QColor>
#include "nemothemefont.h"
class NemoThemeButtonText: public QObject
{
Q_OBJECT
Q_PROPERTY(QColor color READ color NOTIFY colorChanged)
Q_PROPERTY(NemoThemeFont * font READ font CONSTANT)
public:
explicit NemoThemeButtonText(QObject *parent = 0);
QColor color() const;
void setColor(QColor color);
NemoThemeFont * font() const;
Q_SIGNALS:
void colorChanged();
private:
QColor m_color;
NemoThemeFont * m_font;
};
#endif //NEMOTHEMEBUTTONTEXT_H
/*
* Copyright (C) 2013 Andrea Bernabei <and.bernabei@gmail.com>
* Copyright (C) 2013 Lucien Xu <sfietkonstantin@free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -17,40 +17,40 @@
* Boston, MA 02110-1301, USA.
*/
import QtQml 2.1
import "../../Styles/Nemo/themes/Theme1.js" as Theme1
import "../../Styles/Nemo/themes/Theme2.js" as Theme2
// This class is autogenerated using themehelper.py
// Any modification done in this file will be overridden
QtObject {
readonly property var themes: [Theme1.themeName, Theme2.themeName]
#include "nemothemefont.h"
//THIS IS WHAT IS RESPONSIBLE FOR THE THEME CHANGE, changing this will change all the rest
//THEME CONFIG IS THE REFERENCE TO THE .JS FILE HOLDING THE THEME CONFIGS
property var currentThemeConfig: Theme1
NemoThemeFont::NemoThemeFont(QObject *parent)
: QObject(parent)
, m_pointSize(24)
, m_weight(25)
{
}
function setTheme(theme) {
if (themes.indexOf(theme) >= 0) {
var newThemeConfig = getThemeConfigOf(theme)
if (newThemeConfig !== undefined) {
currentThemeConfig = newThemeConfig
} else {
console.log("Theme config not handled, the theme was not changed")
}
} else {
console.log("Theme " + theme + " is not handled");
}
}
int NemoThemeFont::pointSize() const
{
return m_pointSize;
}
function getThemeConfigOf(theme) {
switch (theme) {
case Theme1.themeName:
return Theme1
case Theme2.themeName:
return Theme2
default:
console.log("There is no theme config for the theme " + theme)
return undefined
}
void NemoThemeFont::setPointSize(const int &pointSize)
{
if (m_pointSize != pointSize) {
m_pointSize = pointSize;
emit pointSizeChanged();
}
}
int NemoThemeFont::weight() const
{
return m_weight;
}
void NemoThemeFont::setWeight(const int &weight)
{
if (m_weight != weight) {
m_weight = weight;
emit weightChanged();
}
}
/*
* Copyright (C) 2013 Lucien Xu <sfietkonstantin@free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// This class is autogenerated using themehelper.py
// Any modification done in this file will be overridden
#ifndef NEMOTHEMEFONT_H
#define NEMOTHEMEFONT_H
#include <QtCore/QObject>
class NemoThemeFont: public QObject
{
Q_OBJECT
Q_PROPERTY(int pointSize READ pointSize NOTIFY pointSizeChanged)
Q_PROPERTY(int weight READ weight NOTIFY weightChanged)
public:
explicit NemoThemeFont(QObject *parent = 0);
int pointSize() const;
void setPointSize(const int &pointSize);
int weight() const;
void setWeight(const int &weight);
Q_SIGNALS:
void pointSizeChanged();
void weightChanged();
private:
int m_pointSize;
int m_weight;
};
#endif //NEMOTHEMEFONT_H
......@@ -20,36 +20,30 @@
#include "qquicknemostyleextensionplugin.h"
#include <QtQml>
#include "nemotheme.h"
QQuickNemoStyleExtensionPlugin::QQuickNemoStyleExtensionPlugin(QObject *parent) :
QQmlExtensionPlugin(parent)
{
}
static QObject *nemo_style_singletontype_provider(QQmlEngine *engine, QJSEngine */*scriptEngine*/)
static QObject * nemo_theme_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
QObject *ret = 0;
qWarning() << QFileInfo("private/ControlsStyleConfig.qml").absoluteFilePath();
qWarning() << QDir::currentPath();
QQmlComponent c(engine,QUrl::fromLocalFile("/usr/lib/qt5/qml/QtQuick/Controls/Styles/Nemo/private/ControlsStyleConfig.qml"),QQmlComponent::PreferSynchronous);
if (c.status() == QQmlComponent::Ready) {
ret = c.create();
if (!ret) {
qWarning() << "Can't create Controls Style Config Singleton Object:"<<c.errorString();
}
} else {
qWarning() << "Controls Style Config Component not Ready:"<<c.errorString();
}
return ret;
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
return new NemoTheme();
}
void QQuickNemoStyleExtensionPlugin::registerTypes(const char *uri)
{
Q_ASSERT(uri == QLatin1String("QtQuick.Controls.Styles.Nemo"));
qmlRegisterSingletonType<QObject>(uri,1,0,"Theme",nemo_style_singletontype_provider);
QString reason = QString("Cannot be created");
qmlRegisterUncreatableType<NemoTheme>(uri, 1, 0, "NemoTheme", reason);
qmlRegisterUncreatableType<NemoThemeButton>(uri, 1, 0, "NemoThemeButton", reason);
qmlRegisterUncreatableType<NemoThemeButtonPressedGradient>(uri, 1, 0, "NemoThemeButtonPressedGradient", reason);
qmlRegisterUncreatableType<NemoThemeButtonText>(uri, 1, 0, "NemoThemeButtonText", reason);
qmlRegisterUncreatableType<NemoThemeFont>(uri, 1, 0, "NemoThemeFont", reason);
qmlRegisterSingletonType<QObject>(uri, 1, 0, "Theme", nemo_theme_provider);
}
void QQuickNemoStyleExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
......
......@@ -23,6 +23,9 @@
#include <QtQml/QQmlExtensionPlugin>
class QQmlEngine;
class QJSEngine;
class NemoThemeGlobal;
class QQuickNemoStyleExtensionPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
......
......@@ -28,10 +28,6 @@ QML_FILES = \
ToolBarStyle.qml \
ToolButtonStyle.qml
# Private files
QML_FILES += \
private/ControlsStyleConfig.qml
# Images
#QML_FILES += \
# images/480x854/*.png
......@@ -64,6 +60,8 @@ QML_FILES += \
OTHER_FILES += qmldir \
themes/Theme1.js \
themes/Theme2.js \
themes/glacier.json \
themes/ugly.json \
$$QML_FILES
target.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH
......@@ -72,23 +70,29 @@ qmlfiles.files = $$_PRO_FILE_PWD_/*.qml
qmlfiles.files += $$_PRO_FILE_PWD_/qmldir
qmlfiles.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH
privatefiles.files = $$_PRO_FILE_PWD_/private/*.qml
privatefiles.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH/private
themes.files = $$_PRO_FILE_PWD_/themes/*.js
themes.files = $$_PRO_FILE_PWD_/themes/*.json
themes.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH/themes
images.files = $$_PRO_FILE_PWD_/images
images.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH
HEADERS += \
qquicknemostyleextensionplugin.h
qquicknemostyleextensionplugin.h \
nemothemebutton.h \
nemothemebuttonpressedgradient.h \
nemothemebuttontext.h \
nemothemefont.h \
nemotheme.h
SOURCES += \
qquicknemostyleextensionplugin.cpp
qquicknemostyleextensionplugin.cpp \
nemothemebutton.cpp \
nemothemebuttonpressedgradient.cpp \
nemothemebuttontext.cpp \
nemothemefont.cpp \
nemotheme.cpp
INSTALLS += target images qmlfiles themes privatefiles
INSTALLS += target images qmlfiles themes
# RESOURCES += \
# rsc.qrc
DEFINES += 'THEME_DIR=\'\"$$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH/themes"\''
{
"name": "Glacier",
"description": "Glacier theme",
"defines": {
"accentColor": "#0091e5",
"fillColor": "#474747"
},
"styles": {
"button": {
"background": "fillColor",
"text": {
"color": "white"
},
"pressedGradient": {
"centerColor": "accentColor",
"edgeColor": "transparent"
}
},
"primaryButton": {
"background": "accentColor",
"text": {
"color": "white",
"font": {
"weight": 63
}
},
"pressedGradient": {
"centerColor": "white",
"edgeColor": "accentColor"
}
}
}
}
{
"name": "Ugly",
"description": "Ugly test theme",
"defines": {
"accentColor": "#FF7F00",
"fillColor": "#474747"
},
"styles": {
"button": {
"background": "fillColor",
"text": {
"color": "blue"
},
"pressedGradient": {
"centerColor": "accentColor",
"edgeColor": "transparent"
}
},
"primaryButton": {
"background": "accentColor",
"text": {
"color": "blue",
"font": {
"weight": 63
}
},
"pressedGradient": {
"centerColor": "white",
"edgeColor": "accentColor"
}
}
}
}
#!/usr/bin/python
# Copyright (C) 2013 Lucien Xu. <sfietkonstantin@free.fr>
#
# You may use this file under the terms of the BSD license as follows:
#
# "Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Nemo Mobile nor the names of its contributors
# may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
import json
license = """/*
* Copyright (C) 2013 Lucien Xu <sfietkonstantin@free.fr>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
// This class is autogenerated using themehelper.py
// Any modification done in this file will be overridden
"""
basicTypes = ["int", "float", "double"]
def _getType(property):
if "type" in property:
return property["type"]
if "object" in property:
return "NemoTheme" + _getUpper(property["object"]) + " *"
return None
def _getArgumentType(property):
if "type" in property:
type = property["type"]
if type in basicTypes:
return "const " + type + " &"
return type + " "
if "object" in property:
return "NemoTheme" + _getUpper(property["object"]) + " *"
return None
def _getUpper(name):
return name[0].upper() + name[1:]
def _getInclude(property):
if "type" in property:
type = property["type"]
if type in basicTypes:
return None
if type in ["QString", "QVariant", "QUrl", "QVariantMap", "QDateTime"]:
return "<QtCore/" + type + ">"
if type in ["QColor"]:
return "<QtGui/" + type + ">"
if "object" in property:
return "\"nemotheme" + property["object"].lower() + ".h\""
return None
def _getProperty(property):
propertyName = property["name"]
header = " Q_PROPERTY(" + _getType(property) + " " + propertyName
header += " READ " + propertyName
if "type" in property:
return header + " NOTIFY " + propertyName + "Changed)\n"
if "object" in property:
return header + " CONSTANT)\n"
def _getGetterSetter(property):
propertyName = property["name"]
header = " " + _getType(property) + " " + propertyName + "() const;\n"
if "type" in property:
header += " void set" + _getUpper(propertyName)
header += "(" + _getArgumentType(property) + propertyName + ");\n"
return header
def _getGetterSetterImpl(name, property):
propertyName = property["name"]
source = _getType(property) + " " + name + "::" + propertyName + "() const\n"
source += "{\n"
source += " return m_" + propertyName + ";\n"
source += "}\n"
source += "\n"
if "type" in property:
source += "void " + name + "::set" + _getUpper(propertyName)
source += "(" + _getArgumentType(property) + propertyName + ")\n"
source += "{\n"
source += " if (m_" + propertyName + " != " + propertyName + ") {\n"
source += " m_" + propertyName + " = " + propertyName + ";\n"
source += " emit " + propertyName + "Changed();\n"
source += " }\n"
source += "}\n"
source += "\n"
return source
def _getSignal(property):
if "object" in property:
return ""
return " void " + property["name"] + "Changed();\n"
def _getLoadFromFile(name, data):
# Write helper methods that are used to parse theme file
source = """
static inline QJsonValue jsonValue(const QJsonObject &object, const QString &key,
const QString &objectName = QString())
{
if (!object.contains(key)) {
if (objectName.isEmpty()) {
qWarning() << "W" << "Root JSON object do not have value" << key;
} else {
qWarning() << "W" << "JSON Object" << objectName << "do not have value" << key;
}
return QJsonValue();
}
return object.value(key);
}
static inline QString jsonToString(const QJsonValue &value,
const QMap<QString, QJsonValue> &defines)
{
QString valueString = value.toString();
if (defines.contains(valueString)) {
return defines.value(valueString).toString();
}
return value.toString();
}
static inline QColor jsonToColor(const QJsonValue &value,
const QMap<QString, QJsonValue> &defines)
{
QString color = value.toString();
if (defines.contains(color)) {
color = defines.value(color).toString();
}
if (!QColor::isValidColor(color)) {
qWarning() << "W" << color << "is not a valid color";
return QColor();
}
return QColor(color);
}
static inline int jsonToInt(const QJsonValue &value,
const QMap<QString, QJsonValue> &defines)
{
QJsonValue trueValue = value;
if (value.isString()) {
QString valueString = value.toString();
if (defines.contains(valueString)) {
trueValue = defines.value(valueString);
}
}
double doubleValue = trueValue.toDouble();
return (int) doubleValue;
}
static inline int jsonToDouble(const QJsonValue &value,
const QMap<QString, QJsonValue> &defines)
{
QJsonValue trueValue = value;
if (value.isString()) {
QString valueString = value.toString();
if (defines.contains(valueString)) {
trueValue = defines.value(valueString);
}
}
return trueValue.toDouble();
}
"""
source += "void " + name + "::loadFromFile(const QString &fileName)\n"
source += """{
QDir dir (THEME_DIR);
if (!dir.exists(fileName)) {
qWarning() << "E" << Q_FUNC_INFO << "Theme file" << fileName << "does not exists.";
return;
}
QFile themeFile (dir.absoluteFilePath(fileName));
if (!themeFile.open(QIODevice::ReadOnly)) {
qWarning() << "E" << Q_FUNC_INFO << "Theme file" << fileName << "could not be read.";
return;
}
QJsonParseError error;
QJsonDocument themeDocument = QJsonDocument::fromJson(themeFile.readAll(), &error);
themeFile.close();
if (error.error != QJsonParseError::NoError) {
qWarning() << "E" << Q_FUNC_INFO << "Cannot parse theme file:" << error.errorString();
return;
}
// Fetch all the defines
QMap<QString, QJsonValue> defines;
if (!themeDocument.isObject()) {
qWarning() << "E" << Q_FUNC_INFO << "Theme file has an invalid format";
return;
}
QJsonObject themeObject = themeDocument.object();
if (themeObject.contains(THEME_DEFINES_KEY)) {
QJsonValue definesJson = themeObject.value(THEME_DEFINES_KEY);
if (!definesJson.isObject()) {
qWarning() << "W" << Q_FUNC_INFO << "\\"defines\\" is not defined as an object";
} else {
QJsonObject definesObject = definesJson.toObject();
foreach (const QString key, definesObject.keys()) {
defines.insert(key, definesObject.value(key));
}
}
} else {
qWarning() << "W" << Q_FUNC_INFO
<< "Theme file does not contain a \\"defines\\" object. "\\
"Please add an empty \\"defines\\" object instead";
}
// Set the global values (name, description etc.)
setName(jsonValue(themeObject, THEME_NAME_KEY).toString());
setDescription(jsonValue(themeObject, THEME_DESCRIPTION_KEY).toString());
// Parse the defined objects
QJsonObject styles = jsonValue(themeObject, THEME_STYLES_KEY).toObject();
if (styles.isEmpty()) {
return;
}
"""
# We create a map of components
components = {}
for component in data["components"]:
components[component["name"]] = component["properties"]
for property in data["properties"]:
if "object" in property:
name = property["name"]
type = property["object"]
source += _getSetObject("styles", "m_" + name, name, components[type], components)
source += "}\n"
return source
def _getCasted(property, jsonObject, name, cppObject):
type = property["type"]
castedValue = None
value = "jsonValue(" + jsonObject + _getUpper(name) + ", \""
value += property["name"] + "\", \"" + name + "\")"
if "default" in property:
value = jsonObject + ".value(\"" + name + "\")"
if type == "QString":
castedValue = "jsonToString(" + value + ", defines)"
elif type == "QColor":
castedValue = "jsonToColor(" + value + ", defines)"
elif type == "int":
castedValue = "jsonToInt(" + value + ", defines)"
elif type == "double":
castedValue = "jsonToDouble(" + value + ", defines)"
else:
print "\"" + type + "\" is not a known type. TODO !"
if castedValue == None:
return ""
if "default" in property:
data = " if (" + jsonObject + _getUpper(name) + ".contains(\""
data += property["name"] + "\")) {\n"
data += " " + cppObject + "->set" + _getUpper(property["name"])
data += "(" + castedValue + ");\n"
data += " }\n"
return data
else:
data = " " + cppObject + "->set" + _getUpper(property["name"])
data += "(" + castedValue + ");\n"
return data
def _getSetObject(jsonObject, cppObject, name, properties, components):
data = " // Setting properties for " + name + "\n"
data += " QJsonObject " + jsonObject + _getUpper(name) + " = " + jsonObject
data += ".value(\"" + name + "\").toObject();\n"
for property in properties:
if "object" in property:
type = property["object"]
data += _getSetObject(jsonObject + _getUpper(name),
cppObject + "->" + property["name"] + "()",
property["name"], components[type], components)
if "type" in property:
data += _getCasted(property, jsonObject, name, cppObject)
return data
def generate(data, writeThemeObject = False):
# If we have a name, we are generating a component,
# otherwise, we are generating the global theme object
if "name" in data:
name = "NemoTheme" + _getUpper(data["name"])
else:
name = "NemoTheme"
properties = []
if writeThemeObject:
properties.append({"name": "name", "type": "QString"})
properties.append({"name": "description", "type": "QString"})
for property in data["properties"]:
properties.append(property)
header = license
header += "#ifndef " + name.upper() + "_H\n"
header += "#define " + name.upper() + "_H\n"
header += "\n"
header += "#include <QtCore/QObject>\n"
includes = []
for property in properties:
include = _getInclude(property)
if include != None and not include in includes:
includes.append(include)
for include in includes:
header += "#include " + include + "\n"
header += "\n"
header += "class " + name + ": public QObject\n"
header += "{\n"
header += " Q_OBJECT\n"
# Generate properties
for property in properties:
header += _getProperty(property)
if writeThemeObject:
header += " Q_PROPERTY(QString fontFamily READ fontFamily CONSTANT)\n"
header += "public:\n"
# Constructor
header += " explicit " + name + "(QObject *parent = 0);\n"
# Generates getters and setters
for property in properties:
header += _getGetterSetter(property)
if writeThemeObject:
header += " QString fontFamily() const;\n"
header += "public Q_SLOTS:\n"
header += " void loadFromFile(const QString &fileName);\n"
header += "Q_SIGNALS:\n"
# Generate signals
for property in properties:
header += _getSignal(property)
header += "private:\n"
# Generate private members
for property in properties:
header += " " + _getType(property) + " m_" + property["name"] + ";\n"
if writeThemeObject:
header += " QString m_fontFamily;\n"
header += "};\n"
header += "\n"
header += "#endif //" + name.upper() + "_H\n"
try:
f = open(name.lower() + ".h", "w")
f.write(header)
f.close()
except:
print "Failed to write to " + name.lower() + ".h"
return
source = license
source += "#include \"" + name.lower() + ".h\"\n"
if writeThemeObject:
# Adds the additional includes
source += "#include <QtCore/QDebug>\n#include <QtCore/QDir>\n#include <QtCore/QFile>\n"
source += "#include <QtCore/QJsonDocument>\n#include <QtCore/QJsonArray>\n"
source += "#include <QtCore/QJsonObject>\n#include <QtCore/QJsonValue>\n"
source += "#include <QtGui/QFontDatabase>\n"
source += "\n"
if writeThemeObject:
# Adds the additional defines
source += "static const char *GLACIER_THEME = \"glacier.json\";\n"
source += "static const char *THEME_NAME_KEY = \"name\";\n"
source += "static const char *THEME_DESCRIPTION_KEY = \"description\";\n"
source += "static const char *THEME_DEFINES_KEY = \"defines\";\n"
source += "static const char *THEME_STYLES_KEY = \"styles\";\n"
source += "\n"
# Generate constructor
source += name + "::" + name + "(QObject *parent)\n"
source += " : QObject(parent)\n"
# Init members if needed
for property in properties:
if "type" in property:
if "default" in property:
default = str(property["default"])
if isinstance(property["default"], str) or isinstance(property["default"], unicode):
default = "\"" + default + "\""
source += " , m_" + property["name"] + "(" + default + ")\n"
else:
if property["type"] in basicTypes:
if property["type"] == "int":
source += " , m_" + property["name"] + "(0)\n"
else:
source += " , m_" + property["name"] + "(0.)\n"
elif "object" in property:
source += " , m_" + property["name"] + "(new NemoTheme" + _getUpper(property["object"])
source += "(this))\n"
source += "{\n"
if writeThemeObject:
source += """ loadFromFile(GLACIER_THEME);
int id = QFontDatabase::addApplicationFont(\"""" + data["font"] + """\");
QStringList families = QFontDatabase::applicationFontFamilies(id);
if (families.isEmpty()) {
qWarning() << "W" << "Failed to load font" << QString(\"""" + data["font"] + """\");
return;
}
m_fontFamily = families.first();
"""
source += "}\n"
source += "\n"
# Generate getters and setters
for property in properties:
source += _getGetterSetterImpl(name, property)
source = source[:-1]
if writeThemeObject:
source += "\n"
source += "QString " + name + "::fontFamily() const\n"
source += "{\n"
source += " return m_fontFamily;\n"
source += "}\n"
source += _getLoadFromFile(name, data)
try:
f = open(name.lower() + ".cpp", "w")
f.write(source)
f.close()
except:
print "Failed to write to " + name.lower() + ".cpp"
return
{
"components": [
{
"name": "Button",
"properties": [
{
"name": "background",
"type": "QColor"
},
{
"name": "text",
"object": "ButtonText"
},
{
"name": "pressedGradient",
"object": "ButtonPressedGradient"
}
]
},
{
"name": "ButtonPressedGradient",
"properties": [
{
"name": "centerColor",
"type": "QColor"
},
{
"name": "edgeColor",
"type": "QColor"
},
{
"name": "width",
"type": "int",
"default": 240
},
{
"name": "height",
"type": "int",
"default": 240
},
{
"name": "center",
"type": "double",
"default": 0.29
},
{
"name": "edge",
"type": "double",
"default": 0.5
}
]
},
{
"name": "ButtonText",
"properties": [
{
"name": "color",
"type": "QColor"
},
{
"name": "font",
"object": "Font"
}
]
},
{
"name": "Font",
"properties": [
{
"name": "pointSize",
"type": "int",
"default": 24
},
{
"name": "weight",
"type": "int",
"default": 25
}
]
}
],
"properties": [
{
"name": "button",
"object": "Button"
},
{
"name": "primaryButton",
"object": "Button"
}
],
"font": "/usr/share/fonts/google-opensans/OpenSans-Regular.ttf"
}
# Copyright (C) 2013 Jolla Ltd. <chris.adams@jollamobile.com>
#
# You may use this file under the terms of the BSD license as follows:
#
# "Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Nemo Mobile nor the names of its contributors
# may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
def includeGuard(name):
return name.replace("_", "").upper() + "_H"
def upperCamelCase(name):
camelCased = camelCase(split(name))
return camelCased[0].upper() + camelCased[1:]
def camelCase(name):
splitted = split(name)
newSplitted = []
for splittedWord in splitted:
splittedWord = splittedWord.lower()
splittedWord = splittedWord[0].upper() + splittedWord[1:]
newSplitted.append(splittedWord)
camelCase = "".join(newSplitted)
camelCase = camelCase[0].lower() + camelCase[1:]
return camelCase
def split(name):
return name.split("_")
def addSpaces(string, size):
spacesToAdd = max(size - len(string), 0)
return string + (" " * spacesToAdd)
#!/bin/bash
# Copyright (C) 2013 Lucien Xu <sfietkonstantin@free.fr>
#
# You may use this file under the terms of the BSD license as follows:
#
# "Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Nemo Mobile nor the names of its contributors
# may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
themehelper.py components.json
\ No newline at end of file
#!/usr/bin/python
# Copyright (C) 2013 Lucien Xu. <sfietkonstantin@free.fr>
#
# You may use this file under the terms of the BSD license as follows:
#
# "Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Nemo Mobile nor the names of its contributors
# may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
import json
import classgenerator
import argparse
def generate(descriptionFile):
# First, we try to open JSON description file
try:
f = open(descriptionFile)
except:
print "Failed to open " + descriptionFile
return
data = json.load(f)
classgenerator.generate(data, True)
for componentData in data["components"]:
classgenerator.generate(componentData)
# Main
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Theme helper')
parser.add_argument('description_file', metavar='description_file', type=str,
help="""Input description file (JSON)""")
args = parser.parse_args()
description_file = args.description_file
generate(description_file)
\ No newline at end of file
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