Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add qml #449

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0aa87ed
Fix CMake warnings
bansan85 Oct 17, 2023
94be995
Fix MSVC warnings
bansan85 Oct 17, 2023
c96829b
Add calculator_test
bansan85 Oct 21, 2024
5bf9066
Missing MultiplicationModel.hpp in CMakeLists.txt
bansan85 Oct 23, 2023
c51ebc3
Minors fixes in library
bansan85 Oct 24, 2023
8c6b9fc
Apply clang-format
bansan85 Oct 21, 2024
285ebc9
Remove qml debug messages
bansan85 Oct 21, 2024
dc79eaf
IWYU qml
bansan85 Oct 21, 2024
31a267e
IWYU
bansan85 Oct 21, 2024
05752dd
Avoid overlap between connections and nodes
bansan85 Nov 3, 2023
144a7eb
Add Acquisition Viewer
bansan85 Oct 21, 2024
c755681
Fix Dynamic ports example
bansan85 Nov 6, 2023
671b4c4
Add Compute viewer that embedded parameters
bansan85 Oct 21, 2024
9639b52
Fix Load / Save for Acquisition Viewer
bansan85 Nov 7, 2023
0ea5f78
Implement full compute_viewer
bansan85 Oct 21, 2024
9860f83
Call WINDEPLOYQT_EXECUTABLE for all example
bansan85 Nov 8, 2023
4f8f543
Don't skip default action for mouse event
bansan85 Nov 10, 2023
ef934e0
Use ResultWidget
bansan85 Oct 21, 2024
2941a32
Add images for examples
bansan85 Nov 15, 2023
c650806
Add package init in Config.cmake.in
bansan85 Jan 24, 2024
cc44a1c
Fix examples Win static build
bansan85 Oct 21, 2024
ee0860d
Fix format and dedicated CI
bansan85 Oct 21, 2024
7290349
Remove openGL dependency
bansan85 Jun 26, 2024
7cc0759
Fix CI and reduce dependencies
bansan85 Oct 21, 2024
a70646d
Fix usage of dataInvalidated
bansan85 Oct 21, 2024
0888da8
Fix typos
bansan85 Jun 26, 2024
a195372
setPortData should return true if success
bansan85 Jun 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 5 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
cmake_minimum_required(VERSION 3.8)

cmake_policy(SET CMP0072 NEW) # new in 3.11. The NEW behavior for this policy is to set OpenGL_GL_PREFERENCE to GLVND.
cmake_policy(SET CMP0068 NEW) # new in 3.9. The NEW behavior of this policy is to ignore the RPATH settings for install_name on macOS.


project(QtNodesLibrary CXX)

set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")

set(CMAKE_CXX_STANDARD 11)

set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
set(OpenGL_GL_PREFERENCE LEGACY)
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

get_directory_property(_has_parent PARENT_DIRECTORY)
Expand Down Expand Up @@ -53,7 +50,7 @@ else()
find_package(QT NAMES Qt5 REQUIRED COMPONENTS Widgets)
endif()

find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Gui OpenGL)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Gui Quick QuickWidgets)
message(STATUS "QT_VERSION: ${QT_VERSION}, QT_DIR: ${QT_DIR}")

if (${QT_VERSION} VERSION_LESS 5.11.0)
Expand Down Expand Up @@ -161,7 +158,6 @@ target_link_libraries(QtNodes
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::OpenGL
)

target_compile_definitions(QtNodes
Expand All @@ -188,12 +184,6 @@ if(NOT "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
)
endif()

if(QT_NODES_DEVELOPER_DEFAULTS)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable is not defined anywhere.

target_compile_features(QtNodes PUBLIC cxx_std_14)
set_target_properties(QtNodes PROPERTIES CXX_EXTENSIONS OFF)
endif()


set_target_properties(QtNodes
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
Expand Down
11 changes: 3 additions & 8 deletions cmake/QtNodesConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
get_filename_component(QtNodes_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
@PACKAGE_INIT@
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Config.cmake.in pattern from CMake documentation


include(CMakeFindDependencyMacro)

Expand All @@ -8,11 +8,6 @@ find_dependency(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_dependency(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS
Core
Widgets
Gui
OpenGL)
Gui)

if(NOT TARGET QtNodes::QtNodes)
include("${QtNodes_CMAKE_DIR}/QtNodesTargets.cmake")
endif()

set(QtNodes_LIBRARIES QtNodes::QtNodes)
include("${CMAKE_CURRENT_LIST_DIR}/QtNodesTargets.cmake")
4 changes: 2 additions & 2 deletions docs/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The ``ConnectionId`` is nothing else but a combination of input and output

::

// Definitinos.hpp
// Definitions.hpp
struct ConnectionId
{
NodeId outNodeId;
Expand Down Expand Up @@ -369,7 +369,7 @@ redraw the receiver node and could be hooked up for other user's purposes.
// Source Delegate Model -> source NodeId
DataFlowGraphModel::onOutPortDataUpdated(NodeId, PortIndex)

// soure NodeId -> target NodeId
// source NodeId -> target NodeId
DataFlowGraphModel::setPortData()

// target NodeId -> target Delegate Model
Expand Down
5 changes: 5 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ add_subdirectory(dynamic_ports)

add_subdirectory(lock_nodes_and_connections)

add_subdirectory(calculator_qml)

add_subdirectory(acquisition_viewer)

add_subdirectory(compute_viewer)
14 changes: 14 additions & 0 deletions examples/acquisition_viewer/AcqData.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include <QtNodes/NodeData>

using QtNodes::NodeData;
using QtNodes::NodeDataType;

/// The class can potentially incapsulate any user data which
/// need to be transferred within the Node Editor graph
class AcqData : public NodeData
{
public:
NodeDataType type() const override { return NodeDataType{"acquisition", ""}; }
};
86 changes: 86 additions & 0 deletions examples/acquisition_viewer/AcqModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include "AcqModel.hpp"
#include "AcqData.hpp"
#include <cstdlib>
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#include <QColor>
#include <QInputDialog>
#include <QJsonValue>
#include <QJsonValueRef>
#include <QLineEdit>
#include <QtNodes/NodeDelegateModel>

using QtNodes::NodeStyle;

unsigned int AcqModel::nPorts(PortType portType) const
{
unsigned int result;

if (portType == PortType::In)
result = 1;
else
result = 1;

return result;
}

NodeDataType AcqModel::dataType(PortType, PortIndex) const
{
return AcqData().type();
}

std::shared_ptr<NodeData> AcqModel::outData(PortIndex)
{
return std::static_pointer_cast<NodeData>(_result);
}

void AcqModel::setInData(std::shared_ptr<NodeData> data, PortIndex portIndex)
{
auto numberData = std::dynamic_pointer_cast<AcqData>(data);

if (!data) {
Q_EMIT dataInvalidated(0);
}
}

QWidget *AcqModel::embeddedWidget()
{
if (_result) {
return nullptr;
}

_result = std::make_shared<AcqData>();

if (_title.isEmpty()) {
bool ok;

QString text = QInputDialog::getText(nullptr,
"Acquisition node",
"Title:",
QLineEdit::Normal,
"",
&ok);
if (ok && !text.isEmpty())
_title = text;
}

NodeStyle style;
style.GradientColor0 = {rand() % 256, rand() % 256, rand() % 256};
style.GradientColor1 = {rand() % 256, rand() % 256, rand() % 256};
style.GradientColor2 = {rand() % 256, rand() % 256, rand() % 256};
style.GradientColor3 = {rand() % 256, rand() % 256, rand() % 256};
setNodeStyle(style);

return nullptr;
}

QJsonObject AcqModel::save() const
{
QJsonObject retval = NodeDelegateModel::save();
retval["Title"] = _title;
return retval;
}

void AcqModel::load(QJsonObject const &object)
{
NodeDelegateModel::load(object);
_title = object["Title"].toString();
}
56 changes: 56 additions & 0 deletions examples/acquisition_viewer/AcqModel.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#pragma once

#include <memory>
#include <QJsonObject>
#include <QObject>
#include <QString>
#include <QStringLiteral>
#include <QWidget>
#include <QtNodes/NodeDelegateModel>

class AcqData;

using QtNodes::ConnectionPolicy;
using QtNodes::NodeData;
using QtNodes::NodeDataType;
using QtNodes::NodeDelegateModel;
using QtNodes::PortIndex;
using QtNodes::PortType;

/// The model dictates the number of inputs and outputs for the Node.
/// In this example it has no logic.
class AcqModel : public NodeDelegateModel
{
Q_OBJECT

public:
~AcqModel() override = default;

public:
unsigned int nPorts(PortType portType) const override;

NodeDataType dataType(PortType portType, PortIndex portIndex) const override;

std::shared_ptr<NodeData> outData(PortIndex port) override;

void setInData(std::shared_ptr<NodeData> data, PortIndex portIndex) override;

QWidget *embeddedWidget() override;

QString caption() const override { return _title; }

QString name() const override { return QStringLiteral("Acquisition"); }

ConnectionPolicy portConnectionPolicy(PortType, PortIndex) const override
{
return ConnectionPolicy::Many;
}

QJsonObject save() const override;

void load(QJsonObject const &) override;

private:
std::shared_ptr<AcqData> _result;
QString _title;
};
16 changes: 16 additions & 0 deletions examples/acquisition_viewer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
set(ACQ_SOURCE_FILES main.cpp AcqModel.cpp)

set(ACQ_HEADER_FILES AcqData.hpp AcqModel.hpp)

add_executable(acquisition_viewer WIN32 ${ACQ_SOURCE_FILES} ${ACQ_HEADER_FILES}
CMakeLists.txt)

target_link_libraries(acquisition_viewer QtNodes)

if(WIN32 AND BUILD_SHARED_LIBS)
add_custom_command(
TARGET acquisition_viewer
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E env VCINSTALLDIR=${CMAKE_GENERATOR_INSTANCE}/VC
${WINDEPLOYQT_EXECUTABLE} --pdb "$<TARGET_FILE:acquisition_viewer>")
endif()
96 changes: 96 additions & 0 deletions examples/acquisition_viewer/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include "AcqModel.hpp"
#include <memory>
#include <QAction>
#include <QApplication>
#include <QMenu>
#include <QMenuBar>
#include <QObject>
#include <QPoint>
#include <QRect>
#include <QScreen>
#include <QVBoxLayout>
#include <QWidget>
#include <QtNodes/ConnectionStyle>
#include <QtNodes/DataFlowGraphicsScene>
#include <QtNodes/GraphicsView>

using QtNodes::ConnectionStyle;
using QtNodes::DataFlowGraphicsScene;
using QtNodes::DataFlowGraphModel;
using QtNodes::GraphicsView;
using QtNodes::NodeDelegateModelRegistry;

static std::shared_ptr<NodeDelegateModelRegistry> registerDataModels()
{
auto ret = std::make_shared<NodeDelegateModelRegistry>();

ret->registerModel<AcqModel>("Acquisition");

return ret;
}

static void setStyle()
{
/*
ConnectionStyle::setConnectionStyle(
R"(
{
"ConnectionStyle": {
"ConstructionColor": "gray",
"NormalColor": "black",
"SelectedColor": "gray",
"SelectedHaloColor": "deepskyblue",
"HoveredColor": "deepskyblue",

"LineWidth": 3.0,
"ConstructionLineWidth": 2.0,
"PointDiameter": 10.0,

"UseDataDefinedColors": true
}
}
)");*/
}

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

setStyle();

std::shared_ptr<NodeDelegateModelRegistry> registry = registerDataModels();

QWidget mainWidget;

auto menuBar = new QMenuBar();
QMenu *menu = menuBar->addMenu("File");
auto saveAction = menu->addAction("Save Scene");
auto loadAction = menu->addAction("Load Scene");

QVBoxLayout *l = new QVBoxLayout(&mainWidget);

DataFlowGraphModel dataFlowGraphModel(registry);

l->addWidget(menuBar);
auto scene = new DataFlowGraphicsScene(dataFlowGraphModel, &mainWidget);

auto view = new GraphicsView(scene);
l->addWidget(view);
l->setContentsMargins(0, 0, 0, 0);
l->setSpacing(0);

QObject::connect(saveAction, &QAction::triggered, scene, &DataFlowGraphicsScene::save);

QObject::connect(loadAction, &QAction::triggered, scene, &DataFlowGraphicsScene::load);

QObject::connect(scene, &DataFlowGraphicsScene::sceneLoaded, view, &GraphicsView::centerScene);

mainWidget.setWindowTitle("Data Flow: simplest calculator");
mainWidget.resize(800, 600);
// Center window.
mainWidget.move(QApplication::primaryScreen()->availableGeometry().center()
- mainWidget.rect().center());
mainWidget.showNormal();

return app.exec();
}
Binary file added examples/acquisition_viewer/render.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading