filcuc / nimqml

Qt Qml bindings for the Nim programming language
Other
161 stars 20 forks source link

How to pass variable list of coordinates from Nim to QML? #40

Open arkanoid87 opened 2 years ago

arkanoid87 commented 2 years ago

I've a list of polygons described like

type
  Point = seq[float]
  Polygon = seq[Point]
  Model = seq[Polygon]

let data = @[
  @[
    @[9.183454513549805,45.464374726885],
    @[9.188776016235352,45.46058215193312],
    @[9.190363883972166,45.469039846107734],
    @[9.183454513549805,45.464374726885]
  ]
]

I'm trying to write QAbstractListModel for MapItemView to display those polygons, but the delegate requires path to be an array of javascript objects

Map {
    MapPolygon {
        color: 'green'
        path: [
            { latitude: -27, longitude: 153.0 },
            { latitude: -27, longitude: 154.1 },
            { latitude: -28, longitude: 153.5 }
        ]
    }
}

I'm trying to understand how to pass a seq of coordinates from my data proc considering that each polygon may have a variable number of vertices

method data(self: MapModel, index: QModelIndex, role: int): QVariant = ...

I see that nimqml lacks QVariantList and QVariantMap but I am not aware if a workaround solution is possible.

I'm considering turning Polygon type into a QObject and make seq[Point] one of its properties, but I don't know if it's possible to pass sequences from/to nimqml, that would mean declaring a list property using QQmlListProperty but it seems unavailable

arkanoid87 commented 2 years ago

I see that dotherside already knows about QVariantList

maybe it could be the shortest path to add this feature

arkanoid87 commented 2 years ago

I've successfully passed a list from nim to qml by adding this to dotherside.nim

proc dos_qvariant_setArray(variant: DosQVariant, size: cint, array: ptr DosQVariantArray) {.cdecl, dynlib: dynLibName, importc.}

and this to qvariant.nim

proc toQVariant*(sequence: seq[QVariant]): QVariant =
  result = newQVariant()
  var arr = newSeqOfCap[DosQVariant](sequence.len)
  for e in sequence:
    arr.add e.vptr
  dos_qvariant_setArray(result.vptr, sequence.len.cint, cast[ptr DosQVariantArray](arr[0].unsafeAddr))
  return result

returning the generated QVariant to qml via data method of model it ended up correctly on the other side