diff --git a/Nim/Examples/SimpleMacro/CMakeLists.txt b/Nim/Examples/SimpleMacro/CMakeLists.txt new file mode 100644 index 0000000..79e03af --- /dev/null +++ b/Nim/Examples/SimpleMacro/CMakeLists.txt @@ -0,0 +1,2 @@ +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/main.qml DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +add_nim_executable(TARGET Main SOURCES main.nim PATHS ../../NimQml) \ No newline at end of file diff --git a/Nim/Examples/SimpleMacro/main.nim b/Nim/Examples/SimpleMacro/main.nim new file mode 100644 index 0000000..f3d668c --- /dev/null +++ b/Nim/Examples/SimpleMacro/main.nim @@ -0,0 +1,57 @@ +## This example replicates the functionality of Examples/Simple but uses +## the helper macro, QtObject, from NimQmlMacros, to remove some of the boiler plate. +## Please note we are using templates where ordinarily we would like to use procedures +## due to bug: https://github.com/Araq/Nim/issues/1821 + +import NimQml, NimQmlMacros + +QtObject: + type MyQObject = ref object of QObject + m_name: string + + template newMyQObject(initial: string): MyQObject = + var result = MyQObject(m_name: initial) + result.create + result + + method getName(myQObject: MyQObject): string {.slot.} = + echo "nameChanged" + result = myQObject.m_name + + method nameChanged(myQObject: MyQObject) {.signal.} + + method setName(myQObject: MyQObject, name: string) {.slot.} = + echo "setName" + if myQObject.m_name != name: + myQObject.m_name = name + myQObject.nameChanged() + + QtProperty name of string: + read = getName + write = setName + notify = nameChanged + +proc mainProc() = + var app: QApplication + app.create() + defer: app.delete() + + var myQObject = newMyQObject("InitialName") + defer: myQObject.delete() + + var engine: QQmlApplicationEngine + engine.create() + defer: engine.delete() + + var variant: QVariant + variant.create(myQObject) + defer: variant.delete() + + var rootContext: QQmlContext = engine.rootContext() + rootContext.setContextProperty("myQObject", variant) + engine.load("main.qml") + app.exec() + +when isMainModule: + mainProc() + diff --git a/Nim/Examples/SimpleMacro/main.qml b/Nim/Examples/SimpleMacro/main.qml new file mode 100644 index 0000000..a2943c3 --- /dev/null +++ b/Nim/Examples/SimpleMacro/main.qml @@ -0,0 +1,36 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.1 +import QtQuick.Window 2.1 + +ApplicationWindow +{ + width: 400 + height: 300 + + Component.onCompleted: visible = true + + ColumnLayout + { + anchors.fill: parent + + Label + { + text: "Current name is:" + myQObject.name + } + + TextField + { + id: textField + } + + Button + { + text: "Change Name" + onClicked: { + console.log("QML:", textField.text) + myQObject.name = textField.text + } + } + } +} diff --git a/Nim/NimQml/NimQmlMacros.nim b/Nim/NimQml/NimQmlMacros.nim new file mode 100644 index 0000000..33fecd1 --- /dev/null +++ b/Nim/NimQml/NimQmlMacros.nim @@ -0,0 +1,411 @@ +## Contains helper macros for NimQml + +import macros +import strutils +import typetraits +import tables + +template debug(body: stmt): stmt = + {.push warning[user]: off.} + when defined(debug): + {.pop.} + body + else: + {.pop.} + +let nimFromQtVariant {.compileTime.} = { + "int" : "intVal", + "string" : "stringVal", + "bool" : "boolVal", +}.toTable + +let nim2QtMeta {.compileTime.} = { + "bool": "Bool", + "int " : "Int", + "string" : "QString", + "pointer" : "VoidStar", + "QVariant": "QVariant", + "" : "Void", # no return, which is represented by an nnkEmpty node +}.toTable + +proc getNodeOf*(tree: PNimrodNode, kind: TNimrodNodeKind): PNimrodNode {.compileTime.} = + ## recursively looks for a node of kind, ``kind``, in the tree provided as ``tree`` + ## Returnsthe first node that satisfies this condition + for i in 0.. 2: # more args than just type + for i in 2..