diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7296c14..e8dac26 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,34 +3,18 @@ project (rust_qt_binding_generator)
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
cmake_policy(SET CMP0046 NEW)
cmake_policy(SET CMP0063 NEW)
-set(QT_MIN_VERSION "5.3.0")
-set(KF5_MIN_VERSION "5.2.0")
+set(QT_MIN_VERSION "5.6.0")
-find_package(ECM 1.0.0 REQUIRED NO_MODULE)
-set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
-
-include(ExternalProject)
-include(KDEInstallDirs)
-include(KDECMakeSettings)
-include(KDECompilerSettings)
include(FeatureSummary)
-set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/Rust)
-
# Find Qt modules
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
- Core # QCommandLineParser, QStringLiteral
- Quick
+ Core
Test
- Widgets # QApplication
-)
-
-# Find KDE modules
-find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
- CoreAddons # KAboutData
- I18n # KLocalizedString
- WidgetsAddons # KMessageBox
)
+find_package(Qt5Widgets ${QT_MIN_VERSION} CONFIG)
+find_package(Qt5Quick ${QT_MIN_VERSION} CONFIG)
+set(CMAKE_AUTOMOC ON)
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
@@ -44,6 +28,10 @@ else()
endif()
add_subdirectory(rust_qt_binding_generator)
+enable_testing()
add_subdirectory(tests)
-add_subdirectory(demo)
+
+if(Qt5Widgets_FOUND)
+ add_subdirectory(demo)
+endif()
diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt
index f580bed..fd160f5 100644
--- a/demo/CMakeLists.txt
+++ b/demo/CMakeLists.txt
@@ -1,5 +1,6 @@
set(CMAKE_AUTORCC ON)
+# generate c++ and rust code from fibonacci.json
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/rust/src/fibonacci_interface.rs"
"${CMAKE_CURRENT_SOURCE_DIR}/rust/src/fibonacci_types.rs"
@@ -10,6 +11,7 @@ add_custom_command(
DEPENDS rust_qt_binding_generator fibonacci.json
)
+# generate c++ and rust code from tree.json
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/rust/src/interface.rs"
"${CMAKE_CURRENT_SOURCE_DIR}/rust/src/types.rs"
@@ -20,6 +22,7 @@ add_custom_command(
DEPENDS rust_qt_binding_generator tree.json
)
+# compile the rust code into a static library
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/rust/${RUST_TARGET_DIR}/librust.a"
COMMAND cargo build ${RUST_BUILD_FLAG}
@@ -34,6 +37,11 @@ add_custom_command(
)
add_custom_target(rust_target DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/rust/${RUST_TARGET_DIR}/librust.a")
+if(Qt5Quick_FOUND)
+ add_definitions(-DQTQUICK)
+ set(Qt5Quick_LIBS Qt5::Quick)
+endif()
+
set(Demo_SRCS src/main.cpp src/Tree.cpp src/Fibonacci.cpp
resource_file.qrc)
@@ -41,11 +49,8 @@ add_executable(Demo ${Demo_SRCS})
add_dependencies(Demo rust_target)
target_link_libraries(Demo
- Qt5::Quick
+ "${Qt5Quick_LIBS}"
Qt5::Widgets
- KF5::CoreAddons
- KF5::I18n
- KF5::WidgetsAddons
"${CMAKE_CURRENT_SOURCE_DIR}/rust/${RUST_TARGET_DIR}/librust.a"
)
diff --git a/demo/demo.qml b/demo/demo.qml
index dd7c78e..0d31298 100644
--- a/demo/demo.qml
+++ b/demo/demo.qml
@@ -5,18 +5,32 @@ import QtQuick.Layouts 1.3
import rust 1.0
ApplicationWindow {
- width: 500
- height: 480
+ id: application
+ x: windowX
+ y: windowY
+ width: windowWidth
+ height: windowHeight
visible: true
ItemSelectionModel {
id: selectionModel
model: fsModel
}
- FibonacciList {
- id: fibonacciList
- }
TabView {
anchors.fill: parent
+ Tab {
+ title: "style"
+ ComboBox {
+ currentIndex: qtquickIndex
+ model: styles
+ textRole: "display"
+ onCurrentIndexChanged: {
+ if (currentText && currentText != "QtQuick") {
+ widgets.currentText = currentText;
+ application.close();
+ }
+ }
+ }
+ }
Tab {
title: "object"
RowLayout {
@@ -24,14 +38,12 @@ ApplicationWindow {
id: fibonacciInput
placeholderText: "Your number"
validator: IntValidator {bottom: 0; top: 100;}
+ Component.onCompleted: { text = fibonacci.input }
+ onTextChanged: { fibonacci.input = parseInt(text, 10) }
}
Text {
text: "The Fibonacci number: " + fibonacci.result
}
- Fibonacci {
- id: fibonacci
- input: parseInt(fibonacciInput.text, 10)
- }
}
}
Tab {
diff --git a/demo/resource_file.qrc b/demo/resource_file.qrc
index 6d9c32d..8ace119 100644
--- a/demo/resource_file.qrc
+++ b/demo/resource_file.qrc
@@ -1,5 +1,6 @@
demo.qml
+ demo-qtquick2.qml
diff --git a/demo/src/main.cpp b/demo/src/main.cpp
index cc7557c..54e913e 100644
--- a/demo/src/main.cpp
+++ b/demo/src/main.cpp
@@ -1,77 +1,214 @@
#include "Tree.h"
#include "Fibonacci.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
+#ifdef QTQUICK
#include
#include
#include
+#include
+#include
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+struct Models {
+ Tree tree;
+ QSortFilterProxyModel sortedTree;
+ Fibonacci fibonacci;
+ FibonacciList fibonacciList;
+ QStringListModel styles;
+};
+
+void setStyle(QWidget* w, QStyle* style) {
+ for (QObject* o: w->children()) {
+ QWidget* c = dynamic_cast(o);
+ if (c) {
+ setStyle(c, style);
+ }
+ }
+ w->setStyle(style);
+}
+
+QWindow* getWindow(QWidget* w) {
+ QWidget* top = w;
+ while (top && top->parentWidget()) {
+ top = top->parentWidget();
+ }
+ return top->windowHandle();
+}
+
+#ifdef QTQUICK
+
+void copyWindowGeometry(QWidget* w, QQmlContext* c) {
+ QWindow* window = getWindow(w);
+ if (window) {
+ c->setContextProperty("windowX", window->x());
+ c->setContextProperty("windowY", window->y());
+ c->setContextProperty("windowWidth", window->width());
+ c->setContextProperty("windowHeight", window->height());
+ }
+}
+
+void createQtQuick(Models* models, QWidget* widgets) {
+ QQmlApplicationEngine* engine = new QQmlApplicationEngine();
+ QQmlContext* c = engine->rootContext();
+ c->setContextProperty("fsModel", &models->tree);
+ c->setContextProperty("sortedFsModel", &models->sortedTree);
+ c->setContextProperty("fibonacci", &models->fibonacci);
+ c->setContextProperty("fibonacciList", &models->fibonacciList);
+ c->setContextProperty("styles", &models->styles);
+ c->setContextProperty("widgets", widgets);
+ c->setContextProperty("qtquickIndex",
+ QVariant(models->styles.stringList().indexOf("QtQuick")));
+ copyWindowGeometry(widgets, engine->rootContext());
+ engine->load(QUrl(QStringLiteral("qrc:///demo.qml")));
+}
+
+#endif
+
+QComboBox* createStyleComboBox(Models* models) {
+ QComboBox* box = new QComboBox();
+ box->setModel(&models->styles);
+ auto styles = QStyleFactory::keys();
+ QString currentStyle = QApplication::style()->objectName().toLower();
+ for (auto v: styles) {
+ box->addItem("QWidgets " + v);
+ if (v.toLower() == currentStyle) {
+ box->setCurrentText(v);
+ }
+ }
+#ifdef QTQUICK
+ box->addItem("QtQuick");
+#endif
+ return box;
+}
+
+QWidget* createStyleTab(Models* models, QWidget* tabs) {
+ QComboBox* box = createStyleComboBox(models);
+ QRect windowRect;
+ box->connect(box, &QComboBox::currentTextChanged, box, [windowRect, box, tabs, models](const QString &text) mutable {
+ QWindow* window = getWindow(tabs);
+ bool visible = tabs->isVisible();
+ if (text.startsWith("QWidgets ")) {
+ tabs->setVisible(true);
+ if (window && !visible) {
+ window->setX(windowRect.x());
+ window->setY(windowRect.y());
+ window->setWidth(windowRect.width());
+ window->setHeight(windowRect.height());
+ }
+ setStyle(tabs, QStyleFactory::create(text.mid(9)));
+#ifdef QTQUICK
+ } else {
+ if (window) {
+ windowRect.setX(window->x());
+ windowRect.setY(window->y());
+ windowRect.setWidth(window->width());
+ windowRect.setHeight(window->height());
+ }
+ tabs->setVisible(false);
+ createQtQuick(models, box);
+#endif
+ }
+ });
+ return box;
+}
+
+QWidget* createObjectTab(Models* models) {
+ QWidget* view = new QWidget;
+ Fibonacci* fibonacci = &models->fibonacci;
+
+ QLineEdit* input = new QLineEdit;
+ input->setPlaceholderText("Your number");
+ input->setValidator(new QIntValidator(0, 100));
+ input->connect(input, &QLineEdit::textChanged, fibonacci,
+ [fibonacci](const QString& text) {
+ fibonacci->setInput(text.toInt());
+ });
+ fibonacci->connect(fibonacci, &Fibonacci::inputChanged, input,
+ [input, fibonacci]() {
+ input->setText(QString::number(fibonacci->input()));
+ });
+
+ QLabel* label = new QLabel;
+ fibonacci->connect(fibonacci, &Fibonacci::resultChanged, label,
+ [label, fibonacci]() {
+ label->setText("The Fibonacci number: "
+ + QString::number(fibonacci->result()));
+ });
+
+ QHBoxLayout *layout = new QHBoxLayout;
+ layout->addWidget(input);
+ layout->addWidget(label);
+ view->setLayout(layout);
+ return view;
+}
+
+QWidget* createListTab(Models* models) {
+ QListView* view = new QListView();
+ view->setModel(&models->fibonacciList);
+ return view;
+}
+
+QWidget* createTreeTab(Models* models) {
+ QTreeView* view = new QTreeView();
+ view->setUniformRowHeights(true);
+ view->setSortingEnabled(true);
+ view->setModel(&models->sortedTree);
+ auto root = models->sortedTree.index(0, 0);
+ view->expand(root);
+ view->sortByColumn(0, Qt::AscendingOrder);
+ view->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ return view;
+}
+
+void createWidgets(Models* models) {
+ QTabWidget* tabs = new QTabWidget();
+
+ tabs->addTab(createStyleTab(models, tabs), "style");
+ tabs->addTab(createObjectTab(models), "object");
+ tabs->addTab(createListTab(models), "list");
+ tabs->addTab(createTreeTab(models), "tree");
+ tabs->setMinimumSize(QSize(500, 500));
+ tabs->show();
+}
int main (int argc, char *argv[])
{
QApplication app(argc, argv);
- KLocalizedString::setApplicationDomain("Demo");
-
- KAboutData aboutData(
- // The program name used internally. (componentName)
- QStringLiteral("Demo"),
- // A displayable program name string. (displayName)
- i18n("Demo"),
- // The program version string. (version)
- QStringLiteral("0.1"),
- // Short description of what the app does. (shortDescription)
- i18n("Demo application for Rust bindings"),
- // The license this code is released under
- KAboutLicense::GPL,
- // Copyright Statement (copyrightStatement = QString())
- i18n("(c) 2017"),
- // Optional text shown in the About box.
- // Can contain any information desired. (otherText)
- i18n("Some text..."),
- // The program homepage string. (homePageAddress = QString())
- QStringLiteral("http://kde.org/"),
- // The bug report email address
- // (bugsEmailAddress = QLatin1String("submit@bugs.kde.org")
- QStringLiteral("submit@bugs.kde.org"));
- aboutData.addAuthor(i18n("Jos van den Oever"), i18n("Task"), QStringLiteral("your@email.com"),
- QStringLiteral("http://vandenoever.info"), QStringLiteral("OSC Username"));
- KAboutData::setApplicationData(aboutData);
- QCommandLineParser parser;
- parser.addHelpOption();
- parser.addVersionOption();
- aboutData.setupCommandLine(&parser);
- parser.process(app);
- aboutData.processCommandLine(&parser);
+#ifdef QTQUICK
qmlRegisterType("org.qtproject.example", 1, 0, "SortFilterProxyModel");
qmlRegisterType("rust", 1, 0, "Fibonacci");
qmlRegisterType("rust", 1, 0, "FibonacciList");
- Tree model;
+#endif
+
+ Models models;
+ Tree& model = models.tree;
+ QSortFilterProxyModel& sortedModel = models.sortedTree;
model.setPath("/");
- QSortFilterProxyModel sortedModel;
sortedModel.setSourceModel(&model);
sortedModel.setDynamicSortFilter(true);
- QTreeView view;
- view.setUniformRowHeights(true);
- view.setSortingEnabled(true);
- view.setModel(&sortedModel);
- auto root = sortedModel.index(0, 0);
- view.expand(root);
- view.sortByColumn(0, Qt::AscendingOrder);
- view.show();
- view.header()->setSectionResizeMode(QHeaderView::ResizeToContents);
- QQmlApplicationEngine engine;
- engine.rootContext()->setContextProperty("fsModel", &model);
- engine.rootContext()->setContextProperty("sortedFsModel", &sortedModel);
- engine.load(QUrl(QStringLiteral("qrc:///demo.qml")));
+
+ createWidgets(&models);
return app.exec();
}
diff --git a/dev b/dev
index 385c514..d587b74 100644
--- a/dev
+++ b/dev
@@ -10,8 +10,8 @@ if [ -z "${1-}" ]; then
else
# run with NixPkgs master that has Qt5.9 and QtCharts
export NIX_PATH=nixpkgs=$HOME/nixpkgs
- export QML2_IMPORT_PATH=$QML2_IMPORT_PATH:/nix/store/cmnbj3s42vfwfkibr9ksv28g44iqbq1y-qtquickcontrols2-5.9.1-bin/lib/qt-5.9/qml/:/nix/store/cv2ayyx56jsqifb1b65ksm0n522ji733-kirigami2-2.1.0/lib/qt-5.9/qml
+# export QML2_IMPORT_PATH=$QML2_IMPORT_PATH:/nix/store/cmnbj3s42vfwfkibr9ksv28g44iqbq1y-qtquickcontrols2-5.9.1-bin/lib/qt-5.9/qml/:/nix/store/cv2ayyx56jsqifb1b65ksm0n522ji733-kirigami2-2.1.0/lib/qt-5.9/qml
charts="qt5.qtcharts libsForQt5.kirigami_2"
fi
-nix-shell -p qtcreator cmake ninja gcc rustc cargo qt5.full extra-cmake-modules kdeFrameworks.kwidgetsaddons kdeFrameworks.kcoreaddons kdeFrameworks.ki18n appstream cmakeCurses kdeFrameworks.ktexteditor qt5.qtquickcontrols2 $charts
+nix-shell -p cmake ninja gcc rustc cargo qt5.full extra-cmake-modules kdeFrameworks.kwidgetsaddons kdeFrameworks.kcoreaddons kdeFrameworks.ki18n appstream cmakeCurses kdeFrameworks.ktexteditor qt5.qtquickcontrols2 $charts
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index c73f4a3..76686ed 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,6 +1,6 @@
-enable_testing()
SET(GENERATOR "${CMAKE_BINARY_DIR}/rust_qt_binding_generator/rust_qt_binding_generator")
+include_directories("${CMAKE_CURRENT_BINARY_DIR}")
add_custom_target("clean-rust")
@@ -33,6 +33,10 @@ function(rust_test NAME DIRECTORY)
DEPENDS "${DIR}/${RUST_TARGET_DIR}/librust.a")
add_executable("${NAME}" "${NAME}.cpp" "${NAME}_rust.cpp" "${NAME}_rust.h")
+ set_target_properties("${NAME}" PROPERTIES
+ CXX_STANDARD 11
+ CXX_STANDARD_REQUIRED ON
+ )
add_dependencies("${NAME}" "test_${DIRECTORY}")
target_link_libraries("${NAME}"
Qt5::Core