Commit 4ca99877 authored by SfietKonstantin's avatar SfietKonstantin

Merge pull request #2 from SfietKonstantin/devel

Added support for C++ theming components
parents 5a1e772b e9073375
*.pro.user
*.pyc
......@@ -51,11 +51,11 @@ 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")
}
Button {
......
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>main.qml</file>
<file>content/AndroidDelegate.qml</file>
<file>content/ButtonPage.qml</file>
<file>content/ProgressBarPage.qml</file>
<file>content/SliderPage.qml</file>
<file>content/TabBarPage.qml</file>
<file>content/TextInputPage.qml</file>
<file>images/button_default.png</file>
<file>images/button_pressed.png</file>
<file>images/navigation_next_item.png</file>
<file>images/navigation_previous_item.png</file>
<file>images/tab_selected.png</file>
<file>images/tabs_standard.png</file>
<file>images/textinput.png</file>
<file>images/toolbar.png</file>
</qresource>
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>content/AndroidDelegate.qml</file>
<file>content/ButtonPage.qml</file>
<file>content/ProgressBarPage.qml</file>
<file>content/SliderPage.qml</file>
<file>content/TabBarPage.qml</file>
<file>content/TextInputPage.qml</file>
<file>images/button_default.png</file>
<file>images/button_pressed.png</file>
<file>images/navigation_next_item.png</file>
<file>images/navigation_previous_item.png</file>
<file>images/tab_selected.png</file>
<file>images/tabs_standard.png</file>
<file>images/textinput.png</file>
<file>images/toolbar.png</file>
</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
......
......@@ -24,11 +24,11 @@ Component {
Rectangle {
implicitHeight: 16
implicitWidth: 440
color: Theme.groove.backgroundColor
color: Theme.groove.background
Rectangle {
antialiasing: true
radius: 1
color: Theme.groove.foregroundColor
color: Theme.groove.foreground
height: parent.height
width: parent.width * control.value / control.maximumValue
}
......
/*
* 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))
, m_groove(new NemoThemeGroove(this))
, m_textField(new NemoThemeTextField(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(const QString &name)
{
if (m_name != name) {
m_name = name;
emit nameChanged();
}
}
QString NemoTheme::description() const
{
return m_description;
}
void NemoTheme::setDescription(const 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;
}
NemoThemeGroove * NemoTheme::groove() const
{
return m_groove;
}
NemoThemeTextField * NemoTheme::textField() const
{
return m_textField;
}
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 does not have value" << key;
} else {
qWarning() << "W" << "JSON Object" << objectName << "does 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();
}
// We need to skip the warning caused by a null value,
// so we check if the color is not empty
if (!QColor::isValidColor(color) && !color.isEmpty()) {
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));
}
// Setting properties for groove
QJsonObject stylesGroove = styles.value("groove").toObject();
m_groove->setBackground(jsonToColor(jsonValue(stylesGroove, "background", "groove"), defines));
m_groove->setForeground(jsonToColor(jsonValue(stylesGroove, "foreground", "groove"), defines));
// Setting properties for textField
QJsonObject stylesTextField = styles.value("textField").toObject();
m_textField->setSelectedTextColor(jsonToColor(jsonValue(stylesTextField, "selectedTextColor", "textField"), defines));
m_textField->setSelectionColor(jsonToColor(jsonValue(stylesTextField, "selectionColor", "textField"), 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"
#include "nemothemegroove.h"
#include "nemothemetextfield.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(NemoThemeGroove * groove READ groove CONSTANT)
Q_PROPERTY(NemoThemeTextField * textField READ textField CONSTANT)
Q_PROPERTY(QString fontFamily READ fontFamily CONSTANT)
public:
explicit NemoTheme(QObject *parent = 0);
QString name() const;
void setName(const QString &name);
QString description() const;
void setDescription(const QString &description);
NemoThemeButton * button() const;
NemoThemeButton * primaryButton() const;
NemoThemeGroove * groove() const;
NemoThemeTextField * textField() 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;
NemoThemeGroove * m_groove;
NemoThemeTextField * m_textField;
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(const 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(const 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(const QColor &centerColor)
{
if (m_centerColor != centerColor) {
m_centerColor = centerColor;
emit centerColorChanged();
}
}
QColor NemoThemeButtonPressedGradient::edgeColor() const
{
return m_edgeColor;
}
void NemoThemeButtonPressedGradient::setEdgeColor(const QColor &edgeColor)
{
if (m_edgeColor != edgeColor) {
m_edgeColor = edgeColor;
emit edgeColorChanged();
}
}
int NemoThemeButtonPressedGradient::width() const
{
return m_width;
}
void NemoThemeButtonPressedGradient::setWidth(int width)
{
if (m_width != width) {
m_width = width;
emit widthChanged();
}
}
int NemoThemeButtonPressedGradient::height() const
{
return m_height;
}
void NemoThemeButtonPressedGradient::setHeight(int height)
{
if (m_height != height) {
m_height = height;
emit heightChanged();
}
}
double NemoThemeButtonPressedGradient::center() const
{
return m_center;
}
void NemoThemeButtonPressedGradient::setCenter(double center)
{
if (m_center != center) {
m_center = center;
emit centerChanged();
}
}
double NemoThemeButtonPressedGradient::edge() const
{
return m_edge;
}
void NemoThemeButtonPressedGradient::setEdge(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(const QColor &centerColor);
QColor edgeColor() const;
void setEdgeColor(const QColor &edgeColor);
int width() const;
void setWidth(int width);
int height() const;
void setHeight(int height);
double center() const;
void setCenter(double center);
double edge() const;
void setEdge(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(const 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(const 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(int pointSize)
{
if (m_pointSize != pointSize) {
m_pointSize = pointSize;
emit pointSizeChanged();
}
}
int NemoThemeFont::weight() const
{
return m_weight;
}
void NemoThemeFont::setWeight(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(int pointSize);
int weight() const;
void setWeight(int weight);
Q_SIGNALS:
void pointSizeChanged();
void weightChanged();
private:
int m_pointSize;
int m_weight;
};
#endif //NEMOTHEMEFONT_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 "nemothemegroove.h"
NemoThemeGroove::NemoThemeGroove(QObject *parent)
: QObject(parent)
{
}
QColor NemoThemeGroove::background() const
{
return m_background;
}
void NemoThemeGroove::setBackground(const QColor &background)
{
if (m_background != background) {
m_background = background;
emit backgroundChanged();
}
}
QColor NemoThemeGroove::foreground() const
{
return m_foreground;
}
void NemoThemeGroove::setForeground(const QColor &foreground)
{
if (m_foreground != foreground) {
m_foreground = foreground;
emit foregroundChanged();
}
}
/*
* 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 NEMOTHEMEGROOVE_H
#define NEMOTHEMEGROOVE_H
#include <QtCore/QObject>
#include <QtGui/QColor>
class NemoThemeGroove: public QObject
{
Q_OBJECT
Q_PROPERTY(QColor background READ background NOTIFY backgroundChanged)
Q_PROPERTY(QColor foreground READ foreground NOTIFY foregroundChanged)
public:
explicit NemoThemeGroove(QObject *parent = 0);
QColor background() const;
void setBackground(const QColor &background);
QColor foreground() const;
void setForeground(const QColor &foreground);
Q_SIGNALS:
void backgroundChanged();
void foregroundChanged();
private:
QColor m_background;
QColor m_foreground;
};
#endif //NEMOTHEMEGROOVE_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 "nemothemetextfield.h"
NemoThemeTextField::NemoThemeTextField(QObject *parent)
: QObject(parent)
{
}
QColor NemoThemeTextField::selectedTextColor() const
{
return m_selectedTextColor;
}
void NemoThemeTextField::setSelectedTextColor(const QColor &selectedTextColor)
{
if (m_selectedTextColor != selectedTextColor) {
m_selectedTextColor = selectedTextColor;
emit selectedTextColorChanged();
}
}
QColor NemoThemeTextField::selectionColor() const
{
return m_selectionColor;
}
void NemoThemeTextField::setSelectionColor(const QColor &selectionColor)
{
if (m_selectionColor != selectionColor) {
m_selectionColor = selectionColor;
emit selectionColorChanged();
}
}
/*
* 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 NEMOTHEMETEXTFIELD_H
#define NEMOTHEMETEXTFIELD_H
#include <QtCore/QObject>
#include <QtGui/QColor>
class NemoThemeTextField: public QObject
{
Q_OBJECT
Q_PROPERTY(QColor selectedTextColor READ selectedTextColor NOTIFY selectedTextColorChanged)
Q_PROPERTY(QColor selectionColor READ selectionColor NOTIFY selectionColorChanged)
public:
explicit NemoThemeTextField(QObject *parent = 0);
QColor selectedTextColor() const;
void setSelectedTextColor(const QColor &selectedTextColor);
QColor selectionColor() const;
void setSelectionColor(const QColor &selectionColor);
Q_SIGNALS:
void selectedTextColorChanged();
void selectionColorChanged();
private:
QColor m_selectedTextColor;
QColor m_selectionColor;
};
#endif //NEMOTHEMETEXTFIELD_H
/*
* Copyright (C) 2013 Tomasz Olszak <olszak.tomasz@gmail.com>
* Copyright (C) 2013 Andrea Bernabei <and.bernabei@gmail.com>
*
* 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.
*/
import QtQuick 2.1
import QtQuick.Controls.Nemo 1.0
QtObject {
readonly property string fontFamily: fontLoader.name
property QtObject fontLoader: FontLoader {
source: "/usr/share/fonts/google-opensans/OpenSans-Regular.ttf"
}
// The binding updates this var when NemoControls.setTheme succeeds
readonly property var themeConfig: NemoControls.currentThemeConfig
readonly property string themeName: themeConfig.themeName
onThemeNameChanged: console.log("Theme successfully updated to " + themeName)
// ({ }) is QML notation for assigning JS object to a var property
// Automagically updated when themeConfig is updated
property var button :
({
backgroundColor: themeConfig.button.background,
text: {
color: themeConfig.button.text,
font: {
pointSize: 24,
weight: 25 //Font.Light
}
},
pressedGradient: {
width: 240,
height: 240,
center: 0.29,
edge: 0.5,
centerColor: themeConfig.button.pressedGradient.centerColor,
edgeColor: themeConfig.button.pressedGradient.edgeColor
}
})
// Only holds special styling for the primary button, the rest is in button
property var primaryButton:
({
backgroundColor: themeConfig.primaryButton.background,
text: {
font: {
weight: 63 //Font.DemiBold
}
},
pressedGradient: {
centerColor: themeConfig.primaryButton.pressedGradient.centerColor,
edgeColor: themeConfig.primaryButton.pressedGradient.edgeColor
}
})
property var groove:
({
foregroundColor: themeConfig.groove.foreground,
backgroundColor: themeConfig.groove.background,
})
property var textField:
({
selectionColor: themeConfig.textField.selectionColor,
selectedTextColor: themeConfig.textField.selectedTextColor,
})
}
......@@ -20,36 +20,32 @@
#include "qquicknemostyleextensionplugin.h"
#include <QtQml>
#include "autogenerated/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);
qmlRegisterUncreatableType<NemoThemeGroove>(uri, 1, 0, "NemoThemeGroove", reason);
qmlRegisterUncreatableType<NemoThemeTextField>(uri, 1, 0, "NemoThemeTextField", 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,33 @@ 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 \
autogenerated/nemotheme.h \
autogenerated/nemothemebutton.h \
autogenerated/nemothemebuttonpressedgradient.h \
autogenerated/nemothemebuttontext.h \
autogenerated/nemothemefont.h \
autogenerated/nemothemegroove.h \
autogenerated/nemothemetextfield.h
SOURCES += \
qquicknemostyleextensionplugin.cpp
INSTALLS += target images qmlfiles themes privatefiles
# RESOURCES += \
# rsc.qrc
qquicknemostyleextensionplugin.cpp \
autogenerated/nemotheme.cpp \
autogenerated/nemothemebutton.cpp \
autogenerated/nemothemebuttonpressedgradient.cpp \
autogenerated/nemothemebuttontext.cpp \
autogenerated/nemothemefont.cpp \
autogenerated/nemothemegroove.cpp \
autogenerated/nemothemetextfield.cpp
INSTALLS += target images qmlfiles themes
DEFINES += 'THEME_DIR=\'\"$$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH/themes"\''
{
"name": "Glacier",
"description": "Glacier theme",
"defines": {
"accentColor": "#0091e5",
"fillColor": "#474747",
"fillColorDark": "#313131"
},
"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"
}
},
"groove": {
"foreground": "accentColor",
"background": "fillColorDark"
},
"textField": {
"selectedTextColor": "#ffffff",
"selectionColor": "#0091e5"
}
}
}
{
"name": "Ugly",
"description": "Ugly test theme",
"defines": {
"accentColor": "#FF7F00",
"fillColor": "#474747",
"fillColorDark": "#202020"
},
"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"
}
},
"groove": {
"foreground": "accentColor",
"background": "fillColorDark"
},
"textField": {
"selectedTextColor": "#ffffff",
"selectionColor": "#0091e5"
}
}
}
How to use the components generator
1. Have python 2 installed (the script don't work with Python 3 yet)
2. Add the components in "components.json"
3. call "./themehelper.py components.json"
4. copy all the generated files to the style folder in src
5. qmlRegisterUncreatableType the new created components in qquicknemostyleextensionplugin.cpp and
adds them in the style.pro file
6. update theme files if needed
#!/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
"""
# Used by formatting functions
basicTypes = ["int", "float", "double"]
# Formatting functions
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 not 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:]
# Generates some basic entries
# (includes, Q_PROPERTY macro, getter or setters etc)
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 does not have value" << key;
} else {
qWarning() << "W" << "JSON Object" << objectName << "does 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();
}
// We need to skip the warning caused by a null value,
// so we check if the color is not empty
if (!QColor::isValidColor(color) && !color.isEmpty()) {
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();
}
"""
# Generate the method that loads from file
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 that can be used
# to quickly retrieve a component based on the name
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
# This method is used to generate the tree of components and set calls
# it will start with a root component property, try to load all properties
# from theme file (and ignore those already defined), and continue
# with children components.
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": "Groove",
"properties": [
{
"name": "background",
"type": "QColor"
},
{
"name": "foreground",
"type": "QColor"
}
]
},
{
"name": "TextField",
"properties": [
{
"name": "selectedTextColor",
"type": "QColor"
},
{
"name": "selectionColor",
"type": "QColor"
}
]
},
{
"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"
},
{
"name": "groove",
"object": "Groove"
},
{
"name": "textField",
"object": "TextField"
}
],
"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)
#!/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."
# Generates components from a JSON description file
#
# This script generates components from a JSON description file.
# The JSON description file have the following organization
# {
# "components": [
# list of components
# ],
# "properties": [ list of properties ],
# "font": "/path/to/some_font.ttf"
# }
#
# The "components" is the list of components that should be generated.
# Each component have a "name", and a list of "properties". A property
# is a list of objects defined this way:
# {
# "name": "someName",
# "type": "some_type",
# ["default": some_value]
# }
# or
# {
# "name": "someName",
# "object": "some_object"
# }
#
# The first variation defines a simple property. "type" field should
# contain the name of either a basic type, like int, or float, or
# a Qt object, like QColor and QString. The optional "default" field
# contains a default value that is embedded in the component.
# Properties with default values don't need to be defined in the
# theme file.
#
# The second variation contains an object definition. Usually, an
# object defines a complex type, that needs several basic types to be
# defined, like a gradient, that needs 2 colors, and maybe a radius.
#
# The "properties" field of the root object behave the same, and
# describes the properties that the Theme object have. Note that
# "name" and "description" are automatically provided by the
# script, and don't need to be defined in the properties.
#
# The last field is the font. It provides the default font that
# is available from the Theme object.
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