Also make the ui available in a widget version
parent
4724f2c62f
commit
fd2ff179d8
|
@ -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()
|
||||
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>demo.qml</file>
|
||||
<file>demo-qtquick2.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -1,77 +1,214 @@
|
|||
#include "Tree.h"
|
||||
#include "Fibonacci.h"
|
||||
#include <cstdlib>
|
||||
|
||||
#include <KAboutData>
|
||||
#include <KLocalizedString>
|
||||
#include <KMessageBox>
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QTreeView>
|
||||
#include <QHeaderView>
|
||||
#ifdef QTQUICK
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QtQml/qqml.h>
|
||||
#include <QQmlContext>
|
||||
#include <QQuickView>
|
||||
#include <QQuickItem>
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
#include <QComboBox>
|
||||
#include <QCommandLineParser>
|
||||
#include <QDebug>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QIntValidator>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QListView>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QStringListModel>
|
||||
#include <QStyleFactory>
|
||||
#include <QTabWidget>
|
||||
#include <QTreeView>
|
||||
#include <QWindow>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
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<QWidget*>(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<QSortFilterProxyModel>("org.qtproject.example", 1, 0, "SortFilterProxyModel");
|
||||
qmlRegisterType<Fibonacci>("rust", 1, 0, "Fibonacci");
|
||||
qmlRegisterType<FibonacciList>("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();
|
||||
}
|
||||
|
|
4
dev
4
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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue