dotherside/Nim/NimQml/NimQml.nim

285 lines
12 KiB
Nim
Raw Normal View History

2014-12-08 12:55:09 +01:00
import NimQmlTypes
import tables
## NimQml aims to provide binding to the QML for the Nim programming language
2014-12-08 12:55:09 +01:00
export QObject
export QApplication
export QVariant
export QQmlApplicationEngine
export QQmlContext
type QMetaType* {.pure.} = enum ## \
## Qt metatypes values used for specifing the
## signals and slots argument and return types.
##
## This enum mimic the QMetaType::Type C++ enum
2014-12-08 12:55:09 +01:00
UnknownType = cint(0),
Bool = cint(1),
Int = cint(2),
QString = cint(10),
VoidStar = cint(31),
QVariant = cint(41),
Void = cint(43)
2015-01-06 23:16:26 +00:00
var qobjectRegistry = initTable[ptr QObjectObj, QObject]()
2014-12-08 12:55:09 +01:00
proc debugMsg(message: string) =
echo "NimQml: ", message
proc debugMsg(typeName: string, procName: string) =
var message = typeName
message &= ": "
message &= procName
debugMsg(message)
proc debugMsg(typeName: string, procName: string, userMessage: string) =
var message = typeName
message &= ": "
message &= procName
message &= " "
message &= userMessage
debugMsg(message)
2014-12-08 12:55:09 +01:00
# QVariant
proc dos_qvariant_create(variant: var QVariant) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create_int(variant: var QVariant, value: cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create_bool(variant: var QVariant, value: bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create_string(variant: var QVariant, value: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_create_qobject(variant: var QVariant, value: DynamicQObject) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_delete(variant: QVariant) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_isnull(variant: QVariant, isNull: var bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_toInt(variant: QVariant, value: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_toBool(variant: QVariant, value: var bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_toString(variant: QVariant, value: var cstring, length: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_setInt(variant: QVariant, value: cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_setBool(variant: QVariant, value: bool) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qvariant_setString(variant: QVariant, value: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
2014-12-08 12:55:09 +01:00
proc dos_chararray_delete(rawCString: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc create*(variant: var QVariant) =
## Create a new QVariant
dos_qvariant_create(variant)
2014-12-08 12:55:09 +01:00
proc create*(variant: var QVariant, value: cint) =
## Create a new QVariant given a cint value
dos_qvariant_create_int(variant, value)
2014-12-08 12:55:09 +01:00
proc create*(variant: var QVariant, value: bool) =
## Create a new QVariant given a bool value
dos_qvariant_create_bool(variant, value)
2014-12-08 12:55:09 +01:00
proc create*(variant: var QVariant, value: string) =
## Create a new QVariant given a string value
dos_qvariant_create_string(variant, value)
2014-12-08 12:55:09 +01:00
proc create*(variant: var QVariant, value: QObject) =
## Create a new QVariant given a QObject
dos_qvariant_create_qobject(variant, value.data)
2014-12-08 12:55:09 +01:00
proc delete*(variant: QVariant) =
## Delete a QVariant
2014-12-08 12:55:09 +01:00
debugMsg("QVariant", "delete")
dos_qvariant_delete(variant)
2014-12-08 12:55:09 +01:00
proc isNull*(variant: QVariant): bool =
## Return true if the QVariant value is null, false otherwise
dos_qvariant_isnull(variant, result)
2014-12-08 12:55:09 +01:00
proc intVal*(variant: QVariant): int =
## Return the QVariant value as int
var rawValue: cint
dos_qvariant_toInt(variant, rawValue)
result = rawValue.cint
2014-12-08 12:55:09 +01:00
proc `intVal=`*(variant: QVariant, value: int) =
## Sets the QVariant value int value
var rawValue = value.cint
dos_qvariant_setInt(variant, rawValue)
proc boolVal*(variant: QVariant): bool =
## Return the QVariant value as bool
dos_qvariant_toBool(variant, result)
2014-12-08 12:55:09 +01:00
proc `boolVal=`*(variant: QVariant, value: bool) =
## Sets the QVariant bool value
dos_qvariant_setBool(variant, value)
proc stringVal*(variant: QVariant): string =
## Return the QVariant value as string
2014-12-08 12:55:09 +01:00
var rawCString: cstring
var rawCStringLength: cint
dos_qvariant_toString(variant, rawCString, rawCStringLength)
2014-12-08 12:55:09 +01:00
result = $rawCString
dos_chararray_delete(rawCString)
proc `stringVal=`*(variant: QVariant, value: string) =
## Sets the QVariant string value
dos_qvariant_setString(variant, value)
2014-12-08 12:55:09 +01:00
# QQmlApplicationEngine
proc dos_qqmlapplicationengine_create(engine: var QQmlApplicationEngine) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qqmlapplicationengine_load(engine: QQmlApplicationEngine, filename: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qqmlapplicationengine_context(engine: QQmlApplicationEngine, context: var QQmlContext) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qqmlapplicationengine_delete(engine: QQmlApplicationEngine) {.cdecl, dynlib:"libDOtherSide.so", importc.}
2014-12-08 12:55:09 +01:00
proc create*(engine: var QQmlApplicationEngine) =
## Create an new QQmlApplicationEngine
dos_qqmlapplicationengine_create(engine)
2014-12-08 12:55:09 +01:00
proc load*(engine: QQmlApplicationEngine, filename: cstring) =
## Load the given Qml file
dos_qqmlapplicationengine_load(engine, filename)
2014-12-08 12:55:09 +01:00
proc rootContext*(engine: QQmlApplicationEngine): QQmlContext =
## Return the engine root context
dos_qqmlapplicationengine_context(engine, result)
2014-12-08 12:55:09 +01:00
proc delete*(engine: QQmlApplicationEngine) =
## Delete the given QQmlApplicationEngine
2014-12-08 12:55:09 +01:00
debugMsg("QQmlApplicationEngine", "delete")
dos_qqmlapplicationengine_delete(engine)
2014-12-08 12:55:09 +01:00
# QQmlContext
proc dos_qqmlcontext_setcontextproperty(context: QQmlContext, propertyName: cstring, propertyValue: QVariant) {.cdecl, dynlib:"libDOtherSide.so", importc.}
2014-12-08 12:55:09 +01:00
proc setContextProperty*(context: QQmlContext, propertyName: string, propertyValue: QVariant) =
## Sets a new property with the given value
dos_qqmlcontext_setcontextproperty(context, propertyName, propertyValue)
2014-12-08 12:55:09 +01:00
# QApplication
proc dos_qguiapplication_create() {.cdecl, dynlib: "libDOtherSide.so", importc.}
proc dos_qguiapplication_exec() {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qguiapplication_delete() {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc create*(application: QApplication) =
## Create a new QApplication
2014-12-08 12:55:09 +01:00
dos_qguiapplication_create()
proc exec*(application: QApplication) =
## Start the Qt event loop
2014-12-08 12:55:09 +01:00
dos_qguiapplication_exec()
proc delete*(application: QApplication) =
## Delete the given QApplication
2014-12-08 12:55:09 +01:00
dos_qguiapplication_delete()
# QObject
type QVariantArray {.unchecked.} = array[0..0, QVariant]
type QVariantArrayPtr = ptr QVariantArray
proc toVariantSeq(args: QVariantArrayPtr, numArgs: cint): seq[QVariant] =
result = @[]
for i in 0..numArgs-1:
result.add(args[i])
proc toCIntSeq(metaTypes: openarray[QMetaType]): seq[cint] =
result = @[]
for metaType in metaTypes:
result.add(cint(metaType))
2015-01-06 23:16:26 +00:00
type QObjectCallBack = proc(nimobject: ptr QObjectObj, slotName: QVariant, numArguments: cint, arguments: QVariantArrayPtr) {.cdecl.}
2015-01-06 23:16:26 +00:00
proc dos_qobject_create(qobject: var DynamicQObject, nimobject: ptr QObjectObj, qobjectCallback: QObjectCallBack) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_delete(qobject: DynamicQObject) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_slot_create(qobject: DynamicQObject, slotName: cstring, argumentsCount: cint, argumentsMetaTypes: ptr cint, slotIndex: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_signal_create(qobject: DynamicQObject, signalName: cstring, argumentsCount: cint, argumentsMetaTypes: ptr cint, signalIndex: var cint) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_signal_emit(qobject: DynamicQObject, signalName: cstring, argumentsCount: cint, arguments: ptr QVariant) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qobject_property_create(qobject: DynamicQObject, propertyName: cstring, propertyType: cint, readSlot: cstring, writeSlot: cstring, notifySignal: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
method onSlotCalled*(nimobject: QObject, slotName: string, args: openarray[QVariant]) =
## Called from the NimQml bridge when a slot is called from Qml.
## Subclasses can override the given method for handling the slot call
discard()
2015-01-06 23:16:26 +00:00
proc qobjectCallback(nimobject: ptr QObjectObj, slotName: QVariant, numArguments: cint, arguments: QVariantArrayPtr) {.cdecl, exportc.} =
let qobject = qobjectRegistry[nimobject]
assert qobject != nil, "expecting valid QObject"
# forward to the QObject subtype instance
2015-01-06 23:16:26 +00:00
qobject.onSlotCalled(slotName.stringVal, arguments.toVariantSeq(numArguments))
2014-12-08 12:55:09 +01:00
2015-01-06 23:16:26 +00:00
proc create*(qobject: QObject) =
## Create a new QObject
2015-01-06 23:16:26 +00:00
let internalRef = qobject
let qobjectPtr = addr(qobject[])
qobjectRegistry[qobjectPtr] = internalRef
qobject.name = "QObject"
2014-12-08 12:55:09 +01:00
qobject.slots = initTable[string,cint]()
qobject.signals = initTable[string, cint]()
2015-01-06 23:16:26 +00:00
dos_qobject_create(qobject.data, qobjectPtr, qobjectCallback)
2014-12-08 12:55:09 +01:00
proc delete*(qobject: QObject) =
## Delete the given QObject
2015-01-06 23:16:26 +00:00
let qobjectPtr = addr(qobject[])
qobjectRegistry.del qobjectPtr
2014-12-08 12:55:09 +01:00
dos_qobject_delete(qobject.data)
proc registerSlot*(qobject: QObject,
slotName: string,
metaTypes: openarray[QMetaType]) =
## Register a slot in the QObject with the given name and signature
2014-12-08 12:55:09 +01:00
# Copy the metatypes array
var copy = toCIntSeq(metatypes)
var index: cint
dos_qobject_slot_create(qobject.data, slotName, cint(copy.len), addr(copy[0].cint), index)
2014-12-08 12:55:09 +01:00
qobject.slots[slotName] = index
proc registerSignal*(qobject: QObject,
signalName: string,
metatypes: openarray[QMetaType]) =
## Register a signal in the QObject with the given name and signature
var index: cint
if metatypes.len > 0:
var copy = toCIntSeq(metatypes)
dos_qobject_signal_create(qobject.data, signalName, copy.len.cint, addr(copy[0].cint), index)
else:
dos_qobject_signal_create(qobject.data, signalName, 0, nil, index)
qobject.signals[signalName] = index
proc registerProperty*(qobject: QObject,
propertyName: string,
propertyType: QMetaType,
readSlot: string,
writeSlot: string,
notifySignal: string) =
## Register a property in the QObject with the given name and type.
dos_qobject_property_create(qobject.data, propertyName, propertyType.cint, readSlot, writeSlot, notifySignal)
proc emit*(qobject: QObject, signalName: string, args: openarray[QVariant] = []) =
## Emit the signal with the given name and values
if args.len > 0:
2015-01-06 23:23:32 +00:00
var copy = @args
dos_qobject_signal_emit(qobject.data, signalName, args.len.cint, addr(copy[0]))
else:
dos_qobject_signal_emit(qobject.data, signalName, 0, nil)
2014-12-08 12:55:09 +01:00
# QQuickView
proc dos_qquickview_create(view: var QQuickView) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_delete(view: QQuickView) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_show(view: QQuickView) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_source(view: QQuickView, filename: var cstring, length: var int) {.cdecl, dynlib:"libDOtherSide.so", importc.}
proc dos_qquickview_set_source(view: QQuickView, filename: cstring) {.cdecl, dynlib:"libDOtherSide.so", importc.}
2014-12-08 12:55:09 +01:00
proc create(view: var QQuickView) =
## Create a new QQuickView
dos_qquickview_create(view)
2014-12-08 12:55:09 +01:00
proc source(view: QQuickView): cstring =
## Return the source Qml file loaded by the view
2014-12-08 12:55:09 +01:00
var length: int
dos_qquickview_source(view, result, length)
2014-12-08 12:55:09 +01:00
proc `source=`(view: QQuickView, filename: cstring) =
## Sets the source Qml file laoded by the view
dos_qquickview_set_source(view, filename)
2014-12-08 12:55:09 +01:00
proc show(view: QQuickView) =
## Sets the view visible
dos_qquickview_show(view)
2014-12-08 12:55:09 +01:00
proc delete(view: QQuickView) =
## Delete the given QQuickView
dos_qquickview_delete(view)