├── source
├── QtQmlTricks
│ ├── include
│ │ ├── QtCOBS
│ │ ├── QtJsonPath
│ │ ├── QQmlHelpers
│ │ ├── QQuickPolygon
│ │ ├── QtBitStream
│ │ ├── QQmlSvgIconHelper
│ │ ├── QQmlGadgetListModel
│ │ ├── QQmlObjectListModel
│ │ ├── QQmlVariantListModel
│ │ └── QtQmlTricks
│ ├── examples
│ │ ├── NiceModels
│ │ │ ├── data_nicemodels.qrc
│ │ │ ├── NiceModels.qbs
│ │ │ ├── defs_nicemodels.h
│ │ │ ├── main_nicemodels.cpp
│ │ │ └── ui_nicemodels.qml
│ │ ├── CustomPolygon
│ │ │ ├── data_custompolygon.qrc
│ │ │ ├── CustomPolygon.qbs
│ │ │ ├── ui_custompolygon.qml
│ │ │ └── main_custompolygon.cpp
│ │ ├── IconCache
│ │ │ ├── data_iconcache.qrc
│ │ │ ├── IconCache.qbs
│ │ │ ├── main_iconcache.cpp
│ │ │ └── ui_iconcache.qml
│ │ ├── COBS
│ │ │ ├── QtCOBS.qbs
│ │ │ └── main_cobs.cpp
│ │ ├── JSONPath
│ │ │ ├── QtJsonPath.qbs
│ │ │ └── main_jsonpath.cpp
│ │ └── BitStream
│ │ │ ├── QtBitStream.qbs
│ │ │ └── main_bitstream.cpp
│ ├── import
│ │ ├── QtQmlTricks
│ │ │ ├── TextLabel.qml
│ │ │ ├── components.qrc
│ │ │ ├── qmldir
│ │ │ ├── QmlComponents.qbs
│ │ │ ├── Style.js
│ │ │ ├── SingleLineEditBox.qml
│ │ │ ├── TextButton.qml
│ │ │ ├── TextBox.qml
│ │ │ ├── RowContainer.qml
│ │ │ ├── IconTextButton.qml
│ │ │ ├── QtCoreApi.js
│ │ │ ├── GridContainer.qml
│ │ │ └── ComboList.qml
│ │ └── import.qbs
│ ├── src
│ │ ├── QtLibrary.qbs
│ │ ├── qqmlmodels.h
│ │ ├── qqmlvariantlistmodel_p.h
│ │ ├── qqmlvariantlistmodel.h
│ │ ├── qmlplugin.h
│ │ ├── qtcobs.h
│ │ ├── qquickpolygon.h
│ │ ├── qmlplugin.cpp
│ │ ├── qqmlsvgiconhelper.h
│ │ ├── qqmlhelpers.cpp
│ │ ├── qtjsonpath.h
│ │ ├── qqmlhelpers.h
│ │ ├── qtbitstream.h
│ │ └── qqmlsvgiconhelper.cpp
│ ├── CMakeLists.txt
│ ├── QtQmlTricks.qbs
│ └── README.md
├── Application
│ ├── Application.qrc
│ └── main.cpp
├── SSGContextPlugin
│ ├── SSGContextPlugin.json
│ ├── SSGContext.h
│ ├── CMakeLists.txt
│ ├── SSGContextPlugin.cpp
│ ├── SSGContextPlugin.h
│ ├── SSGContext.cpp
│ └── SSGQuickLayer.h
├── qmldir
├── StackStreamPlugin.qrc
├── TileBackground.qml
├── PythonModule
│ └── CMakeLists.txt
├── SSView.cpp
├── SSView.h
├── SSQmlPlugin.h
├── GilLocker.h
├── SSImageItem.h
├── GilLocker.cpp
├── SSQmlPlugin.cpp
├── CMakeLists.txt
├── SSImageItem.cpp
├── common.h
├── SSGSimpleTextureNode.h
├── SSGTextureMaterial.h
├── SSGTexture.h
├── StackStreamMainWindow.qml
└── SSGTextureMaterial.cpp
├── todo_mindmap.vym
├── Gradient-16bit.png
├── devtest
└── PyQmlProof
│ ├── PyQmlProof.pro
│ ├── PyQmlProof.qml
│ ├── TiledBackground.qml
│ ├── PyQmlProof.py
│ ├── PointTablePane.qml
│ └── ImagePane.qml
├── cmake_modules
├── FindSIP.py
├── FindFreeImage.cmake
├── FindFreeImagePlus.cmake
├── FindSIP.cmake
├── SIPMacros.cmake
└── FindPyQt5.cmake
├── .gitignore
├── README.md
└── CMakeLists.txt
/source/QtQmlTricks/include/QtCOBS:
--------------------------------------------------------------------------------
1 | #include "../src/qtcobs.h"
2 |
3 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/include/QtJsonPath:
--------------------------------------------------------------------------------
1 | #include "../src/qtjsonpath.h"
2 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/include/QQmlHelpers:
--------------------------------------------------------------------------------
1 | #include "../src/qqmlhelpers.h"
2 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/include/QQuickPolygon:
--------------------------------------------------------------------------------
1 | #include "../src/qquickpolygon.h"
2 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/include/QtBitStream:
--------------------------------------------------------------------------------
1 | #include "../src/qtbitstream.h"
2 |
--------------------------------------------------------------------------------
/source/Application/Application.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/include/QQmlSvgIconHelper:
--------------------------------------------------------------------------------
1 | #include "../src/qqmlsvgiconhelper.h"
2 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/include/QQmlGadgetListModel:
--------------------------------------------------------------------------------
1 | #include "../src/qqmlgadgetlistmodel.h"
2 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/include/QQmlObjectListModel:
--------------------------------------------------------------------------------
1 | #include "../src/qqmlobjectlistmodel.h"
2 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/include/QQmlVariantListModel:
--------------------------------------------------------------------------------
1 | #include "../src/qqmlvariantlistmodel.h"
2 |
--------------------------------------------------------------------------------
/todo_mindmap.vym:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/erikhvatum/StackStream/HEAD/todo_mindmap.vym
--------------------------------------------------------------------------------
/Gradient-16bit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/erikhvatum/StackStream/HEAD/Gradient-16bit.png
--------------------------------------------------------------------------------
/source/SSGContextPlugin/SSGContextPlugin.json:
--------------------------------------------------------------------------------
1 | {
2 | "Keys" : [ "SSGContextPlugin" ]
3 | }
4 |
--------------------------------------------------------------------------------
/source/qmldir:
--------------------------------------------------------------------------------
1 | module StackStream
2 | StackStreamMainWindow 1.0 StackStreamMainWindow.qml
3 | plugin StackStreamPlugin
4 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/NiceModels/data_nicemodels.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | ui_nicemodels.qml
4 |
5 |
6 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/CustomPolygon/data_custompolygon.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | ui_custompolygon.qml
4 |
5 |
6 |
--------------------------------------------------------------------------------
/source/StackStreamPlugin.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | StackStreamMainWindow.qml
4 | TileBackground.qml
5 |
6 |
7 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/IconCache/data_iconcache.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | ui_iconcache.qml
4 | mark.svg
5 |
6 |
7 |
--------------------------------------------------------------------------------
/devtest/PyQmlProof/PyQmlProof.pro:
--------------------------------------------------------------------------------
1 | DISTFILES += \
2 | list_role_model.py \
3 | PyQmlProof.py \
4 | PyQmlProof.qml \
5 | SplinePoint.qml \
6 | ImagePane.qml \
7 | PointTablePane.qml \
8 | TiledBackground.qml
9 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/TextLabel.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.1;
2 | import "Style.js" as Style;
3 |
4 | Text {
5 | color: (enabled ? Style.colorBlack : Style.colorGray);
6 | font {
7 | weight: Font.Light;
8 | family: Style.fontName;
9 | pixelSize: Style.fontSizeNormal;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/COBS/QtCOBS.qbs:
--------------------------------------------------------------------------------
1 | import qbs;
2 |
3 | Application {
4 | name: "example-cobs";
5 | targetName: "QtCOBS";
6 |
7 | Depends { name: "Qt"; }
8 | Depends { name: "cpp"; }
9 | Depends { name: "sdk-utilities"; }
10 | Group {
11 | name: "C++ sources";
12 | files: ["*.cpp"];
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/JSONPath/QtJsonPath.qbs:
--------------------------------------------------------------------------------
1 | import qbs;
2 |
3 | Application {
4 | name: "example-jsonpath";
5 | targetName: "QtJsonPath";
6 |
7 | Depends { name: "Qt"; }
8 | Depends { name: "cpp"; }
9 | Depends { name: "sdk-utilities"; }
10 | Group {
11 | name: "C++ sources";
12 | files: ["*.cpp"];
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/BitStream/QtBitStream.qbs:
--------------------------------------------------------------------------------
1 | import qbs;
2 |
3 | Application {
4 | name: "example-bitstream";
5 | targetName: "QtBitStream";
6 |
7 | Depends { name: "Qt"; }
8 | Depends { name: "cpp"; }
9 | Depends { name: "sdk-utilities"; }
10 | Group {
11 | name: "C++ sources";
12 | files: ["*.cpp"];
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/import.qbs:
--------------------------------------------------------------------------------
1 | import qbs 1.0;
2 |
3 | Product {
4 | name: "qml-js-imports";
5 |
6 | Group {
7 | name: "JavaScript modules";
8 | files: "*.js";
9 | }
10 | Group {
11 | name: "QML components";
12 | files: "*.qml";
13 | }
14 | Group {
15 | name: "QML directory";
16 | files: "qmldir";
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/components.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | GridContainer.qml
4 | QtCoreApi.js
5 | qmldir
6 | RowContainer.qml
7 | WrapLeftRightContainer.qml
8 | ScrollContainer.qml
9 | IconTextButton.qml
10 | SingleLineEditBox.qml
11 |
12 |
13 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/qmldir:
--------------------------------------------------------------------------------
1 | module QtQmlTricks
2 |
3 | QtCoreApi 1.0 QtCoreApi.js
4 | RowContainer 1.0 RowContainer.qml
5 | GridContainer 1.0 GridContainer.qml
6 | ScrollContainer 1.0 ScrollContainer.qml
7 | WrapLeftRightContainer 1.0 WrapLeftRightContainer.qml
8 | IconTextButton 1.0 IconTextButton.qml
9 | SingleLineEditBox 1.0 SingleLineEditBox.qml
10 |
11 | plugin QtQmlTricksPlugin
12 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/IconCache/IconCache.qbs:
--------------------------------------------------------------------------------
1 | import qbs;
2 |
3 | Application {
4 | name: "example-icon-cache";
5 | targetName: "IconCache";
6 |
7 | Depends { name: "Qt"; }
8 | Depends { name: "cpp"; }
9 | Depends { name: "sdk-utilities"; }
10 | Group {
11 | name: "C++ sources & headers";
12 | files: ["*.cpp", "*.h"];
13 | }
14 | Group {
15 | name: "QML documents";
16 | files: "*.qml";
17 | }
18 | Group {
19 | name: "Qt resources";
20 | files: "*.qrc";
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/NiceModels/NiceModels.qbs:
--------------------------------------------------------------------------------
1 | import qbs;
2 |
3 | Application {
4 | name: "example-nice-models";
5 | targetName: "NiceModels";
6 |
7 | Depends { name: "Qt"; }
8 | Depends { name: "cpp"; }
9 | Depends { name: "sdk-utilities"; }
10 | Group {
11 | name: "C++ sources & headers";
12 | files: ["*.cpp", "*.h"];
13 | }
14 | Group {
15 | name: "QML documents";
16 | files: "*.qml";
17 | }
18 | Group {
19 | name: "Qt resources";
20 | files: "*.qrc";
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/CustomPolygon/CustomPolygon.qbs:
--------------------------------------------------------------------------------
1 | import qbs;
2 |
3 | Application {
4 | name: "example-custom-polygon";
5 | targetName: "CustomPolygon";
6 |
7 | Depends { name: "Qt"; }
8 | Depends { name: "cpp"; }
9 | Depends { name: "sdk-utilities"; }
10 | Group {
11 | name: "C++ sources & headers";
12 | files: ["*.cpp", "*.h"];
13 | }
14 | Group {
15 | name: "QML documents";
16 | files: "*.qml";
17 | }
18 | Group {
19 | name: "Qt resources";
20 | files: "*.qrc";
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/QtLibrary.qbs:
--------------------------------------------------------------------------------
1 | import qbs 1.0;
2 |
3 | StaticLibrary {
4 | name: "lib-qt-qml-tricks";
5 | targetName: "QtQmlTricks";
6 |
7 | Depends { name: "cpp"; }
8 | Depends { name: "Qt"; submodules: ["core", "qml", "gui", "quick", "svg"]; }
9 | Group {
10 | name: "C++ sources";
11 | files: "*.cpp";
12 | fileTags: "source";
13 | overrideTags: false;
14 | }
15 | Group {
16 | name: "C++ headers";
17 | files: "*.h";
18 | fileTags: "source";
19 | overrideTags: false;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/cmake_modules/FindSIP.py:
--------------------------------------------------------------------------------
1 | # FindSIP.py
2 | #
3 | # Copyright (c) 2007, Simon Edwards
4 | # Redistribution and use is allowed according to the terms of the BSD license.
5 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
6 |
7 | import sys
8 | import sipconfig
9 |
10 | sipcfg = sipconfig.Configuration()
11 | print("sip_version:%06.0x" % sipcfg.sip_version)
12 | print("sip_version_str:%s" % sipcfg.sip_version_str)
13 | print("sip_bin:%s" % sipcfg.sip_bin)
14 | print("default_sip_dir:%s" % sipcfg.default_sip_dir)
15 | print("sip_inc_dir:%s" % sipcfg.sip_inc_dir)
16 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/QmlComponents.qbs:
--------------------------------------------------------------------------------
1 | import qbs
2 |
3 | StaticLibrary {
4 | name: "qml-js-imports";
5 | targetName: "QmlJsTricks";
6 |
7 | Depends { name: "Qt"; }
8 | Depends { name: "cpp"; }
9 | Group {
10 | name: "JavaScript modules";
11 | files: "*.js";
12 | }
13 | Group {
14 | name: "QML components";
15 | files: "*.qml";
16 | }
17 | Group {
18 | name: "QML directory";
19 | files: "qmldir";
20 | }
21 | Group {
22 | name: "Qt resources";
23 | files: "*.qrc";
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/IconCache/main_iconcache.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include
10 |
11 | int main (int argc, char * argv []) {
12 | QGuiApplication app (argc, argv);
13 |
14 | QQmlSvgIconHelper::setBasePath ("://");
15 |
16 | QQuickView view;
17 | registerQtQmlTricksModule (view.engine ());
18 | view.setResizeMode (QQuickView::SizeRootObjectToView);
19 | view.setSource (QUrl ("qrc:/ui_iconcache.qml"));
20 | view.show ();
21 |
22 | return app.exec ();
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qqmlmodels.h:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include
5 |
6 | #define NO_PARENT QModelIndex ()
7 | #define BASE_ROLE Qt::UserRole
8 | #define EMPTY_STR QStringLiteral ("")
9 | #define EMPTY_BA QByteArrayLiteral ("")
10 |
11 | /*!
12 | \defgroup QT_QML_MODELS Qt models for QML
13 |
14 | Brings a bunch of nice, ready-to-use, C++ models for usual use-cases in C++/QML apps :
15 | \li Exposing a list of QObject-derived objects to QML while supporting dynamic changes
16 | \li Using a simple list of QVariant / QVariantMap just as easy as the plain QML ListModel item
17 | \li etc...
18 | */
19 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qqmlvariantlistmodel_p.h:
--------------------------------------------------------------------------------
1 | #ifndef QQMLVARIANTLISTMODEL_P_H
2 | #define QQMLVARIANTLISTMODEL_P_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | class QQmlVariantListModel;
14 |
15 | class QQmlVariantListModelPrivate : public QObject {
16 | Q_OBJECT
17 |
18 | public:
19 | explicit QQmlVariantListModelPrivate (QQmlVariantListModel * parent);
20 |
21 | void updateCounter ();
22 |
23 | int m_count;
24 | QVariantList m_items;
25 | QHash m_roles;
26 | QQmlVariantListModel * m_publicObject;
27 | };
28 |
29 |
30 | #endif // QQMLVARIANTLISTMODEL_P_H
31 |
--------------------------------------------------------------------------------
/source/TileBackground.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.5
2 |
3 | ShaderEffect {
4 | property real tileSize: 16
5 | property color color1: Qt.rgba(0.9, 0.9, 0.9, 1);
6 | property color color2: Qt.rgba(0.85, 0.85, 0.85, 1);
7 |
8 | property size pixelSize: Qt.size(width / tileSize, height / tileSize);
9 |
10 | fragmentShader:
11 | "
12 | uniform lowp vec4 color1;
13 | uniform lowp vec4 color2;
14 | uniform highp vec2 pixelSize;
15 | varying highp vec2 qt_TexCoord0;
16 | void main() {
17 | highp vec2 tc = sign(sin(3.14152 * qt_TexCoord0 * pixelSize));
18 | if (tc.x != tc.y)
19 | gl_FragColor = color1;
20 | else
21 | gl_FragColor = color2;
22 | }
23 | "
24 | }
25 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/NiceModels/defs_nicemodels.h:
--------------------------------------------------------------------------------
1 | #ifndef DEFS_H
2 | #define DEFS_H
3 |
4 | #include
5 | #include
6 |
7 | #include
8 |
9 | QML_ENUM_CLASS (MyEnum, Unknown = 0, First, Second, Third, Fourth, Fifth, Sixth, Seventh)
10 |
11 | class MyItem : public QObject {
12 | Q_OBJECT
13 | QML_WRITABLE_PROPERTY (int, foo)
14 | QML_WRITABLE_PROPERTY (QString, bar)
15 | QML_READONLY_PROPERTY (MyEnum::Type, test)
16 | QML_CONSTANT_PROPERTY (QString, type)
17 | QML_CONSTANT_PROPERTY (bool, model)
18 |
19 | public:
20 | explicit MyItem (QObject * parent = NULL) : QObject (parent) {
21 | m_foo = 0;
22 | m_bar = "";
23 | m_test = MyEnum::Unknown;
24 | m_type = metaObject ()->className ();
25 | }
26 | };
27 |
28 | #endif // DEFS_H
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # This file is used to ignore files which are generated
2 | # ----------------------------------------------------------------------------
3 |
4 | *~
5 | *.autosave
6 | *.a
7 | *.core
8 | *.moc
9 | *.o
10 | *.obj
11 | *.orig
12 | *.rej
13 | *.so
14 | *.so.*
15 | *_pch.h.cpp
16 | *_resource.rc
17 | *.qm
18 | .#*
19 | *.*#
20 | core
21 | !core/
22 | tags
23 | .DS_Store
24 | *.debug
25 | Makefile*
26 | *.prl
27 | *.app
28 | moc_*.cpp
29 | ui_*.h
30 | qrc_*.cpp
31 | Thumbs.db
32 | *.res
33 | *.rc
34 | /.qmake.cache
35 | /.qmake.stash
36 |
37 | # qtcreator generated files
38 | *.pro.user*
39 |
40 | # xemacs temporary files
41 | *.flc
42 |
43 | # Vim temporary files
44 | .*.swp
45 |
46 | # Visual Studio generated files
47 | *.ib_pdb_index
48 | *.idb
49 | *.ilk
50 | *.pdb
51 | *.sln
52 | *.suo
53 | *.vcproj
54 | *vcproj.*.*.user
55 | *.ncb
56 | *.sdf
57 | *.opensdf
58 | *.vcxproj
59 | *vcxproj.*
60 |
61 | # MinGW generated files
62 | *.Debug
63 | *.Release
64 |
65 | # Python byte code
66 | *.pyc
67 |
68 | # Binaries
69 | # --------
70 | *.dll
71 | *.exe
72 |
73 |
74 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/IconCache/ui_iconcache.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.1;
2 | import QtQmlTricks 1.0;
3 |
4 | Rectangle {
5 | id: window;
6 | width: 600;
7 | height: 400;
8 |
9 | Row {
10 | spacing: 20;
11 | anchors.centerIn: parent;
12 |
13 | Repeater {
14 | model: [
15 | { "size" : 20, "color" : "gray" },
16 | { "size" : 32, "color" : "orange" },
17 | { "size" : 48, "color" : "steelblue" },
18 | { "size" : 64, "color" : "transparent" },
19 | ];
20 | delegate: Image {
21 | cache: true;
22 | smooth: false;
23 | fillMode: Image.Pad;
24 | asynchronous: true;
25 | antialiasing: false;
26 |
27 | SvgIconHelper on source {
28 | icon: "mark";
29 | size: modelData ["size"];
30 | color: Qt.lighter (modelData ["color"], 1.0);
31 | }
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/include/QtQmlTricks:
--------------------------------------------------------------------------------
1 | #ifndef QTQMLTRICKS
2 | #define QTQMLTRICKS
3 |
4 | #include
5 | #include
6 |
7 | #include "QQuickPolygon"
8 | #include "QQmlSvgIconHelper"
9 | #include "QQmlObjectListModel"
10 | #include "QQmlVariantListModel"
11 |
12 | static void registerQtQmlTricksModule (QQmlEngine * engine) {
13 | Q_INIT_RESOURCE (components);
14 |
15 | const char * uri = "QtQmlTricks"; // @uri QtQmlTricks
16 | const int maj = 1;
17 | const int min = 0;
18 |
19 | qmlRegisterType (uri, maj, min, "Polygon");
20 | qmlRegisterType (uri, maj, min, "SvgIconHelper");
21 |
22 | qmlRegisterUncreatableType (uri, maj, min, "AbstractItemModel", "!!!");
23 | qmlRegisterUncreatableType (uri, maj, min, "AbstractListModel", "!!!");
24 | qmlRegisterUncreatableType (uri, maj, min, "VariantListModel", "!!!");
25 | qmlRegisterUncreatableType (uri, maj, min, "ObjectListModelBase", "!!!");
26 |
27 | if (engine) {
28 | engine->addImportPath ("qrc:/import");
29 | }
30 | }
31 |
32 | #endif // QTQMLTRICKS
33 |
34 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/NiceModels/main_nicemodels.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include
10 |
11 | #include "defs_nicemodels.h"
12 |
13 | int main (int argc, char * argv []) {
14 | QGuiApplication app (argc, argv);
15 |
16 | QQmlObjectListModel * testModel = new QQmlObjectListModel (&app, "foo", "bar");
17 |
18 | int year = QDateTime::currentDateTime ().date ().year ();
19 | QDate date (year, 1, 1);
20 | while (date.year () == year) {
21 | MyItem * item = new MyItem;
22 | item->set_foo (date.dayOfYear ());
23 | item->set_bar (date.toString ("yyyy-MM-dd"));
24 | item->update_test (MyEnum::Type (date.dayOfWeek ()));
25 | testModel->append (item);
26 | date = date.addDays (1);
27 | }
28 |
29 | QQuickView view;
30 | registerQtQmlTricksModule (view.engine ());
31 | view.rootContext ()->setContextProperty ("testModel", testModel);
32 | view.setResizeMode (QQuickView::SizeRootObjectToView);
33 | view.setSource (QUrl ("qrc:/ui_nicemodels.qml"));
34 | view.show ();
35 |
36 | return app.exec ();
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/source/PythonModule/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 | #
3 | # Copyright (c) 2016 Erik Hvatum
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy
6 | # of this software and associated documentation files (the "Software"), to deal
7 | # in the Software without restriction, including without limitation the rights
8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | # copies of the Software, and to permit persons to whom the Software is
10 | # furnished to do so, subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | # SOFTWARE.
22 | #
23 | # Authors: Erik Hvatum
24 |
--------------------------------------------------------------------------------
/source/SSView.cpp:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #include "SSView.h"
26 |
27 | SSView::SSView()
28 | {
29 | setFlag(QQuickItem::ItemClipsChildrenToShape);
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/source/SSView.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #pragma once
26 | #include "common.h"
27 |
28 | class SSView
29 | : public QQuickItem
30 | {
31 | Q_OBJECT
32 | public:
33 | SSView();
34 | // TODO: custom transform node
35 |
36 | signals:
37 |
38 | public slots:
39 | };
40 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/BitStream/main_bitstream.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 |
5 | #include
6 |
7 | int main (int argc, char * argv []) {
8 | Q_UNUSED (argc)
9 | Q_UNUSED (argv)
10 |
11 | const unsigned char data [] = { 0x35, 0x02 , 0x26, 0x7F, 0x65, 0x4F, 0xAB, 0x03, 0x85, 0x7B };
12 | const unsigned int size = (sizeof (data) / sizeof (data [0]));
13 |
14 | QtBitStream streamOut (QByteArray::fromRawData ((const char *) data, size));
15 |
16 | qDebug () << "streamOut=" << streamOut.toBinary ();
17 |
18 | bool ok = false;
19 |
20 | for (int bit = 0; bit < 8; bit++) {
21 | qDebug () << "bit as bool :" << streamOut.getPosition () << streamOut.readBits (1, &ok);
22 | }
23 | qDebug () << "bits 8-24 in quint16 :" << streamOut.getPosition () << streamOut.readBits (16);
24 |
25 | QtBitStream streamIn (QByteArray (4, 0x00));
26 | quint8 test1 = 0x7;
27 | streamIn.writeBits (test1, 3, &ok);
28 | qDebug () << "streamIn after test1=" << streamIn.toBinary () << ok;
29 | qreal test2 = 0x7;
30 | streamIn.writeBits (test2, 5, &ok);
31 | qDebug () << "streamIn after test2=" << streamIn.toBinary () << ok;
32 | QByteArray test3 = "toto";
33 | streamIn.writeBits (test3, 23, &ok);
34 | qDebug () << "streamIn after test3=" << streamIn.toBinary () << ok;
35 | streamIn.writeBits (5651, 12, &ok);
36 | qDebug () << "streamIn after test3=" << streamIn.toBinary () << ok;
37 |
38 | return 0;
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qqmlvariantlistmodel.h:
--------------------------------------------------------------------------------
1 | #ifndef QQMLVARIANTLISTMODEL_H
2 | #define QQMLVARIANTLISTMODEL_H
3 |
4 | #include "qqmlmodels.h"
5 |
6 | class QQmlVariantListModelPrivate;
7 |
8 | class QQmlVariantListModel : public QAbstractListModel {
9 | Q_OBJECT
10 | Q_PROPERTY (int count READ count NOTIFY countChanged)
11 |
12 | public:
13 | explicit QQmlVariantListModel (QObject * parent);
14 | virtual ~QQmlVariantListModel ();
15 |
16 | public: // QAbstractItemModel interface reimplemented
17 | virtual int rowCount (const QModelIndex & parent = QModelIndex ()) const;
18 | virtual bool setData (const QModelIndex & index, const QVariant & value, int role);
19 | virtual QVariant data (const QModelIndex & index, int role) const;
20 | virtual QHash roleNames () const;
21 |
22 | public slots: // public API
23 | void clear ();
24 | int count () const;
25 | bool isEmpty () const;
26 | void append (QVariant item);
27 | void prepend (QVariant item);
28 | void insert (int idx, QVariant item);
29 | void appendList (QVariantList itemList);
30 | void prependList (QVariantList itemList);
31 | void replace (int pos, QVariant item);
32 | void insertList (int idx, QVariantList itemList);
33 | void move (int idx, int pos);
34 | void remove (int idx);
35 | QVariant get (int idx) const;
36 | QVariantList list () const;
37 |
38 | signals: // notifiers
39 | void countChanged (int count);
40 |
41 | private:
42 | QQmlVariantListModelPrivate * m_privateImpl;
43 | };
44 |
45 | #endif // QQMLVARIANTLISTMODEL_H
46 |
--------------------------------------------------------------------------------
/source/SSGContextPlugin/SSGContext.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #pragma once
26 |
27 | class QSGContext;
28 | class QSGLayer;
29 |
30 | class SSGContext
31 | : public QSGContext
32 | {
33 | public:
34 | explicit SSGContext(QObject* parent=nullptr);
35 |
36 | QSGImageNode* createImageNode() override;
37 | QSGLayer* createLayer(QSGRenderContext* renderContext) override;
38 | };
39 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # StackStream
2 | A small collection of Qt and QML widgets for viewing images and image stack collections of any size + a QML scene graph plugin providing 32 bit per channel floating point framebuffer and layer support for optimal compositing, manipulation, and display of HDR and high-depth images, including in 30-bit mode (10 bit per channel).
3 |
4 | At this time, StackStream includes:
5 |
6 | * The first open source QML scene graph plugin of any kind. Implemented in C++.
7 | * The first open source 30-bit display support for QML and QtQuick2. Implemented in C++.
8 | * The first open source float32-component framebuffer and texture map support for QML and QtQuick2. Implemented in C++.
9 | * The SSImage class, supporting higher bitdepths than QImage and floating point components (which QImage does not support at all). Implemented in C++, exposed to QML.
10 | * The SSLayer class, a QQuickItem for displaying SSImage objects with gamma transformation. Implemented in C++, exposed to QML.
11 | * An SSLayer viewer with a GUI interface for gamma transform parameters and associated classes and objects. Implemented QML.
12 |
13 | StackStream will soon include:
14 |
15 | * Support for blending any arbitrary number SSLayers with any combination of the blend modes specified by SVG.
16 | * An extensive Python API exposed via SIP.
17 | * An SSImage and SSLayer stack flipbook presented as a table, with a complete Python API and intuitive multi-image drag and drop support.
18 | * A QAbstractModel-derived model exposed to Python as a simple Python list in addition to its full PyQt API, eliminating the need to represent anything as a QQmlList ever again.
19 |
--------------------------------------------------------------------------------
/source/SSQmlPlugin.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #pragma once
26 | #include "common.h"
27 | #include
28 |
29 | class SSQmlPlugin
30 | : public QQmlExtensionPlugin
31 | {
32 | Q_OBJECT
33 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
34 | public:
35 | explicit SSQmlPlugin(QObject* parent=nullptr);
36 |
37 | void registerTypes(const char* uri) override;
38 | };
39 |
--------------------------------------------------------------------------------
/devtest/PyQmlProof/PyQmlProof.qml:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | import QtQuick 2.5
26 | import QtQuick.Controls 1.4
27 | import QtQuick.Layouts 1.2
28 |
29 | Rectangle {
30 | id: containerRect
31 | implicitWidth: 1024
32 | implicitHeight: 768
33 |
34 | SplitView {
35 | id: splitView
36 | anchors.fill: parent
37 | orientation: Qt.Horizontal
38 |
39 | PointTablePane {}
40 | ImagePane {}
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qmlplugin.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #pragma once
26 | #include
27 | #include
28 | #include
29 |
30 | class QtQmlTricksPlugin
31 | : public QQmlExtensionPlugin
32 | {
33 | Q_OBJECT
34 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
35 | public:
36 | explicit QtQmlTricksPlugin(QObject* parent=nullptr);
37 |
38 | void registerTypes(const char* uri) override;
39 | };
40 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/COBS/main_cobs.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 |
5 | #include
6 |
7 | int main (int argc, char * argv []) {
8 | QCoreApplication (argc, argv);
9 |
10 | const char _raw1 [1] = {0x00};
11 | const QByteArray raw1 = QByteArray::fromRawData (_raw1, 1);
12 | const char _cob1 [2] = {0x01, 0x01};
13 | const QByteArray cob1 = QByteArray::fromRawData (_cob1, 2);
14 | qDebug () << "TST1 :"
15 | << "RAW=" << raw1.toHex ()
16 | << "COBS=" << cob1.toHex ()
17 | << "ENCODE=" << (QtCOBS::encode (raw1) == cob1)
18 | << "DECODE=" << (QtCOBS::decode (cob1) == raw1);
19 |
20 | const char _raw2 [4] = {0x11, 0x22, 0x00, 0x33};
21 | const QByteArray raw2 = QByteArray::fromRawData (_raw2, 4);
22 | const char _cob2 [5] = {0x03, 0x11, 0x22, 0x02, 0x33};
23 | const QByteArray cob2 = QByteArray::fromRawData (_cob2, 5);
24 | qDebug () << "TST2 :"
25 | << "RAW=" << raw2.toHex ()
26 | << "COBS=" << cob2.toHex ()
27 | << "ENCODE=" << (QtCOBS::encode (raw2) == cob2)
28 | << "DECODE=" << (QtCOBS::decode (cob2) == raw2);
29 |
30 | const char _raw3 [4] = {0x11, 0x00, 0x00, 0x00};
31 | const QByteArray raw3 = QByteArray::fromRawData (_raw3, 4);
32 | const char _cob3 [5] = {0x02, 0x11, 0x01, 0x01, 0x01};
33 | const QByteArray cob3 = QByteArray::fromRawData (_cob3, 5);
34 | qDebug () << "TST3 :"
35 | << "RAW=" << raw3.toHex ()
36 | << "COBS=" << cob3.toHex ()
37 | << "ENCODE=" << (QtCOBS::encode (raw3) == cob3)
38 | << "DECODE=" << (QtCOBS::decode (cob3) == raw3);
39 |
40 | return 0;
41 | }
42 |
--------------------------------------------------------------------------------
/source/SSGContextPlugin/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 | #
3 | # Copyright (c) 2016 Erik Hvatum
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy
6 | # of this software and associated documentation files (the "Software"), to deal
7 | # in the Software without restriction, including without limitation the rights
8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | # copies of the Software, and to permit persons to whom the Software is
10 | # furnished to do so, subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | # SOFTWARE.
22 | #
23 | # Authors: Erik Hvatum
24 |
25 | project(SSGContextPlugin)
26 |
27 | set(SOURCE_FILES
28 | ../common.h
29 | SSGContext.h
30 | SSGContext.cpp
31 | SSGContextPlugin.h
32 | SSGContextPlugin.cpp
33 | SSGQuickLayer.h
34 | SSGQuickLayer.cpp)
35 | set(LIBRARIES
36 | ${OPENGL_LIBRARIES}
37 | ${FREEIMAGE_LIBRARY}
38 | ${FREEIMAGEPLUS_LIBRARY})
39 |
40 | add_library(SSGContextPlugin SHARED ${SOURCE_FILES})
41 | qt5_use_modules(SSGContextPlugin Core Gui Qml OpenGL Quick Widgets)
42 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/CustomPolygon/ui_custompolygon.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.1;
2 | import QtQmlTricks 1.0;
3 |
4 | Rectangle {
5 | id: window;
6 | width: 600;
7 | height: 400;
8 |
9 | readonly property real centerX : (width / 2);
10 | readonly property real centerY : (height / 2);
11 |
12 | readonly property real size : (Math.min (centerX, centerY) * 0.85);
13 |
14 | Timer {
15 | id: timer;
16 | repeat: true;
17 | running: true;
18 | interval: 1000;
19 | triggeredOnStart: true;
20 | onTriggered: { polygon.count++; }
21 | }
22 | FocusScope {
23 | focus: true;
24 | Keys.onPressed: { timer.running = !timer.running; }
25 | }
26 | Polygon {
27 | id: polygon;
28 | color: Qt.hsla (0.5, 0.5, 0.5, 0.5);
29 | points:{
30 | var ret = [];
31 | for (var idx = 0; idx < count; idx++) {
32 | var rad = (Math.PI * 2) * (idx / count);
33 | ret.push (Qt.point (centerX + size * Math.cos (rad),
34 | centerY + size * Math.sin (rad)));
35 | }
36 | return ret;
37 | }
38 |
39 | property int count : 0;
40 |
41 | Repeater {
42 | model: parent.points;
43 | delegate: Text {
44 | text: ("P" + model.index);
45 | x: (modelData ["x"] - contentWidth / 2);
46 | y: (modelData ["y"] - contentHeight / 2);
47 | color: "white";
48 | style: Text.Outline;
49 | styleColor: "black";
50 | font {
51 | bold: true;
52 | pixelSize: 20;
53 | }
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/source/GilLocker.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #pragma once
26 | #include "common.h"
27 |
28 | #ifdef WITH_PYTHON
29 | class STACKSTREAM_DLLSPEC GilLocker
30 | {
31 | public:
32 | GilLocker();
33 | ~GilLocker();
34 | GilLocker(const GilLocker&) = delete;
35 | GilLocker& operator = (const GilLocker&) = delete;
36 |
37 | private:
38 | PyGILState_STATE m_PyGILState_STATE;
39 | };
40 |
41 | class STACKSTREAM_DLLSPEC GilUnlocker
42 | {
43 | public:
44 | GilUnlocker();
45 | ~GilUnlocker();
46 | GilUnlocker(const GilUnlocker&) = delete;
47 | GilUnlocker& operator = (const GilUnlocker&) = delete;
48 |
49 | private:
50 | PyThreadState* m_pyThreadState;
51 | };
52 | #endif
53 |
--------------------------------------------------------------------------------
/cmake_modules/FindFreeImage.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Try to find the FreeImage library and include path.
3 | # Once done this will define
4 | #
5 | # FREEIMAGE_FOUND
6 | # FREEIMAGE_INCLUDE_PATH
7 | # FREEIMAGE_LIBRARY
8 | #
9 |
10 | IF (WIN32)
11 | FIND_PATH( FREEIMAGE_INCLUDE_PATH FreeImage.h
12 | C:/FreeImage/Dist/x64
13 | ${PROJECT_SOURCE_DIR}/extern/FreeImage
14 | DOC "The directory where FreeImage.h resides")
15 | FIND_LIBRARY( FREEIMAGE_LIBRARY
16 | NAMES FreeImage freeimage
17 | PATHS
18 | C:/FreeImage/Dist/x64
19 | ${PROJECT_SOURCE_DIR}/FreeImage
20 | DOC "The FreeImage library")
21 | ELSE (WIN32)
22 | FIND_PATH( FREEIMAGE_INCLUDE_PATH FreeImage.h
23 | /usr/include
24 | /usr/local/include
25 | /sw/include
26 | /opt/local/include
27 | DOC "The directory where FreeImage.h resides")
28 | FIND_LIBRARY( FREEIMAGE_LIBRARY
29 | NAMES FreeImage freeimage
30 | PATHS
31 | /usr/lib64
32 | /usr/lib
33 | /usr/local/lib64
34 | /usr/local/lib
35 | /sw/lib
36 | /opt/local/lib
37 | DOC "The FreeImage library")
38 | ENDIF (WIN32)
39 |
40 | SET(FREEIMAGE_LIBRARIES ${FREEIMAGE_LIBRARY})
41 |
42 | IF (FREEIMAGE_INCLUDE_PATH AND FREEIMAGE_LIBRARY)
43 | SET( FREEIMAGE_FOUND TRUE CACHE BOOL "Set to TRUE if FreeImage is found, FALSE otherwise")
44 | ELSE (FREEIMAGE_INCLUDE_PATH AND FREEIMAGE_LIBRARY)
45 | SET( FREEIMAGE_FOUND FALSE CACHE BOOL "Set to TRUE if FreeImage is found, FALSE otherwise")
46 | ENDIF (FREEIMAGE_INCLUDE_PATH AND FREEIMAGE_LIBRARY)
47 |
48 | MARK_AS_ADVANCED(
49 | FREEIMAGE_FOUND
50 | FREEIMAGE_LIBRARY
51 | FREEIMAGE_LIBRARIES
52 | FREEIMAGE_INCLUDE_PATH)
53 |
54 | IF (FREEIMAGE_FOUND)
55 | MESSAGE(STATUS "FREEIMAGE_INCLUDE_PATH = ${FREEIMAGE_INCLUDE_PATH}")
56 | MESSAGE(STATUS "FREEIMAGE_LIBRARY = ${FREEIMAGE_LIBRARY}")
57 | ELSE (FREEIMAGE_FOUND)
58 | IF (FreeImage_FIND_REQUIRED)
59 | MESSAGE(FATAL_ERROR "Could not find FreeImage")
60 | ENDIF (FreeImage_FIND_REQUIRED)
61 | ENDIF (FREEIMAGE_FOUND)
62 |
--------------------------------------------------------------------------------
/source/SSGContextPlugin/SSGContextPlugin.cpp:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #include "SSGContextPlugin.h"
26 | #include "SSGContext.h"
27 |
28 | SSGContextPlugin::SSGContextPlugin(QObject* parent)
29 | : QObject(parent)
30 | {
31 | qDebug() << "SSGContextPlugin loaded";
32 | }
33 |
34 | QStringList SSGContextPlugin::keys() const
35 | {
36 | // This never seems to be invoked. Perhaps it is vestigial? It does appear to be
37 | // redundant, given that the json metadata file contains a "Keys" entry.
38 | QStringList ret;
39 | ret << "SSGContextPlugin";
40 | return ret;
41 | }
42 |
43 | QSGContext* SSGContextPlugin::create(const QString& key) const
44 | {
45 | return (key == "SSGContextPlugin") ? new SSGContext() : nullptr;
46 | }
47 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qtcobs.h:
--------------------------------------------------------------------------------
1 | #ifndef QTCOBS_H
2 | #define QTCOBS_H
3 |
4 | #include
5 |
6 | class QtCOBS {
7 | public:
8 | static QByteArray encode (const QByteArray & rawData) {
9 | QByteArray encodedData;
10 | quint8 code = 0x01;
11 | int readIndex = 0;
12 | int writeIndex = 1;
13 | int codeIndex = 0;
14 | const int len = rawData.size ();
15 | while (readIndex < len) {
16 | if (rawData [readIndex] == 0x00) {
17 | encodedData [codeIndex] = code;
18 | code = 0x01;
19 | codeIndex = writeIndex++;
20 | readIndex++;
21 | }
22 | else {
23 | encodedData [writeIndex++] = rawData [readIndex++];
24 | code++;
25 | if (code == 0xFF) {
26 | encodedData [codeIndex] = code;
27 | code = 0x01;
28 | codeIndex = writeIndex++;
29 | }
30 | }
31 | }
32 | encodedData [codeIndex] = code;
33 | return encodedData;
34 | }
35 | static QByteArray decode (const QByteArray & cobsData) {
36 | QByteArray decodedData;
37 | quint8 code;
38 | int readIndex = 0;
39 | int writeIndex = 0;
40 | const int len = cobsData.size ();
41 | while (readIndex < len) {
42 | code = cobsData [readIndex];
43 | if (readIndex + code > len && code != 0x01) {
44 | decodedData.clear ();
45 | break;
46 | }
47 | readIndex++;
48 | for (quint8 pos = 1; pos < code; pos++) {
49 | decodedData [writeIndex++] = cobsData [readIndex++];
50 | }
51 | if (code != 0xFF && readIndex != len) {
52 | decodedData [writeIndex++] = 0x00;
53 | }
54 | }
55 | return decodedData;
56 | }
57 | };
58 |
59 | #endif // QTCOBS_H
60 |
--------------------------------------------------------------------------------
/source/SSImageItem.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #pragma once
26 | #include "common.h"
27 | #include "SSImage.h"
28 |
29 | class SSImageItem
30 | : public QQuickItem
31 | {
32 | Q_OBJECT
33 | Q_PROPERTY(SSImage* image READ image WRITE setImage STORED false NOTIFY imageChanged FINAL)
34 | public:
35 | explicit SSImageItem(QQuickItem* parent=nullptr);
36 |
37 | SSImage* image();
38 | const SSImage* image() const;
39 | void setImage(SSImage* image);
40 |
41 | signals:
42 | void imageChanged();
43 |
44 | protected:
45 | QSharedPointer m_image;
46 | bool m_imageSerialSet;
47 | std::size_t m_imageSerial;
48 |
49 | QSGNode* updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* updatePaintNodeData) override;
50 | };
51 |
--------------------------------------------------------------------------------
/source/GilLocker.cpp:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #ifdef WITH_PYTHON
26 | #include "GilLocker.h"
27 |
28 | GilLocker::GilLocker()
29 | : m_PyGILState_STATE(PyGILState_Ensure())
30 | {
31 | }
32 |
33 | GilLocker::~GilLocker()
34 | {
35 | if(PyGILState_Check() == 0)
36 | qFatal("GilLocker::~GilLocker(): About to release the GIL, but the GIL is not "
37 | "currently held by this thread.");
38 | PyGILState_Release(m_PyGILState_STATE);
39 | }
40 |
41 | GilUnlocker::GilUnlocker()
42 | : m_pyThreadState(PyEval_SaveThread())
43 | {
44 | if(m_pyThreadState == nullptr)
45 | qFatal("GilUnlocker::GilUnlocker(): PyEval_SaveThread() returned nullptr.")
46 | }
47 |
48 | GilUnlocker::~GilUnlocker()
49 | {
50 | PyEval_RestoreThread(m_pyThreadState);
51 | }
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/CustomPolygon/main_custompolygon.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | #include
11 | #include
12 |
13 | static QVector getPolygonForCircleArc (const QPointF & center, qreal radius, int startAngle = 0, int endAngle = 359, bool clockWise = true) {
14 | static const int degrees = 360;
15 | static QVector trigoVector;
16 | if (trigoVector.isEmpty ()) {
17 | trigoVector.resize (degrees);
18 | const qreal PI_RAD = (M_PI / 180.0);
19 | for (int angle = 0; angle < degrees; angle++) {
20 | const qreal radians = (angle * PI_RAD);
21 | trigoVector [angle].setX (qCos (radians));
22 | trigoVector [angle].setY (qSin (radians));
23 | }
24 | }
25 | QVector ret;
26 | const int firstAngle = ((startAngle + degrees) % degrees);
27 | const int lastAngle = ((endAngle + degrees) % degrees);
28 | const int stepAngle = (clockWise ? +1 : -1);
29 | for (int currAngle = firstAngle;
30 | currAngle != lastAngle;
31 | currAngle = ((currAngle + stepAngle + degrees) % degrees)) {
32 | ret.append (center + (trigoVector [currAngle] * radius));
33 | }
34 | return ret;
35 | }
36 |
37 | int main (int argc, char * argv []) {
38 | QGuiApplication app (argc, argv);
39 |
40 | QVector tmp = getPolygonForCircleArc (QPointF (78.9, 45.6), 12.3);
41 |
42 | QVariantList circle;
43 | circle.reserve (tmp.size ());
44 | foreach (const QPointF & val, tmp) {
45 | circle.append (QVariant::fromValue (val));
46 | }
47 |
48 | QQuickView view;
49 | registerQtQmlTricksModule (view.engine ());
50 | view.rootContext ()->setContextProperty ("Circle", QVariant::fromValue (circle));
51 | view.setResizeMode (QQuickView::SizeRootObjectToView);
52 | view.setSource (QUrl ("qrc:/ui_custompolygon.qml"));
53 | view.show ();
54 |
55 | return app.exec ();
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/Style.js:
--------------------------------------------------------------------------------
1 | .pragma library;
2 |
3 | var fontSizeSmall = 11;
4 | var fontSizeNormal = 14;
5 | var fontSizeBig = 16;
6 | var fontSizeTitle = 18;
7 |
8 | var colorGray = "gray";
9 | var colorBlack = "black";
10 | var colorWhite = "white";
11 | var colorDarkGray = "darkgray";
12 | var colorLightGray = "lightgray";
13 | var colorDarkRed = "darkred";
14 | var colorOrange = "orange";
15 | var colorSteelBlue = "steelblue";
16 | var colorDarkBlue = "darkblue";
17 | var colorLightBlue = "lightblue";
18 |
19 | var fontName = selectFont ([
20 | "Sail Sans Pro",
21 | "Source Sans Pro",
22 | "Ubuntu",
23 | "Roboto",
24 | "Droid Sans",
25 | "Liberation Sans",
26 | "Trebuchet MS",
27 | "Deja Vu Sans",
28 | "Tahoma",
29 | "Arial",
30 | ],
31 | "sans-serif");
32 |
33 | var fontFixedName = selectFont ([
34 | "Ubuntu Mono",
35 | "Deja Vu Mono",
36 | "Courier New",
37 | "Lucida Console",
38 | ],
39 | "monospace");
40 |
41 | function gray (val) {
42 | var tmp = (val / 255);
43 | return Qt.rgba (tmp, tmp, tmp, 1.0);
44 | }
45 | function opacify (tint, alpha) {
46 | var tmp = Qt.darker (tint, 1.0);
47 | return Qt.rgba (tmp.r, tmp.g, tmp.b, alpha);
48 | }
49 |
50 | function selectFont (list, fallback) {
51 | var ret;
52 | var all = Qt.fontFamilies ();
53 | for (var idx = 0; idx < list.length; idx++) {
54 | var tmp = list [idx];
55 | if (all.indexOf (tmp) >= 0) {
56 | ret = tmp;
57 | break;
58 | }
59 | }
60 | return (ret || fallback);
61 | }
62 |
--------------------------------------------------------------------------------
/devtest/PyQmlProof/TiledBackground.qml:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | import QtQuick 2.5
26 |
27 | ShaderEffect {
28 | anchors.fill: parent
29 | // layer.enabled: true
30 |
31 | property real tileSize: 16
32 | property color color1: Qt.rgba(0.9, 0.9, 0.9, 1);
33 | property color color2: Qt.rgba(0.85, 0.85, 0.85, 1);
34 |
35 | property size pixelSize: Qt.size(width / tileSize, height / tileSize);
36 |
37 | fragmentShader:
38 | "
39 | uniform lowp vec4 color1;
40 | uniform lowp vec4 color2;
41 | uniform highp vec2 pixelSize;
42 | varying highp vec2 qt_TexCoord0;
43 | void main() {
44 | highp vec2 tc = sign(sin(3.14152 * qt_TexCoord0 * pixelSize));
45 | if (tc.x != tc.y)
46 | gl_FragColor = color1;
47 | else
48 | gl_FragColor = color2;
49 | }
50 | "
51 | }
52 |
--------------------------------------------------------------------------------
/source/SSQmlPlugin.cpp:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #include "SSQmlPlugin.h"
26 | #include "SSImage.h"
27 | #include "SSImageItem.h"
28 | #include "SSView.h"
29 |
30 | SSQmlPlugin::SSQmlPlugin(QObject* parent)
31 | : QQmlExtensionPlugin(parent)
32 | {
33 | qDebug() << "SSQmlPlugin loaded";
34 | }
35 |
36 | void SSQmlPlugin::registerTypes(const char* uri)
37 | {
38 | Q_ASSERT(uri == QLatin1String("StackStream"));
39 | qDebug() << "SSQmlPlugin::registerTypes(..)";
40 |
41 | const char ss[] = "StackStream";
42 | const int ver[] = {1, 0};
43 | qmlRegisterType(ss, ver[0], ver[1], "SSImage");
44 | qRegisterMetaType("DType");
45 | qRegisterMetaType("Components");
46 | qRegisterMetaType("std::size_t");
47 | qmlRegisterType(ss, ver[0], ver[1], "SSImageItem");
48 | qmlRegisterType(ss, ver[0], ver[1], "SSView");
49 | }
50 |
--------------------------------------------------------------------------------
/cmake_modules/FindFreeImagePlus.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Try to find the FreeImagePlus library and include path.
3 | # Once done this will define
4 | #
5 | # FREEIMAGEPLUS_FOUND
6 | # FREEIMAGEPLUS_INCLUDE_PATH
7 | # FREEIMAGEPLUS_LIBRARY
8 | #
9 |
10 | IF (WIN32)
11 | FIND_PATH( FREEIMAGEPLUS_INCLUDE_PATH FreeImagePlus.h
12 | ${PROJECT_SOURCE_DIR}/extern/FreeImage
13 | C:/FreeImage/Wrapper/FreeImagePlus/dist/x64
14 | DOC "The directory where FreeImagePlus.h resides")
15 | FIND_LIBRARY( FREEIMAGEPLUS_LIBRARY
16 | NAMES FreeImagePlus freeimageplus
17 | PATHS
18 | C:/FreeImage/Wrapper/FreeImagePlus/dist/x64
19 | ${PROJECT_SOURCE_DIR}/FreeImage
20 | DOC "The FreeImage library")
21 | ELSE (WIN32)
22 | FIND_PATH( FREEIMAGEPLUS_INCLUDE_PATH FreeImagePlus.h
23 | /usr/include
24 | /usr/local/include
25 | /sw/include
26 | /opt/local/include
27 | DOC "The directory where FreeImagePlus.h resides")
28 | FIND_LIBRARY( FREEIMAGEPLUS_LIBRARY
29 | NAMES FreeImagePlus freeimageplus
30 | PATHS
31 | /usr/lib64
32 | /usr/lib
33 | /usr/local/lib64
34 | /usr/local/lib
35 | /sw/lib
36 | /opt/local/lib
37 | DOC "The FreeImage library")
38 | ENDIF (WIN32)
39 |
40 | SET(FREEIMAGEPLUS_LIBRARIES ${FREEIMAGEPLUS_LIBRARY})
41 |
42 | IF (FREEIMAGEPLUS_INCLUDE_PATH AND FREEIMAGEPLUS_LIBRARY)
43 | SET( FREEIMAGEPLUS_FOUND TRUE CACHE BOOL "Set to TRUE if FreeImagePlus is found, FALSE otherwise")
44 | ELSE (FREEIMAGEPLUS_INCLUDE_PATH AND FREEIMAGEPLUS_LIBRARY)
45 | SET( FREEIMAGEPLUS_FOUND FALSE CACHE BOOL "Set to TRUE if FreeImagePlus is found, FALSE otherwise")
46 | ENDIF (FREEIMAGEPLUS_INCLUDE_PATH AND FREEIMAGEPLUS_LIBRARY)
47 |
48 | MARK_AS_ADVANCED(
49 | FREEIMAGEPLUS_FOUND
50 | FREEIMAGEPLUS_LIBRARY
51 | FREEIMAGEPLUS_LIBRARIES
52 | FREEIMAGEPLUS_INCLUDE_PATH)
53 |
54 | IF (FREEIMAGEPLUS_FOUND)
55 | MESSAGE(STATUS "FREEIMAGEPLUS_INCLUDE_PATH = ${FREEIMAGEPLUS_INCLUDE_PATH}")
56 | MESSAGE(STATUS "FREEIMAGEPLUS_LIBRARY = ${FREEIMAGEPLUS_LIBRARY}")
57 | ELSE (FREEIMAGEPLUS_FOUND)
58 | IF (FreeImagePlus_FIND_REQUIRED)
59 | MESSAGE(FATAL_ERROR "Could not find FreeImagePlus")
60 | ENDIF (FreeImagePlus_FIND_REQUIRED)
61 | ENDIF (FREEIMAGEPLUS_FOUND)
62 |
--------------------------------------------------------------------------------
/source/SSGContextPlugin/SSGContextPlugin.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #pragma once
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | struct QSGContextFactoryInterface;
32 |
33 | class SSGContextPlugin
34 | : public QObject,
35 | public QSGContextFactoryInterface
36 | {
37 | Q_OBJECT
38 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QSGContextFactoryInterface" FILE "SSGContextPlugin.json")
39 | Q_INTERFACES(QSGContextFactoryInterface:QFactoryInterface)
40 |
41 | public:
42 | explicit SSGContextPlugin(QObject* parent=nullptr);
43 |
44 | QSGContext* create(const QString& key) const override;
45 | QStringList keys() const override;
46 | virtual QQuickTextureFactory *createTextureFactoryFromImage(const QImage &) override { return 0; }
47 | virtual QSGRenderLoop *createWindowManager() override { return 0; }
48 | };
49 |
--------------------------------------------------------------------------------
/source/SSGContextPlugin/SSGContext.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** (C) 2016 Erik Hvatum
4 | **
5 | ** $QT_BEGIN_LICENSE:LGPL21$
6 | ** Commercial License Usage
7 | ** Licensees holding valid commercial Qt licenses may use this file in
8 | ** accordance with the commercial license agreement provided with the
9 | ** Software or, alternatively, in accordance with the terms contained in
10 | ** a written agreement between you and The Qt Company. For licensing terms
11 | ** and conditions see http://www.qt.io/terms-conditions. For further
12 | ** information use the contact form at http://www.qt.io/contact-us.
13 | **
14 | ** GNU Lesser General Public License Usage
15 | ** Alternatively, this file may be used under the terms of the GNU Lesser
16 | ** General Public License version 2.1 or version 3 as published by the Free
17 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
18 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
19 | ** following information to ensure the GNU Lesser General Public License
20 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
21 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22 | **
23 | ** As a special exception, The Qt Company gives you certain additional
24 | ** rights. These rights are described in The Qt Company LGPL Exception
25 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
26 | **
27 | ** $QT_END_LICENSE$
28 | **
29 | ****************************************************************************/
30 |
31 | #include
32 | #include
33 | #include "SSGContext.h"
34 | #include "SSGQuickLayer.h"
35 |
36 | SSGContext::SSGContext(QObject* parent)
37 | : QSGContext(parent)
38 | {
39 | }
40 |
41 | QSGImageNode* SSGContext::createImageNode()
42 | {
43 | qDebug() << "QSGImageNode* SSGContext::createImageNode()";
44 | return QSGContext::createImageNode();
45 | }
46 |
47 | QSGLayer* SSGContext::createLayer(QSGRenderContext* renderContext)
48 | {
49 | qDebug() << "QSGLayer* SSGContext::createLayer(QSGRenderContext* renderContext)";
50 | return new SSGQuickLayer(renderContext);
51 | // return QSGContext::createLayer(renderContext);
52 | }
53 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/JSONPath/main_jsonpath.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 |
5 | #include
6 |
7 | int main (int argc, char * argv []) {
8 | Q_UNUSED (argc)
9 | Q_UNUSED (argv)
10 |
11 | QByteArray json ("{ \"store\": {"
12 | " \"book\": [ "
13 | " { \"category\": \"reference\","
14 | " \"author\": \"Nigel Rees\","
15 | " \"title\": \"Sayings of the Century\","
16 | " \"price\": 8.95"
17 | " },"
18 | " { \"category\": \"fiction\","
19 | " \"author\": \"Evelyn Waugh\","
20 | " \"title\": \"Sword of Honour\","
21 | " \"price\": 12.99"
22 | " },"
23 | " { \"category\": \"fiction\","
24 | " \"author\": \"Herman Melville\","
25 | " \"title\": \"Moby Dick\","
26 | " \"isbn\": \"0-553-21311-3\","
27 | " \"price\": 8.99"
28 | " },"
29 | " { \"category\": \"fiction\","
30 | " \"author\": \"J. R. R. Tolkien\","
31 | " \"title\": \"The Lord of the Rings\","
32 | " \"isbn\": \"0-395-19395-8\","
33 | " \"price\": 22.99"
34 | " }"
35 | " ],"
36 | " \"bicycle\": {"
37 | " \"color\": \"red\","
38 | " \"price\": 19.95"
39 | " }"
40 | " }"
41 | "}");
42 |
43 | QJsonDocument jsonDoc = QJsonDocument::fromJson (json);
44 |
45 | QtJsonPath jsonPath (jsonDoc);
46 |
47 | qDebug () << "/store/book/1" << jsonPath.getValue ("/store/book/1");
48 | qDebug () << "/store/book/2/author" << jsonPath.getValue ("/store/book/2/author");
49 | qDebug () << "/store/bicycle" << jsonPath.getValue ("/store/bicycle");
50 | qDebug () << "/store/toto" << jsonPath.getValue ("/store/toto", "N/A");
51 |
52 | return 0;
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/SingleLineEditBox.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.1;
2 |
3 | FocusScope {
4 | width: implicitWidth;
5 | height: implicitHeight;
6 | implicitWidth: (input.contentWidth + padding * 2);
7 | implicitHeight: (input.contentHeight + padding * 2);
8 |
9 | property int padding : 6;
10 |
11 | property color backgroundColor : "white";
12 | property color foregroundColor : "black";
13 | property color highlightColor : "steelblue";
14 | property color secondaryColor : "lightgray";
15 | property color borderColor : "gray";
16 |
17 | property alias textFont : input.font;
18 | property alias rounding : rect.radius;
19 | property alias editableText : input.text;
20 | property alias isEditLocked : input.readOnly;
21 | property alias placeholderText : placeholder.text;
22 |
23 | Rectangle {
24 | id: rect;
25 | color: backgroundColor;
26 | radius: 4;
27 | antialiasing: true;
28 | anchors.fill: parent;
29 | }
30 | Item {
31 | clip: true;
32 | anchors.fill: parent;
33 |
34 | TextInput {
35 | id: input;
36 | focus: true;
37 | color: (enabled ? foregroundColor : secondaryColor);
38 | selectByMouse: true;
39 | selectionColor: highlightColor;
40 | selectedTextColor: backgroundColor;
41 | activeFocusOnPress: true;
42 | font {
43 | weight: Font.Light;
44 | pixelSize: 18;
45 | }
46 | anchors {
47 | left: parent.left;
48 | right: parent.right;
49 | margins: padding;
50 | verticalCenter: parent.verticalCenter;
51 | }
52 | }
53 | Text {
54 | id: placeholder;
55 | font: input.font;
56 | color: secondaryColor;
57 | visible: (!input.activeFocus && !input.length);
58 | anchors.fill: input;
59 | }
60 | }
61 | Rectangle {
62 | color: "transparent";
63 | radius: rect.radius;
64 | antialiasing: true;
65 | border {
66 | width: (input.activeFocus ? 2 : 1);
67 | color: (input.activeFocus ? highlightColor : borderColor);
68 | }
69 | anchors.fill: parent;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/source/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 | #
3 | # Copyright (c) 2016 Erik Hvatum
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy
6 | # of this software and associated documentation files (the "Software"), to deal
7 | # in the Software without restriction, including without limitation the rights
8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | # copies of the Software, and to permit persons to whom the Software is
10 | # furnished to do so, subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | # SOFTWARE.
22 | #
23 | # Authors: Erik Hvatum
24 |
25 | set(SOURCE_FILES
26 | common.h
27 | GilLocker.cpp
28 | GilLocker.h
29 | qmldir
30 | SSGSimpleTextureNode.cpp
31 | SSGSimpleTextureNode.h
32 | SSGTexture.cpp
33 | SSGTexture.h
34 | SSGTextureMaterial.cpp
35 | SSGTextureMaterial.h
36 | SSImage.cpp
37 | SSImage.h
38 | SSImageItem.cpp
39 | SSImageItem.h
40 | SSQmlPlugin.cpp
41 | SSQmlPlugin.h
42 | SSView.cpp
43 | SSView.h)
44 | set(LIBRARIES
45 | ${OPENGL_LIBRARIES}
46 | ${FREEIMAGE_LIBRARY}
47 | ${FREEIMAGEPLUS_LIBRARY})
48 |
49 | qt5_add_resources(RESOURCES StackStreamPlugin.qrc)
50 | add_library(StackStreamPlugin SHARED ${SOURCE_FILES} ${RESOURCES})
51 | qt5_use_modules(StackStreamPlugin Core Gui Qml OpenGL Quick Widgets)
52 | target_link_libraries(StackStreamPlugin ${LIBRARIES})
53 | set_target_properties(StackStreamPlugin PROPERTIES COMPILE_OPTIONS "-DSTACKSTREAM")
54 | #set_target_properties(StackStreamPlugin PROPERTIES COMPILE_OPTIONS "-DENABLE_GL_DEBUG_LOGGING")
55 |
56 | add_subdirectory(QtQmlTricks)
57 | add_subdirectory(SSGContextPlugin)
58 | add_subdirectory(Application)
59 | if(BUILD_STACKSTREAM_PYTHON_MODULE)
60 | add_subdirectory(PythonModule)
61 | endif()
62 |
63 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 | #
3 | # Copyright (c) 2016 Erik Hvatum
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy
6 | # of this software and associated documentation files (the "Software"), to deal
7 | # in the Software without restriction, including without limitation the rights
8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | # copies of the Software, and to permit persons to whom the Software is
10 | # furnished to do so, subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | # SOFTWARE.
22 | #
23 | # Authors: Erik Hvatum
24 |
25 | project(QtQmlTricksPlugin)
26 |
27 | set(SOURCE_FILES
28 | # src/qqmlgadgetlistmodel.cpp
29 | # src/qqmlgadgetlistmodel.h
30 | src/qmlplugin.cpp
31 | src/qmlplugin.h
32 | src/qqmlhelpers.cpp
33 | src/qqmlhelpers.h
34 | src/qqmlmodels.h
35 | src/qqmlobjectlistmodel.cpp
36 | src/qqmlobjectlistmodel.h
37 | src/qqmlsvgiconhelper.cpp
38 | src/qqmlsvgiconhelper.h
39 | src/qqmlvariantlistmodel.cpp
40 | src/qqmlvariantlistmodel.h
41 | src/qqmlvariantlistmodel_p.h
42 | src/qquickpolygon.cpp
43 | src/qquickpolygon.h
44 | src/qtbitstream.h
45 | src/qtcobs.h
46 | src/qtjsonpath.h
47 | import/QtQmlTricks/qmldir
48 | include/QQmlGadgetListModel
49 | include/QQmlHelpers
50 | include/QQmlObjectListModel
51 | include/QQmlSvgIconHelper
52 | include/QQmlVariantListModel
53 | include/QQuickPolygon
54 | include/QtBitStream
55 | include/QtCOBS
56 | include/QtJsonPath
57 | include/QtQmlTricks
58 | )
59 |
60 | unset(RESOURCES)
61 | qt5_add_resources(RESOURCES import/QtQmlTricks/components.qrc)
62 | add_library(QtQmlTricksPlugin SHARED ${SOURCE_FILES} ${RESOURCES})
63 | qt5_use_modules(QtQmlTricksPlugin Core Gui Qml OpenGL Quick Svg Widgets)
64 |
--------------------------------------------------------------------------------
/cmake_modules/FindSIP.cmake:
--------------------------------------------------------------------------------
1 | # Find SIP
2 | # ~~~~~~~~
3 | #
4 | # SIP website: http://www.riverbankcomputing.co.uk/sip/index.php
5 | #
6 | # Find the installed version of SIP. FindSIP should be called after Python
7 | # has been found.
8 | #
9 | # This file defines the following variables:
10 | #
11 | # SIP_VERSION - The version of SIP found expressed as a 6 digit hex number
12 | # suitable for comparison as a string.
13 | #
14 | # SIP_VERSION_STR - The version of SIP found as a human readable string.
15 | #
16 | # SIP_EXECUTABLE - Path and filename of the SIP command line executable.
17 | #
18 | # SIP_INCLUDE_DIR - Directory holding the SIP C++ header file.
19 | #
20 | # SIP_DEFAULT_SIP_DIR - Default directory where .sip files should be installed
21 | # into.
22 |
23 | # Copyright (c) 2007, Simon Edwards
24 | # Redistribution and use is allowed according to the terms of the BSD license.
25 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
26 |
27 |
28 |
29 | IF(SIP_VERSION)
30 | # Already in cache, be silent
31 | SET(SIP_FOUND TRUE)
32 | ELSE(SIP_VERSION)
33 |
34 | FIND_FILE(_find_sip_py FindSIP.py PATHS ${CMAKE_MODULE_PATH})
35 |
36 | EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_sip_py} OUTPUT_VARIABLE sip_config)
37 | IF(sip_config)
38 | STRING(REGEX REPLACE "^sip_version:([^\n]+).*$" "\\1" SIP_VERSION ${sip_config})
39 | STRING(REGEX REPLACE ".*\nsip_version_str:([^\n]+).*$" "\\1" SIP_VERSION_STR ${sip_config})
40 | STRING(REGEX REPLACE ".*\nsip_bin:([^\n]+).*$" "\\1" SIP_EXECUTABLE ${sip_config})
41 | IF(NOT SIP_DEFAULT_SIP_DIR)
42 | STRING(REGEX REPLACE ".*\ndefault_sip_dir:([^\n]+).*$" "\\1" SIP_DEFAULT_SIP_DIR ${sip_config})
43 | ENDIF(NOT SIP_DEFAULT_SIP_DIR)
44 | STRING(REGEX REPLACE ".*\nsip_inc_dir:([^\n]+).*$" "\\1" SIP_INCLUDE_DIR ${sip_config})
45 | FILE(TO_CMAKE_PATH ${SIP_DEFAULT_SIP_DIR} SIP_DEFAULT_SIP_DIR)
46 | FILE(TO_CMAKE_PATH ${SIP_INCLUDE_DIR} SIP_INCLUDE_DIR)
47 | IF(EXISTS ${SIP_EXECUTABLE})
48 | SET(SIP_FOUND TRUE)
49 | ELSE()
50 | MESSAGE(STATUS "Found SIP configuration but the sip executable could not be found.")
51 | ENDIF()
52 | ENDIF(sip_config)
53 |
54 | IF(SIP_FOUND)
55 | IF(NOT SIP_FIND_QUIETLY)
56 | MESSAGE(STATUS "Found SIP version: ${SIP_VERSION_STR}")
57 | ENDIF(NOT SIP_FIND_QUIETLY)
58 | ELSE(SIP_FOUND)
59 | IF(SIP_FIND_REQUIRED)
60 | MESSAGE(FATAL_ERROR "Could not find SIP")
61 | ENDIF(SIP_FIND_REQUIRED)
62 | ENDIF(SIP_FOUND)
63 |
64 | ENDIF(SIP_VERSION)
65 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/TextButton.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.1;
2 | import "Style.js" as Style;
3 |
4 | MouseArea {
5 | id: clicker;
6 | width: implicitWidth;
7 | height: implicitHeight;
8 | implicitWidth: (lbl.contentWidth + padding * 2);
9 | implicitHeight: (lbl.contentHeight + padding * 2);
10 |
11 | property int padding : 6;
12 | property bool checked : false;
13 | property alias text : lbl.text;
14 | property alias textFont : lbl.font;
15 | property alias textColor : lbl.color;
16 | property alias backColor : rect.color;
17 | property alias rounding : rect.radius;
18 |
19 | Gradient {
20 | id: gradientIdle;
21 |
22 | GradientStop { color: Qt.lighter (Style.colorLightGray, 1.15); position: 0.0; }
23 | GradientStop { color: Qt.darker (Style.colorLightGray, 1.15); position: 1.0; }
24 | }
25 | Gradient {
26 | id: gradientPressed;
27 |
28 | GradientStop { color: Qt.darker (Style.colorDarkGray, 1.15); position: 0.0; }
29 | GradientStop { color: Qt.lighter (Style.colorDarkGray, 1.15); position: 1.0; }
30 | }
31 | Gradient {
32 | id: gradientChecked;
33 |
34 | GradientStop { color: Qt.darker (Style.colorLightBlue, 1.15); position: 0.0; }
35 | GradientStop { color: Qt.lighter (Style.colorLightBlue, 1.15); position: 1.0; }
36 | }
37 | Gradient {
38 | id: gradientDisabled;
39 |
40 | GradientStop { color: Style.colorLightGray; position: 0.0; }
41 | GradientStop { color: Style.colorLightGray; position: 1.0; }
42 | }
43 | Rectangle {
44 | id: rect;
45 | radius: 3;
46 | antialiasing: true;
47 | gradient: (clicker.enabled
48 | ? (checked
49 | ? gradientChecked
50 | : (pressed
51 | ? gradientPressed
52 | : gradientIdle))
53 | : gradientDisabled);
54 | border {
55 | width: 1;
56 | color: (checked ? Style.colorSteelBlue : Style.colorGray);
57 | }
58 | anchors.fill: parent;
59 | }
60 | Text {
61 | id: lbl;
62 | color: (clicker.enabled ? (checked ? Style.colorDarkBlue : Style.colorBlack) : Style.colorGray);
63 | visible: (text !== "");
64 | font {
65 | family: Style.fontName;
66 | weight: Font.Light;
67 | pixelSize: Style.fontSizeNormal;
68 | }
69 | anchors.centerIn: parent;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qquickpolygon.h:
--------------------------------------------------------------------------------
1 | #ifndef QMLPOLYGON_H
2 | #define QMLPOLYGON_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | class QQuickPolygon : public QQuickItem {
16 | Q_OBJECT
17 | Q_PROPERTY (bool closed READ getClosed WRITE setClosed NOTIFY closedChanged) // whether last point should connect to first
18 | Q_PROPERTY (qreal border READ getBorder WRITE setBorder NOTIFY borderChanged) // border width
19 | Q_PROPERTY (QColor color READ getColor WRITE setColor NOTIFY colorChanged) // back color
20 | Q_PROPERTY (QColor stroke READ getStroke WRITE setStroke NOTIFY strokeChanged) // border color
21 | Q_PROPERTY (QVariantList points READ getPoints WRITE setPoints NOTIFY pointsChanged) // points list
22 |
23 | public:
24 | explicit QQuickPolygon (QQuickItem * parent = NULL);
25 |
26 | Q_INVOKABLE bool getClosed (void) const;
27 | Q_INVOKABLE qreal getBorder (void) const;
28 | Q_INVOKABLE QColor getColor (void) const;
29 | Q_INVOKABLE QColor getStroke (void) const;
30 | Q_INVOKABLE QVariantList getPoints (void) const;
31 |
32 | public slots:
33 | void setClosed (bool closed);
34 | void setBorder (qreal border);
35 | void setColor (const QColor & color);
36 | void setStroke (const QColor & stroke);
37 | void setPoints (const QVariantList & points);
38 |
39 | signals:
40 | void colorChanged (void);
41 | void pointsChanged (void);
42 | void borderChanged (void);
43 | void closedChanged (void);
44 | void strokeChanged (void);
45 |
46 | protected:
47 | virtual QSGNode * updatePaintNode (QSGNode * oldNode, UpdatePaintNodeData * updatePaintNodeData);
48 |
49 | protected slots:
50 | void processTriangulation (void);
51 |
52 | private:
53 | bool m_closed;
54 | qreal m_border;
55 | qreal m_minX;
56 | qreal m_maxX;
57 | qreal m_minY;
58 | qreal m_maxY;
59 | QColor m_color;
60 | QColor m_stroke;
61 | QPolygonF m_points;
62 | QVector m_triangles;
63 | QSGNode * m_node;
64 | QSGGeometryNode * m_foreNode;
65 | QSGGeometryNode * m_backNode;
66 | QSGGeometry * m_foreGeometry;
67 | QSGGeometry * m_backGeometry;
68 | QSGFlatColorMaterial * m_foreMaterial;
69 | QSGFlatColorMaterial * m_backMaterial;
70 | };
71 |
72 | #endif // QMLPOLYGON_H
73 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qmlplugin.cpp:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #include "qmlplugin.h"
26 | #include "include/QQuickPolygon"
27 | #include "include/QQmlSvgIconHelper"
28 | #include "include/QQmlObjectListModel"
29 | #include "include/QQmlVariantListModel"
30 |
31 | QtQmlTricksPlugin::QtQmlTricksPlugin(QObject* parent)
32 | : QQmlExtensionPlugin(parent)
33 | {
34 | qDebug() << "QtQmlTricksPlugin loaded";
35 | }
36 |
37 | void QtQmlTricksPlugin::registerTypes(const char* uri)
38 | {
39 | Q_ASSERT(uri == QLatin1String("QtQmlTricks"));
40 | qDebug() << "QtQmlTricksPlugin::registerTypes(..)";
41 |
42 |
43 | // Q_INIT_RESOURCE (components);
44 |
45 | // const char * uri = "QtQmlTricks"; // @uri QtQmlTricks
46 | const int maj = 1;
47 | const int min = 0;
48 |
49 | qmlRegisterType (uri, maj, min, "Polygon");
50 | qmlRegisterType (uri, maj, min, "SvgIconHelper");
51 |
52 | qmlRegisterUncreatableType (uri, maj, min, "AbstractItemModel", "!!!");
53 | qmlRegisterUncreatableType (uri, maj, min, "AbstractListModel", "!!!");
54 | qmlRegisterUncreatableType (uri, maj, min, "VariantListModel", "!!!");
55 | qmlRegisterUncreatableType (uri, maj, min, "ObjectListModelBase", "!!!");
56 |
57 | // if (engine) {
58 | // engine->addImportPath ("qrc:/import");
59 | // }
60 | }
61 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qqmlsvgiconhelper.h:
--------------------------------------------------------------------------------
1 | #ifndef QQMLSVGICONHELPER_H
2 | #define QQMLSVGICONHELPER_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | class QQmlSvgIconHelper : public QObject, public QQmlParserStatus, public QQmlPropertyValueSource {
13 | Q_OBJECT
14 | Q_INTERFACES (QQmlParserStatus)
15 | Q_INTERFACES (QQmlPropertyValueSource)
16 | Q_PROPERTY (int size READ getSize WRITE setSize NOTIFY sizeChanged)
17 | Q_PROPERTY (qreal verticalRatio READ getVerticalRatio WRITE setVerticalRatio NOTIFY verticalRatioChanged)
18 | Q_PROPERTY (qreal horizontalRatio READ getHorizontalRatio WRITE setHorizontalRatio NOTIFY horizontalRatioChanged)
19 | Q_PROPERTY (QColor color READ getColor WRITE setColor NOTIFY colorChanged)
20 | Q_PROPERTY (QString icon READ getIcon WRITE setIcon NOTIFY iconChanged)
21 |
22 | public:
23 | explicit QQmlSvgIconHelper (QObject * parent = NULL);
24 | virtual ~QQmlSvgIconHelper (void);
25 |
26 | virtual void setTarget (const QQmlProperty & target);
27 | virtual void classBegin (void);
28 | virtual void componentComplete (void);
29 |
30 | static void setBasePath (const QString & basePath);
31 | static void setCachePath (const QString & cachePath);
32 |
33 | int getSize (void) const;
34 | qreal getVerticalRatio (void) const;
35 | qreal getHorizontalRatio (void) const;
36 | QColor getColor (void) const;
37 | QString getIcon (void) const;
38 |
39 | public slots:
40 | void setSize (int size);
41 | void setVerticalRatio (qreal ratio);
42 | void setHorizontalRatio (qreal ratio);
43 | void setColor (QColor color);
44 | void setIcon (QString icon);
45 |
46 | signals:
47 | void sizeChanged (void);
48 | void verticalRatioChanged (void);
49 | void horizontalRatioChanged (void);
50 | void colorChanged (void);
51 | void iconChanged (void);
52 |
53 | protected:
54 | void refresh (void);
55 |
56 | private:
57 | int m_size;
58 | bool m_ready;
59 | qreal m_verticalRatio;
60 | qreal m_horizontalRatio;
61 | QColor m_color;
62 | QString m_icon;
63 |
64 | QQmlProperty m_property;
65 |
66 | static QString s_basePath;
67 | static QString s_cachePath;
68 | static QSvgRenderer s_renderer;
69 | };
70 |
71 | #endif // QQMLSVGICONHELPER_H
72 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/TextBox.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.1;
2 | import "Style.js" as Style;
3 |
4 | FocusScope {
5 | id: base;
6 | width: implicitWidth;
7 | height: implicitHeight;
8 | implicitWidth: (input.contentWidth + padding * 2);
9 | implicitHeight: (input.contentHeight + padding * 2);
10 |
11 | property int padding : 6;
12 | property alias text : input.text;
13 | property alias textFont : input.font;
14 | property alias textColor : input.color;
15 | property alias textAlign : input.horizontalAlignment;
16 | property alias textHolder : holder.text;
17 | property alias inputMask : input.inputMask;
18 | property alias validator : input.validator;
19 | property alias rounding : rect.radius;
20 |
21 | signal accepted ();
22 |
23 | function selectAll () {
24 | input.selectAll ();
25 | }
26 | function clear () {
27 | input.text = "";
28 | }
29 |
30 | Gradient {
31 | id: gradientIdle;
32 |
33 | GradientStop { color: Style.colorWhite; position: 0.0; }
34 | GradientStop { color: Style.colorWhite; position: 1.0; }
35 | }
36 | Gradient {
37 | id: gradientDisabled;
38 |
39 | GradientStop { color: Style.colorLightGray; position: 0.0; }
40 | GradientStop { color: Style.colorLightGray; position: 1.0; }
41 | }
42 | Rectangle {
43 | id: rect;
44 | radius: 3;
45 | antialiasing: true;
46 | gradient: (base.enabled ? gradientIdle : gradientDisabled);
47 | border {
48 | width: 1;
49 | color: (input.activeFocus ? Style.colorSteelBlue : Style.colorGray);
50 | }
51 | anchors.fill: parent;
52 | }
53 | Item {
54 | clip: true;
55 | anchors {
56 | fill: rect;
57 | margins: rect.border.width;
58 | }
59 |
60 | TextInput {
61 | id: input;
62 | focus: true;
63 | color: (base.enabled ? Style.colorBlack : Style.colorGray);
64 | font {
65 | family: Style.fontName;
66 | weight: Font.Light;
67 | pixelSize: Style.fontSizeNormal;
68 | }
69 | anchors {
70 | left: parent.left;
71 | right: parent.right;
72 | margins: padding;
73 | verticalCenter: parent.verticalCenter;
74 | }
75 | onAccepted: { base.accepted (); }
76 | }
77 | }
78 | Text {
79 | id: holder;
80 | font: input.font;
81 | color: Style.colorGray;
82 | visible: (!input.activeFocus && input.text.trim ().length === 0);
83 | horizontalAlignment: input.horizontalAlignment;
84 | anchors {
85 | left: parent.left;
86 | right: parent.right;
87 | margins: padding;
88 | verticalCenter: parent.verticalCenter;
89 | }
90 | }
91 | }
92 |
93 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/examples/NiceModels/ui_nicemodels.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.1;
2 | import QtQmlTricks 1.0;
3 |
4 | Rectangle {
5 | id: window;
6 | width: 600;
7 | height: 400;
8 |
9 | ScrollContainer {
10 | anchors.fill: parent;
11 |
12 | Flickable {
13 | id: flicker;
14 | contentWidth: width;
15 | contentHeight: layout.height;
16 | flickableDirection: Flickable.VerticalFlick;
17 |
18 | Column {
19 | id: layout;
20 | anchors {
21 | top: parent.top;
22 | left: parent.left;
23 | right: parent.right;
24 | }
25 |
26 | SingleLineEditBox {
27 | placeholderText: "Type here...";
28 | anchors {
29 | left: parent.left;
30 | right: parent.right;
31 | }
32 | }
33 |
34 | Repeater {
35 | model: testModel;
36 | delegate: Text {
37 | text: "%1. %2 (%3) -> %4 = %5".arg (model.foo).arg (model.bar).arg (model.test).arg (model.type).arg (model.qtObject);
38 | }
39 | }
40 | }
41 | }
42 | }
43 | Timer {
44 | id: timer;
45 | repeat: true;
46 | running: true;
47 | interval: 1000;
48 | triggeredOnStart: true;
49 | onTriggered: {
50 | if (listOperations.length) {
51 | listOperations.shift () ();
52 | }
53 | }
54 |
55 | property var listOperations : [
56 | function () {
57 | console.log ("model count=", testModel.count);
58 | },
59 | function () {
60 | var uid = Qt.formatDate (new Date (), "yyyy-MM-dd");
61 | var obj = testModel.get (uid);
62 | console.log ("uid=", uid, "obj=", obj, "val=", obj.bar);
63 | },
64 | function () {
65 | console.log ("model remove idx 3=", (testModel.remove (3) || "DONE"));
66 | },
67 | function () {
68 | console.log ("model move idx 100 to position 1=", (testModel.move (100, 1) || "DONE"));
69 | },
70 | function () {
71 | console.log ("'foobar' at 2 :", "foobar".at (2));
72 | },
73 | function () {
74 | var arr = ["fo", "ob", "ar"];
75 | console.log ("arr before=", JSON.stringify (arr));
76 | console.log ("arr first=", arr.first ());
77 | console.log ("arr last=", arr.last ());
78 | arr.removeAt (1);
79 | console.log ("arr after remove at 1 =", JSON.stringify (arr));
80 | },
81 | function () {
82 | console.log ("remove all 'o' in 'foobar'=", "foobar".remove ('o'));
83 | },
84 | ];
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qqmlhelpers.cpp:
--------------------------------------------------------------------------------
1 | #include "qqmlhelpers.h"
2 |
3 | /*!
4 | \defgroup QT_QML_HELPERS Qt helper macros
5 |
6 | Brings a couple of macros that can help saving development time,
7 | by avoiding manual code duplication, often leading to heavy copy-and-paste,
8 | which is largely error-prone and not productive at all.
9 | */
10 |
11 |
12 | /*!
13 | \def QML_WRITABLE_PROPERTY(type, name)
14 | \ingroup QT_QML_HELPERS
15 | \hideinitializer
16 | \details Creates a \c Q_PROPERTY that will be readable / writable from QML.
17 |
18 | \param type The C++ type of the property
19 | \param name The name for the property
20 |
21 | It generates for this goal :
22 | \code
23 | {type} m_{name}; // private member variable
24 | {type} get_{name} () const; // public getter method
25 | void set_{name} ({type}); // public setter slot
26 | void {name}Changed ({type}); // notifier signal
27 | \endcode
28 |
29 | \b Note : Any change from either C++ or QML side will trigger the notification.
30 | */
31 |
32 |
33 | /*!
34 | \def QML_READONLY_PROPERTY(type, name)
35 | \ingroup QT_QML_HELPERS
36 | \hideinitializer
37 | \details Creates a \c Q_PROPERTY that will be readable from QML and writable from C++.
38 |
39 | \param type The C++ type of the property
40 | \param name The name for the property
41 |
42 | It generates for this goal :
43 | \code
44 | {type} m_{name}; // private member variable
45 | {type} get_{name} () const; // public getter method
46 | void update_{name} ({type}); // public setter method
47 | void {name}Changed ({type}); // notifier signal
48 | \endcode
49 |
50 | \b Note : Any change from C++ side will trigger the notification to QML.
51 | */
52 |
53 |
54 | /*!
55 | \def QML_CONSTANT_PROPERTY(type, name)
56 | \ingroup QT_QML_HELPERS
57 | \hideinitializer
58 | \details Creates a \c Q_PROPERTY for a constant value exposed from C++ to QML.
59 |
60 | \param type The C++ type of the property
61 | \param name The name for the property
62 |
63 | It generates for this goal :
64 | \code
65 | {type} m_{name}; // private member variable
66 | {type} get_{name} () const; // public getter method
67 | \endcode
68 |
69 | \b Note : There is no change notifier because value is constant.
70 | */
71 |
72 |
73 | /*!
74 | \def QML_ENUM_CLASS(name, ...)
75 | \ingroup QT_QML_HELPERS
76 | \hideinitializer
77 | \details Creates a class that contains a C++ enum that can be exposed to QML.
78 |
79 | \param name The name for the class
80 | \param ... The variadic list of values for the enum (comma-separated)
81 |
82 | It generates for this goal :
83 | \li The \c {name} C++ QObject-derived class
84 | \li The \c {name}::Type enumeration containing the values list
85 | \li The \c Q_ENUMS macro call to allow QML usage
86 |
87 | Example in use :
88 | \code
89 | QML_ENUM_CLASS (DaysOfWeek, Monday = 1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)
90 | \endcode
91 |
92 | \b Note : The QML registration using \c qmlRegisterUncreatableType() will still be needed.
93 | */
94 |
--------------------------------------------------------------------------------
/source/SSImageItem.cpp:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #include "SSImageItem.h"
26 | #include "SSGSimpleTextureNode.h"
27 |
28 | SSImageItem::SSImageItem(QQuickItem* parent)
29 | : QQuickItem(parent),
30 | m_imageSerialSet(false)
31 | {
32 | setFlag(ItemHasContents);
33 | }
34 |
35 | SSImage* SSImageItem::image()
36 | {
37 | return m_image.data();
38 | }
39 |
40 | const SSImage* SSImageItem::image() const
41 | {
42 | return m_image.data();
43 | }
44 |
45 | static void noopDeleter(SSImage*) {}
46 |
47 | void SSImageItem::setImage(SSImage* image)
48 | {
49 | if(image != m_image.data())
50 | {
51 | if(image)
52 | {
53 | m_image = image->sharedFromThis();
54 | if(!m_image) m_image = QSharedPointer(image, noopDeleter);
55 | setImplicitSize(m_image->size().width(), m_image->size().height());
56 | }
57 | else
58 | {
59 | m_image.reset();
60 | setImplicitSize(0,0);
61 | }
62 | imageChanged();
63 | update();
64 | }
65 | }
66 |
67 | QSGNode* SSImageItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* updatePaintNodeData)
68 | {
69 | SSGSimpleTextureNode* n{static_cast(oldNode)};
70 | if(m_image)
71 | {
72 | if(!n)
73 | {
74 | n = new SSGSimpleTextureNode();
75 | n->setTextureCoordinatesTransform(SSGSimpleTextureNode::MirrorVertically);
76 | }
77 | if(!m_imageSerialSet || m_imageSerial != m_image->serial())
78 | {
79 | m_imageSerialSet = true;
80 | m_imageSerial = m_image->serial();
81 | SSGTexture* t = SSGTexture::fromImage(m_image.data());
82 | n->setTexture(t);
83 | }
84 | n->setRect(x(), y(), width(), height());
85 | }
86 | else
87 | {
88 | if(n)
89 | {
90 | delete n;
91 | n = nullptr;
92 | }
93 | m_imageSerialSet = false;
94 | }
95 | return n;
96 | }
97 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qtjsonpath.h:
--------------------------------------------------------------------------------
1 | #ifndef QTJSONPATH
2 | #define QTJSONPATH
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | class QtJsonPath {
13 | public:
14 | explicit QtJsonPath (QJsonValue & jsonVal) {
15 | QJsonObject jsonObj = jsonVal.toObject ();
16 | if (!jsonObj.isEmpty ()) {
17 | initWithNode (jsonObj);
18 | }
19 | else {
20 | QJsonArray jsonArray = jsonVal.toArray ();
21 | if (!jsonArray.isEmpty ()) {
22 | initWithNode (jsonArray);
23 | }
24 | else { }
25 | }
26 | }
27 |
28 | explicit QtJsonPath (QJsonObject & jsonObj) {
29 | initWithNode (jsonObj);
30 | }
31 |
32 | explicit QtJsonPath (QJsonArray & jsonArray) {
33 | initWithNode (jsonArray);
34 | }
35 |
36 | explicit QtJsonPath (QJsonDocument & jsonDoc) {
37 | QJsonObject jsonObj = jsonDoc.object ();
38 | if (!jsonObj.isEmpty ()) {
39 | initWithNode (jsonObj);
40 | }
41 | else {
42 | QJsonArray jsonArray = jsonDoc.array ();
43 | if (!jsonArray.isEmpty ()) {
44 | initWithNode (jsonArray);
45 | }
46 | else { }
47 | }
48 | }
49 |
50 | QVariant getValue (QString path, QVariant fallback = QVariant ()) const {
51 | QVariant ret;
52 | QStringList list = path.split ('/', QString::SkipEmptyParts);
53 | if (!list.empty () && !m_rootNode.isUndefined () && !m_rootNode.isNull ()) {
54 | QJsonValue currNode = m_rootNode;
55 | bool error = false;
56 | const unsigned int len = list.size ();
57 | for (unsigned int depth = 0; (depth < len) && (!error); depth++) {
58 | QString part = list.at (depth);
59 | bool isNum = false;
60 | int index = part.toInt (&isNum, 10);
61 | if (isNum) { // NOTE : array subpath
62 | if (currNode.isArray ()) {
63 | QJsonArray arrayNode = currNode.toArray ();
64 | if (index < arrayNode.size ()) {
65 | currNode = arrayNode.at (index);
66 | }
67 | else { error = true; }
68 | }
69 | else { error = true; }
70 | }
71 | else { // NOTE : object subpath
72 | if (currNode.isObject ()) {
73 | QJsonObject objNode = currNode.toObject ();
74 | if (objNode.contains (part)) {
75 | currNode = objNode.value (part);
76 | }
77 | else { error = true; }
78 | }
79 | else { error = true; }
80 | }
81 | }
82 | ret = (!error ? currNode.toVariant () : fallback);
83 | }
84 | return ret;
85 | }
86 |
87 | protected:
88 | void initWithNode (QJsonValue jsonNode) {
89 | m_rootNode = jsonNode;
90 | }
91 |
92 | private:
93 | QJsonValue m_rootNode;
94 | };
95 |
96 | #endif // QTJSONPATH
97 |
98 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/RowContainer.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0;
2 |
3 | /**
4 | * @brief Item that layouts its children within a row, respecting size hints and spacers.
5 | *
6 | */
7 | Item {
8 | id: layout;
9 | width: implicitWidth;
10 | height: implicitHeight;
11 | onWidthChanged: { relayout (); }
12 | onChildrenChanged: {
13 | if (layout && layout.ready) {
14 | var tmp = [];
15 | var dirty = false;
16 | items.forEach (function (item) {
17 | if (item && item ["parent"] === layout) {
18 | tmp.push (item);
19 | }
20 | else {
21 | dirty = true;
22 | }
23 | });
24 | for (var idx = 0; idx < children.length; idx++) {
25 | var child = children [idx];
26 | if (items.indexOf (child) < 0 && !("delegate" in child)) {
27 | child.visibleChanged.connect (relayout);
28 | child.implicitWidthChanged.connect (relayout);
29 | child.implicitHeightChanged.connect (relayout);
30 | tmp.push (child);
31 | dirty = true;
32 | }
33 | }
34 | if (dirty) {
35 | items = tmp;
36 | relayout ();
37 | }
38 | }
39 | }
40 | Component.onCompleted: {
41 | ready = true;
42 | layout.childrenChanged ();
43 | }
44 | Component.onDestruction: {
45 | ready = false;
46 | }
47 |
48 | property int spacing : 0;
49 | property var items : [];
50 |
51 | property bool ready : false;
52 |
53 | default property alias content : layout.data;
54 |
55 | function relayout () {
56 | if (layout && layout.ready) {
57 | var tmpW = 0;
58 | var tmpH = 0;
59 | var nbStretch = 0;
60 | var nb = 0;
61 | items.forEach (function (child) {
62 | if (child && child ["visible"]) {
63 | if (child ["implicitHeight"] > tmpH) {
64 | tmpH = child ["implicitHeight"];
65 | }
66 | if (nb) {
67 | tmpW += spacing;
68 | }
69 | if (child ["implicitWidth"] >= 0) {
70 | tmpW += child ["implicitWidth"];
71 | }
72 | else {
73 | nbStretch++;
74 | }
75 | nb++;
76 | }
77 | });
78 | implicitWidth = tmpW;
79 | implicitHeight = tmpH;
80 | var autoSize = (nbStretch > 0 ? (width - implicitWidth) / nbStretch : 0);
81 | var currX = 0;
82 | items.forEach (function (child) {
83 | if (child && child ["visible"]) {
84 | if (currX) {
85 | currX += spacing;
86 | }
87 | child ["x"] = currX;
88 | child ["width"] = (child ["implicitWidth"] >= 0 ? child ["implicitWidth"] : autoSize);
89 | currX += child ["width"];
90 | }
91 | });
92 | }
93 | }
94 |
95 | /* CONTENT HERE */
96 | }
97 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qqmlhelpers.h:
--------------------------------------------------------------------------------
1 | #ifndef QQMLHELPERS_H
2 | #define QQMLHELPERS_H
3 |
4 | #include
5 |
6 | #define QML_WRITABLE_PROPERTY(type, name) \
7 | protected: \
8 | Q_PROPERTY (type name READ get_##name WRITE set_##name NOTIFY name##Changed) \
9 | private: \
10 | type m_##name; \
11 | public: \
12 | type get_##name () const { \
13 | return m_##name ; \
14 | } \
15 | public Q_SLOTS: \
16 | bool set_##name (type name) { \
17 | bool ret = false; \
18 | if ((ret = m_##name != name)) { \
19 | m_##name = name; \
20 | emit name##Changed (m_##name); \
21 | } \
22 | return ret; \
23 | } \
24 | Q_SIGNALS: \
25 | void name##Changed (type name); \
26 | private:
27 |
28 | #define QML_READONLY_PROPERTY(type, name) \
29 | protected: \
30 | Q_PROPERTY (type name READ get_##name NOTIFY name##Changed) \
31 | private: \
32 | type m_##name; \
33 | public: \
34 | type get_##name () const { \
35 | return m_##name ; \
36 | } \
37 | bool update_##name (type name) { \
38 | bool ret = false; \
39 | if ((ret = m_##name != name)) { \
40 | m_##name = name; \
41 | emit name##Changed (m_##name); \
42 | } \
43 | return ret; \
44 | } \
45 | Q_SIGNALS: \
46 | void name##Changed (type name); \
47 | private:
48 |
49 | #define QML_CONSTANT_PROPERTY(type, name) \
50 | protected: \
51 | Q_PROPERTY (type name READ get_##name CONSTANT) \
52 | private: \
53 | type m_##name; \
54 | public: \
55 | type get_##name () const { \
56 | return m_##name ; \
57 | } \
58 | private:
59 |
60 | #define QML_LIST_PROPERTY(CLASS, NAME, TYPE) \
61 | public: \
62 | static int NAME##_count (QQmlListProperty * prop) { \
63 | CLASS * instance = qobject_cast (prop->object); \
64 | return (instance != NULL ? instance->m_##NAME.count () : 0); \
65 | } \
66 | static void NAME##_clear (QQmlListProperty * prop) { \
67 | CLASS * instance = qobject_cast (prop->object); \
68 | if (instance != NULL) { \
69 | instance->m_##NAME.clear (); \
70 | } \
71 | } \
72 | static void NAME##_append (QQmlListProperty * prop, TYPE * obj) { \
73 | CLASS * instance = qobject_cast (prop->object); \
74 | if (instance != NULL && obj != NULL) { \
75 | instance->m_##NAME.append (obj); \
76 | } \
77 | } \
78 | static TYPE * NAME##_at (QQmlListProperty * prop, int idx) { \
79 | CLASS * instance = qobject_cast (prop->object); \
80 | return (instance != NULL ? instance->m_##NAME.at (idx) : NULL); \
81 | } \
82 | QList get_##NAME##s (void) const { \
83 | return m_##NAME; \
84 | } \
85 | private: \
86 | QList m_##NAME;
87 |
88 | #define QML_ENUM_CLASS(name, ...) \
89 | class name : public QObject { \
90 | Q_GADGET \
91 | public: \
92 | enum Type { __VA_ARGS__ }; \
93 | Q_ENUMS (Type) \
94 | };
95 |
96 | class QmlProperty : public QObject { Q_OBJECT }; // NOTE : to avoid "no suitable class found" MOC note
97 |
98 | #endif // QQMLHELPERS_H
99 |
--------------------------------------------------------------------------------
/source/Application/main.cpp:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #include "../common.h"
26 | #include "../SSImageItem.h"
27 | #include
28 | #include
29 |
30 | static QSurfaceFormat fmt;
31 |
32 | static void onStackStreamWindowCreated(QObject* object, const QUrl&)
33 | {
34 | QQuickWindow* stackStreamMainWindow{qobject_cast(object)};
35 | if(stackStreamMainWindow && stackStreamMainWindow->objectName() == "stackStreamMainWindow")
36 | {
37 | stackStreamMainWindow->setFormat(fmt);
38 | stackStreamMainWindow->show();
39 | }
40 | }
41 |
42 | int main(int argc, char *argv[])
43 | {
44 | setenv("QMLSCENE_DEVICE", "SSGContextPlugin", 1);
45 | QApplication app(argc, argv);
46 | {
47 | fmt.setRenderableType(QSurfaceFormat::OpenGL);
48 | fmt.setProfile(QSurfaceFormat::CompatibilityProfile);
49 | fmt.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
50 | fmt.setSwapInterval(1);
51 | fmt.setVersion(4, 5);
52 | #ifdef ENABLE_GL_DEBUG_LOGGING
53 | fmt.setOptions(QSurfaceFormat::DebugContext | QSurfaceFormat::DeprecatedFunctions);
54 | #else
55 | fmt.setOptions(QSurfaceFormat::DeprecatedFunctions);
56 | #endif
57 | fmt.setStencilBufferSize(8);
58 | fmt.setSamples(8);
59 | // We request 30-bit color; if it's not available, Qt automatically falls back to 24-bit
60 | fmt.setRedBufferSize(10);
61 | fmt.setGreenBufferSize(10);
62 | fmt.setBlueBufferSize(10);
63 | // NB: Requesting 2-bit alpha and getting it on Linux leads to crashes
64 | // fmt.setAlphaBufferSize(2);
65 | QSurfaceFormat::setDefaultFormat(fmt);
66 | }
67 |
68 | QQmlApplicationEngine engine;
69 | QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, onStackStreamWindowCreated);
70 | engine.load(QUrl(QStringLiteral("qrc:/StackStreamMainWindow.qml")));
71 | // MakeImage ssimageFactory;
72 | // engine.rootContext()->setContextProperty("ssimageFactory", &ssimageFactory);
73 | // engine.setObjectOwnership(&ssimageFactory, QQmlEngine::CppOwnership);
74 |
75 | int ret{app.exec()};
76 | #ifdef ENABLE_GL_DEBUG_LOGGING
77 | if(g_glDebugLogger)
78 | {
79 | delete g_glDebugLogger;
80 | g_glDebugLogger = nullptr;
81 | }
82 | #endif
83 | return ret;
84 | }
85 |
86 | #include "main.moc"
87 |
--------------------------------------------------------------------------------
/source/common.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | #pragma once
26 |
27 | #ifndef QT_NO_DEBUG
28 | #define QT_QML_DEBUG
29 | #endif
30 |
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 | #include
48 | #include
49 | #include
50 | #include
51 | #include
52 |
53 | #ifdef WITH_PYTHON
54 | #include
55 | #endif
56 |
57 | #ifdef STACKSTREAM
58 | #define STACKSTREAM_DLLSPEC Q_DECL_EXPORT
59 | #ifdef ENABLE_GL_DEBUG_LOGGING
60 | extern QOpenGLDebugLogger* g_glDebugLogger;
61 | #endif
62 | #else
63 | #define STACKSTREAM_DLLSPEC Q_DECL_IMPORT
64 | #endif
65 |
66 | #ifdef min
67 | #undef min
68 | #endif
69 |
70 | #ifdef max
71 | #undef max
72 | #endif
73 |
74 | #ifdef read
75 | #undef read
76 | #endif
77 |
78 | #ifdef write
79 | #undef write
80 | #endif
81 |
82 | #include
83 | #include
84 | #include
85 |
86 | class TimeThisBlock
87 | {
88 | public:
89 | TimeThisBlock() : t0(std::chrono::high_resolution_clock::now()) {}
90 | ~TimeThisBlock()
91 | {
92 | std::chrono::high_resolution_clock::time_point t1{std::chrono::high_resolution_clock::now()};
93 | double nanoseconds_elapsed = static_cast(std::chrono::duration_cast(t1 - t0).count());
94 | if(nanoseconds_elapsed < 1000)
95 | std::cout << nanoseconds_elapsed << "ns";
96 | else if(nanoseconds_elapsed < 1e6)
97 | std::cout << nanoseconds_elapsed * static_cast(1e-3) << "µs";
98 | else if(nanoseconds_elapsed < 1e9)
99 | std::cout << nanoseconds_elapsed * static_cast(1e-6) << "ms";
100 | else
101 | std::cout << nanoseconds_elapsed * static_cast(1e-9) << "s";
102 | std::cout << std::endl;
103 | }
104 | protected:
105 | std::chrono::high_resolution_clock::time_point t0;
106 | };
107 |
--------------------------------------------------------------------------------
/source/SSGSimpleTextureNode.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Portions (C) 2015 The Qt Company Ltd.
4 | ** Portions (C) 2016 Erik Hvatum
5 | ** Contact: http://www.qt.io/licensing/
6 | **
7 | ** This file is part of the QtQuick module of the Qt Toolkit.
8 | **
9 | ** $QT_BEGIN_LICENSE:LGPL21$
10 | ** Commercial License Usage
11 | ** Licensees holding valid commercial Qt licenses may use this file in
12 | ** accordance with the commercial license agreement provided with the
13 | ** Software or, alternatively, in accordance with the terms contained in
14 | ** a written agreement between you and The Qt Company. For licensing terms
15 | ** and conditions see http://www.qt.io/terms-conditions. For further
16 | ** information use the contact form at http://www.qt.io/contact-us.
17 | **
18 | ** GNU Lesser General Public License Usage
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser
20 | ** General Public License version 2.1 or version 3 as published by the Free
21 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
22 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
23 | ** following information to ensure the GNU Lesser General Public License
24 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
25 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
26 | **
27 | ** As a special exception, The Qt Company gives you certain additional
28 | ** rights. These rights are described in The Qt Company LGPL Exception
29 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
30 | **
31 | ** $QT_END_LICENSE$
32 | **
33 | ****************************************************************************/
34 |
35 | #pragma once
36 | #include "common.h"
37 | #include "SSGTexture.h"
38 | #include "SSGTextureMaterial.h"
39 |
40 | class SSGSimpleTextureNodePrivate;
41 |
42 | class Q_QUICK_EXPORT SSGSimpleTextureNode
43 | : public QSGGeometryNode
44 | {
45 | public:
46 | SSGSimpleTextureNode();
47 | ~SSGSimpleTextureNode();
48 |
49 | void setRect(const QRectF &rect);
50 | inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); }
51 | QRectF rect() const;
52 |
53 | void setSourceRect(const QRectF &r);
54 | inline void setSourceRect(qreal x, qreal y, qreal w, qreal h) { setSourceRect(QRectF(x, y, w, h)); }
55 | QRectF sourceRect() const;
56 |
57 | void setTexture(SSGTexture *texture);
58 | SSGTexture *texture() const;
59 |
60 | void setMinFiltering(SSGTexture::Filtering filtering);
61 | SSGTexture::Filtering minFiltering() const;
62 |
63 | void setMagFiltering(SSGTexture::Filtering filtering);
64 | SSGTexture::Filtering magFiltering() const;
65 |
66 | enum TextureCoordinatesTransformFlag {
67 | NoTransform = 0x00,
68 | MirrorHorizontally = 0x01,
69 | MirrorVertically = 0x02
70 | };
71 | Q_DECLARE_FLAGS(TextureCoordinatesTransformMode, TextureCoordinatesTransformFlag)
72 |
73 | void setTextureCoordinatesTransform(TextureCoordinatesTransformMode mode);
74 | TextureCoordinatesTransformMode textureCoordinatesTransform() const;
75 |
76 | void setOwnsTexture(bool owns);
77 | bool ownsTexture() const;
78 |
79 | protected:
80 | QSGGeometry m_geometry;
81 | SSGTextureMaterial m_material;
82 | bool m_ownsTexture;
83 | TextureCoordinatesTransformMode m_texCoordMode;
84 | QRectF m_rect;
85 | QRectF m_sourceRect;
86 |
87 | private:
88 | Q_DECLARE_PRIVATE(SSGSimpleTextureNode)
89 | };
90 |
91 | Q_DECLARE_OPERATORS_FOR_FLAGS(SSGSimpleTextureNode::TextureCoordinatesTransformMode)
92 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/QtQmlTricks.qbs:
--------------------------------------------------------------------------------
1 | import qbs;
2 | import qbs.Process;
3 |
4 | Project {
5 | name: "The Qt QML Tricks";
6 | references: [
7 | "src/QtLibrary.qbs",
8 | "import/QtQmlTricks/QmlComponents.qbs",
9 | "examples/IconCache/IconCache.qbs",
10 | "examples/NiceModels/NiceModels.qbs",
11 | "examples/CustomPolygon/CustomPolygon.qbs",
12 | "examples/COBS/QtCOBS.qbs",
13 | "examples/BitStream/QtBitStream.qbs",
14 | "examples/JSONPath/QtJsonPath.qbs",
15 | ];
16 |
17 | Product {
18 | name: "sdk-utilities";
19 |
20 | Export {
21 | cpp.includePaths: "./include";
22 |
23 | Depends { name: "cpp"; }
24 | Depends {
25 | name: "Qt";
26 | submodules: ["core", "gui", "qml", "quick", "svg"];
27 | }
28 | Depends { name: "lib-qt-qml-tricks"; }
29 | Depends { name: "qml-js-imports"; }
30 | }
31 | Depends {
32 | name: "Qt";
33 | submodules: ["qml", "quick"];
34 | }
35 | Group {
36 | name: "Includes";
37 | prefix: "include/";
38 | files: ["Q*"];
39 | excludeFiles: "*.qbs";
40 | }
41 | }
42 | Product {
43 | name: "project-utils";
44 | type: "docs";
45 |
46 | Group {
47 | name: "Git files";
48 | files: [
49 | ".gitignore"
50 | ];
51 | }
52 | Group {
53 | name: "Doyxgen config";
54 | prefix: "doc/"
55 | files: ["Doxyfile"];
56 | fileTags: "doxyconf";
57 | }
58 | Group {
59 | name: "Schema";
60 | prefix: "doc/"
61 | files: ["*.svg"];
62 | }
63 | Group {
64 | name: "Doxygen CSS style";
65 | prefix: "doc/"
66 | files: ["*.css"];
67 | fileTags: "style";
68 | }
69 | Group {
70 | name: "Doxygen C++ inputs";
71 | prefix: "src/";
72 | files: ["*.h", "*.cpp"];
73 | fileTags: "source";
74 | }
75 | Group {
76 | name: "Doxygen JavaScript & QML inputs";
77 | prefix: "import/**/";
78 | files: ["*.qml", "*.js"];
79 | fileTags: "source";
80 | }
81 | Group {
82 | name: "MarkDown documents";
83 | files: ["*.md"];
84 | fileTags: "markdown";
85 | }
86 | Rule {
87 | inputs: ["doxyconf", "source", "style", "markdown"];
88 | multiplex: "true";
89 | prepare: {
90 | var cmd = new JavaScriptCommand ();
91 | cmd.description = "generating documentation from doxygen config";
92 | cmd.highlight = "doxygen";
93 | cmd.sourceCode = function () {
94 | for (var idx = 0; idx < inputs ["doxyconf"].length; idx++) {
95 | var file = inputs ["doxyconf"][idx].filePath;
96 | var proc = new Process ();
97 | proc.setWorkingDirectory (product.sourceDirectory + "/doc");
98 | proc.exec ("doxygen", [file]);
99 | }
100 | }
101 | return cmd;
102 | }
103 |
104 | Artifact {
105 | fileTags: "docs";
106 | filePath: "force.doc";
107 | alwaysUpdated: true;
108 | }
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/source/SSGTextureMaterial.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Portions (C) 2015 The Qt Company Ltd.
4 | ** Portions (C) 2016 Erik Hvatum
5 | ** Contact: http://www.qt.io/licensing/
6 | **
7 | ** This file is part of the QtQuick module of the Qt Toolkit.
8 | **
9 | ** $QT_BEGIN_LICENSE:LGPL21$
10 | ** Commercial License Usage
11 | ** Licensees holding valid commercial Qt licenses may use this file in
12 | ** accordance with the commercial license agreement provided with the
13 | ** Software or, alternatively, in accordance with the terms contained in
14 | ** a written agreement between you and The Qt Company. For licensing terms
15 | ** and conditions see http://www.qt.io/terms-conditions. For further
16 | ** information use the contact form at http://www.qt.io/contact-us.
17 | **
18 | ** GNU Lesser General Public License Usage
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser
20 | ** General Public License version 2.1 or version 3 as published by the Free
21 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
22 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
23 | ** following information to ensure the GNU Lesser General Public License
24 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
25 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
26 | **
27 | ** As a special exception, The Qt Company gives you certain additional
28 | ** rights. These rights are described in The Qt Company LGPL Exception
29 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
30 | **
31 | ** $QT_END_LICENSE$
32 | **
33 | ****************************************************************************/
34 |
35 | #pragma once
36 | #include "common.h"
37 | #include "SSGTexture.h"
38 |
39 | class SSGTextureMaterial
40 | : public QSGMaterial
41 | {
42 | public:
43 | SSGTextureMaterial();
44 |
45 | virtual QSGMaterialType *type() const;
46 | virtual QSGMaterialShader *createShader() const;
47 | virtual int compare(const QSGMaterial *other) const;
48 |
49 | void setTexture(SSGTexture *texture);
50 | SSGTexture *texture() const { return m_texture; }
51 |
52 | void setMinFiltering(SSGTexture::Filtering filteringType) { m_min_filtering = filteringType; }
53 | SSGTexture::Filtering minFiltering() const { return SSGTexture::Filtering(m_min_filtering); }
54 |
55 | void setMagFiltering(SSGTexture::Filtering filteringType) { m_mag_filtering = filteringType; }
56 | SSGTexture::Filtering magFiltering() const { return SSGTexture::Filtering(m_mag_filtering); }
57 |
58 | void setMinMipmapFiltering(SSGTexture::Filtering filteringType) { m_min_mipmap_filtering = filteringType; }
59 | SSGTexture::Filtering minMipmapFiltering() const { return SSGTexture::Filtering(m_min_mipmap_filtering); }
60 |
61 | void setMagMipmapFiltering(SSGTexture::Filtering filteringType) { m_mag_mipmap_filtering = filteringType; }
62 | SSGTexture::Filtering magMipmapFiltering() const { return SSGTexture::Filtering(m_mag_mipmap_filtering); }
63 |
64 | void setHorizontalWrapMode(SSGTexture::WrapMode mode) { m_horizontal_wrap = mode; }
65 | SSGTexture::WrapMode horizontalWrapMode() const { return SSGTexture::WrapMode(m_horizontal_wrap); }
66 |
67 | void setVerticalWrapMode(SSGTexture::WrapMode mode) { m_vertical_wrap = mode; }
68 | SSGTexture::WrapMode verticalWrapMode() const { return SSGTexture::WrapMode(m_vertical_wrap); }
69 |
70 | protected:
71 | SSGTexture *m_texture;
72 |
73 | uint m_min_filtering: 2;
74 | uint m_mag_filtering: 2;
75 | uint m_min_mipmap_filtering: 2;
76 | uint m_mag_mipmap_filtering: 2;
77 | uint m_horizontal_wrap : 1;
78 | uint m_vertical_wrap: 1;
79 |
80 | uint m_reserved : 26;
81 | };
82 |
83 |
--------------------------------------------------------------------------------
/devtest/PyQmlProof/PyQmlProof.py:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 | #
3 | # Copyright (c) 2016 Erik Hvatum
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy
6 | # of this software and associated documentation files (the "Software"), to deal
7 | # in the Software without restriction, including without limitation the rights
8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | # copies of the Software, and to permit persons to whom the Software is
10 | # furnished to do so, subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | # SOFTWARE.
22 | #
23 | # Authors: Erik Hvatum
24 |
25 | from pathlib import Path
26 | from PyQt5 import Qt
27 | import sys
28 | from ris_widget import om
29 | from list_role_model import ListRoleModel
30 |
31 | class OutlinePoint(Qt.QObject):
32 | x_Changed = Qt.pyqtSignal(float)
33 | y_Changed = Qt.pyqtSignal(float)
34 |
35 | def __init__(self, x=0, y=0, parent=None):
36 | super().__init__(parent)
37 | self._x = float(x)
38 | self._y = float(y)
39 |
40 | def __repr__(self):
41 | return 'OutlinePoint({}, {})'.format(self._x, self._y)
42 |
43 | def getX_(self):
44 | return self._x
45 |
46 | def setX_(self, x):
47 | x = float(x)
48 | if abs(x - self._x) > 0.00001:
49 | self._x = x
50 | self.x_Changed.emit(x)
51 |
52 | x_ = Qt.pyqtProperty(float, fget=getX_, fset=setX_, notify=x_Changed)
53 |
54 | def getY_(self):
55 | return self._y
56 |
57 | def setY_(self, y):
58 | if abs(y - self._y) > 0.00001:
59 | self._y = y
60 | self.y_Changed.emit(y)
61 |
62 | y_ = Qt.pyqtProperty(float, fget=getY_, fset=setY_, notify=y_Changed)
63 |
64 | class OutlinePointList(om.UniformSignalingList):
65 | def take_input_element(self, obj):
66 | if isinstance(obj, OutlinePoint):
67 | return obj
68 | elif isinstance(obj, (Qt.QPointF, Qt.QPoint)):
69 | return OutlinePoint(obj.x(), obj.y())
70 | else:
71 | i = iter(obj)
72 | return OutlinePoint(next(i), next(i))
73 |
74 | class PointListModel(ListRoleModel):
75 | @Qt.pyqtSlot(float, float)
76 | def append(self, x, y):
77 | self.signaling_list.append(OutlinePoint(x, y))
78 |
79 | @Qt.pyqtSlot(int)
80 | def delAtIndex(self, idx):
81 | del self.signaling_list[idx]
82 |
83 | _QML_TYPES_REGISTERED = False
84 |
85 | class PickerWidget(Qt.QQuickWidget):
86 | def __init__(self, parent=None):
87 | super().__init__(parent)
88 | global _QML_TYPES_REGISTERED
89 | if not _QML_TYPES_REGISTERED:
90 | Qt.qmlRegisterType(OutlinePoint)
91 | Qt.qmlRegisterType(ListRoleModel)
92 | _QML_TYPES_REGISTERED = True
93 | self.setResizeMode(Qt.QQuickWidget.SizeRootObjectToView)
94 | self.point_list = OutlinePointList()
95 | self.point_list_model = PointListModel(('x_', 'y_'), self.point_list)
96 | self.rootContext().setContextProperty("pointListModel", self.point_list_model)
97 | self.setSource(Qt.QUrl(str(Path(__file__).parent / 'PyQmlProof.qml')))
98 | self.show()
99 |
100 | if __name__ == "__main__":
101 | app = Qt.QApplication(sys.argv)
102 | picker_widget = PickerWidget()
103 | app.exec_()
104 |
--------------------------------------------------------------------------------
/devtest/PyQmlProof/PointTablePane.qml:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | import QtQuick 2.5
26 | import QtQuick.Controls 1.4
27 | import QtQuick.Layouts 1.2
28 |
29 | GroupBox {
30 | id: pointsGroupBox
31 | title: "Points"
32 | Layout.minimumWidth: 1
33 | Layout.margins: 5
34 | width: 400
35 | clip: true
36 |
37 | Column {
38 | id: "column"
39 | anchors.fill: parent
40 | z: 1
41 |
42 | TableView {
43 | id: tableView
44 | anchors.margins: 5
45 | anchors.left: parent.left
46 | anchors.right: parent.right
47 | model: pointListModel
48 | selectionMode: SelectionMode.ExtendedSelection
49 | activeFocusOnTab: true
50 |
51 | TableViewColumn {
52 | role: "x_"
53 | title: "x"
54 | width: column.width / 2 - 20
55 | movable: false
56 | }
57 |
58 | TableViewColumn {
59 | role: "y_"
60 | title: "y"
61 | width: column.width / 2 - 20
62 | movable: false
63 | }
64 |
65 | // Keys.onPressed: {
66 | // console.log("pressed")
67 | // tableView.selection.forEach(function(row){console.log(row)})
68 | // }
69 |
70 | // onFocusChanged: {
71 | // console.log(focus)
72 | // }
73 |
74 | // onClicked: {
75 | // console.log("clicked")
76 | // parent.parent.forceActiveFocus()
77 | // parent.parent.focus = true
78 | // }
79 | }
80 |
81 | Repeater {
82 | id: spinBoxRepeater
83 | model: pointListModel
84 | delegate: Row {
85 | spacing: 5
86 |
87 | Label {
88 | text: index.toString()
89 | }
90 |
91 | SpinBox {
92 | id: xSpinBox
93 | minimumValue: -999999
94 | maximumValue: 999999
95 | decimals: 5
96 | value: x_
97 | onValueChanged: {
98 | if(Math.abs(x_ - value) > 0.00001) x_ = value
99 | }
100 | }
101 |
102 | SpinBox {
103 | id: ySpinBox
104 | minimumValue: -999999
105 | maximumValue: 999999
106 | decimals: 5
107 | value: y_
108 | onValueChanged: {
109 | if(Math.abs(y_ - value) > 0.00001) y_ = value
110 | }
111 | }
112 |
113 | Button {
114 | id: delButton
115 | text: 'X'
116 | onClicked: {
117 | pointListModel.delAtIndex(index)
118 | }
119 | }
120 | }
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qtbitstream.h:
--------------------------------------------------------------------------------
1 | #ifndef QTBITSTREAM_H
2 | #define QTBITSTREAM_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | // TODO : handle little/big endian
9 |
10 | // TODO : handle sign bit moves
11 |
12 | // NOTE : using template partial specialization + SFINAE to ensure compile-time type checking and no build error
13 |
14 | typedef unsigned int UInt;
15 | typedef unsigned char Byte;
16 |
17 | template class CheckInt {
18 | public:
19 | static const bool isInt = false;
20 | static bool testBit (T, UInt) { return false; }
21 | };
22 |
23 | #define CheckInt_SPECIALIZE(TYPE) \
24 | template<> class CheckInt { \
25 | public: static const bool isInt = true; \
26 | public: static bool testBit (TYPE src, UInt bit) { return ((src >> bit) & 0x1); } }
27 |
28 | CheckInt_SPECIALIZE (bool);
29 | CheckInt_SPECIALIZE (qint8);
30 | CheckInt_SPECIALIZE (qint16);
31 | CheckInt_SPECIALIZE (qint32);
32 | CheckInt_SPECIALIZE (qint64);
33 | CheckInt_SPECIALIZE (quint8);
34 | CheckInt_SPECIALIZE (quint16);
35 | CheckInt_SPECIALIZE (quint32);
36 | CheckInt_SPECIALIZE (quint64);
37 |
38 | class QtBitStream {
39 | public:
40 | explicit QtBitStream (QByteArray data)
41 | : m_len (data.size () * 8)
42 | , m_pos (0)
43 | , m_data (data) {
44 | if (!m_len) {
45 | qWarning () << "QtBitStream with an empty data buffer is useless, nothing can be done on it !";
46 | }
47 | }
48 |
49 | QByteArray getData (void) const {
50 | return m_data;
51 | }
52 |
53 | UInt getPosition (void) const {
54 | return m_pos;
55 | }
56 |
57 | QString toBinary (bool blocks = true) const {
58 | QString ret;
59 | for (UInt bit = 0; bit < m_len; bit++) {
60 | if (blocks && bit % 8 == 0) {
61 | ret.append (' ');
62 | }
63 | ret.append (testBit (bit) ? '1' : '0');
64 | }
65 | return ret;
66 | }
67 |
68 | bool testBit (UInt bit) const {
69 | Byte byte (m_data [bit / 8]);
70 | return ((byte >> (bit % 8)) & 0x1);
71 | }
72 |
73 | void setPosition (UInt pos) {
74 | m_pos = pos;
75 | }
76 |
77 | void setBit (UInt bit, bool value) {
78 | Byte byte = m_data [bit / 8];
79 | if (value) {
80 | byte |= (1 << (bit % 8));
81 | }
82 | else {
83 | byte &= ~(1 << (bit % 8));
84 | }
85 | m_data [bit / 8] = byte;
86 | }
87 |
88 | template IntegerType readBits (UInt count, bool * ok = NULL) {
89 | IntegerType ret = 0;
90 | bool result = false;
91 | if (CheckInt::isInt) {
92 | if (m_pos + count < m_len && count <= (sizeof (ret) * 8)) {
93 | for (UInt bit = 0; bit < count; bit++, m_pos++) {
94 | if (testBit (m_pos)) {
95 | ret |= (IntegerType)(1 << bit);
96 | }
97 | else {
98 | ret &= (IntegerType)~(1 << bit);
99 | }
100 | }
101 | result = true;
102 | }
103 | }
104 | else {
105 | qWarning () << "QtBitStream::readBits MUST be used with bool / int8 / int16 / int32 / int64 types only !";
106 | }
107 | if (ok != NULL) {
108 | *ok = result;
109 | }
110 | return ret;
111 | }
112 |
113 | template void writeBits (IntegerType src, UInt count, bool * ok = NULL) {
114 | bool result = false;
115 | if (CheckInt::isInt) {
116 | if (m_pos + count < m_len && count <= (sizeof (src) * 8)) {
117 | for (UInt bit = 0; bit < count; bit++, m_pos++) {
118 | setBit (m_pos, CheckInt::testBit (src, bit));
119 | }
120 | result = true;
121 | }
122 | }
123 | else {
124 | qWarning () << "QtBitStream::writeBits MUST be used with bool / int8 / int16 / int32 / int64 types only !";
125 | }
126 | if (ok != NULL) {
127 | *ok = result;
128 | }
129 | }
130 |
131 | private:
132 | UInt m_len, m_pos;
133 | QByteArray m_data;
134 | };
135 |
136 | #endif // QTBITSTREAM_H
137 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/IconTextButton.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.1;
2 | import QtQmlTricks 1.0;
3 |
4 | MouseArea {
5 | id: clicker;
6 | width: implicitWidth;
7 | height: implicitHeight;
8 | states: [
9 | State {
10 | name: "icon_and_text";
11 | when: (img.visible && lbl.visible);
12 |
13 | PropertyChanges {
14 | target: clicker;
15 | implicitWidth: (img.width + lbl.contentWidth + padding * 3);
16 | implicitHeight: (img.height > lbl.contentHeight ? img.height + padding * 2: lbl.contentHeight + padding * 2);
17 | }
18 | AnchorChanges {
19 | target: img;
20 | anchors {
21 | left: parent.left;
22 | verticalCenter: parent.verticalCenter;
23 | }
24 | }
25 | AnchorChanges {
26 | target: lbl;
27 | anchors {
28 | left: img.right;
29 | right: parent.right;
30 | verticalCenter: parent.verticalCenter;
31 | }
32 | }
33 | },
34 | State {
35 | name: "text_only";
36 | when: (!img.visible && lbl.visible);
37 |
38 | PropertyChanges {
39 | target: clicker;
40 | implicitWidth: (lbl.contentWidth + padding * 2);
41 | implicitHeight: (lbl.contentHeight + padding * 2);
42 | }
43 | AnchorChanges {
44 | target: lbl;
45 | anchors {
46 | verticalCenter: parent.verticalCenter;
47 | horizontalCenter: parent.horizontalCenter;
48 | }
49 | }
50 | },
51 | State {
52 | name: "icon_only";
53 | when: (img.visible && !lbl.visible);
54 |
55 | PropertyChanges {
56 | target: clicker;
57 | implicitWidth: (img.width + padding * 2);
58 | implicitHeight: (img.height + padding * 2);
59 | }
60 | AnchorChanges {
61 | target: img;
62 | anchors {
63 | verticalCenter: parent.verticalCenter;
64 | horizontalCenter: parent.horizontalCenter;
65 | }
66 | }
67 | },
68 | State {
69 | name: "empty";
70 | when: (!img.visible && !lbl.visible);
71 |
72 | PropertyChanges {
73 | target: clicker;
74 | implicitWidth: 0;
75 | implicitHeight: 0;
76 | }
77 | }
78 | ]
79 |
80 | property int padding : 12;
81 |
82 | property alias label : lbl.text;
83 | property alias labelFont : lbl.font;
84 | property alias labelColor : lbl.color;
85 | property alias iconSize : helper.size;
86 | property alias iconName : helper.icon;
87 | property alias iconColor : helper.color;
88 | property alias backColor : rect.color;
89 | property alias rounding : rect.radius;
90 |
91 | Rectangle {
92 | id: shadow;
93 | color: Qt.darker (backColor, 1.35);
94 | radius: rounding;
95 | visible: !pressed;
96 | antialiasing: true;
97 | anchors {
98 | fill: parent;
99 | topMargin: +2;
100 | bottomMargin: -2;
101 | }
102 | }
103 | Rectangle {
104 | id: rect;
105 | color: (pressed ? "lightblue" : "lightgray");
106 | radius: 6;
107 | antialiasing: true;
108 | border {
109 | color: "steelblue";
110 | width: (pressed ? 1 : 0);
111 | }
112 | anchors.fill: parent;
113 | }
114 | Image {
115 | id: img;
116 | width: (helper.size * helper.horizontalRatio);
117 | height: (helper.size * helper.verticalRatio);
118 | visible: (status !== Image.Null);
119 | fillMode: Image.Pad
120 | anchors.margins: padding;
121 |
122 | SvgIconHelper on source {
123 | id: helper;
124 | size: 24;
125 | color: lbl.color;
126 | }
127 | }
128 | Text {
129 | id: lbl;
130 | color: (pressed ? "darkblue" : "black");
131 | visible: (text !== "");
132 | horizontalAlignment: (img.visible ? Text.AlignLeft : Text.AlignHCenter);
133 | font {
134 | weight: Font.Light;
135 | pixelSize: 18;
136 | }
137 | anchors.margins: padding;
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/source/SSGTexture.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Portions (C) 2015 The Qt Company Ltd.
4 | ** Portions (C) 2016 Erik Hvatum
5 | ** Contact: http://www.qt.io/licensing/
6 | **
7 | ** This file is part of the QtQuick module of the Qt Toolkit.
8 | **
9 | ** $QT_BEGIN_LICENSE:LGPL21$
10 | ** Commercial License Usage
11 | ** Licensees holding valid commercial Qt licenses may use this file in
12 | ** accordance with the commercial license agreement provided with the
13 | ** Software or, alternatively, in accordance with the terms contained in
14 | ** a written agreement between you and The Qt Company. For licensing terms
15 | ** and conditions see http://www.qt.io/terms-conditions. For further
16 | ** information use the contact form at http://www.qt.io/contact-us.
17 | **
18 | ** GNU Lesser General Public License Usage
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser
20 | ** General Public License version 2.1 or version 3 as published by the Free
21 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
22 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
23 | ** following information to ensure the GNU Lesser General Public License
24 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
25 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
26 | **
27 | ** As a special exception, The Qt Company gives you certain additional
28 | ** rights. These rights are described in The Qt Company LGPL Exception
29 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
30 | **
31 | ** $QT_END_LICENSE$
32 | **
33 | ****************************************************************************/
34 |
35 | #pragma once
36 | #include "common.h"
37 | #include "SSImage.h"
38 |
39 | class SSGTexture
40 | : public QObject
41 | {
42 | Q_OBJECT
43 | public:
44 | struct ComponentCountFormats {
45 | QOpenGLTexture::TextureFormat texFormat;
46 | QOpenGLTexture::PixelFormat srcPixelFormat;
47 | };
48 | static const ComponentCountFormats sm_componentCountFormats[];
49 | static const QOpenGLTexture::PixelType sm_componentPixelTypes[];
50 |
51 | enum WrapMode {
52 | Repeat,
53 | ClampToEdge
54 | };
55 |
56 | enum Filtering {
57 | None,
58 | Nearest,
59 | Linear
60 | };
61 |
62 | SSGTexture();
63 | virtual ~SSGTexture();
64 |
65 | void setOwnsTexture(bool owns) { m_owns_texture = owns; }
66 | bool ownsTexture() const { return m_owns_texture; }
67 |
68 | void setTextureId(int id);
69 | int textureId() const;
70 | inline void setTextureSize(const QSize &size) { m_texture_size = size; }
71 | inline QSize textureSize() const { return m_texture_size; }
72 | inline bool hasAlphaChannel() const { return m_has_alpha; }
73 | inline bool hasMipmaps() const { return minMipmapFiltering() != SSGTexture::None || magMipmapFiltering() != SSGTexture::None; }
74 | inline QRectF normalizedTextureSubRect() const { return QRectF(0, 0, 1, 1); }
75 | QRectF convertToNormalizedSourceRect(const QRectF &rect) const;
76 |
77 | void setImage(SSImage* image);
78 | SSImage* image() { return m_image.data(); }
79 |
80 | virtual void bind();
81 | virtual void updateBindOptions(bool force=false);
82 |
83 | void setMinMipmapFiltering(Filtering filter);
84 | SSGTexture::Filtering minMipmapFiltering() const;
85 |
86 | void setMagMipmapFiltering(Filtering filter);
87 | SSGTexture::Filtering magMipmapFiltering() const;
88 |
89 | void setMinFiltering(Filtering filter);
90 | SSGTexture::Filtering minFiltering() const;
91 |
92 | void setMagFiltering(Filtering filter);
93 | SSGTexture::Filtering magFiltering() const;
94 |
95 | void setHorizontalWrapMode(WrapMode hwrap);
96 | SSGTexture::WrapMode horizontalWrapMode() const;
97 |
98 | void setVerticalWrapMode(WrapMode vwrap);
99 | SSGTexture::WrapMode verticalWrapMode() const;
100 |
101 | static SSGTexture *fromImage(SSImage* image);
102 |
103 | protected:
104 | QSharedPointer m_image;
105 |
106 | uint m_wrapChanged : 1;
107 | uint m_filteringChanged : 1;
108 |
109 | uint m_horizontalWrap : 1;
110 | uint m_verticalWrap : 1;
111 | uint m_minMipmapMode : 2;
112 | uint m_magMipmapMode : 2;
113 | uint m_minFilterMode : 2;
114 | uint m_magFilterMode : 2;
115 |
116 | GLuint m_texture_id;
117 | QSize m_texture_size;
118 | QRectF m_texture_rect;
119 |
120 | uint m_has_alpha : 1;
121 | uint m_dirty_texture : 1;
122 | uint m_dirty_bind_options : 1;
123 | uint m_owns_texture : 1;
124 | uint m_mipmaps_generated : 1;
125 | uint m_retain_image: 1;
126 | };
127 |
128 | bool ssg_safeguard_texture(SSGTexture *);
129 |
--------------------------------------------------------------------------------
/source/SSGContextPlugin/SSGQuickLayer.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Portions (C) 2015 The Qt Company Ltd.
4 | ** Portions (C) 2016 Erik Hvatum
5 | ** Contact: http://www.qt.io/licensing/
6 | **
7 | ** This file is part of the QtQuick module of the Qt Toolkit.
8 | **
9 | ** $QT_BEGIN_LICENSE:LGPL21$
10 | ** Commercial License Usage
11 | ** Licensees holding valid commercial Qt licenses may use this file in
12 | ** accordance with the commercial license agreement provided with the
13 | ** Software or, alternatively, in accordance with the terms contained in
14 | ** a written agreement between you and The Qt Company. For licensing terms
15 | ** and conditions see http://www.qt.io/terms-conditions. For further
16 | ** information use the contact form at http://www.qt.io/contact-us.
17 | **
18 | ** GNU Lesser General Public License Usage
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser
20 | ** General Public License version 2.1 or version 3 as published by the Free
21 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
22 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
23 | ** following information to ensure the GNU Lesser General Public License
24 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
25 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
26 | **
27 | ** As a special exception, The Qt Company gives you certain additional
28 | ** rights. These rights are described in The Qt Company LGPL Exception
29 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
30 | **
31 | ** $QT_END_LICENSE$
32 | **
33 | ****************************************************************************/
34 |
35 | // NB: SSGQuickLayer is *not* the scene graph personality of an SSLayer. SSGQuickLayer replaces QSGDefaultLayer,
36 | // the thing that is created when a QML Item's .layer property is set to true.
37 |
38 | #pragma once
39 | #include
40 | #include
41 | #include
42 |
43 | #define QSG_DEBUG_FBO_OVERLAY
44 |
45 | class SSGQuickLayer
46 | : public QSGLayer
47 | {
48 | Q_OBJECT
49 | public:
50 | SSGQuickLayer(QSGRenderContext *context);
51 | ~SSGQuickLayer();
52 |
53 | bool updateTexture() override;
54 |
55 | // The item's "paint node", not effect node.
56 | QSGNode *item() const { return m_item; }
57 | void setItem(QSGNode *item) override;
58 |
59 | QRectF rect() const { return m_rect; }
60 | void setRect(const QRectF &rect) override;
61 |
62 | QSize size() const { return m_size; }
63 | void setSize(const QSize &size) override;
64 |
65 | void setHasMipmaps(bool mipmap) override;
66 |
67 | void bind() override;
68 |
69 | bool hasAlphaChannel() const override;
70 | bool hasMipmaps() const override;
71 | int textureId() const override;
72 | QSize textureSize() const override { return m_size; }
73 |
74 | GLenum format() const { return m_format; }
75 | void setFormat(GLenum format) override;
76 |
77 | bool live() const { return bool(m_live); }
78 | void setLive(bool live) override;
79 |
80 | bool recursive() const { return bool(m_recursive); }
81 | void setRecursive(bool recursive) override;
82 |
83 | void setDevicePixelRatio(qreal ratio) override { m_device_pixel_ratio = ratio; }
84 |
85 | bool mirrorHorizontal() const { return bool(m_mirrorHorizontal); }
86 | void setMirrorHorizontal(bool mirror) override;
87 |
88 | bool mirrorVertical() const { return bool(m_mirrorVertical); }
89 | void setMirrorVertical(bool mirror) override;
90 |
91 | void scheduleUpdate() override;
92 |
93 | QImage toImage() const override;
94 |
95 | QRectF normalizedTextureSubRect() const override;
96 |
97 | public Q_SLOTS:
98 | void markDirtyTexture() override;
99 | void invalidated() override;
100 |
101 | protected:
102 | void grab();
103 |
104 | QSGNode *m_item;
105 | QRectF m_rect;
106 | QSize m_size;
107 | qreal m_device_pixel_ratio;
108 | GLenum m_format;
109 |
110 | QSGRenderer *m_renderer;
111 | QOpenGLFramebufferObject *m_fbo;
112 | QOpenGLFramebufferObject *m_secondaryFbo;
113 | QSharedPointer m_depthStencilBuffer;
114 |
115 | GLuint m_transparentTexture;
116 |
117 | #ifdef QSG_DEBUG_FBO_OVERLAY
118 | QSGSimpleRectNode *m_debugOverlay;
119 | #endif
120 |
121 | QSGRenderContext *m_context;
122 |
123 | uint m_mipmap : 1;
124 | uint m_live : 1;
125 | uint m_recursive : 1;
126 | uint m_dirtyTexture : 1;
127 | uint m_multisamplingChecked : 1;
128 | uint m_multisampling : 1;
129 | uint m_grab : 1;
130 | uint m_mirrorHorizontal : 1;
131 | uint m_mirrorVertical : 1;
132 | };
133 |
--------------------------------------------------------------------------------
/source/StackStreamMainWindow.qml:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | import QtQuick 2.5
26 | import QtQuick.Controls 1.3
27 | import QtQuick.Dialogs 1.2
28 | import QtQuick.Extras 1.4
29 | import QtQuick.Layouts 1.2
30 | import QtQuick.Window 2.2
31 |
32 | import StackStream 1.0
33 | import QtQmlTricks 1.0
34 |
35 | ApplicationWindow {
36 | visible: false
37 | width: 1024
38 | height: 768
39 | title: qsTr("StackStream")
40 | objectName: "stackStreamMainWindow"
41 | property SSImage image: SSImage{}
42 |
43 | SSView {
44 | id: mainView
45 | // anchors.left: parent.left
46 | // anchors.top: parent.top
47 | // anchors.bottom: parent.bottom
48 | // width: parent.width - layerPropertiesGroupBox.width - 20
49 | anchors.fill: parent
50 | z: -1
51 |
52 | TileBackground {
53 | anchors.fill: parent
54 | }
55 |
56 | SSImageItem {
57 | id: imageItem
58 | y: 0
59 | x: 0
60 | layer.enabled: true
61 | Drag.active: mouseArea.drag.active
62 | Drag.hotSpot.x: 10
63 | Drag.hotSpot.y: 10
64 |
65 | transform: Scale {
66 | id: scale
67 | property real factor: 1.0
68 | xScale: factor
69 | yScale: factor
70 | }
71 |
72 | MouseArea {
73 | id: mouseArea
74 | anchors.fill: parent
75 | drag.target: parent
76 | property var factors: [ 4.0 , 3.8 , 3.6 , 3.4 , 3.2 ,
77 | 3.0 , 2.8 , 2.6 , 2.4 , 2.2 ,
78 | 2.0 , 1.8 , 1.6 , 1.4 , 1.2 ,
79 | 1.0 , 0.91700404, 0.84089642, 0.77110541, 0.70710678,
80 | 0.64841978, 0.59460356, 0.54525387, 0.5 , 0.45850202,
81 | 0.42044821, 0.38555271, 0.35355339, 0.32420989, 0.29730178,
82 | 0.27262693, 0.25 ]
83 | property int factorIdx: 15
84 | onWheel: {
85 | factorIdx = (factorIdx + (wheel.angleDelta.y / 120)) | 0
86 | if(factorIdx < 0) factorIdx = 0
87 | else if (factorIdx >= factors.length) factorIdx = factors.length - 1
88 | scale.factor = factors[factorIdx]
89 | }
90 | }
91 |
92 | Text {
93 | smooth: true
94 | text: 'hello world'
95 | color: 'red'
96 | x: 400
97 | y: 300
98 | width: 100
99 | height: 20
100 | }
101 | }
102 |
103 | // Rectangle {
104 | // x: 0
105 | // y: 0
106 | // width: 100
107 | // height: 200
108 | // anchors.fill: imageItem
109 | // anchors.margins: 5
110 | // color: 'blue'
111 | // opacity: 0.5
112 | // layer.enabled: true
113 | // }
114 |
115 | DropArea {
116 | anchors.fill: parent
117 | onEntered: {
118 | // console.log('drop area entered');
119 | drag.accept(Qt.CopyAction);
120 | }
121 | onDropped: {
122 | image.read(drop.urls[0])
123 | imageItem.image = image
124 | }
125 | // onExited: {
126 | // console.log('drop area exited');
127 | // }
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/devtest/PyQmlProof/ImagePane.qml:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2016 Erik Hvatum
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | // Authors: Erik Hvatum
24 |
25 | import QtQuick 2.5
26 | import QtQuick.Controls 1.4
27 | import QtQuick.Layouts 1.2
28 |
29 | Item {
30 | id: imageContainer
31 | Layout.fillWidth: true
32 | clip: true
33 |
34 | DropArea {
35 | anchors.fill: parent
36 | onEntered: {
37 | // console.log('drop area entered');
38 | drag.accept(Qt.CopyAction);
39 | }
40 | onDropped: {
41 | image.source = drop.urls[0]
42 | }
43 | // onExited: {
44 | // console.log('drop area exited');
45 | // }
46 | }
47 |
48 | TiledBackground {}
49 |
50 | Image {
51 | id: image
52 | anchors.top: parent.top
53 | anchors.bottom: parent.bottom
54 | anchors.horizontalCenter: imageContainer.horizontalCenter
55 | property real scaleRel: sourceSize.height / height
56 | width: (sourceSize.width / sourceSize.height) * height
57 |
58 | Repeater {
59 | id: controlPointRepeater
60 | model: pointListModel
61 | delegate: Rectangle {
62 | id: rect
63 | x: x_ / image.scaleRel
64 | y: y_ / image.scaleRel
65 | z: 2
66 | width: 11
67 | height: 11
68 | color: activeFocus ? "red" : "yellow"
69 | Drag.active: dragArea.drag.active
70 | Keys.onDeletePressed: pointListModel.delAtIndex(index)
71 | onXChanged: x_ = x * image.scaleRel
72 | onYChanged: y_ = y * image.scaleRel
73 |
74 | MouseArea {
75 | id: dragArea
76 | anchors.fill: parent
77 | drag.target: parent
78 | onPressed: parent.focus = true
79 | drag.threshold: 0
80 | }
81 |
82 | transform: Translate {
83 | x: -5
84 | y: -5
85 | }
86 | }
87 | }
88 |
89 | Canvas {
90 | anchors.fill: parent
91 | // renderStrategy: Canvas.Threaded
92 | // renderTarget: Canvas.FramebufferObject
93 | antialiasing: true
94 | smooth: true
95 | Component.onCompleted: {
96 | pointListModel.dataChanged.connect(requestPaint)
97 | pointListModel.rowsInserted.connect(requestPaint)
98 | pointListModel.rowsRemoved.connect(requestPaint)
99 | pointListModel.modelReset.connect(requestPaint)
100 | pointListModel.rowsMoved.connect(requestPaint)
101 | }
102 | onPaint: {
103 | var rowCount = pointListModel.rowCount()
104 | if(rowCount >= 2) {
105 | var ctx = getContext("2d")
106 | ctx.reset()
107 | ctx.strokeStyle = Qt.rgba(0,1,0,1)
108 | ctx.lineWidth = 2
109 | ctx.beginPath()
110 | var p = pointListModel.data(pointListModel.index(0, 0), 0)
111 | ctx.moveTo(p.x_/image.scaleRel, p.y_/image.scaleRel)
112 | var idx_=1
113 | for(; idx_ < rowCount; idx_++) {
114 | p = pointListModel.data(pointListModel.index(idx_, 0), 0)
115 | ctx.lineTo(p.x_/image.scaleRel, p.y_/image.scaleRel)
116 | }
117 | ctx.stroke()
118 | }
119 | }
120 | }
121 |
122 | MouseArea {
123 | anchors.fill: parent
124 | onClicked: {
125 | pointListModel.append(mouseX * image.scaleRel, mouseY * image.scaleRel)
126 | }
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/QtCoreApi.js:
--------------------------------------------------------------------------------
1 | .pragma library
2 |
3 | /************** Adds most of QString/QByteArray API to JS String *******************************/
4 |
5 | function addMethod (object, method) {
6 | Object.defineProperty (object, method.name, {
7 | "value" : method,
8 | "enumerable" : false
9 | });
10 | }
11 |
12 |
13 | function at (idx) {
14 | return (this [idx]);
15 | }
16 | addMethod (Array.prototype, at);
17 | addMethod (String.prototype, at);
18 |
19 |
20 | function first () {
21 | return this [0];
22 | }
23 | addMethod (Array.prototype, first);
24 | addMethod (String.prototype, first);
25 |
26 |
27 | function last () {
28 | return (this.length ? this [this.length -1] : undefined);
29 | }
30 | addMethod (Array.prototype, last);
31 | addMethod (String.prototype, last);
32 |
33 |
34 | function contains (value) {
35 | return (this.indexOf (value) > -1);
36 | }
37 | addMethod (Array.prototype, contains);
38 | addMethod (String.prototype, contains);
39 |
40 |
41 | function size () {
42 | return (this.length);
43 | }
44 | addMethod (Array.prototype, size);
45 | addMethod (String.prototype, size);
46 |
47 |
48 | function isEmpty () {
49 | return (!this.length);
50 | }
51 | addMethod (Array.prototype, isEmpty);
52 | addMethod (String.prototype, isEmpty);
53 |
54 |
55 | function clear () {
56 | this.splice (0, this.length);
57 | }
58 | addMethod (Array.prototype, clear);
59 |
60 |
61 | function foreach (callback) {
62 | for (var i = 0; i < this.length; callback (i, this [i]), i++);
63 | }
64 | addMethod (Array.prototype, foreach);
65 |
66 |
67 | function append (value) {
68 | this.push (value);
69 | }
70 | addMethod (Array.prototype, append);
71 |
72 |
73 | function prepend (value) {
74 | this.unshift (value);
75 | }
76 | addMethod (Array.prototype, prepend);
77 |
78 |
79 | function removeAt (idx) {
80 | this.splice (idx, 1);
81 | }
82 | addMethod (Array.prototype, removeAt);
83 |
84 |
85 | function removeAll (value) {
86 | var ret = 0;
87 | var it = 0;
88 | while (it < this.length) {
89 | if (this [it] === (value)) {
90 | this.splice (it, 1);
91 | ret++;
92 | }
93 | else { it++; }
94 | }
95 | return ret;
96 | }
97 | addMethod (Array.prototype, removeAll);
98 |
99 |
100 | function takeAt (idx) {
101 | var ret = this [idx];
102 | this.splice (idx, 1);
103 | return ret;
104 | }
105 | addMethod (Array.prototype, takeAt);
106 |
107 |
108 | function erase (idx) {
109 | this [idx] = undefined;
110 | }
111 | addMethod (Array.prototype, erase);
112 |
113 |
114 | function swap (idx1, idx2) {
115 | var tmp = this [idx1];
116 | this [idx1] = this [idx2];
117 | this [idx2] = tmp;
118 | }
119 | addMethod (Array.prototype, swap);
120 |
121 |
122 | function replace (idx, value) {
123 | this [idx] = value;
124 | }
125 | addMethod (Array.prototype, replace);
126 |
127 |
128 | function squeeze () {
129 | var it = 0;
130 | while (it < this.length) {
131 | if (this [it] !== null && this [it] !== undefined) {
132 | this.splice (it, 1);
133 | }
134 | else { it++; }
135 | }
136 | }
137 | addMethod (Array.prototype, squeeze);
138 |
139 |
140 | function append (str) {
141 | return String (this + (str || ""));
142 | }
143 | addMethod (String.prototype, append);
144 |
145 |
146 | function prepend (str) {
147 | return String ((str || "") + this);
148 | }
149 | addMethod (String.prototype, prepend);
150 |
151 |
152 | function trimmed () {
153 | return String (this.replace (/\s*$/, '').replace (/^\s*/, ''));
154 | }
155 | addMethod (String.prototype, trimmed);
156 |
157 |
158 | function remove (str) {
159 | var ret = String (this);
160 | while (ret.indexOf (str) > -1) {
161 | ret = ret.replace (str, '');
162 | }
163 | return ret;
164 | }
165 | addMethod (String.prototype, remove);
166 |
167 |
168 | function repeat (str, count) {
169 | return (new Array (count +1).join (str));
170 | }
171 | addMethod (String, repeat);
172 |
173 |
174 | function mid (pos, len) {
175 | return this.substr (pos, len);
176 | }
177 | addMethod (String.prototype, mid);
178 |
179 |
180 | function left (len) {
181 | return (len < this.length ? this.substr (0, len) : this);
182 | }
183 | addMethod (String.prototype, left);
184 |
185 |
186 | function right (len) {
187 | return (len < this.length ? this.substr (this.length - len, len) : this);
188 | }
189 | addMethod (String.prototype, right);
190 |
191 |
192 | function startsWith (str) {
193 | return (str && this.indexOf (str) === 0);
194 | }
195 | addMethod (String.prototype, startsWith);
196 |
197 |
198 | function endsWith (str) {
199 | return (str && this.lastIndexOf (str) > -1 && this.lastIndexOf (str) === (this.length - str.length));
200 | }
201 | addMethod (String.prototype, endsWith);
202 |
203 |
204 | function toBase64 () {
205 | return Qt.atob (this);
206 | }
207 | addMethod (String.prototype, toBase64);
208 |
209 |
210 | function fromBase64 (str) {
211 | return Qt.btoa (str);
212 | }
213 | addMethod (String, fromBase64);
214 |
215 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/README.md:
--------------------------------------------------------------------------------
1 | About the project
2 | =================
3 |
4 | _The **QtQmlTricks** library contains useful classes and macros. It also has some test cases and examples._
5 |
6 |
7 | ### Why this project ?
8 | All the people out there who have done / are doing a mixed C++ / QML project, have surely been thinking that it needs too much code on C++ side, and that this code is often not that easy to do right. So here is the solution :
9 |
10 | **A nice library of classes and helpers that have been designed to simplify as much as possible the C++ side, so that it's finally not harder than QML side (which is already nice enough).**
11 |
12 |
13 | ### What does it bring at the moment ?
14 |
15 | We have done a very simple library, which brings mainly some C++ **classes** :
16 |
17 | * `QQmlObjectListModel` : a much nicer way to expose C++ list to QML than the quick & dirty `QList` property . Supports all the strong model features of `QAbstractListModel` while showing the simple and well know API of QList.
18 | * `QQmlVariantListModel` : a dead-simple way to create a dynamic C++ list of any type and expose it to QML, way better than using a `QVariantList` property.
19 | * `QQmlSvgIconHelper` : a class that takes a SVG file as input, plus size/ratio information, and makes a PNG file in persistant cache as output. If additional color information other than transparent is provided, the opaque pixels of the output will be colorized with the given tint.
20 | * `QQuickPolygon` : a simple QtQuick item that takes a list of points and draw them with a provided color.
21 | * `QtCOBS` : a codec to create COBS-encoded QByteArray from raw data, and vice-versa.
22 | * `QtBitStream` : a helper class to extract or inject custom amount of bits (between 1 and 64) in a `QByteArray` using a position cursor like `QDataStream` does for bytes...
23 | * `QtJsonPath` : a nice way to retreive specific sub-values from a QJson*** class as a QVariant, by simply asking it by path.
24 |
25 | It also strouts a pack of helper C++ **macros** :
26 |
27 | * `QML_WRITABLE_PROPERTY` : a macro that takes a type and a name, and creates automatically the member attribute, the public getter and setter, and the Qt signal for notifier, and allow use in QML by exposing a read/write `Q_PROPERTY`.
28 | * `QML_READONLY_PROPERTY` : another macro that does almost the same as `QML_WRITABLE_PROPERTY` except that the property is not modifiable from the QML side, only C++ can access the setter.
29 | * `QML_CONSTANT_PROPERTY` : a simplified version of the previous macros, that exposes a constant property with no getter and no setter, from C++ or QML side.
30 | * `QML_LIST_PROPERTY` : a really handy macro to create a QML list property that maps to an internal `QList` of objects, without having to declare and implement all static function pointers...
31 | * `QML_ENUM_CLASS` : a macro to declare a `QObject` class that only contains a `Q_ENUM` and can be exposed as is to QML.
32 |
33 | A nice set of JavaScript prototype modifications :
34 |
35 | * `String` and `Array` classes extended to have API closer to `QString`/`QByteArray` and `QList`/`QVector` : addition of `startsWith`, `contains`, `at`, `size`, `append`, `prepend`, `insert`, `isEmpty`, ...
36 |
37 | And a bunch of QML components :
38 |
39 | * `RowContainer` : an horizontal layout, that positions its childrens side-by-side, setting their size in consequence of their implicit size hints, and using remaining space in the layout to distribute it between all items that expose a negative implicit width.
40 | * `GridContainer` : a smart grid that dimensions itself according to the sum/max of its children's implicit size hints, and then distributes regularly the available space between all children, positioned against a col/row model.
41 | * `WrapLeftRightContainer` : a simplified layout for one of the most common positioning scheme in UI, on the same line, put some items at left, the others at right. But it has extra intelligency, to wrap itslef it left/right items do not fit in the provided space.
42 | * `ScrollContainer` : put a `Flickable` (or derived, e.g. `ListView`) in it to get vertical/horizontal scrollbars displayed around it (according to the flicking direction axis that are set).
43 | * `IconTextButton` : a simple and customizable push button that can have either an icon, a label, or both. Colors, sizes, fonts and rounding are customizable.
44 |
45 | **Note :** All these API are documented using _Doxygen_ so that one can easily generate HTML documentation or even Qt Help file (.qch).
46 |
47 |
48 | ### What are the plans for later ?
49 |
50 | First we want to add a lot of new classes and helpers for common use.
51 |
52 | Next, add more helpers and components for QML / JavaScript side too.
53 |
54 | And maybe then, propose this for integration into standard Qt module QtCore, if it's really useful to people !
55 |
56 | ### How can I use it ?
57 |
58 | Well, license here is pretty "super-open", not even copy-left or copy-right, just use it as you want, as it's the most practical to you :
59 |
60 | * if you want to use it as GIT submodule and compile it in your app, do it ;
61 | * if you prefer separate project as a shared library, do it ;
62 | * if you need to modify the project to be able to integrate in you app (opensource or not), do it ;
63 | * if you want to share you work on the library, thanks a lot, but if you don't, no problem ;
64 | * if you think about some weird case I didn't talk about, well, do whatever you want, I don't need to know about it.
65 |
66 | **Enjoy !**
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 | #
3 | # Copyright (c) 2016 Erik Hvatum
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy
6 | # of this software and associated documentation files (the "Software"), to deal
7 | # in the Software without restriction, including without limitation the rights
8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | # copies of the Software, and to permit persons to whom the Software is
10 | # furnished to do so, subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | # SOFTWARE.
22 | #
23 | # Authors: Erik Hvatum
24 |
25 | cmake_minimum_required(VERSION 3.0)
26 | project(StackStream)
27 |
28 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_modules")
29 | if(NOT MSVC)
30 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
31 | endif()
32 | set(CMAKE_INCLUDE_CURRENT_DIR ON)
33 | set(CMAKE_AUTOMOC ON)
34 | set(CMAKE_AUTORCC ON)
35 |
36 | find_package(FreeImage REQUIRED)
37 | find_package(FreeImagePlus REQUIRED)
38 | find_package(OpenGL REQUIRED)
39 | find_package(Qt5 COMPONENTS Core Gui OpenGL Qml Quick Svg Widgets)
40 | find_package(Qt5Core REQUIRED Private)
41 | find_package(Qt5Gui REQUIRED Private)
42 | find_package(Qt5Qml REQUIRED Private)
43 | find_package(Qt5Quick REQUIRED Private)
44 |
45 | set(Python_ADDITIONAL_VERSIONS ${Python_ADDITIONAL_VERSIONS} "3.4")
46 | find_package(PythonInterp 3.4 REQUIRED)
47 | if(NOT APPLE)
48 | find_package(PythonLibs 3.4 REQUIRED)
49 | else()
50 | # FindPythonLibs.cmake is totally horked on OS X and will probably remain so until the end of time and beyond: http://www.itk.org/Bug/view.php?id=14809
51 | # Because Find*.cmake modules must support cross compilation, the obvious fix of just asking the interpreter where its stuff is can't go into the
52 | # official CMake distribution. Because it's better to have it not work at all under any circumstance, I guess? Okay, that would be fine, except
53 | # we need this to work. So, we resort to asking the interpreter.
54 | execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import distutils.sysconfig; vs = distutils.sysconfig.get_config_vars(); print('LIBPL:\"{}\"LIBRARY:\"{}\"get_python_lib:\"{}\"get_python_inc:\"{}\"'.format(vs['LIBPL'], vs['LIBRARY'], distutils.sysconfig.get_python_lib(), distutils.sysconfig.get_python_inc()))"
55 | RESULT_VARIABLE _PYC_RESULT
56 | ERROR_VARIABLE _PYC_ERROR
57 | OUTPUT_VARIABLE _PYC_OUT
58 | OUTPUT_STRIP_TRAILING_WHITESPACE)
59 | if(NOT _PYC_RESULT MATCHES 0)
60 | message(FATAL_ERROR "Failed to interrogate Python interpreter (which must be done in order to locate the CPython library and header directories):\n${_PYC_ERROR}")
61 | return()
62 | endif()
63 | string(REGEX REPLACE
64 | "LIBPL:\"(.+)\"LIBRARY:\"(.+)\"get_python_lib:\"(.+)\"get_python_inc:\"(.+)\""
65 | "\\1;\\2;\\3;\\4"
66 | _PYC_OUTS
67 | ${_PYC_OUT})
68 | set(PYTHONLIBS_FOUND true)
69 | list(GET _PYC_OUTS 0 _PYTHON_LIB_DIR)
70 | list(GET _PYC_OUTS 1 _PYTHON_LIB_NAME)
71 | set(PYTHON_LIBRARIES "${_PYTHON_LIB_DIR}/${_PYTHON_LIB_NAME}")
72 | set(PYTHON_LIBRARY ${PYTHON_LIBRARIES})
73 | list(GET _PYC_OUTS 3 PYTHON_INCLUDE_PATH)
74 | list(GET _PYC_OUTS 3 PYTHON_INCLUDE_DIRS)
75 | unset(_PYC_RESULT)
76 | unset(_PYC_ERROR)
77 | unset(_PYC_OUT)
78 | unset(_PYC_OUTS)
79 | unset(_PYTHON_LIB_DIR)
80 | unset(_PYTHON_LIB_NAME)
81 | message(STATUS "Found PythonLibs: ${PYTHON_LIBRARY} (do not be alarmed if the filename ends in .a; dynamic linking will be used nonetheless, if possible)")
82 | include_directories(SYSTEM ${PYTHON_INCLUDE_DIRS})
83 | endif()
84 |
85 | execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import numpy;print(numpy.get_include())"
86 | RESULT_VARIABLE _NUMPY_INCLUDE_DIR_FOUND
87 | ERROR_VARIABLE _NUMPY_INCLUDE_DIR_ERROR
88 | OUTPUT_VARIABLE NUMPY_INCLUDE_DIR
89 | OUTPUT_STRIP_TRAILING_WHITESPACE)
90 | if(NOT _NUMPY_INCLUDE_DIR_FOUND MATCHES 0)
91 | message(FATAL_ERROR "Failed to import numpy (which must be done in order to locate the numpy C API header directory):\n${_NUMPY_INCLUDE_DIR_ERROR}")
92 | return()
93 | endif()
94 | unset(_NUMPY_INCLUDE_DIR_FOUND)
95 | unset(_NUMPY_INCLUDE_DIR_ERROR)
96 |
97 | set(BUILD_STACKSTREAM_PYTHON_MODULE ON)
98 |
99 | include_directories(SYSTEM ${FREEIMAGE_INCLUDE_PATH})
100 | include_directories(SYSTEM ${FREEIMAGEPLUS_INCLUDE_PATH})
101 | include_directories(SYSTEM ${NUMPY_INCLUDE_DIR})
102 | include_directories(SYSTEM ${PYTHON_INCLUDE_DIR})
103 | include_directories(SYSTEM ${Qt5Core_PRIVATE_INCLUDE_DIRS})
104 | include_directories(SYSTEM ${Qt5Gui_PRIVATE_INCLUDE_DIRS})
105 | include_directories(SYSTEM ${Qt5Qml_PRIVATE_INCLUDE_DIRS})
106 | include_directories(SYSTEM ${Qt5Quick_PRIVATE_INCLUDE_DIRS})
107 |
108 | add_subdirectory(source)
109 |
--------------------------------------------------------------------------------
/cmake_modules/SIPMacros.cmake:
--------------------------------------------------------------------------------
1 | # Macros for SIP
2 | # ~~~~~~~~~~~~~~
3 | # Copyright (c) 2007, Simon Edwards
4 | # Redistribution and use is allowed according to the terms of the BSD license.
5 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
6 | #
7 | # SIP website: http://www.riverbankcomputing.co.uk/sip/index.php
8 | #
9 | # This file defines the following macros:
10 | #
11 | # ADD_SIP_PYTHON_MODULE (MODULE_NAME MODULE_SIP [library1, libaray2, ...])
12 | # Specifies a SIP file to be built into a Python module and installed.
13 | # MODULE_NAME is the name of Python module including any path name. (e.g.
14 | # os.sys, Foo.bar etc). MODULE_SIP the path and filename of the .sip file
15 | # to process and compile. libraryN are libraries that the Python module,
16 | # which is typically a shared library, should be linked to. The built
17 | # module will also be install into Python's site-packages directory.
18 | #
19 | # The behaviour of the ADD_SIP_PYTHON_MODULE macro can be controlled by a
20 | # number of variables:
21 | #
22 | # SIP_INCLUDES - List of directories which SIP will scan through when looking
23 | # for included .sip files. (Corresponds to the -I option for SIP.)
24 | #
25 | # SIP_TAGS - List of tags to define when running SIP. (Corresponds to the -t
26 | # option for SIP.)
27 | #
28 | # SIP_CONCAT_PARTS - An integer which defines the number of parts the C++ code
29 | # of each module should be split into. Defaults to 8. (Corresponds to the
30 | # -j option for SIP.)
31 | #
32 | # SIP_DISABLE_FEATURES - List of feature names which should be disabled
33 | # running SIP. (Corresponds to the -x option for SIP.)
34 | #
35 | # SIP_EXTRA_OPTIONS - Extra command line options which should be passed on to
36 | # SIP.
37 |
38 | SET(SIP_INCLUDES)
39 | SET(SIP_TAGS)
40 | SET(SIP_CONCAT_PARTS 8)
41 | SET(SIP_DISABLE_FEATURES)
42 | SET(SIP_EXTRA_OPTIONS)
43 |
44 | MACRO(ADD_SIP_PYTHON_MODULE MODULE_NAME MODULE_SIP)
45 |
46 | SET(EXTRA_LINK_LIBRARIES ${ARGN})
47 |
48 | STRING(REPLACE "." "/" _x ${MODULE_NAME})
49 | GET_FILENAME_COMPONENT(_parent_module_path ${_x} PATH)
50 | GET_FILENAME_COMPONENT(_child_module_name ${_x} NAME)
51 |
52 | GET_FILENAME_COMPONENT(_module_path ${MODULE_SIP} PATH)
53 |
54 | if(_module_path STREQUAL "")
55 | set(CMAKE_CURRENT_SIP_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
56 | else(_module_path STREQUAL "")
57 | set(CMAKE_CURRENT_SIP_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${_module_path}")
58 | endif(_module_path STREQUAL "")
59 |
60 | GET_FILENAME_COMPONENT(_abs_module_sip ${MODULE_SIP} ABSOLUTE)
61 |
62 | # We give this target a long logical target name.
63 | # (This is to avoid having the library name clash with any already
64 | # install library names. If that happens then cmake dependancy
65 | # tracking get confused.)
66 | STRING(REPLACE "." "_" _logical_name ${MODULE_NAME})
67 | SET(_logical_name "python_module_${_logical_name}")
68 |
69 | FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_SIP_OUTPUT_DIR}) # Output goes in this dir.
70 |
71 | SET(_sip_includes)
72 | FOREACH (_inc ${SIP_INCLUDES})
73 | GET_FILENAME_COMPONENT(_abs_inc ${_inc} ABSOLUTE)
74 | LIST(APPEND _sip_includes -I ${_abs_inc})
75 | ENDFOREACH (_inc )
76 |
77 | SET(_sip_tags)
78 | FOREACH (_tag ${SIP_TAGS})
79 | LIST(APPEND _sip_tags -t ${_tag})
80 | ENDFOREACH (_tag)
81 |
82 | SET(_sip_x)
83 | FOREACH (_x ${SIP_DISABLE_FEATURES})
84 | LIST(APPEND _sip_x -x ${_x})
85 | ENDFOREACH (_x ${SIP_DISABLE_FEATURES})
86 |
87 | SET(_message "-DMESSAGE=Generating CPP code for module ${MODULE_NAME}")
88 | SET(_sip_output_files)
89 | FOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} )
90 | IF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} )
91 | SET(_sip_output_files ${_sip_output_files} ${CMAKE_CURRENT_SIP_OUTPUT_DIR}/sip${_child_module_name}part${CONCAT_NUM}.cpp )
92 | ENDIF( ${CONCAT_NUM} LESS ${SIP_CONCAT_PARTS} )
93 | ENDFOREACH(CONCAT_NUM RANGE 0 ${SIP_CONCAT_PARTS} )
94 |
95 | IF(NOT WIN32)
96 | SET(TOUCH_COMMAND touch)
97 | ELSE(NOT WIN32)
98 | SET(TOUCH_COMMAND echo)
99 | # instead of a touch command, give out the name and append to the files
100 | # this is basically what the touch command does.
101 | FOREACH(filename ${_sip_output_files})
102 | FILE(APPEND filename "")
103 | ENDFOREACH(filename ${_sip_output_files})
104 | ENDIF(NOT WIN32)
105 | ADD_CUSTOM_COMMAND(
106 | OUTPUT ${_sip_output_files}
107 | COMMAND ${CMAKE_COMMAND} -E echo ${message}
108 | COMMAND ${TOUCH_COMMAND} ${_sip_output_files}
109 | COMMAND ${SIP_EXECUTABLE} ${_sip_tags} ${_sip_x} ${SIP_EXTRA_OPTIONS} -j ${SIP_CONCAT_PARTS} -c ${CMAKE_CURRENT_SIP_OUTPUT_DIR} ${_sip_includes} ${_abs_module_sip}
110 | DEPENDS ${_abs_module_sip} ${SIP_EXTRA_FILES_DEPEND}
111 | )
112 | # not sure if type MODULE could be uses anywhere, limit to cygwin for now
113 | IF (CYGWIN)
114 | ADD_LIBRARY(${_logical_name} MODULE ${_sip_output_files} )
115 | ELSE (CYGWIN)
116 | ADD_LIBRARY(${_logical_name} SHARED ${_sip_output_files} )
117 | ENDIF (CYGWIN)
118 | TARGET_LINK_LIBRARIES(${_logical_name} ${PYTHON_LIBRARY})
119 | TARGET_LINK_LIBRARIES(${_logical_name} ${EXTRA_LINK_LIBRARIES})
120 | SET_TARGET_PROPERTIES(${_logical_name} PROPERTIES PREFIX "" OUTPUT_NAME ${_child_module_name})
121 |
122 | INSTALL(TARGETS ${_logical_name} DESTINATION "${PYTHON_SITE_PACKAGES_INSTALL_DIR}/${_parent_module_path}")
123 |
124 | ENDMACRO(ADD_SIP_PYTHON_MODULE)
125 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/GridContainer.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0;
2 |
3 | /**
4 | * @brief Item that layouts its children within a grid according to row/column count.
5 | *
6 | */
7 | Item {
8 | id: layout;
9 | width: implicitWidth;
10 | height: implicitHeight;
11 | onColsChanged: { relayout (); }
12 | onWidthChanged: { relayout (); }
13 | onHeightChanged: { relayout (); }
14 | onCapacityChanged: { relayout (); }
15 | onFillEmptyChanged: { relayout (); }
16 | onVerticalFlowChanged: { relayout (); }
17 | onInvertDirectionChanged: { relayout (); }
18 | onChildrenChanged: {
19 | if (layout && layout.ready) {
20 | var tmp = [];
21 | var dirty = false;
22 | items.forEach (function (item) {
23 | if (item && item ["parent"] === layout) {
24 | tmp.push (item);
25 | }
26 | else {
27 | dirty = true;
28 | }
29 | });
30 | for (var idx = 0; idx < children.length; idx++) {
31 | var child = children [idx];
32 | if (items.indexOf (child) < 0 && !("delegate" in child)) {
33 | child.visibleChanged.connect (relayout);
34 | child.implicitWidthChanged.connect (relayout);
35 | child.implicitHeightChanged.connect (relayout);
36 | tmp.push (child);
37 | dirty = true;
38 | }
39 | }
40 | items = tmp;
41 | if (dirty) {
42 | relayout ();
43 | }
44 | }
45 | }
46 | Component.onCompleted: {
47 | ready = true;
48 | layout.childrenChanged ();
49 | }
50 | Component.onDestruction: {
51 | ready = false;
52 | }
53 |
54 | property int cols : 1;
55 | property int rows : 1;
56 |
57 | property int rowSpacing : 0;
58 | property int colSpacing : 0;
59 |
60 | property int capacity : -1;
61 |
62 | property bool ready : false;
63 |
64 | property bool fillEmpty : true;
65 | property bool verticalFlow : false;
66 | property bool invertDirection : false;
67 |
68 | property var items : [];
69 |
70 | function relayout () {
71 | if (layout && layout.ready) {
72 | var count = 0;
73 | var maxChildWidth = 0;
74 | var maxChildHeight = 0;
75 | items.forEach (function (child) {
76 | if (child && (child ["visible"] || !fillEmpty)) {
77 | if (child ["implicitWidth"] > maxChildWidth) {
78 | maxChildWidth = child ["implicitWidth"];
79 | }
80 | if (child ["implicitHeight"] > maxChildHeight) {
81 | maxChildHeight = child ["implicitHeight"];
82 | }
83 | count++;
84 | }
85 | });
86 | if (cols > 0) {
87 | if (capacity > 0) {
88 | rows = Math.ceil (capacity / cols);
89 | }
90 | else if (count > 0) {
91 | rows = Math.ceil (count / cols);
92 | }
93 | else {
94 | rows = 1;
95 | }
96 | }
97 | else {
98 | rows = 1;
99 | }
100 | implicitWidth = (cols * maxChildWidth) + ((cols -1) * colSpacing);
101 | implicitHeight = (rows * maxChildHeight) + ((rows -1) * rowSpacing);
102 | var itemWidth = (((width + colSpacing) / cols) - colSpacing);
103 | var itemHeight = (((height + rowSpacing) / rows) - rowSpacing);
104 | var curX = (invertDirection ? width - itemWidth : 0);
105 | var curY = (invertDirection ? height - itemHeight : 0);
106 | var stepX = (itemWidth + colSpacing);
107 | var stepY = (itemHeight + rowSpacing);
108 | if (rows && cols) {
109 | var nb = 0;
110 | items.forEach (function (child) {
111 | if (child && (child ["visible"]|| !fillEmpty)) {
112 | child ["width"] = itemWidth;
113 | child ["height"] = itemHeight;
114 | child ["x"] = curX;
115 | child ["y"] = curY;
116 | if (!verticalFlow) { // horizontal
117 | if ((nb +1) % cols > 0) { // next column
118 | curX = (invertDirection ? curX - stepX : curX + stepX);
119 | }
120 | else { // next row
121 | curX = (invertDirection ? width - itemWidth : 0);
122 | curY = (invertDirection ? curY - stepY : curY + stepY);
123 | }
124 | }
125 | else { // vertical
126 | if ((nb +1) % rows > 0) { // next row
127 | curY = (invertDirection ? curY - stepY : curY + stepY);
128 | }
129 | else { // next column
130 | curY = (invertDirection ? height - itemHeight : 0);
131 | curX = (invertDirection ? curX - stepX : curX + stepX);
132 | }
133 | }
134 | nb++;
135 | }
136 | });
137 | }
138 | }
139 | }
140 |
141 | /* CONTENT HERE */
142 | }
143 |
--------------------------------------------------------------------------------
/source/QtQmlTricks/src/qqmlsvgiconhelper.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "qqmlsvgiconhelper.h"
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | QString QQmlSvgIconHelper::s_basePath;
15 | QString QQmlSvgIconHelper::s_cachePath;
16 | QSvgRenderer QQmlSvgIconHelper::s_renderer;
17 |
18 | QQmlSvgIconHelper::QQmlSvgIconHelper (QObject * parent)
19 | : QObject (parent)
20 | , m_size (0)
21 | , m_ready (false)
22 | , m_verticalRatio (1.0)
23 | , m_horizontalRatio (1.0)
24 | , m_color (Qt::transparent)
25 | , m_icon (QString ())
26 | {
27 | if (s_basePath.isEmpty ()) {
28 | QQmlSvgIconHelper::s_basePath = qApp->applicationDirPath ();
29 | }
30 | if (s_cachePath.isEmpty ()) {
31 | QQmlSvgIconHelper::s_cachePath = (QDir::homePath () % "/.CachedSvgIcon/" % qApp->applicationName ());
32 | }
33 | }
34 |
35 | QQmlSvgIconHelper::~QQmlSvgIconHelper (void) {
36 |
37 | }
38 |
39 | void QQmlSvgIconHelper::classBegin (void) {
40 | m_ready = false;
41 | }
42 |
43 | void QQmlSvgIconHelper::componentComplete (void) {
44 | m_ready = true;
45 | refresh ();
46 | }
47 |
48 | void QQmlSvgIconHelper::setTarget (const QQmlProperty & target) {
49 | m_property = target;
50 | refresh ();
51 | }
52 |
53 | void QQmlSvgIconHelper::setBasePath (const QString & basePath) {
54 | QQmlSvgIconHelper::s_basePath = basePath;
55 | }
56 |
57 | void QQmlSvgIconHelper::setCachePath (const QString & cachePath) {
58 | QQmlSvgIconHelper::s_cachePath = cachePath;
59 | }
60 |
61 | int QQmlSvgIconHelper::getSize (void) const {
62 | return m_size;
63 | }
64 |
65 | qreal QQmlSvgIconHelper::getVerticalRatio (void) const {
66 | return m_verticalRatio;
67 | }
68 |
69 | qreal QQmlSvgIconHelper::getHorizontalRatio (void) const {
70 | return m_horizontalRatio;
71 | }
72 |
73 | QColor QQmlSvgIconHelper::getColor (void) const {
74 | return m_color;
75 | }
76 |
77 | QString QQmlSvgIconHelper::getIcon (void) const {
78 | return m_icon;
79 | }
80 |
81 | void QQmlSvgIconHelper::setSize (int size) {
82 | if (m_size != size) {
83 | m_size = size;
84 | refresh ();
85 | emit sizeChanged ();
86 | }
87 | }
88 |
89 | void QQmlSvgIconHelper::setVerticalRatio (qreal ratio) {
90 | if (m_verticalRatio != ratio) {
91 | m_verticalRatio = ratio;
92 | refresh ();
93 | emit verticalRatioChanged ();
94 | }
95 | }
96 |
97 | void QQmlSvgIconHelper::setHorizontalRatio (qreal ratio) {
98 | if (m_horizontalRatio != ratio) {
99 | m_horizontalRatio = ratio;
100 | refresh ();
101 | emit horizontalRatioChanged ();
102 | }
103 | }
104 |
105 | void QQmlSvgIconHelper::setColor (QColor color) {
106 | if (m_color != color) {
107 | m_color = color;
108 | refresh ();
109 | emit colorChanged ();
110 | }
111 | }
112 |
113 | void QQmlSvgIconHelper::setIcon (QString icon) {
114 | if (m_icon != icon) {
115 | m_icon = icon;
116 | refresh ();
117 | emit iconChanged ();
118 | }
119 | }
120 |
121 | void QQmlSvgIconHelper::refresh (void) {
122 | if (m_ready) {
123 | QUrl url;
124 | if (!m_icon.isEmpty () && m_size > 0 && m_horizontalRatio > 0.0 && m_verticalRatio > 0.0) {
125 | QImage image (m_size * m_horizontalRatio, m_size * m_verticalRatio, QImage::Format_ARGB32);
126 | QString uri (m_icon
127 | % "?color=" % (m_color.isValid () ? m_color.name () : "none")
128 | % "&width=" % QString::number (image.width ())
129 | % "&height=" % QString::number (image.height ()));
130 | QString hash (QCryptographicHash::hash (uri.toLocal8Bit (), QCryptographicHash::Md5).toHex ());
131 | QString sourcePath (s_basePath % "/" % m_icon % ".svg");
132 | QString cachedPath (s_cachePath % "/" % hash % ".png");
133 | if (!QFile::exists (cachedPath)) {
134 | QPainter painter (&image);
135 | image.fill (Qt::transparent);
136 | painter.setRenderHint (QPainter::Antialiasing, true);
137 | painter.setRenderHint (QPainter::SmoothPixmapTransform, true);
138 | painter.setRenderHint (QPainter::HighQualityAntialiasing, true);
139 | if (QFile::exists (sourcePath)) {
140 | s_renderer.load (sourcePath);
141 | if (s_renderer.isValid ()) {
142 | s_renderer.render (&painter);
143 | if (m_color.isValid () && m_color.alpha () > 0) {
144 | QColor tmp (m_color);
145 | for (int x (0); x < image.width (); x++) {
146 | for (int y (0); y < image.height (); y++) {
147 | tmp.setAlpha (qAlpha (image.pixel (x, y)));
148 | image.setPixel (x, y, tmp.rgba ());
149 | }
150 | }
151 | }
152 | QDir ().mkpath (s_cachePath);
153 | image.save (cachedPath, "PNG", 0);
154 | url = QUrl::fromLocalFile (cachedPath);
155 | }
156 | }
157 | else {
158 | qWarning () << ">>> QmlSvgIconHelper : Can't render" << sourcePath << ", no such file !";
159 | }
160 | }
161 | else {
162 | url = QUrl::fromLocalFile (cachedPath);
163 | }
164 | }
165 | if (m_property.isValid () && m_property.isWritable ()) {
166 | m_property.write (url);
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/source/SSGTextureMaterial.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Portions (C) 2015 The Qt Company Ltd.
4 | ** Portions (C) 2016 Erik Hvatum
5 | ** Contact: http://www.qt.io/licensing/
6 | **
7 | ** This file is part of the QtQuick module of the Qt Toolkit.
8 | **
9 | ** $QT_BEGIN_LICENSE:LGPL21$
10 | ** Commercial License Usage
11 | ** Licensees holding valid commercial Qt licenses may use this file in
12 | ** accordance with the commercial license agreement provided with the
13 | ** Software or, alternatively, in accordance with the terms contained in
14 | ** a written agreement between you and The Qt Company. For licensing terms
15 | ** and conditions see http://www.qt.io/terms-conditions. For further
16 | ** information use the contact form at http://www.qt.io/contact-us.
17 | **
18 | ** GNU Lesser General Public License Usage
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser
20 | ** General Public License version 2.1 or version 3 as published by the Free
21 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
22 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
23 | ** following information to ensure the GNU Lesser General Public License
24 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
25 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
26 | **
27 | ** As a special exception, The Qt Company gives you certain additional
28 | ** rights. These rights are described in The Qt Company LGPL Exception
29 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
30 | **
31 | ** $QT_END_LICENSE$
32 | **
33 | ****************************************************************************/
34 |
35 | #include "SSGTextureMaterial.h"
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 |
42 | class SSGTextureMaterialShader : public QSGMaterialShader
43 | {
44 | public:
45 | SSGTextureMaterialShader();
46 |
47 | virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
48 | virtual char const *const *attributeNames() const;
49 |
50 | static QSGMaterialType type;
51 |
52 | protected:
53 | virtual void initialize();
54 |
55 | int m_matrix_id;
56 | int m_opacity_id;
57 | };
58 |
59 | inline static bool isPowerOfTwo(int x)
60 | {
61 | // Assumption: x >= 1
62 | return x == (x & -x);
63 | }
64 |
65 | QSGMaterialType SSGTextureMaterialShader::type;
66 |
67 | SSGTextureMaterialShader::SSGTextureMaterialShader()
68 | : QSGMaterialShader()
69 | {
70 | setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/opaquetexture.vert"));
71 | setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/texture.frag"));
72 | }
73 |
74 | char const *const *SSGTextureMaterialShader::attributeNames() const
75 | {
76 | static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", 0 };
77 | return attr;
78 | }
79 |
80 | void SSGTextureMaterialShader::initialize()
81 | {
82 | m_matrix_id = program()->uniformLocation("qt_Matrix");
83 | m_opacity_id = program()->uniformLocation("opacity");
84 | }
85 |
86 | void SSGTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
87 | {
88 | Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());
89 | SSGTextureMaterial *tx = static_cast(newEffect);
90 | SSGTextureMaterial *oldTx = static_cast(oldEffect);
91 |
92 | if (state.isOpacityDirty())
93 | program()->setUniformValue(m_opacity_id, state.opacity());
94 |
95 | SSGTexture *t = tx->texture();
96 |
97 | #ifndef QT_NO_DEBUG
98 | if (!ssg_safeguard_texture(t))
99 | return;
100 | #endif
101 |
102 | t->setMinFiltering(tx->minFiltering());
103 | t->setMagFiltering(tx->magFiltering());
104 |
105 | t->setHorizontalWrapMode(tx->horizontalWrapMode());
106 | t->setVerticalWrapMode(tx->verticalWrapMode());
107 | bool npotSupported = const_cast(state.context())
108 | ->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat);
109 | if (!npotSupported) {
110 | QSize size = t->textureSize();
111 | const bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height());
112 | if (isNpot) {
113 | t->setHorizontalWrapMode(SSGTexture::ClampToEdge);
114 | t->setVerticalWrapMode(SSGTexture::ClampToEdge);
115 | }
116 | }
117 |
118 | t->setMinMipmapFiltering(tx->minMipmapFiltering());
119 | t->setMagMipmapFiltering(tx->magMipmapFiltering());
120 |
121 | if (oldTx == 0 || oldTx->texture()->textureId() != t->textureId())
122 | t->bind();
123 | else
124 | t->updateBindOptions();
125 |
126 | if (state.isMatrixDirty())
127 | program()->setUniformValue(m_matrix_id, state.combinedMatrix());
128 | }
129 |
130 | SSGTextureMaterial::SSGTextureMaterial()
131 | : m_texture(0),
132 | m_min_filtering(SSGTexture::Nearest),
133 | m_mag_filtering(SSGTexture::Nearest),
134 | m_min_mipmap_filtering(SSGTexture::None),
135 | m_mag_mipmap_filtering(SSGTexture::None),
136 | m_horizontal_wrap(SSGTexture::ClampToEdge),
137 | m_vertical_wrap(SSGTexture::ClampToEdge)
138 | {
139 | }
140 |
141 | QSGMaterialType *SSGTextureMaterial::type() const
142 | {
143 | return &SSGTextureMaterialShader::type;
144 | }
145 |
146 | QSGMaterialShader *SSGTextureMaterial::createShader() const
147 | {
148 | return new SSGTextureMaterialShader();
149 | }
150 |
151 | void SSGTextureMaterial::setTexture(SSGTexture *texture)
152 | {
153 | m_texture = texture;
154 | setFlag(Blending, m_texture ? m_texture->hasAlphaChannel() : false);
155 | }
156 |
157 | int SSGTextureMaterial::compare(const QSGMaterial *o) const
158 | {
159 | Q_ASSERT(o && type() == o->type());
160 | qDebug() << "int SSGTextureMaterial::compare(const QSGMaterial *o) const";
161 | const SSGTextureMaterial *other = static_cast(o);
162 | int diff = m_texture->textureId() - other->texture()->textureId();
163 | if (diff)
164 | return diff;
165 | diff = int(m_min_filtering) - int(other->m_min_filtering);
166 | if (diff)
167 | return diff;
168 | return int(m_mag_filtering) - int(other->m_mag_filtering);
169 | }
170 |
171 |
--------------------------------------------------------------------------------
/cmake_modules/FindPyQt5.cmake:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 | #
3 | # Copyright (c) 2014 WUSTL ZPLAB
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy
6 | # of this software and associated documentation files (the "Software"), to deal
7 | # in the Software without restriction, including without limitation the rights
8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | # copies of the Software, and to permit persons to whom the Software is
10 | # furnished to do so, subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | # SOFTWARE.
22 | #
23 | # Authors: Erik Hvatum
24 |
25 | # Do find_package(PythonInterp) or otherwise set PYTHON_EXECUTABLE before using this module.
26 | # Do find_package(SIP) or otherwise set SIP_DEFAULT_SIP_DIR before using this module.
27 | #
28 | # This module may do more in the future if I need it to, such as setting PYQT5_PYUIC5. However, right now, it just sets
29 | # the following variables:
30 | #
31 | # PYQT5_FOUND - System has PyQt5.
32 | #
33 | # PYQT5_SIP_FLAGS - Value of PyQt5.QtCore.PYQT_CONFIGURATION['sip_flags'], a string containing the -t and -x flags that
34 | # that were used by sip during the PyQt5 build process (ie, PyQt5's configure.py script called sip
35 | # with these -t and -x parameters while building PyQt5). C++ PyQt5 extensions are advised to use the
36 | # same -t and -x arguments when calling sip.
37 | #
38 | # PYQT5_SIP_DIR - Location of PyQt5 .sip files. Unlike PyQt4, which offers an API for determining this path, PyQt5
39 | # does... not........... So, we check the default sip includes directory, and if we don't find our
40 | # PyQt5 .sip files, we fail and the user must specify PYQT5_SIP_DIR.
41 |
42 | set(PYQT5_FOUND false)
43 | execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import PyQt5.QtCore;print(PyQt5.QtCore.PYQT_CONFIGURATION['sip_flags'])"
44 | RESULT_VARIABLE _PYQT5_SIP_FLAGS_RETRIEVED
45 | ERROR_VARIABLE _PYQT5_SIP_FLAGS_ERROR
46 | OUTPUT_VARIABLE PYQT5_SIP_FLAGS
47 | OUTPUT_STRIP_TRAILING_WHITESPACE)
48 | if(NOT _PYQT5_SIP_FLAGS_RETRIEVED MATCHES 0)
49 | if(PyQt5_FIND_REQUIRED)
50 | message(FATAL_ERROR "Failed to import PyQt5 (which must be done in order to determine the proper -x and -t sip arguments for this system):\n${_PYQT5_SIP_FLAGS_ERROR}")
51 | endif()
52 | else()
53 | unset(_PYQT5_SIP_FLAGS_RETRIEVED)
54 | unset(_PYQT5_SIP_FLAGS_ERROR)
55 | set(_PYQT5_SIP_FLAGS ${PYQT5_SIP_FLAGS})
56 | separate_arguments(PYQT5_SIP_FLAGS)
57 | if(NOT PYQT5_SIP_DIR) # Only attempt to guess value if not specified by user
58 | if(NOT SIP_DEFAULT_SIP_DIR)
59 | if(PyQt5_FIND_REQUIRED})
60 | message(FATAL_ERROR "Neither PYQT5_SIP_DIR nor SIP_DEFAULT_SIP_DIR are set. It is necessary to either, a) call find_package(SIP), or b) set(SIP_DEFAULT_SIP_DIR ...) or call cmake with -DSIP_DEFAULT_DIR=..., or c) set(PYQT5_SIP_DIR ...) or call cmake with -DPYQT5_SIP_DIR=... before attempting to find_package(PyQt5).")
61 | endif()
62 | else()
63 | set(PYQT5_SIP_DIR "${SIP_DEFAULT_SIP_DIR}/PyQt5")
64 | if(EXISTS "${PYQT5_SIP_DIR}/QtCore/QtCoremod.sip") # Any functional PyQt5 installation includes QtCoreMod.sip
65 | set(PYQT5_FOUND true)
66 | else()
67 | if(APPLE)
68 | execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils import sysconfig;print(sysconfig.PREFIX)"
69 | RESULT_VARIABLE _TRY_DIR_RETRIEVED
70 | ERROR_VARIABLE _TRY_DIR_ERROR
71 | OUTPUT_VARIABLE _TRY_DIR
72 | OUTPUT_STRIP_TRAILING_WHITESPACE)
73 | if(NOT _TRY_DIR_RETRIEVED MATCHES 0)
74 | messge(FATAL_ERROR "Failed to query python prefix:\n${_TRY_DIR_ERROR}")
75 | else()
76 | set(_TRY_DIR "${_TRY_DIR}/share/sip/PyQt5")
77 | message(WARNING "Guessed value for PYQT5_SIP_DIR, \"${PYQT5_SIP_DIR}\", does not seem to be correct. Trying \"${_TRY_DIR}\".")
78 | set(PYQT5_SIP_DIR ${_TRY_DIR})
79 | if(EXISTS "${PYQT5_SIP_DIR}/QtCore/QtCoremod.sip")
80 | set(PYQT5_FOUND true)
81 | endif()
82 | unset(_TRY_DIR_RETRIEVED)
83 | unset(_TRY_DIR_ERROR)
84 | unset(_TRY_DIR)
85 | endif()
86 | endif()
87 | endif()
88 | if(NOT PYQT5_FOUND AND PyQt5_FIND_REQUIRED)
89 | if(APPLE)
90 | message(FATAL_ERROR "Could not determine correct value for PYQT5_SIP_DIR. Please specify a value for PYQT5_SIP_DIR (for example, by calling cmake with -DPYQT5_SIP_DIR=foo/bar).")
91 | else()
92 | message(FATAL_ERROR "Guessed value for PYQT5_SIP_DIR, \"${PYQT5_SIP_DIR}\", does not seem to be correct. Please specify a value for PYQT5_SIP_DIR (for example, by calling cmake with -DPYQT5_SIP_DIR=foo/bar).")
93 | endif()
94 | endif()
95 | endif()
96 | else()
97 | if(NOT EXISTS "${PYQT5_SIP_DIR}/QtCore/QtCoremod.sip")
98 | if(PyQt5_FIND_REQUIRED)
99 | message(FATAL_ERROR "Specified or cached value for PYQT5_SIP_DIR, \"${PYQT5_SIP_DIR}\", does not seem to be correct.")
100 | endif()
101 | else()
102 | set(PYQT5_FOUND true)
103 | endif()
104 | endif()
105 | endif()
106 |
107 | if(PYQT5_FOUND)
108 | message(STATUS "Found PyQt5:")
109 | message(STATUS " PyQt5 sip flags: ${_PYQT5_SIP_FLAGS}")
110 | message(STATUS " PyQt5 .sip file directory: ${PYQT5_SIP_DIR}")
111 | endif()
112 |
113 | mark_as_advanced(PYQT5_FOUND PYQT5_SIP_FLAGS PYQT5_SIP_DIR)
114 | unset(_PYQT5_SIP_FLAGS)
--------------------------------------------------------------------------------
/source/QtQmlTricks/import/QtQmlTricks/ComboList.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.1;
2 | import "Style.js" as Style;
3 |
4 | Item {
5 | id: base;
6 | width: implicitWidth;
7 | height: implicitHeight;
8 | implicitWidth: (lbl.contentWidth + padding * 2);
9 | implicitHeight: (lbl.contentHeight + padding * 2);
10 |
11 | property int padding : 6;
12 | property alias textColor : lbl.color;
13 | property alias backColor : rect.color;
14 | property alias rounding : rect.radius;
15 |
16 | property ListModel model : null;
17 |
18 | property int currentIdx : -1;
19 | readonly property var currentValue : (model && currentIdx >= 0 && currentIdx < model.count ? model.get (currentIdx) ["value"] : undefined);
20 | readonly property var currentKey : (model && currentIdx >= 0 && currentIdx < model.count ? model.get (currentIdx) ["key"] : undefined);
21 |
22 | Gradient {
23 | id: gradientIdle;
24 |
25 | GradientStop { color: Qt.lighter (Style.colorLightGray, 1.15); position: 0.0; }
26 | GradientStop { color: Qt.darker (Style.colorLightGray, 1.15); position: 1.0; }
27 | }
28 | Gradient {
29 | id: gradientPressed;
30 |
31 | GradientStop { color: Qt.darker (Style.colorDarkGray, 1.15); position: 0.0; }
32 | GradientStop { color: Qt.lighter (Style.colorDarkGray, 1.15); position: 1.0; }
33 | }
34 | Gradient {
35 | id: gradientDisabled;
36 |
37 | GradientStop { color: Style.colorLightGray; position: 0.0; }
38 | GradientStop { color: Style.colorLightGray; position: 1.0; }
39 | }
40 | MouseArea {
41 | id: clicker;
42 | anchors.fill: parent;
43 | onClicked: {
44 | if (dropdownItem) {
45 | destroyDropdown ();
46 | }
47 | else {
48 | createDropdown ();
49 | }
50 | }
51 | Component.onDestruction: { destroyDropdown (); }
52 |
53 | property Item dropdownItem : null;
54 |
55 | readonly property Item rootItem : {
56 | var tmp = base;
57 | while ("parent" in tmp && tmp ["parent"] !== null && "visible" in tmp ["parent"]) {
58 | tmp = tmp ["parent"];
59 | }
60 | return tmp;
61 | }
62 |
63 | function createDropdown () {
64 | dropdownItem = compoDropdown.createObject (rootItem, { "referenceItem" : base });
65 | }
66 |
67 | function destroyDropdown () {
68 | if (dropdownItem) {
69 | dropdownItem.destroy ();
70 | dropdownItem = null;
71 | }
72 | }
73 | }
74 | Rectangle {
75 | id: rect;
76 | radius: 3;
77 | antialiasing: true;
78 | gradient: (enabled
79 | ? (clicker.pressed ||
80 | clicker.dropdownItem
81 | ? gradientPressed
82 | : gradientIdle)
83 | : gradientDisabled);
84 | border {
85 | width: 1;
86 | color: Style.colorGray;
87 | }
88 | anchors.fill: parent;
89 | }
90 | TextLabel {
91 | id: lbl;
92 | text: (currentValue || "");
93 | color: (enabled ? Style.colorBlack : Style.colorGray);
94 | elide: Text.ElideRight;
95 | visible: (text !== "");
96 | anchors {
97 | left: parent.left;
98 | right: arrow.left;
99 | margins: padding;
100 | verticalCenter: parent.verticalCenter;
101 | }
102 | }
103 | Item {
104 | id: arrow;
105 | clip: true;
106 | width: 12;
107 | height: (width / 2);
108 | anchors {
109 | right: parent.right;
110 | margins: padding;
111 | verticalCenter: parent.verticalCenter;
112 | }
113 |
114 | Rectangle {
115 | color: Style.colorBlack;
116 | width: (parent.height * Math.SQRT2);
117 | height: width;
118 | rotation: 45;
119 | antialiasing: true;
120 | anchors {
121 | verticalCenter: parent.top;
122 | horizontalCenter: parent.horizontalCenter;
123 | }
124 | }
125 | }
126 | Component {
127 | id: compoDropdown;
128 |
129 | MouseArea {
130 | id: dimmer;
131 | anchors.fill: parent;
132 | onWheel: { }
133 | onPressed: { clicker.destroyDropdown (); }
134 |
135 | property Item referenceItem : null;
136 |
137 | Rectangle {
138 | color: "lightgray";
139 | height: Math.max (layout.height, 24);
140 | border {
141 | width: 1;
142 | color: Style.colorGray;
143 | }
144 | Component.onCompleted: {
145 | if (dimmer.referenceItem) {
146 | var pos = mapFromItem (dimmer.referenceItem.parent,
147 | dimmer.referenceItem.x,
148 | dimmer.referenceItem.y +
149 | dimmer.referenceItem.height);
150 | width = dimmer.referenceItem.width;
151 | x = pos ["x"];
152 | y = pos ["y"];
153 | }
154 | }
155 |
156 | Column {
157 | id: layout;
158 | anchors {
159 | top: parent.top;
160 | left: parent.left;
161 | right: parent.right;
162 | }
163 |
164 | Repeater {
165 | model: base.model;
166 | delegate: MouseArea {
167 | height: 24;
168 | anchors {
169 | left: layout.left;
170 | right: layout.right;
171 | }
172 | onClicked: {
173 | currentIdx = model.index;
174 | clicker.destroyDropdown ();
175 | }
176 |
177 | TextLabel {
178 | clip: true;
179 | text: (model ["value"] || "");
180 | font.bold: (model.index === currentIdx);
181 | anchors {
182 | left: parent.left;
183 | right: parent.right;
184 | margins: padding;
185 | verticalCenter: parent.verticalCenter;
186 | }
187 | }
188 | }
189 | }
190 | }
191 | }
192 | }
193 | }
194 | }
195 |
--------------------------------------------------------------------------------