├── .gitignore ├── LICENSE ├── README.md ├── doc └── nimqml.md ├── examples ├── abstractitemmodel │ ├── .gitignore │ ├── abstractitemmodel.nimble │ ├── main.nim │ ├── main.nim.cfg │ ├── main.qml │ └── mylistmodel.nim ├── charts │ ├── .gitignore │ ├── charts.nimble │ ├── main.nim │ ├── main.nim.cfg │ ├── main.qml │ └── mylistmodel.nim ├── contactapp │ ├── .gitignore │ ├── applicationlogic.nim │ ├── contact.nim │ ├── contactapp.nimble │ ├── contactlist.nim │ ├── main.nim │ ├── main.nim.cfg │ └── main.qml ├── helloworld │ ├── .gitignore │ ├── helloworld.nimble │ ├── main.nim │ ├── main.nim.cfg │ └── main.qml ├── qmlregistertype │ ├── .gitignore │ ├── contact.nim │ ├── main.nim │ ├── main.nim.cfg │ ├── main.qml │ └── qmlregistertype.nimble ├── resourcebundling │ ├── .gitignore │ ├── main.nim │ ├── main.nim.cfg │ ├── main.qml │ ├── resourcebundling.nimble │ └── resources.qrc ├── simpledata │ ├── .gitignore │ ├── main.nim │ ├── main.nim.cfg │ ├── main.qml │ └── simpledata.nimble └── slotsandproperties │ ├── .gitignore │ ├── contact.nim │ ├── main.nim │ ├── main.nim.cfg │ ├── main.qml │ └── slotsandproperties.nimble ├── nimqml.nimble └── src ├── nimqml.nim └── nimqml └── private ├── dotherside.nim ├── nimqmlmacros.nim ├── nimqmltypes.nim ├── qabstractitemmodel.nim ├── qabstractlistmodel.nim ├── qabstracttablemodel.nim ├── qapplication.nim ├── qdeclarative.nim ├── qguiapplication.nim ├── qhashintbytearray.nim ├── qmetaobject.nim ├── qmodelindex.nim ├── qnetworkconfigurationmanager.nim ├── qobject.nim ├── qqmlapplicationengine.nim ├── qquickview.nim ├── qresource.nim ├── qsettings.nim ├── qtimer.nim ├── qurl.nim ├── qvariant.nim ├── singleinstance.nim └── status ├── statusevent.nim ├── statuskeychainmanager.nim └── statusosnotification.nim /.gitignore: -------------------------------------------------------------------------------- 1 | *.c 2 | *.o 3 | nimcache 4 | *.nimproject* 5 | *.exe 6 | *.qmlc 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | 167 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NimQML 2 | 3 | QML binding for the Nim programming language 4 | 5 | ## Requirements 6 | * [DOtherside](https://github.com/filcuc/DOtherSide) 0.6.3 or higher 7 | * [Nim](http://nim-lang.org/) 1.0.0 or higher 8 | 9 | ## Build instructions 10 | * Compile and Install [DOtherside](https://github.com/filcuc/DOtherSide) in your system PATH (i.e. /usr/lib) 11 | * ```nimble install nimqml``` 12 | 13 | ## Examples 14 | The examples can be built by executing the following command 15 | ``` 16 | nimble build 17 | ``` 18 | 19 | ## Documentation 20 | The project documentation can be read [here](http://filcuc.github.io/nimqml/) 21 | -------------------------------------------------------------------------------- /doc/nimqml.md: -------------------------------------------------------------------------------- 1 | :Authors: 2 | Filippo Cucchetto 3 | 4 | Will Szumski 5 | :Version: 0.7.7 6 | :Date: 2019/10/01 7 | 8 | 9 | Introduction 10 | ----------- 11 | The NimQml module adds Qt Qml bindings to the Nim programming language 12 | allowing you to create new modern UI by mixing the Qml declarative syntax 13 | and the Nim imperative language. 14 | 15 | You will need: 16 | * The DOtherSide C++ shared library 17 | * The NimQml Nim module 18 | 19 | This first component implements the glue code necessary for 20 | communicating with the Qt C++ library, the latter module wraps 21 | the libDOtherSide exported symbols in Nim 22 | 23 | 24 | Building the C++ DOtherSide bindings 25 | -------- 26 | At the time of writing the DOtherSide C++ library must be compiled 27 | and installed manually from source. 28 | 29 | First clone the DOtherSide git repo 30 | :: 31 | git clone https://github.com/filcuc/DOtherSide 32 | 33 | than you can proceed with the common CMake build steps 34 | 35 | :: 36 | mkdir build 37 | cd build 38 | cmake .. 39 | make 40 | make install 41 | 42 | 43 | Installation of NimQml module 44 | ---------- 45 | The installation is not mandatory, in fact you could try 46 | the built-in examples in the following way 47 | :: 48 | cd path/to/repo/nimqml 49 | cd examples/helloworld 50 | export LD_LIBRARY_PATH=path/to/libDOtherSide.so 51 | nim c -r main 52 | 53 | Alternatively you can use the ``nimble`` package manager 54 | :: 55 | nimble install NimQml 56 | 57 | or 58 | :: 59 | cd to/build/dir/Nim/NimQml 60 | nimble install 61 | 62 | 63 | Example 1: HelloWorld 64 | ---------- 65 | As usual lets start with an HelloWorld example. 66 | Most of the NimQml projects are made by one or more nim and qml 67 | files. Usually the .nim files contains your app logic and data 68 | layer. The qml files contain the presentation layer and expose 69 | the data in your nim files. 70 | 71 | ``examples/helloworld/main.nim`` 72 | 73 | .. code-block:: nim 74 | :file: ../examples/helloworld/main.nim 75 | 76 | ``examples/helloworld/main.qml`` 77 | 78 | .. code-block:: qml 79 | :file: ../examples/helloworld/main.qml 80 | 81 | The example shows the mandatory steps of each NimQml app 82 | 1. Create the ``QApplication`` for initializing the Qt runtime 83 | 2. Create the `QQmlApplicationEngine` and load your main .qml file 84 | 3. Call the `exec` proc of the QApplication instance for starting the Qt event loop 85 | 86 | Example 2: exposing data to Qml 87 | ------------------------------------ 88 | The previous example shown how to startup the Qt event loop 89 | to create an application with a window. 90 | 91 | It's time to explore how to pass data to Qml but lets see the 92 | example code first: 93 | 94 | ``examples/simpledata/main.nim`` 95 | 96 | .. code-block:: nim 97 | :file: ../examples/simpledata/main.nim 98 | 99 | ``examples/simpledata/main.qml`` 100 | 101 | .. code-block:: qml 102 | :file: ../examples/simpledata/main.qml 103 | 104 | The example shows how to expose simple values to Qml: 105 | 1. Create a `QVariant` and set its value. 106 | 2. Set a property in the Qml root context with a given name. 107 | 108 | Once a property is set through the ``setContextProperty`` proc, it's available 109 | globally in all the Qml script loaded by the current engine (see the official Qt 110 | documentation for more details about the engine and context objects) 111 | 112 | At the time of writing the QVariant class support the following types: 113 | * int 114 | * string 115 | * bool 116 | * float 117 | * QObject derived classes 118 | 119 | Example 3: exposing complex data and procedures to Qml 120 | ---------------------------------------------------------- 121 | As seen by the second example, simple data is fine. However most 122 | applications need to expose complex data, functions and 123 | update the view when something changes in the data layer. 124 | This is achieved by creating an object that derives from QObject. 125 | 126 | A QObject is made of : 127 | 1. ``slots``: functions that could be called from the qml engine and/or connected to Qt signals 128 | 2. ``signals``: functions for sending events and to which slots connect 129 | 3. ``properties``: properties allow the passing of data to the Qml view and make it aware of changes in the data layer 130 | 131 | A QObject `property` is made of three things: 132 | * a read slot: a method that returns the current value of the property 133 | * a write slot: a method that sets the value of the property 134 | * a notify signal: emitted when the current value of the property is changed 135 | 136 | We'll start by looking at the main.nim file 137 | 138 | ``examples/slotsandproperties/main.nim`` 139 | 140 | .. code-block:: nim 141 | :file: ../examples/slotsandproperties/main.nim 142 | 143 | We can see: 144 | 1. The creation of a Contact object 145 | 2. The injection of the Contact object to the Qml root context using the ``setContextProperty`` as seen in the previous example 146 | 147 | The Qml file is as follows: 148 | 149 | ``examples/slotsandproperties/main.qml`` 150 | 151 | .. code-block:: qml 152 | :file: ../examples/slotsandproperties/main.qml 153 | 154 | The qml is made up of: a Label, a TextInput widget, and a button. 155 | The label displays the contact name - this automatically updates when 156 | the contact name changes. 157 | 158 | When clicked, the button updates the contact name with the text from 159 | the TextInput widget. 160 | 161 | So where's the magic? 162 | 163 | The magic is in the Contact.nim file 164 | 165 | ``examples/slotsandproperties/contact.nim`` 166 | 167 | .. code-block:: nim 168 | :file: ../examples/slotsandproperties/contact.nim 169 | 170 | A Contact is a subtype derived from `QObject` 171 | 172 | Defining a `QObject` is done using the nim `QtObject` macro 173 | 174 | .. code-block:: nim 175 | QtObject: 176 | type Contact* = ref object of QObject 177 | m_name: string 178 | 179 | Inside the `QtObject` just define your subclass as your would normally do in Nim. 180 | 181 | Since Nim doesn't support automatic invocation of base class constructors and destructors 182 | you need to call manually the base class `setup` and `delete` functions. 183 | 184 | .. code-block:: nim 185 | proc delete*(self: Contact) = 186 | self.QObject.delete 187 | 188 | proc setup(self: Contact) = 189 | self.QObject.setup 190 | 191 | Don't forget to call the `setup` function and `delete` in your exported constructor 192 | procedure 193 | 194 | .. code-block:: nim 195 | proc newContact*(): Contact = 196 | new(result, delete) 197 | result.m_name = "InitialName" 198 | result.setup 199 | 200 | The creation of a property is done in the following way: 201 | 202 | .. code-block:: nim 203 | QtProperty[string] name: 204 | read = getName 205 | write = setName 206 | notify = nameChanged 207 | 208 | A `QtProperty` is defined by a: 209 | 1. type, in this case `string` 210 | 2. name, in this case `name` 211 | 3. read slot, in this case `getName` 212 | 4. write slot, in this case `setName` 213 | 5. notify signal, in this case `nameChanged` 214 | 215 | Looking at the ``getName`, `setName``, `nameChanged` procs, show that slots and signals 216 | are nothing more than standard procedures annotated with `{.slot.}` and `{.signal.}` 217 | 218 | 219 | Example 4: ContactApp 220 | ------------------------- 221 | The last example tries to show you all the stuff presented 222 | in the previous chapters and gives you an introduction to how 223 | to expose lists to qml. 224 | 225 | Qt models are a huge topic and explaining in detail how they work is 226 | out of scope. For further information please read the official 227 | Qt documentation. 228 | 229 | The main file follows the basic logic of creating a qml 230 | engine and exposing a QObject derived object "ApplicationLogic" 231 | through a global "logic" property 232 | 233 | ``examples/contactapp/main.nim`` 234 | 235 | .. code-block:: nim 236 | :file: ../examples/contactapp/main.nim 237 | 238 | The qml file shows a simple app with a central tableview 239 | 240 | ``examples/contactapp/main.qml`` 241 | 242 | .. code-block:: qml 243 | :file: ../examples/contactapp/main.qml 244 | 245 | The important things to notice are: 246 | 1. The menubar load, save and exit items handlers call the logic load, save and exit slots 247 | 2. The TableView model is retrieved by the logic.contactList property 248 | 3. The delete and add buttons call the del and add slots of the logic.contactList model 249 | 250 | The ApplicationLogic object is as follows: 251 | 252 | ``examples/contactapp/applicationlogic.nim`` 253 | 254 | .. code-block:: nim 255 | :file: ../examples/contactapp/applicationlogic.nim 256 | 257 | The ApplicationLogic object, 258 | 1. expose some slots for handling the qml menubar triggered signals 259 | 2. expose a contactList property that return a QAbstractListModel derived object that manage the list of contacts 260 | 261 | The ContactList object is as follows: 262 | 263 | ``examples/contactapp/contactlist.nim`` 264 | 265 | .. code-block:: nim 266 | :file: ../examples/contactapp/contactlist.nim 267 | 268 | The ContactList object: 269 | 1. overrides the ``rowCount`` method for returning the number of rows stored in the model 270 | 2. overrides the ``data`` method for returning the value for the exported roles 271 | 3. overrides the ``roleNames`` method for returning the names of the roles of the model. This name are then available in the qml item delegates 272 | 4. defines two slots ``add`` and ``del`` that add or delete a Contact. During this operations the model execute the ``beginInsertRows`` and ``beginRemoveRows`` for notifing the view of an upcoming change. Once the add or delete operations are done the model execute the ``endInsertRows`` and ``endRemoveRows``. 273 | -------------------------------------------------------------------------------- /examples/abstractitemmodel/.gitignore: -------------------------------------------------------------------------------- 1 | main 2 | nimcache -------------------------------------------------------------------------------- /examples/abstractitemmodel/abstractitemmodel.nimble: -------------------------------------------------------------------------------- 1 | [Package] 2 | bin = "main" 3 | name = "abstractitemmodel" 4 | version = "0.1.0" 5 | author = "Filippo Cucchetto" 6 | description = "abstractitemmodel" 7 | license = "MIT" 8 | 9 | [Deps] 10 | Requires: "nim >= 1.0.0, nimqml >= 0.7.7" 11 | -------------------------------------------------------------------------------- /examples/abstractitemmodel/main.nim: -------------------------------------------------------------------------------- 1 | import NimQml, mylistmodel 2 | 3 | proc mainProc() = 4 | echo "Starting" 5 | var app = newQApplication() 6 | defer: app.delete 7 | 8 | var myListModel = newMyListModel(); 9 | defer: myListModel.delete 10 | 11 | var engine = newQQmlApplicationEngine() 12 | defer: engine.delete 13 | 14 | var variant = newQVariant(myListModel) 15 | defer: variant.delete 16 | 17 | engine.setRootContextProperty("myListModel", variant) 18 | engine.load("main.qml") 19 | 20 | app.exec() 21 | 22 | when isMainModule: 23 | mainProc() 24 | GC_fullcollect() 25 | -------------------------------------------------------------------------------- /examples/abstractitemmodel/main.nim.cfg: -------------------------------------------------------------------------------- 1 | --path:"../../src" 2 | -------------------------------------------------------------------------------- /examples/abstractitemmodel/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.8 2 | import QtQuick.Controls 2.3 3 | 4 | ApplicationWindow { 5 | width: 400 6 | height: 300 7 | title: "AbstractItemModel" 8 | 9 | Component.onCompleted: visible = true 10 | 11 | Component { 12 | id: myListModelDelegate 13 | Label { text: "Name:" + name } 14 | } 15 | 16 | ListView { 17 | anchors.fill: parent 18 | model: myListModel 19 | delegate: myListModelDelegate 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/abstractitemmodel/mylistmodel.nim: -------------------------------------------------------------------------------- 1 | import NimQml, Tables 2 | 3 | type 4 | RoleNames {.pure.} = enum 5 | Name = UserRole + 1, 6 | 7 | QtObject: 8 | type 9 | MyListModel* = ref object of QAbstractListModel 10 | names*: seq[string] 11 | 12 | proc delete(self: MyListModel) = 13 | self.QAbstractListModel.delete 14 | 15 | proc setup(self: MyListModel) = 16 | self.QAbstractListModel.setup 17 | 18 | proc newMyListModel*(): MyListModel = 19 | new(result, delete) 20 | result.names = @["John", "Max", "Paul", "Anna"] 21 | result.setup 22 | 23 | method rowCount(self: MyListModel, index: QModelIndex = nil): int = 24 | return self.names.len 25 | 26 | method data(self: MyListModel, index: QModelIndex, role: int): QVariant = 27 | if not index.isValid: 28 | return 29 | if index.row < 0 or index.row >= self.names.len: 30 | return 31 | return newQVariant(self.names[index.row]) 32 | 33 | method roleNames(self: MyListModel): Table[int, string] = 34 | { RoleNames.Name.int:"name"}.toTable 35 | -------------------------------------------------------------------------------- /examples/charts/.gitignore: -------------------------------------------------------------------------------- 1 | main 2 | nimcache -------------------------------------------------------------------------------- /examples/charts/charts.nimble: -------------------------------------------------------------------------------- 1 | [Package] 2 | bin = "main" 3 | name = "charts" 4 | version = "0.1.0" 5 | author = "Filippo Cucchetto" 6 | description = "charts" 7 | license = "MIT" 8 | 9 | [Deps] 10 | Requires: "nim >= 1.0.0, nimqml >= 0.7.7" 11 | 12 | -------------------------------------------------------------------------------- /examples/charts/main.nim: -------------------------------------------------------------------------------- 1 | import NimQml, mylistmodel 2 | 3 | proc mainProc() = 4 | echo "Starting" 5 | var app = newQApplication() 6 | defer: app.delete 7 | 8 | var myListModel = newMyListModel(); 9 | defer: myListModel.delete 10 | 11 | var engine = newQQmlApplicationEngine() 12 | defer: engine.delete 13 | 14 | var variant = newQVariant(myListModel) 15 | defer: variant.delete 16 | 17 | engine.setRootContextProperty("myListModel", variant) 18 | engine.load("main.qml") 19 | 20 | app.exec() 21 | 22 | when isMainModule: 23 | mainProc() 24 | GC_fullcollect() 25 | -------------------------------------------------------------------------------- /examples/charts/main.nim.cfg: -------------------------------------------------------------------------------- 1 | --path:"../../src" 2 | -------------------------------------------------------------------------------- /examples/charts/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.8 2 | import QtCharts 2.2 3 | import QtQuick.Layouts 1.3 4 | import QtQuick.Controls 2.3 5 | 6 | ApplicationWindow { 7 | width: 400 8 | height: 300 9 | title: "Charts" 10 | 11 | Component.onCompleted: visible = true 12 | 13 | ColumnLayout { 14 | anchors.fill: parent 15 | 16 | ChartView { 17 | id: view 18 | 19 | Layout.fillHeight: true 20 | Layout.fillWidth: true 21 | 22 | VXYModelMapper { 23 | id: mapper 24 | model: myListModel 25 | series: lineSeries 26 | xColumn: 0 27 | yColumn: 1 28 | } 29 | 30 | LineSeries { 31 | id: lineSeries 32 | name: "LineSeries" 33 | axisX: ValueAxis { 34 | min: 0 35 | max: myListModel.maxX 36 | } 37 | axisY: ValueAxis { 38 | min: 0 39 | max: myListModel.maxY 40 | } 41 | } 42 | } 43 | 44 | RowLayout { 45 | Layout.fillWidth: true 46 | 47 | Button { 48 | text: "Add random point" 49 | onClicked: myListModel.addRandomPoint() 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /examples/charts/mylistmodel.nim: -------------------------------------------------------------------------------- 1 | import NimQml, Tables, random 2 | 3 | type 4 | Point = object 5 | x: int 6 | y: int 7 | 8 | QtObject: 9 | type 10 | MyListModel* = ref object of QAbstractTableModel 11 | points*: seq[Point] 12 | maxX: int 13 | maxY: int 14 | 15 | proc delete(self: MyListModel) = 16 | self.QAbstractTableModel.delete 17 | 18 | proc setup(self: MyListModel) = 19 | self.QAbstractTableModel.setup 20 | 21 | method rowCount(self: MyListModel, index: QModelIndex = nil): int = 22 | return self.points.len 23 | 24 | method columnCount(self: MyListModel, index: QModelIndex = nil): int = 25 | return 2 26 | 27 | method data(self: MyListModel, index: QModelIndex, role: int): QVariant = 28 | result = nil 29 | if not index.isValid or index.row < 0 or index.row >= self.rowCount() or index.column < 0 or index.column >= self.columnCount(): 30 | return 31 | if role == 0: 32 | let point = self.points[index.row] 33 | if index.column == 0: 34 | return newQVariant(point.x) 35 | elif index.column == 1: 36 | return newQVariant(point.y) 37 | 38 | proc getMaxY(self: MyListModel): int {.slot.} = 39 | return self.maxY 40 | 41 | proc maxYChanged(self: MyListModel, value: int) {.signal.} 42 | 43 | QtProperty[int] maxY: 44 | read = getMaxY 45 | notify = maxYChanged 46 | 47 | proc getMaxX(self: MyListModel): int {.slot.} = 48 | return self.maxX 49 | 50 | proc maxXChanged(self: MyListModel, value: int) {.signal.} 51 | 52 | QtProperty[int] maxX: 53 | read = getMaxX 54 | notify = maxXChanged 55 | 56 | proc addRandomPoint(self: MyListModel) {.slot.} = 57 | let pos = self.points.len 58 | self.beginInsertRows(newQModelIndex(), pos, pos) 59 | let x = self.maxX + 1 60 | let y = random(50) 61 | if x > self.maxX: 62 | self.maxX = x 63 | self.maxXChanged(x) 64 | if y > self.maxY: 65 | self.maxY = y 66 | self.maxYChanged(y) 67 | self.points.add(Point(x: x, y: y)) 68 | self.endInsertRows() 69 | 70 | proc newMyListModel*(): MyListModel = 71 | new(result, delete) 72 | result.setup 73 | result.points = @[] 74 | result.maxX = 0 75 | result.maxY = 50 76 | result.addRandomPoint() 77 | -------------------------------------------------------------------------------- /examples/contactapp/.gitignore: -------------------------------------------------------------------------------- 1 | main 2 | nimcache -------------------------------------------------------------------------------- /examples/contactapp/applicationlogic.nim: -------------------------------------------------------------------------------- 1 | import NimQml, contactlist 2 | 3 | QtObject: 4 | type ApplicationLogic* = ref object of QObject 5 | contactList: ContactList 6 | app: QApplication 7 | 8 | proc delete*(self: ApplicationLogic) = 9 | self.QObject.delete 10 | self.contactList.delete 11 | 12 | proc setup(self: ApplicationLogic) = 13 | self.QObject.setup 14 | 15 | proc newApplicationLogic*(app: QApplication): ApplicationLogic = 16 | new(result) 17 | result.contactList = newContactList() 18 | result.app = app 19 | result.setup() 20 | 21 | proc getContactList(self: ApplicationLogic): QVariant {.slot.} = 22 | return newQVariant(self.contactList) 23 | 24 | proc onLoadTriggered(self: ApplicationLogic) {.slot.} = 25 | echo "Load Triggered" 26 | self.contactList.add("John", "Doo") 27 | 28 | proc onSaveTriggered(self: ApplicationLogic) {.slot.} = 29 | echo "Save Triggered" 30 | 31 | proc onExitTriggered(self: ApplicationLogic) {.slot.} = 32 | self.app.quit 33 | 34 | QtProperty[QVariant] contactList: 35 | read = getContactList 36 | -------------------------------------------------------------------------------- /examples/contactapp/contact.nim: -------------------------------------------------------------------------------- 1 | import NimQml 2 | 3 | QtObject: 4 | type Contact* = ref object of QObject 5 | name: string 6 | surname: string 7 | 8 | proc delete*(self: Contact) = 9 | self.QObject.delete 10 | 11 | proc setup(self: Contact) = 12 | self.QObject.setup 13 | 14 | proc newContact*(): Contact = 15 | new(result) 16 | result.name = "" 17 | result.setup 18 | 19 | proc firstName*(self: Contact): string {.slot.} = 20 | result = self.name 21 | 22 | proc firstNameChanged*(self: Contact, firstName: string) {.signal.} 23 | 24 | proc setFirstName(self: Contact, name: string) {.slot.} = 25 | if self.name == name: return 26 | self.name = name 27 | self.firstNameChanged(name) 28 | 29 | proc `firstName=`*(self: Contact, name: string) = self.setFirstName(name) 30 | 31 | QtProperty[string] firstName: 32 | read = firstName 33 | write = setFirstName 34 | notify = firstNameChanged 35 | 36 | proc surname*(self: Contact): string {.slot.} = 37 | result = self.surname 38 | 39 | proc surnameChanged*(self: Contact, surname: string) {.signal.} 40 | 41 | proc setSurname(self: Contact, surname: string) {.slot.} = 42 | if self.surname == surname: return 43 | self.surname = surname 44 | self.surnameChanged(surname) 45 | 46 | proc `surname=`*(self: Contact, surname: string) = self.setSurname(surname) 47 | 48 | QtProperty[string] surname: 49 | read = surname 50 | write = setSurname 51 | notify = surnameChanged 52 | -------------------------------------------------------------------------------- /examples/contactapp/contactapp.nimble: -------------------------------------------------------------------------------- 1 | [Package] 2 | bin = "main" 3 | name = "contactapp" 4 | version = "0.1.0" 5 | author = "Filippo Cucchetto" 6 | description = "contactapp" 7 | license = "MIT" 8 | 9 | [Deps] 10 | Requires: "nim >= 1.0.0, nimqml >= 0.7.7" 11 | -------------------------------------------------------------------------------- /examples/contactapp/contactlist.nim: -------------------------------------------------------------------------------- 1 | import NimQml, contact, Tables 2 | 3 | type 4 | ContactRoles {.pure.} = enum 5 | FirstName = UserRole + 1 6 | Surname = UserRole + 2 7 | 8 | QtObject: 9 | type 10 | ContactList* = ref object of QAbstractListModel 11 | contacts*: seq[Contact] 12 | 13 | proc delete(self: ContactList) = 14 | self.QAbstractListModel.delete 15 | for contact in self.contacts: 16 | contact.delete 17 | self.contacts = @[] 18 | 19 | proc setup(self: ContactList) = 20 | self.QAbstractListModel.setup 21 | 22 | proc newContactList*(): ContactList = 23 | new(result, delete) 24 | result.contacts = @[] 25 | result.setup 26 | 27 | method rowCount(self: ContactList, index: QModelIndex = nil): int = 28 | return self.contacts.len 29 | 30 | method data(self: ContactList, index: QModelIndex, role: int): QVariant = 31 | if not index.isValid: 32 | return 33 | if index.row < 0 or index.row >= self.contacts.len: 34 | return 35 | let contact = self.contacts[index.row] 36 | let contactRole = role.ContactRoles 37 | case contactRole: 38 | of ContactRoles.FirstName: result = newQVariant(contact.firstName) 39 | of ContactRoles.Surname: result = newQVariant(contact.surname) 40 | 41 | method roleNames(self: ContactList): Table[int, string] = 42 | { ContactRoles.FirstName.int:"firstName", 43 | ContactRoles.Surname.int:"surname"}.toTable 44 | 45 | proc add*(self: ContactList, name: string, surname: string) {.slot.} = 46 | let contact = newContact() 47 | contact.firstName = name 48 | contact.surname = surname 49 | self.beginInsertRows(newQModelIndex(), self.contacts.len, self.contacts.len) 50 | self.contacts.add(contact) 51 | self.endInsertRows() 52 | 53 | proc del*(self: ContactList, pos: int) {.slot.} = 54 | if pos < 0 or pos >= self.contacts.len: 55 | return 56 | self.beginRemoveRows(newQModelIndex(), pos, pos) 57 | self.contacts.del(pos) 58 | self.endRemoveRows 59 | -------------------------------------------------------------------------------- /examples/contactapp/main.nim: -------------------------------------------------------------------------------- 1 | import NimQml 2 | import applicationlogic 3 | 4 | proc mainProc() = 5 | let app = newQApplication() 6 | defer: app.delete 7 | 8 | let logic = newApplicationLogic(app) 9 | defer: logic.delete 10 | 11 | let engine = newQQmlApplicationEngine() 12 | defer: engine.delete 13 | 14 | let logicVariant = newQVariant(logic) 15 | defer: logicVariant.delete 16 | 17 | engine.setRootContextProperty("logic", logicVariant) 18 | engine.load("main.qml") 19 | app.exec() 20 | 21 | when isMainModule: 22 | mainProc() 23 | GC_fullcollect() 24 | -------------------------------------------------------------------------------- /examples/contactapp/main.nim.cfg: -------------------------------------------------------------------------------- 1 | --path:"../../src" 2 | -------------------------------------------------------------------------------- /examples/contactapp/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.3 2 | import QtQuick.Controls 1.3 3 | import QtQuick.Controls 2.3 4 | import QtQuick.Layouts 1.3 5 | 6 | ApplicationWindow { 7 | width: 500 8 | height: 300 9 | title: "ContactApp" 10 | visible: true 11 | 12 | menuBar: MenuBar { 13 | Menu { 14 | title: "&File" 15 | MenuItem { text: "&Load"; onTriggered: logic.onLoadTriggered() } 16 | MenuItem { text: "&Save"; onTriggered: logic.onSaveTriggered() } 17 | MenuItem { text: "&Exit"; onTriggered: logic.onExitTriggered() } 18 | } 19 | } 20 | 21 | ColumnLayout { 22 | anchors.fill: parent 23 | 24 | Component { 25 | id: tableTextDelegate 26 | Label { 27 | id: tableTextDelegateInstance 28 | property var styleData: undefined 29 | states: State { 30 | when: styleData !== undefined 31 | PropertyChanges { 32 | target: tableTextDelegateInstance; 33 | text: styleData.value; 34 | color: styleData.textColor 35 | } 36 | } 37 | } 38 | } 39 | 40 | Component { 41 | id: tableButtonDelegate 42 | Button { 43 | id: tableButtonDelegateInstance 44 | property var styleData: undefined 45 | text: "Delete" 46 | onClicked: logic.contactList.del(styleData.row) 47 | } 48 | } 49 | 50 | Component { 51 | id: tableItemDelegate 52 | Loader { 53 | id: tableItemDelegateInstance 54 | sourceComponent: { 55 | if (styleData.column === 0 || styleData.column === 1) 56 | return tableTextDelegate 57 | else if (styleData.column === 2) 58 | return tableButtonDelegate 59 | else 60 | return tableTextDelegate 61 | } 62 | Binding { 63 | target: tableItemDelegateInstance.item 64 | property: "styleData" 65 | value: styleData 66 | } 67 | } 68 | } 69 | 70 | TableView { 71 | model: logic.contactList 72 | Layout.fillWidth: true 73 | Layout.fillHeight: true 74 | TableViewColumn { role: "firstName"; title: "FirstName"; width: 200 } 75 | TableViewColumn { role: "surname"; title: "LastName"; width: 200} 76 | TableViewColumn { width: 100; } 77 | itemDelegate: tableItemDelegate 78 | } 79 | 80 | RowLayout { 81 | Label { text: "FirstName" } 82 | TextField { id: nameTextField; Layout.fillWidth: true; text: "" } 83 | Label { text: "LastName" } 84 | TextField { id: surnameTextField; Layout.fillWidth: true; text: "" } 85 | Button { 86 | text: "Add" 87 | onClicked: logic.contactList.add(nameTextField.text, surnameTextField.text) 88 | enabled: nameTextField.text !== "" && surnameTextField.text !== "" 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /examples/helloworld/.gitignore: -------------------------------------------------------------------------------- 1 | main 2 | nimcache -------------------------------------------------------------------------------- /examples/helloworld/helloworld.nimble: -------------------------------------------------------------------------------- 1 | [Package] 2 | bin = "main" 3 | name = "helloworld" 4 | version = "0.1.0" 5 | author = "Filippo Cucchetto" 6 | description = "helloworld" 7 | license = "MIT" 8 | 9 | [Deps] 10 | Requires: "nim >= 1.0.0, nimqml >= 0.7.7" 11 | -------------------------------------------------------------------------------- /examples/helloworld/main.nim: -------------------------------------------------------------------------------- 1 | import NimQml 2 | import macros 3 | import typeinfo 4 | 5 | proc mainProc() = 6 | var app = newQApplication() 7 | defer: app.delete() 8 | 9 | var engine = newQQmlApplicationEngine() 10 | defer: engine.delete() 11 | 12 | engine.load("main.qml") 13 | app.exec() 14 | 15 | when isMainModule: 16 | mainProc() 17 | GC_fullcollect() 18 | -------------------------------------------------------------------------------- /examples/helloworld/main.nim.cfg: -------------------------------------------------------------------------------- 1 | --path:"../../src" 2 | -------------------------------------------------------------------------------- /examples/helloworld/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import QtQuick.Controls 1.2 3 | import QtQuick.Layouts 1.1 4 | import QtQuick.Window 2.1 5 | 6 | ApplicationWindow { 7 | width: 400 8 | height: 300 9 | title: "Hello World" 10 | Component.onCompleted: visible = true 11 | } 12 | -------------------------------------------------------------------------------- /examples/qmlregistertype/.gitignore: -------------------------------------------------------------------------------- 1 | main 2 | nimcache -------------------------------------------------------------------------------- /examples/qmlregistertype/contact.nim: -------------------------------------------------------------------------------- 1 | import NimQml 2 | 3 | QtObject: 4 | type Contact* = ref object of QObject 5 | firstName: string 6 | lastName: string 7 | 8 | proc delete*(self: Contact) = 9 | self.QObject.delete 10 | 11 | proc setup(self: Contact) = 12 | self.QObject.setup 13 | 14 | proc newContact*(): Contact = 15 | new(result) 16 | result.firstName = "" 17 | result.lastName = "" 18 | result.setup 19 | 20 | proc firstName*(self: Contact): string {.slot.} = 21 | result = self.firstName 22 | 23 | proc firstNameChanged*(self: Contact) {.signal.} 24 | 25 | proc setFirstName(self: Contact, firstName: string) {.slot.} = 26 | if self.firstName == firstName: return 27 | self.firstName = firstName 28 | self.firstNameChanged() 29 | 30 | proc `firstName=`*(self: Contact, firstName: string) = self.setFirstName(firstName) 31 | 32 | QtProperty[string] firstName: 33 | read = firstName 34 | write = setFirstName 35 | notify = firstNameChanged 36 | 37 | proc lastName*(self: Contact): string {.slot.} = 38 | result = self.lastName 39 | 40 | proc lastNameChanged*(self: Contact) {.signal.} 41 | 42 | proc setLastName(self: Contact, lastName: string) {.slot.} = 43 | if self.lastName == lastName: return 44 | self.lastName = lastName 45 | self.lastNameChanged() 46 | 47 | proc `lastName=`*(self: Contact, lastName: string) = self.setLastName(lastName) 48 | 49 | QtProperty[string] lastName: 50 | read = lastName 51 | write = setLastName 52 | notify = lastNameChanged 53 | -------------------------------------------------------------------------------- /examples/qmlregistertype/main.nim: -------------------------------------------------------------------------------- 1 | import NimQml 2 | import contact 3 | import macros 4 | 5 | proc mainProc() = 6 | var app = newQApplication() 7 | defer: app.delete() 8 | 9 | let id = qmlRegisterType("ContactModule", 1, 0, "Contact", proc(): Contact = newContact()); 10 | 11 | var engine = newQQmlApplicationEngine() 12 | defer: engine.delete() 13 | 14 | engine.load("main.qml") 15 | app.exec() 16 | 17 | when isMainModule: 18 | mainProc() 19 | GC_fullcollect() 20 | -------------------------------------------------------------------------------- /examples/qmlregistertype/main.nim.cfg: -------------------------------------------------------------------------------- 1 | --path:"../../src" 2 | -------------------------------------------------------------------------------- /examples/qmlregistertype/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.8 2 | import QtQuick.Controls 2.3 3 | import QtQuick.Layouts 1.3 4 | import ContactModule 1.0 5 | 6 | ApplicationWindow { 7 | width: 400 8 | height: 300 9 | title: "qmlregistertype" 10 | 11 | Component.onCompleted: visible = true 12 | 13 | Contact { 14 | id: contact 15 | firstName: "John" 16 | lastName: "Doo" 17 | } 18 | 19 | Label { 20 | anchors.centerIn: parent; 21 | text: contact.firstName + " " + contact.lastName 22 | } 23 | 24 | RowLayout { 25 | anchors { left: parent.left; right: parent.right; bottom: parent.bottom } 26 | Item { Layout.fillWidth: true } 27 | Label { text: "FirstName:" } 28 | TextField { Layout.preferredWidth: 100; onEditingFinished: contact.firstName = text } 29 | Item { width: 30 } 30 | Label { text: "LastName: " } 31 | TextField { Layout.preferredWidth: 100; onEditingFinished: contact.lastName = text } 32 | Item { Layout.fillWidth: true } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/qmlregistertype/qmlregistertype.nimble: -------------------------------------------------------------------------------- 1 | [Package] 2 | bin = "main" 3 | name = "qmlregistertype" 4 | version = "0.1.0" 5 | author = "Filippo Cucchetto" 6 | description = "qmlregistertype" 7 | license = "MIT" 8 | 9 | [Deps] 10 | Requires: "nim >= 1.0.0, nimqml >= 0.7.7" 11 | -------------------------------------------------------------------------------- /examples/resourcebundling/.gitignore: -------------------------------------------------------------------------------- 1 | nimcache 2 | main 3 | *.rcc -------------------------------------------------------------------------------- /examples/resourcebundling/main.nim: -------------------------------------------------------------------------------- 1 | import nimqml 2 | 3 | proc mainProc() = 4 | let app = newQApplication() 5 | defer: app.delete 6 | let engine = newQQmlApplicationEngine() 7 | defer: engine.delete 8 | let appDirPath = app.applicationDirPath & "/" & "main.rcc" 9 | QResource.registerResource(appDirPath) 10 | engine.load(newQUrl("qrc:///main.qml")) 11 | 12 | app.exec() 13 | 14 | when isMainModule: 15 | mainProc() 16 | GC_fullcollect() 17 | -------------------------------------------------------------------------------- /examples/resourcebundling/main.nim.cfg: -------------------------------------------------------------------------------- 1 | --path:"../../src" 2 | -------------------------------------------------------------------------------- /examples/resourcebundling/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.8 2 | import QtQuick.Controls 2.3 3 | 4 | ApplicationWindow { 5 | width: 400 6 | height: 300 7 | title: "Hello World" 8 | Component.onCompleted: visible = true 9 | } 10 | -------------------------------------------------------------------------------- /examples/resourcebundling/resourcebundling.nimble: -------------------------------------------------------------------------------- 1 | # Package 2 | 3 | version = "0.1.0" 4 | author = "Filippo Cucchetto" 5 | description = "resourcebundling" 6 | license = "MIT" 7 | 8 | bin = @["main"] 9 | 10 | # Dependencies 11 | 12 | requires @["nim >= 1.0.0", "nimqml >= 0.7.7"] 13 | 14 | task build, "Compile the binary": 15 | exec ("nim c main") 16 | 17 | before build: 18 | exec ("rcc --binary resources.qrc -o main.rcc") 19 | -------------------------------------------------------------------------------- /examples/resourcebundling/resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | main.qml 5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/simpledata/.gitignore: -------------------------------------------------------------------------------- 1 | main 2 | nimcache -------------------------------------------------------------------------------- /examples/simpledata/main.nim: -------------------------------------------------------------------------------- 1 | import NimQml 2 | import macros 3 | import typeinfo 4 | 5 | proc mainProc() = 6 | var app = newQApplication() 7 | defer: app.delete() 8 | 9 | var engine = newQQmlApplicationEngine() 10 | defer: engine.delete() 11 | 12 | var qVar1 = newQVariant(10) 13 | defer: qVar1.delete() 14 | 15 | var qVar2 = newQVariant("Hello World") 16 | defer: qVar2.delete() 17 | 18 | var qVar3 = newQVariant(false) 19 | defer: qVar3.delete() 20 | 21 | var qVar4 = newQVariant(3.5.float) 22 | defer: qVar4.delete() 23 | 24 | engine.setRootContextProperty("qVar1", qVar1) 25 | engine.setRootContextProperty("qVar2", qVar2) 26 | engine.setRootContextProperty("qVar3", qVar3) 27 | engine.setRootContextProperty("qVar4", qVar4) 28 | engine.load("main.qml") 29 | app.exec() 30 | 31 | when isMainModule: 32 | mainProc() 33 | GC_fullcollect() 34 | -------------------------------------------------------------------------------- /examples/simpledata/main.nim.cfg: -------------------------------------------------------------------------------- 1 | --path:"../../src" 2 | -------------------------------------------------------------------------------- /examples/simpledata/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.8 2 | import QtQuick.Controls 2.3 3 | import QtQuick.Layouts 1.3 4 | 5 | ApplicationWindow { 6 | width: 400 7 | height: 300 8 | title: "SimpleData" 9 | 10 | Component.onCompleted: visible = true 11 | 12 | ColumnLayout { 13 | anchors.fill: parent 14 | SpinBox { value: qVar1} 15 | TextField { text: qVar2} 16 | CheckBox { checked: qVar3} 17 | SpinBox { value: qVar4 } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/simpledata/simpledata.nimble: -------------------------------------------------------------------------------- 1 | [Package] 2 | bin = "main" 3 | name = "simpledata" 4 | version = "0.1.0" 5 | author = "Filippo Cucchetto" 6 | description = "simpledata" 7 | license = "MIT" 8 | 9 | [Deps] 10 | Requires: "nim >= 1.0.0, nimqml >= 0.7.7" 11 | 12 | -------------------------------------------------------------------------------- /examples/slotsandproperties/.gitignore: -------------------------------------------------------------------------------- 1 | main 2 | nimcache -------------------------------------------------------------------------------- /examples/slotsandproperties/contact.nim: -------------------------------------------------------------------------------- 1 | import NimQml 2 | 3 | QtObject: 4 | type Contact* = ref object of QObject 5 | m_name: string 6 | 7 | proc delete*(self: Contact) = 8 | self.QObject.delete 9 | 10 | proc setup(self: Contact) = 11 | self.QObject.setup 12 | 13 | proc newContact*(): Contact = 14 | new(result, delete) 15 | result.m_name = "InitialName" 16 | result.setup 17 | 18 | proc getName*(self: Contact): string {.slot.} = 19 | result = self.m_name 20 | 21 | proc nameChanged*(self: Contact, name: string) {.signal.} 22 | 23 | proc setName*(self: Contact, name: string) {.slot.} = 24 | if self.m_name == name: 25 | return 26 | self.m_name = name 27 | self.nameChanged(name) 28 | 29 | QtProperty[string] name: 30 | read = getName 31 | write = setName 32 | notify = nameChanged 33 | -------------------------------------------------------------------------------- /examples/slotsandproperties/main.nim: -------------------------------------------------------------------------------- 1 | import NimQml 2 | import contact 3 | 4 | proc mainProc() = 5 | var app = newQApplication() 6 | defer: app.delete() 7 | 8 | var contact = newContact() 9 | defer: contact.delete() 10 | 11 | var engine = newQQmlApplicationEngine() 12 | defer: engine.delete() 13 | 14 | var variant = newQVariant(contact) 15 | defer: variant.delete() 16 | 17 | engine.setRootContextProperty("contact", variant) 18 | engine.load("main.qml") 19 | app.exec() 20 | 21 | when isMainModule: 22 | mainProc() 23 | GC_fullcollect() 24 | -------------------------------------------------------------------------------- /examples/slotsandproperties/main.nim.cfg: -------------------------------------------------------------------------------- 1 | --path:"../../src" 2 | -------------------------------------------------------------------------------- /examples/slotsandproperties/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.8 2 | import QtQuick.Controls 2.3 3 | import QtQuick.Layouts 1.3 4 | 5 | ApplicationWindow { 6 | width: 400 7 | height: 300 8 | 9 | Component.onCompleted: visible = true 10 | 11 | ColumnLayout { 12 | anchors.fill: parent 13 | 14 | Label { text: "Current name is:" + contact.name } 15 | 16 | TextField { id: textField } 17 | 18 | Button { 19 | text: "Change Name" 20 | onClicked: contact.name = textField.text 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/slotsandproperties/slotsandproperties.nimble: -------------------------------------------------------------------------------- 1 | [Package] 2 | bin = "main" 3 | name = "slotsandproperties" 4 | version = "0.1.0" 5 | author = "Filippo Cucchetto" 6 | description = "slotsandproperties" 7 | license = "MIT" 8 | 9 | [Deps] 10 | Requires: "nim >= 1.0.0, nimqml >= 0.7.7" 11 | -------------------------------------------------------------------------------- /nimqml.nimble: -------------------------------------------------------------------------------- 1 | [Package] 2 | name = "nimqml" 3 | version = "0.7.7" 4 | author = "Filippo Cucchetto" 5 | description = "QML bindings for Nim" 6 | license = "LGPLv3" 7 | srcDir = "src" 8 | 9 | [Deps] 10 | Requires: "nim >= 1.0.0" 11 | -------------------------------------------------------------------------------- /src/nimqml.nim: -------------------------------------------------------------------------------- 1 | ## NimQml aims to provide binding to the QML for the Nim programming language 2 | 3 | template debugMsg(message: string) = 4 | echo "NimQml: ", message 5 | 6 | template debugMsg(typeName: string, procName: string) = 7 | when defined(debugNimQml): 8 | var message = typeName 9 | message &= ": " 10 | message &= procName 11 | debugMsg(message) 12 | 13 | import os 14 | 15 | include "nimqml/private/dotherside.nim" 16 | include "nimqml/private/nimqmltypes.nim" 17 | include "nimqml/private/qmetaobject.nim" 18 | include "nimqml/private/qnetworkconfigurationmanager.nim" 19 | include "nimqml/private/qvariant.nim" 20 | include "nimqml/private/qobject.nim" 21 | include "nimqml/private/qqmlapplicationengine.nim" 22 | include "nimqml/private/qguiapplication.nim" 23 | include "nimqml/private/qurl.nim" 24 | include "nimqml/private/qquickview.nim" 25 | include "nimqml/private/qhashintbytearray.nim" 26 | include "nimqml/private/qmodelindex.nim" 27 | include "nimqml/private/qabstractitemmodel.nim" 28 | include "nimqml/private/qabstractlistmodel.nim" 29 | include "nimqml/private/qabstracttablemodel.nim" 30 | include "nimqml/private/qresource.nim" 31 | include "nimqml/private/qdeclarative.nim" 32 | include "nimqml/private/qsettings.nim" 33 | include "nimqml/private/qtimer.nim" 34 | include "nimqml/private/nimqmlmacros.nim" 35 | include "nimqml/private/singleinstance.nim" 36 | include "nimqml/private/status/statusevent.nim" 37 | include "nimqml/private/status/statusosnotification.nim" 38 | include "nimqml/private/status/statuskeychainmanager.nim" 39 | 40 | proc signal_handler*(receiver: pointer, signal: cstring, slot: cstring) = 41 | var dosqobj = cast[DosQObject](receiver) 42 | if(dosqobj.isNil == false): 43 | dos_signal(receiver, signal, slot) 44 | 45 | proc plain_text*(htmlString: string): string = 46 | let plainText = dos_plain_text(htmlString.cstring) 47 | defer: dos_chararray_delete(plainText) 48 | result = $(plainText) 49 | 50 | proc escape_html*(input: string): string = 51 | let escapedHtml = dos_escape_html(input.cstring) 52 | defer: dos_chararray_delete(escapedHtml) 53 | result = $(escapedHtml) 54 | 55 | proc url_fromUserInput*(input: string): string = 56 | let urlStr = dos_qurl_fromUserInput(input.cstring) 57 | defer: dos_chararray_delete(urlStr) 58 | result = $(urlStr) 59 | 60 | proc url_host*(host: string): string = 61 | let qurlHost = dos_qurl_host(host.cstring) 62 | defer: dos_chararray_delete(qurlHost) 63 | result = $(qurlHost) 64 | 65 | proc url_replaceHostAndAddPath*(url: string, newHost: string, protocol: string = "", pathPrefix: string = ""): string = 66 | let newUrl = dos_qurl_replaceHostAndAddPath(url.cstring, protocol.cstring, newHost.cstring, pathPrefix.cstring) 67 | defer: dos_chararray_delete(newUrl) 68 | result = $(newUrl) 69 | 70 | proc url_toLocalFile*(fileUrl: string): string = 71 | let filePath = dos_to_local_file(fileUrl.cstring) 72 | defer: dos_chararray_delete(filePath) 73 | result = $(filePath) 74 | 75 | proc url_fromLocalFile*(filePath: string): string = 76 | let url = dos_from_local_file(filePath.cstring) 77 | defer: dos_chararray_delete(url) 78 | result = $(url) 79 | 80 | proc app_isActive*(engine: QQmlApplicationEngine): bool = 81 | result = dos_app_is_active(engine.vptr) 82 | 83 | proc app_makeItActive*(engine: QQmlApplicationEngine) = 84 | dos_app_make_it_active(engine.vptr) 85 | -------------------------------------------------------------------------------- /src/nimqml/private/dotherside.nim: -------------------------------------------------------------------------------- 1 | import strutils 2 | 3 | const dynLibName = 4 | case system.hostOS: 5 | of "windows": 6 | "DOtherSide.dll" 7 | of "macosx": 8 | "libDOtherSide.dylib" 9 | else: 10 | "libDOtherSide.so.0.6" 11 | 12 | type 13 | NimQObject = pointer 14 | NimQAbstractItemModel = pointer 15 | NimQAbstractListModel = pointer 16 | NimQAbstractTableModel = pointer 17 | DosQMetaObject = distinct pointer 18 | DosQObject = distinct pointer 19 | DosQQNetworkAccessManagerFactory = pointer 20 | DosQQNetworkAccessManager = distinct DosQObject 21 | DosQObjectWrapper = distinct pointer 22 | DosQVariant = distinct pointer 23 | DosQQmlContext = distinct pointer 24 | DosQQmlApplicationEngine = distinct pointer 25 | DosQVariantArray = UncheckedArray[DosQVariant] 26 | DosQMetaType = cint 27 | DosQMetaTypeArray = UncheckedArray[DosQMetaType] 28 | DosQUrl = distinct pointer 29 | DosQQuickView = distinct pointer 30 | DosQHashIntByteArray = distinct pointer 31 | DosQModelIndex = distinct pointer 32 | DosQAbstractItemModel = distinct pointer 33 | DosQAbstractTableModel = distinct pointer 34 | DosQAbstractListModel = distinct pointer 35 | DosStatusEvent = DosQObject 36 | DosStatusOSNotification = DosQObject 37 | DosQSettings = DosQObject 38 | DosStatusKeychainManager = DosQObject 39 | DosQTimer = DosQObject 40 | 41 | DosParameterDefinition = object 42 | name: cstring 43 | metaType: cint 44 | 45 | DosSignalDefinition = object 46 | name: cstring 47 | parametersCount: cint 48 | parameters: pointer 49 | 50 | DosSignalDefinitions = object 51 | count: cint 52 | definitions: pointer 53 | 54 | DosSlotDefinition = object 55 | name: cstring 56 | returnMetaType: cint 57 | parametersCount: cint 58 | parameters: pointer 59 | 60 | DosSlotDefinitions = object 61 | count: cint 62 | definitions: pointer 63 | 64 | DosPropertyDefinition = object 65 | name: cstring 66 | propertyMetaType: cint 67 | readSlot: cstring 68 | writeSlot: cstring 69 | notifySignal: cstring 70 | 71 | DosPropertyDefinitions = object 72 | count: cint 73 | definitions: pointer 74 | 75 | DosCreateCallback = proc(id: cint, wrapper: DosQObjectWrapper, nimQObject: var NimQObject, dosQObject: var DosQObject) {.cdecl.} 76 | DosDeleteCallback = proc(id: cint, nimQObject: NimQObject) {.cdecl.} 77 | 78 | DosQmlRegisterType = object 79 | major: cint 80 | minor: cint 81 | uri: cstring 82 | qml: cstring 83 | staticMetaObject: DosQMetaObject 84 | createCallback: DosCreateCallback 85 | deleteCallback: DosDeleteCallback 86 | 87 | DosQObjectCallBack = proc(nimobject: NimQObject, slotName: DosQVariant, numArguments: cint, arguments: ptr DosQVariantArray) {.cdecl.} 88 | 89 | DosRowCountCallback = proc(nimmodel: NimQAbstractItemModel, rawIndex: DosQModelIndex, result: var cint) {.cdecl.} 90 | DosColumnCountCallback = proc(nimmodel: NimQAbstractItemModel, rawIndex: DosQModelIndex, result: var cint) {.cdecl.} 91 | DosDataCallback = proc(nimmodel: NimQAbstractItemModel, rawIndex: DosQModelIndex, role: cint, result: DosQVariant) {.cdecl.} 92 | DosSetDataCallback = proc(nimmodel: NimQAbstractItemModel, rawIndex: DosQModelIndex, value: DosQVariant, role: cint, result: var bool) {.cdecl.} 93 | DosRoleNamesCallback = proc(nimmodel: NimQAbstractItemModel, result: DosQHashIntByteArray) {.cdecl.} 94 | DosFlagsCallback = proc(nimmodel: NimQAbstractItemModel, index: DosQModelIndex, result: var cint) {.cdecl.} 95 | DosHeaderDataCallback = proc(nimmodel: NimQAbstractItemModel, section: cint, orientation: cint, role: cint, result: DosQVariant) {.cdecl.} 96 | DosIndexCallback = proc(nimmodel: NimQAbstractItemModel, row: cint, column: cint, parent: DosQModelIndex, result: DosQModelIndex) {.cdecl.} 97 | DosParentCallback = proc(nimmodel: NimQAbstractItemModel, child: DosQModelIndex, result: DosQModelIndex) {.cdecl.} 98 | DosHasChildrenCallback = proc(nimmodel: NimQAbstractItemModel, parent: DosQModelIndex, result: var bool) {.cdecl.} 99 | DosCanFetchMoreCallback = proc(nimmodel: NimQAbstractItemModel, parent: DosQModelIndex, result: var bool) {.cdecl.} 100 | DosFetchMoreCallback = proc(nimmodel: NimQAbstractItemModel, parent: DosQModelIndex) {.cdecl.} 101 | 102 | DosQAbstractItemModelCallbacks = object 103 | rowCount: DosRowCountCallback 104 | columnCount: DosColumnCountCallback 105 | data: DosDataCallback 106 | setData: DosSetDataCallback 107 | roleNames: DosRoleNamesCallback 108 | flags: DosFlagsCallback 109 | headerData: DosHeaderDataCallback 110 | index: DosIndexCallback 111 | parent: DosParentCallback 112 | hasChildren: DosHasChildrenCallback 113 | canFetchMore: DosCanFetchMoreCallback 114 | fetchMore: DosFetchMoreCallback 115 | 116 | DosMessageHandler = proc(messageType: cint, message: cstring, category: cstring, file: cstring, function: cstring, lint: cint) {.cdecl.} 117 | 118 | # Conversion 119 | proc resetToNil[T](x: var T) = x = nil.pointer.T 120 | proc isNil(x: DosQMetaObject): bool = x.pointer.isNil 121 | proc isNil(x: DosQVariant): bool = x.pointer.isNil 122 | proc isNil(x: DosQObject): bool = x.pointer.isNil 123 | proc isNil(x: DosQQmlApplicationEngine): bool = x.pointer.isNil 124 | proc isNil(x: DosQUrl): bool = x.pointer.isNil 125 | proc isNil(x: DosQQuickView): bool = x.pointer.isNil 126 | proc isNil(x: DosQHashIntByteArray): bool = x.pointer.isNil 127 | proc isNil(x: DosQModelIndex): bool = x.pointer.isNil 128 | 129 | # CharArray 130 | proc dos_chararray_delete(str: cstring) {.cdecl, dynlib: dynLibName, importc.} 131 | 132 | # QGuiApplication 133 | proc dos_qguiapplication_application_dir_path(): cstring {.cdecl, dynlib: dynLibName, importc.} 134 | proc dos_qguiapplication_enable_hdpi(uiScaleFilePath: cstring) {.cdecl, dynlib: dynLibName, importc.} 135 | proc dos_qguiapplication_initialize_opengl() {.cdecl, dynlib: dynLibName, importc.} 136 | proc dos_qtwebview_initialize() {.cdecl, dynlib: dynLibName, importc.} 137 | proc dos_qguiapplication_try_enable_threaded_renderer() {.cdecl, dynlib: dynLibName, importc.} 138 | proc dos_qguiapplication_create() {.cdecl, dynlib: dynLibName, importc.} 139 | proc dos_qguiapplication_exec() {.cdecl, dynlib: dynLibName, importc.} 140 | proc dos_qguiapplication_quit() {.cdecl, dynlib: dynLibName, importc.} 141 | proc dos_qguiapplication_restart() {.cdecl, dynlib: dynLibName, importc.} 142 | proc dos_qguiapplication_icon(filename: cstring) {.cdecl, dynlib: dynLibName, importc.} 143 | proc dos_qguiapplication_delete() {.cdecl, dynlib: dynLibName, importc.} 144 | 145 | proc dos_qguiapplication_clipboard_setText(content: cstring) {.cdecl, dynlib: dynLibName, importc.} 146 | proc dos_qguiapplication_clipboard_getText(): cstring {.cdecl, dynlib: dynLibName, importc.} 147 | proc dos_qguiapplication_installEventFilter(engine: DosStatusEvent) {.cdecl, dynlib: dynLibName, importc.} 148 | proc dos_qguiapplication_clipboard_setImage(content: cstring) {.cdecl, dynlib: dynLibName, importc.} 149 | proc dos_qguiapplication_download_image(imageSource: cstring, filePath: cstring) {.cdecl, dynlib: dynLibName, importc.} 150 | proc dos_qguiapplication_clipboard_setImageByUrl(url: cstring) {.cdecl, dynlib: dynLibName, importc.} 151 | proc dos_qguiapplication_download_imageByUrl(url: cstring, filePath: cstring) {.cdecl, dynlib: dynLibName, importc.} 152 | 153 | proc dos_add_self_signed_certificate(content: cstring) {.cdecl, dynlib: dynLibName, importc.} 154 | 155 | # QQmlContext 156 | proc dos_qqmlcontext_setcontextproperty(context: DosQQmlContext, propertyName: cstring, propertyValue: DosQVariant) {.cdecl, dynlib: dynLibName, importc.} 157 | 158 | # QQmlApplicationEngine 159 | proc dos_qqmlapplicationengine_create(): DosQQmlApplicationEngine {.cdecl, dynlib: dynLibName, importc.} 160 | proc dos_qqmlapplicationengine_getNetworkAccessManager(engine: DosQQmlApplicationEngine): DosQQNetworkAccessManager {.cdecl, dynlib: dynLibName, importc.} 161 | proc dos_qqmlapplicationengine_setNetworkAccessManagerFactory(engine: DosQQmlApplicationEngine, factory: DosQQNetworkAccessManagerFactory) {.cdecl, dynlib: dynLibName, importc.} 162 | proc dos_qqmlapplicationengine_load(engine: DosQQmlApplicationEngine, filename: cstring) {.cdecl, dynlib: dynLibName, importc.} 163 | proc dos_qqmlapplicationengine_load_url(engine: DosQQmlApplicationEngine, url: DosQUrl) {.cdecl, dynlib: dynLibName, importc.} 164 | proc dos_qqmlapplicationengine_load_data(engine: DosQQmlApplicationEngine, data: cstring) {.cdecl, dynlib: dynLibName, importc.} 165 | proc dos_qqmlapplicationengine_add_import_path(engine: DosQQmlApplicationEngine, path: cstring) {.cdecl, dynlib: dynLibName, importc.} 166 | proc dos_qqmlapplicationengine_context(engine: DosQQmlApplicationEngine): DosQQmlContext {.cdecl, dynlib: dynLibName, importc.} 167 | proc dos_qqmlapplicationengine_delete(engine: DosQQmlApplicationEngine) {.cdecl, dynlib: dynLibName, importc.} 168 | proc dos_qguiapplication_load_translation(engine: DosQQmlApplicationEngine, content: cstring, shouldRetranslate: bool) {.cdecl, dynlib: dynLibName, importc.} 169 | 170 | # QVariant 171 | proc dos_qvariant_create(): DosQVariant {.cdecl, dynlib: dynLibName, importc.} 172 | proc dos_qvariant_create_int(value: cint): DosQVariant {.cdecl, dynlib: dynLibName, importc.} 173 | proc dos_qvariant_create_uint(value: cuint): DosQVariant {.cdecl, dynlib: dynLibName, importc.} 174 | proc dos_qvariant_create_longlong(value: clonglong): DosQVariant {.cdecl, dynlib: dynLibName, importc.} 175 | proc dos_qvariant_create_ulonglong(value: culonglong): DosQVariant {.cdecl, dynlib: dynLibName, importc.} 176 | proc dos_qvariant_create_bool(value: bool): DosQVariant {.cdecl, dynlib: dynLibName, importc.} 177 | proc dos_qvariant_create_string(value: cstring): DosQVariant {.cdecl, dynlib: dynLibName, importc.} 178 | proc dos_qvariant_create_qobject(value: DosQObject): DosQVariant {.cdecl, dynlib: dynLibName, importc.} 179 | proc dos_qvariant_create_qvariant(value: DosQVariant): DosQVariant {.cdecl, dynlib: dynLibName, importc.} 180 | proc dos_qvariant_create_float(value: cfloat): DosQVariant {.cdecl, dynlib: dynLibName, importc.} 181 | proc dos_qvariant_create_double(value: cdouble): DosQVariant {.cdecl, dynlib: dynLibName, importc.} 182 | proc dos_qvariant_delete(variant: DosQVariant) {.cdecl, dynlib: dynLibName, importc.} 183 | proc dos_qvariant_isnull(variant: DosQVariant): bool {.cdecl, dynlib: dynLibName, importc.} 184 | proc dos_qvariant_toInt(variant: DosQVariant): cint {.cdecl, dynlib: dynLibName, importc.} 185 | proc dos_qvariant_toUInt(variant: DosQVariant): cuint {.cdecl, dynlib: dynLibName, importc.} 186 | proc dos_qvariant_toLongLong(variant: DosQVariant): clonglong {.cdecl, dynlib: dynLibName, importc.} 187 | proc dos_qvariant_toULongLong(variant: DosQVariant): culonglong {.cdecl, dynlib: dynLibName, importc.} 188 | proc dos_qvariant_toBool(variant: DosQVariant): bool {.cdecl, dynlib: dynLibName, importc.} 189 | proc dos_qvariant_toString(variant: DosQVariant): cstring {.cdecl, dynlib: dynLibName, importc.} 190 | proc dos_qvariant_toDouble(variant: DosQVariant): cdouble {.cdecl, dynlib: dynLibName, importc.} 191 | proc dos_qvariant_toFloat(variant: DosQVariant): cfloat {.cdecl, dynlib: dynLibName, importc.} 192 | proc dos_qvariant_setInt(variant: DosQVariant, value: cint) {.cdecl, dynlib: dynLibName, importc.} 193 | proc dos_qvariant_setUInt(variant: DosQVariant, value: cuint) {.cdecl, dynlib: dynLibName, importc.} 194 | proc dos_qvariant_setLongLong(variant: DosQVariant, value: clonglong) {.cdecl, dynlib: dynLibName, importc.} 195 | proc dos_qvariant_setULongLong(variant: DosQVariant, value: culonglong) {.cdecl, dynlib: dynLibName, importc.} 196 | proc dos_qvariant_setBool(variant: DosQVariant, value: bool) {.cdecl, dynlib: dynLibName, importc.} 197 | proc dos_qvariant_setString(variant: DosQVariant, value: cstring) {.cdecl, dynlib: dynLibName, importc.} 198 | proc dos_qvariant_assign(leftValue: DosQVariant, rightValue: DosQVariant) {.cdecl, dynlib: dynLibName, importc.} 199 | proc dos_qvariant_setFloat(variant: DosQVariant, value: cfloat) {.cdecl, dynlib: dynLibName, importc.} 200 | proc dos_qvariant_setDouble(variant: DosQVariant, value: cdouble) {.cdecl, dynlib: dynLibName, importc.} 201 | proc dos_qvariant_setQObject(variant: DosQVariant, value: DosQObject) {.cdecl, dynlib: dynLibName, importc.} 202 | 203 | # QObject 204 | proc dos_qobject_qmetaobject(): DosQMetaObject {.cdecl, dynlib: dynLibName, importc.} 205 | proc dos_qobject_create(nimobject: NimQObject, metaObject: DosQMetaObject, dosQObjectCallback: DosQObjectCallBack): DosQObject {.cdecl, dynlib: dynLibName, importc.} 206 | proc dos_qobject_objectName(qobject: DosQObject): cstring {.cdecl, dynlib: dynLibName, importc.} 207 | proc dos_qobject_setObjectName(qobject: DosQObject, name: cstring) {.cdecl, dynlib: dynLibName, importc.} 208 | proc dos_qobject_signal_emit(qobject: DosQObject, signalName: cstring, argumentsCount: cint, arguments: ptr DosQVariantArray) {.cdecl, dynlib: dynLibName, importc.} 209 | proc dos_qobject_delete(qobject: DosQObject) {.cdecl, dynlib: dynLibName, importc.} 210 | proc dos_qobject_signal_connect(sender: DosQObject, signalName: cstring, receiver: DosQObject, slot: cstring, signalType: cint) {.cdecl, dynlib: dynLibName, importc.} 211 | 212 | # QAbstractItemModel 213 | proc dos_qabstractitemmodel_qmetaobject(): DosQMetaObject {.cdecl dynlib: dynLibName, importc.} 214 | 215 | # QMetaObject 216 | proc dos_qmetaobject_create(superclassMetaObject: DosQMetaObject, 217 | className: cstring, 218 | signalDefinitions: ptr DosSignalDefinitions, 219 | slotDefinitions: ptr DosSlotDefinitions, 220 | propertyDefinitions: ptr DosPropertyDefinitions): DosQMetaObject {.cdecl, dynlib: dynLibName, importc.} 221 | proc dos_qmetaobject_delete(vptr: DosQMetaObject) {.cdecl, dynlib: dynLibName, importc.} 222 | 223 | # status-go signal handler 224 | proc dos_signal(vptr: pointer, signal: cstring, slot: cstring) {.cdecl, dynlib: dynLibName, importc.} 225 | 226 | # QUrl 227 | proc dos_qurl_create(url: cstring, parsingMode: cint): DosQUrl {.cdecl, dynlib: dynLibName, importc.} 228 | proc dos_qurl_delete(vptr: DosQUrl) {.cdecl, dynlib: dynLibName, importc.} 229 | proc dos_qurl_to_string(vptr: DosQUrl): cstring {.cdecl, dynlib: dynLibName, importc.} 230 | 231 | # QNetworkConfigurationManager 232 | proc dos_qncm_create(): DosQObject {.cdecl, dynlib: dynLibName, importc.} 233 | proc dos_qncm_delete(vptr: DosQObject) {.cdecl, dynlib: dynLibName, importc.} 234 | 235 | # QNetworkAccessManagerFactory 236 | proc dos_qqmlnetworkaccessmanagerfactory_create(tmpPath: cstring): DosQQNetworkAccessManagerFactory {.cdecl, dynlib: dynLibName, importc.} 237 | 238 | # QNetworkAccessManager 239 | proc dos_qqmlnetworkaccessmanager_clearconnectioncache(vptr: DosQQNetworkAccessManager) {.cdecl, dynlib: dynLibName, importc.} 240 | proc dos_qqmlnetworkaccessmanager_setnetworkaccessible(vptr: DosQQNetworkAccessManager, accessible: cint) {.cdecl, dynlib: dynLibName, importc.} 241 | 242 | # QQuickView 243 | proc dos_qquickview_create(): DosQQuickView {.cdecl, dynlib: dynLibName, importc.} 244 | proc dos_qquickview_delete(view: DosQQuickView) {.cdecl, dynlib: dynLibName, importc.} 245 | proc dos_qquickview_show(view: DosQQuickView) {.cdecl, dynlib: dynLibName, importc.} 246 | proc dos_qquickview_source(view: DosQQuickView): cstring {.cdecl, dynlib: dynLibName, importc.} 247 | proc dos_qquickview_set_source(view: DosQQuickView, filename: cstring) {.cdecl, dynlib: dynLibName, importc.} 248 | 249 | # QHash 250 | proc dos_qhash_int_qbytearray_create(): DosQHashIntByteArray {.cdecl, dynlib: dynLibName, importc.} 251 | proc dos_qhash_int_qbytearray_delete(qHash: DosQHashIntByteArray) {.cdecl, dynlib: dynLibName, importc.} 252 | proc dos_qhash_int_qbytearray_insert(qHash: DosQHashIntByteArray, key: int, value: cstring) {.cdecl, dynlib: dynLibName, importc.} 253 | proc dos_qhash_int_qbytearray_value(qHash: DosQHashIntByteArray, key: int): cstring {.cdecl, dynlib: dynLibName, importc.} 254 | 255 | # QModelIndex 256 | proc dos_qmodelindex_create(): DosQModelIndex {.cdecl, dynlib: dynLibName, importc.} 257 | proc dos_qmodelindex_create_qmodelindex(other: DosQModelIndex): DosQModelIndex {.cdecl, dynlib: dynLibName, importc.} 258 | proc dos_qmodelindex_delete(modelIndex: DosQModelIndex) {.cdecl, dynlib: dynLibName, importc.} 259 | proc dos_qmodelindex_row(modelIndex: DosQModelIndex): cint {.cdecl, dynlib: dynLibName, importc.} 260 | proc dos_qmodelindex_column(modelIndex: DosQModelIndex): cint {.cdecl, dynlib: dynLibName, importc.} 261 | proc dos_qmodelindex_isValid(modelIndex: DosQModelIndex): bool {.cdecl, dynlib: dynLibName, importc.} 262 | proc dos_qmodelindex_data(modelIndex: DosQModelIndex, role: cint): DosQVariant {.cdecl, dynlib: dynLibName, importc.} 263 | proc dos_qmodelindex_parent(modelIndex: DosQModelIndex): DosQModelIndex {.cdecl, dynlib: dynLibName, importc.} 264 | proc dos_qmodelindex_child(modelIndex: DosQModelIndex, row: cint, column: cint): DosQModelIndex {.cdecl, dynlib: dynLibName, importc.} 265 | proc dos_qmodelindex_sibling(modelIndex: DosQModelIndex, row: cint, column: cint): DosQModelIndex {.cdecl, dynlib: dynLibName, importc.} 266 | proc dos_qmodelindex_assign(leftSide: DosQModelIndex, rightSide: DosQModelIndex) {.cdecl, dynlib: dynLibName, importc.} 267 | proc dos_qmodelindex_internalPointer(modelIndex: DosQModelIndex): pointer {.cdecl, dynlib: dynLibName, importc.} 268 | 269 | # QAbstractItemModel 270 | proc dos_qabstractitemmodel_create(modelPtr: NimQAbstractItemModel, 271 | metaObject: DosQMetaObject, 272 | qobjectCallback: DosQObjectCallBack, 273 | qaimCallbacks: DosQAbstractItemModelCallbacks): DosQAbstractItemModel {.cdecl, dynlib: dynLibName, importc.} 274 | 275 | proc dos_qabstractitemmodel_beginInsertRows(model: DosQAbstractItemModel, 276 | parentIndex: DosQModelIndex, 277 | first: cint, 278 | last: cint) {.cdecl, dynlib: dynLibName, importc.} 279 | proc dos_qabstractitemmodel_endInsertRows(model: DosQAbstractItemModel) {.cdecl, dynlib: dynLibName, importc.} 280 | proc dos_qabstractitemmodel_beginRemoveRows(model: DosQAbstractItemModel, 281 | parentIndex: DosQModelIndex, 282 | first: cint, 283 | last: cint) {.cdecl, dynlib: dynLibName, importc.} 284 | proc dos_qabstractitemmodel_endRemoveRows(model: DosQAbstractItemModel) {.cdecl, dynlib: dynLibName, importc.} 285 | proc dos_qabstractitemmodel_beginMoveRows(model: DosQAbstractItemModel, 286 | sourceParentIndex: DosQModelIndex, sourceFirst: cint, sourceLast: cint, 287 | destParentIndex: DosQModelIndex, destinationChild: cint) {.cdecl, dynlib: dynLibName, importc.} 288 | proc dos_qabstractitemmodel_endMoveRows(model: DosQAbstractItemModel) {.cdecl, dynlib: dynLibName, importc.} 289 | proc dos_qabstractitemmodel_beginInsertColumns(model: DosQAbstractItemModel, 290 | parentIndex: DosQModelIndex, 291 | first: cint, 292 | last: cint) {.cdecl, dynlib: dynLibName, importc.} 293 | proc dos_qabstractitemmodel_endInsertColumns(model: DosQAbstractItemModel) {.cdecl, dynlib: dynLibName, importc.} 294 | proc dos_qabstractitemmodel_beginRemoveColumns(model: DosQAbstractItemModel, 295 | parentIndex: DosQModelIndex, 296 | first: cint, 297 | last: cint) {.cdecl, dynlib: dynLibName, importc.} 298 | proc dos_qabstractitemmodel_endRemoveColumns(model: DosQAbstractItemModel) {.cdecl, dynlib: dynLibName, importc.} 299 | proc dos_qabstractitemmodel_beginResetModel(model: DosQAbstractItemModel) {.cdecl, dynlib: dynLibName, importc.} 300 | proc dos_qabstractitemmodel_endResetModel(model: DosQAbstractItemModel) {.cdecl, dynlib: dynLibName, importc.} 301 | proc dos_qabstractitemmodel_dataChanged(model: DosQAbstractItemModel, 302 | parentLeft: DosQModelIndex, 303 | bottomRight: DosQModelIndex, 304 | rolesArrayPtr: ptr cint, 305 | rolesArrayLength: cint) {.cdecl, dynlib: dynLibName, importc.} 306 | proc dos_qabstractitemmodel_createIndex(model: DosQAbstractItemModel, row: cint, column: cint, data: pointer): DosQModelIndex {.cdecl, dynlib: dynLibName, importc.} 307 | proc dos_qabstractitemmodel_hasChildren(model: DosQAbstractItemModel, parent: DosQModelIndex): bool {.cdecl, dynlib: dynLibName, importc.} 308 | proc dos_qabstractitemmodel_hasIndex(model: DosQAbstractItemModel, row: int, column: int, parent: DosQModelIndex): bool {.cdecl, dynlib: dynLibName, importc.} 309 | proc dos_qabstractitemmodel_canFetchMore(model: DosQAbstractItemModel, parent: DosQModelIndex): bool {.cdecl, dynlib: dynLibName, importc.} 310 | proc dos_qabstractitemmodel_fetchMore(model: DosQAbstractItemModel, parent: DosQModelIndex) {.cdecl, dynlib: dynLibName, importc.} 311 | 312 | 313 | # QResource 314 | proc dos_qresource_register(filename: cstring) {.cdecl, dynlib: dynLibName, importc.} 315 | 316 | # QDeclarative 317 | proc dos_qdeclarative_qmlregistertype(value: ptr DosQmlRegisterType): cint {.cdecl, dynlib: dynLibName, importc.} 318 | proc dos_qdeclarative_qmlregistersingletontype(value: ptr DosQmlRegisterType): cint {.cdecl, dynlib: dynLibName, importc.} 319 | 320 | # QAbstractListModel 321 | proc dos_qabstractlistmodel_qmetaobject(): DosQMetaObject {.cdecl dynlib: dynLibName, importc.} 322 | 323 | proc dos_qabstractlistmodel_create(modelPtr: NimQAbstractListModel, 324 | metaObject: DosQMetaObject, 325 | qobjectCallback: DosQObjectCallBack, 326 | qaimCallbacks: DosQAbstractItemModelCallbacks): DosQAbstractListModel {.cdecl, dynlib: dynLibName, importc.} 327 | proc dos_qabstractlistmodel_columnCount(modelPtr: DosQAbstractListModel, index: DosQModelIndex): cint {.cdecl, dynlib: dynLibName, importc.} 328 | proc dos_qabstractlistmodel_parent(modelPtr: DosQAbstractListModel, index: DosQModelIndex): DosQModelIndex {.cdecl, dynlib: dynLibName, importc.} 329 | proc dos_qabstractlistmodel_index(modelPtr: DosQAbstractListModel, row: cint, column: cint, parent: DosQModelIndex): DosQModelIndex {.cdecl, dynlib: dynLibName, importc.} 330 | 331 | # QAbstractTableModel 332 | proc dos_qabstracttablemodel_qmetaobject(): DosQMetaObject {.cdecl dynlib: dynLibName, importc.} 333 | proc dos_qabstracttablemodel_create(modelPtr: NimQAbstractTableModel, 334 | metaObject: DosQMetaObject, 335 | qobjectCallback: DosQObjectCallBack, 336 | qaimCallbacks: DosQAbstractItemModelCallbacks): DosQAbstractTableModel {.cdecl, dynlib: dynLibName, importc.} 337 | proc dos_qabstracttablemodel_parent(modelPtr: DosQAbstractTableModel, index: DosQModelIndex): DosQModelIndex {.cdecl, dynlib: dynLibName, importc.} 338 | proc dos_qabstracttablemodel_index(modelPtr: DosQAbstractTableModel, row: cint, column: cint, parent: DosQModelIndex): DosQModelIndex {.cdecl, dynlib: dynLibName, importc.} 339 | 340 | proc dos_plain_text(htmlString: cstring): cstring {.cdecl, dynlib: dynLibName, importc.} 341 | proc dos_escape_html(input: cstring): cstring {.cdecl, dynlib: dynLibName, importc.} 342 | proc dos_qurl_fromUserInput(input: cstring): cstring {.cdecl, dynlib: dynLibName, importc.} 343 | proc dos_qurl_host(host: cstring): cstring {.cdecl, dynlib: dynLibName, importc.} 344 | proc dos_qurl_replaceHostAndAddPath(url: cstring, newScheme: cstring, newHost: cstring, pathPrefix: cstring): cstring {.cdecl, dynlib: dynLibName, importc.} 345 | 346 | # SingleInstance 347 | proc dos_singleinstance_create(uniqueName: cstring, eventStr: cstring): DosQObject {.cdecl, dynlib: dynLibName, importc.} 348 | proc dos_singleinstance_isfirst(vptr: DosQObject): bool {.cdecl, dynlib: dynLibName, importc.} 349 | proc dos_singleinstance_delete(vptr: DosQObject) {.cdecl, dynlib: dynLibName, importc.} 350 | 351 | # DosStatusEvent 352 | proc dos_event_create_osThemeEvent(engine: DosQQmlApplicationEngine): DosStatusEvent {.cdecl, dynlib: dynLibName, importc.} 353 | proc dos_event_create_urlSchemeEvent(): DosStatusEvent {.cdecl, dynlib: dynLibName, importc.} 354 | proc dos_event_delete(vptr: DosStatusEvent) {.cdecl, dynlib: dynLibName, importc.} 355 | 356 | # DosStatusOSNotification 357 | proc dos_osnotification_create(): DosStatusOSNotification 358 | {.cdecl, dynlib: dynLibName, importc.} 359 | proc dos_osnotification_show_notification(vptr: DosStatusOSNotification, 360 | title: cstring, messsage: cstring, identifier: cstring) 361 | {.cdecl, dynlib: dynLibName, importc.} 362 | proc dos_osnotification_show_badge_notification(vptr: DosStatusOSNotification, notificationsCount: int) 363 | {.cdecl, dynlib: dynLibName, importc.} 364 | proc dos_osnotification_delete(vptr: DosStatusOSNotification) 365 | {.cdecl, dynlib: dynLibName, importc.} 366 | 367 | # QSettings 368 | proc dos_qsettings_create(fileName: cstring, format: int): DosQSettings 369 | {.cdecl, dynlib: dynLibName, importc.} 370 | proc dos_qsettings_value(vptr: DosQSettings, key: cstring, 371 | defaultValue: DosQVariant): DosQVariant 372 | {.cdecl, dynlib: dynLibName, importc.} 373 | proc dos_qsettings_set_value(vptr: DosQSettings, key: cstring, 374 | value: DosQVariant) 375 | {.cdecl, dynlib: dynLibName, importc.} 376 | proc dos_qsettings_remove(vptr: DosQSettings, key: cstring) 377 | {.cdecl, dynlib: dynLibName, importc.} 378 | proc dos_qsettings_delete(vptr: DosQSettings) 379 | {.cdecl, dynlib: dynLibName, importc.} 380 | proc dos_qsettings_begin_group(vptr: DosQSettings, group: cstring) 381 | {.cdecl, dynlib: dynLibName, importc.} 382 | proc dos_qsettings_end_group(vptr: DosQSettings) 383 | {.cdecl, dynlib: dynLibName, importc.} 384 | 385 | # QTimer 386 | proc dos_qtimer_create(): DosQTimer 387 | {.cdecl, dynlib: dynLibName, importc.} 388 | proc dos_qtimer_delete(vptr: DosQTimer) 389 | {.cdecl, dynlib: dynLibName, importc.} 390 | proc dos_qtimer_set_interval(vptr: DosQTimer, interval: int) 391 | {.cdecl, dynlib: dynLibName, importc.} 392 | proc dos_qtimer_interval(vptr: DosQTimer): int 393 | {.cdecl, dynlib: dynLibName, importc.} 394 | proc dos_qtimer_start(vptr: DosQTimer) 395 | {.cdecl, dynlib: dynLibName, importc.} 396 | proc dos_qtimer_stop(vptr: DosQTimer) 397 | {.cdecl, dynlib: dynLibName, importc.} 398 | proc dos_qtimer_set_single_shot(vptr: DosQTimer, singleShot: bool) 399 | {.cdecl, dynlib: dynLibName, importc.} 400 | proc dos_qtimer_is_single_shot(vptr: DosQTimer): bool 401 | {.cdecl, dynlib: dynLibName, importc.} 402 | proc dos_qtimer_is_active(vptr: DosQTimer): bool 403 | {.cdecl, dynlib: dynLibName, importc.} 404 | 405 | # DosStatusKeychainManager 406 | proc dos_keychainmanager_create(service: cstring, authenticationReason: cstring): 407 | DosStatusKeychainManager 408 | {.cdecl, dynlib: dynLibName, importc.} 409 | proc dos_keychainmanager_read_data_sync(vptr: DosStatusKeychainManager, 410 | key: cstring): string {.cdecl, dynlib: dynLibName, importc.} 411 | proc dos_keychainmanager_read_data_async(vptr: DosStatusKeychainManager, 412 | key: cstring) {.cdecl, dynlib: dynLibName, importc.} 413 | proc dos_keychainmanager_store_data_async(vptr: DosStatusKeychainManager, 414 | key: cstring, data: cstring) {.cdecl, dynlib: dynLibName, importc.} 415 | proc dos_keychainmanager_delete_data_async(vptr: DosStatusKeychainManager, 416 | key: cstring) {.cdecl, dynlib: dynLibName, importc.} 417 | proc dos_keychainmanager_delete(vptr: DosStatusKeychainManager) 418 | {.cdecl, dynlib: dynLibName, importc.} 419 | 420 | proc dos_to_local_file(fileUrl: cstring): cstring 421 | {.cdecl, dynlib: dynLibName, importc.} 422 | 423 | proc dos_from_local_file(filePath: cstring): cstring 424 | {.cdecl, dynlib: dynLibName, importc.} 425 | 426 | proc dos_app_is_active(engine: DosQQmlApplicationEngine): bool {.cdecl, dynlib: dynLibName, importc.} 427 | proc dos_app_make_it_active(engine: DosQQmlApplicationEngine) {.cdecl, dynlib: dynLibName, importc.} 428 | 429 | # Common 430 | proc dos_installMessageHandler(handler: DosMessageHandler) {.cdecl, dynlib: dynLibName, importc.} 431 | -------------------------------------------------------------------------------- /src/nimqml/private/nimqmlmacros.nim: -------------------------------------------------------------------------------- 1 | ## Contains helper macros for NimQml 2 | 3 | import macros 4 | import strutils 5 | import sequtils 6 | import typetraits 7 | 8 | 9 | type 10 | FindQObjectTypeResult = tuple 11 | typeIdent: NimNode 12 | superTypeIdent: NimNode 13 | 14 | ProcInfo = object 15 | name: string 16 | returnType: string 17 | parametersTypes: seq[string] 18 | parametersNames: seq[string] 19 | 20 | PropertyInfo = object 21 | name: string 22 | typ: string 23 | read: string 24 | write: string 25 | notify: string 26 | 27 | QObjectInfo = object 28 | name: string 29 | superType: string 30 | slots: seq[ProcInfo] 31 | signals: seq[ProcInfo] 32 | properties: seq[PropertyInfo] 33 | 34 | 35 | proc childPos(node: NimNode, child: NimNode): int = 36 | ## Return the position of the given child or -1 37 | var i = 0 38 | for c in node.children: 39 | if c == child: 40 | return i 41 | inc(i) 42 | return -1 43 | 44 | 45 | proc removeChild(node: NimNode, child: NimNode): bool = 46 | ## Remove the child from a node 47 | let pos = node.childPos(child) 48 | if pos == -1: return false 49 | node.del(pos) 50 | return true 51 | 52 | 53 | proc toString(info: ProcInfo): string {.compiletime.} = 54 | ## Convert a ProcInfo to string 55 | let str = "ProcInfo {\n Name:\"$1\",\n Return Type:$2,\n Param Types:[$3],\n Param Names:[$4]\n}" 56 | str % [info.name, info.returnType, info.parametersTypes.join(","), info.parametersNames.join(",")] 57 | 58 | 59 | proc display(info: ProcInfo) {.compiletime.} = 60 | ## Display a ProcInfo 61 | echo info.toString 62 | 63 | 64 | proc toString(info: PropertyInfo): string {.compiletime.} = 65 | ## Convert a PropertyInfo to string 66 | "PropertyInfo {\"$1\", \"$2\", \"$3\", \"$4\", \"$5\"}" % [info.name, info.typ, info.read, info.write, info.notify] 67 | 68 | 69 | proc display(info: PropertyInfo) {.compiletime.} = 70 | ## Display a PropertyInfo 71 | echo info.toString 72 | 73 | 74 | proc toString(info: QObjectInfo): string {.compiletime.} = 75 | ## Convert a QObjectInfo to string 76 | let slots = info.slots.map(proc (x: auto): auto = x.toString) 77 | let signals = info.signals.map(proc(x: auto): auto = x.toString) 78 | let properties = info.properties.map(proc(x: auto): auto = x.toString) 79 | "QObjectInfo {\"$1\", \"$2\", [\"$3\"], [\"$4\"], [\"$5\"]}" % [info.name, info.superType, slots.join(", "), signals.join(", "), properties.join(", ")] 80 | 81 | 82 | proc display(info: QObjectInfo) {.compiletime.} = 83 | ## Display a QObjectInfo 84 | echo info.toString 85 | 86 | 87 | proc fromQVariantConversion(x: string): string {.compiletime.} = 88 | ## Return the correct conversion call from a QVariant 89 | ## to the given nim type 90 | case x: 91 | of "int": result = "intVal" 92 | of "string": result = "stringVal" 93 | of "bool": result = "boolVal" 94 | of "float32": result = "floatVal" 95 | of "float": result = "doubleVal" 96 | of "QObject": result = "qobjectVal" 97 | of "QVariant": result = "" 98 | else: error("Unsupported conversion from QVariant to $1" % x) 99 | 100 | 101 | proc toMetaType(x: string): string {.compiletime.} = 102 | ## Convert a nim type to QMetaType 103 | case x 104 | of "": result = "Void" 105 | of "void": result = "Void" 106 | of "int": result = "Int" 107 | of "bool": result = "Bool" 108 | of "string": result = "QString" 109 | of "float": result = "Double" 110 | of "float32": result = "Float" 111 | of "pointer": result = "VoidStar" 112 | of "QVariant": result = "QVariant" 113 | of "QObject": result = "QObjectStar" 114 | else: error("Unsupported conversion of $1 to metatype" % x) 115 | result = "QMetaType.$1" % result 116 | 117 | 118 | proc toMetaType(types: seq[string]): seq[string] {.compiletime.} = 119 | ## Convert a sequence of nim types to a sequence of QMetaTypes 120 | result = @[] 121 | for t in types: 122 | result.add(t.toMetaType) 123 | 124 | 125 | proc childrenOfKind(n: NimNode, kind: NimNodeKind): seq[NimNode] {.compiletime.} = 126 | ## Return the sequence of child nodes of the given kind 127 | result = @[] 128 | for c in n: 129 | if c.kind == kind: 130 | result.add(c) 131 | 132 | proc numChildrenOfKind(n: NimNode, kind: NimNodeKind): int {.compiletime.} = 133 | ## Return the number of child nodes of the given kind 134 | childrenOfKind(n, kind).len 135 | 136 | 137 | proc getPragmas(n: NimNode): seq[string] {.compiletime.} = 138 | ## Return the pragmas of a node 139 | result = @[] 140 | let pragmas = n.childrenOfKind(nnkPragma) 141 | if pragmas.len != 1: 142 | return 143 | let pragma = pragmas[0] 144 | for c in pragma: 145 | if c.kind == nnkIdent: 146 | result.add($c) 147 | 148 | 149 | proc extractQObjectTypeDef(head: NimNode): FindQObjectTypeResult {.compiletime.} = 150 | ## Extract the first type section and extract the first type Name and SuperType 151 | ## i.e. Given "type Bar = ref object of Foo" you get "Bar" and "Foo" 152 | let sections = head.childrenOfKind(nnkTypeSection) 153 | 154 | if sections.len == 0: 155 | error("No type section found") 156 | 157 | if sections.len != 1: 158 | error("Only one type section is supported") 159 | 160 | let definitions = sections[0].childrenOfKind(nnkTypeDef) 161 | 162 | if definitions.len == 0: 163 | error("No type definition found") 164 | 165 | if definitions.len != 1: 166 | error("Only ne type definition is supported") 167 | 168 | let def = definitions[0] 169 | 170 | var name = def[0] # type Object = ... <--- 171 | let pragma = def[1] # type Object {.something.} = ... <--- 172 | let typeKind = def[2] # .. = ref/distinct/object .. 173 | 174 | if name.kind == nnkPostFix: 175 | if name.len != 2: error("Expected two children in nnkPostFix node") 176 | if name[0].kind != nnkIdent or $(name[0]) != "*": error("Expected * in nnkPostFix node") 177 | if name[1].kind != nnkIdent: error("Expected ident as second argument in nnkPostFix node") 178 | name = name[1] 179 | 180 | if def[2].kind != nnkRefTy: # .. = ref .. 181 | error("ref type expected") 182 | 183 | if typekind[0].kind != nnkObjectTy: # .. = ref object of ... 184 | error("ref object expected") 185 | 186 | let objectType = typekind[0] 187 | if objectType[1].kind != nnkOfInherit: 188 | error("ref object with super type expected") 189 | 190 | let superType = objectType[1][0] 191 | 192 | result.typeIdent = name 193 | result.superTypeIdent = superType 194 | 195 | 196 | proc extractProcInfo(n: NimNode): ProcInfo {.compiletime.} = 197 | ## Extract the ProcInfo for the given node 198 | let procName = n[0] 199 | if procName.kind == nnkIdent: # proc name <-- without * 200 | result.name = $procName 201 | elif procName.kind == nnkPostFix: # proc name* <-- with * 202 | result.name = procName[1].repr # We handle both proc name and proc `name=` 203 | else: error("Unexpected node kind") 204 | 205 | let paramsSeq = n.childrenOfKind(nnkFormalParams) 206 | if paramsSeq.len != 1: error("Failed to find parameters") 207 | let params = paramsSeq[0] 208 | result.returnType = repr params[0] 209 | result.parametersNames = @[] 210 | result.parametersTypes = @[] 211 | for def in params.childrenOfKind(nnkIdentDefs): 212 | result.parametersNames.add(repr def[0]) 213 | result.parametersTypes.add(repr def[1]) 214 | 215 | 216 | proc extractPropertyInfo(node: NimNode): tuple[ok: bool, info: PropertyInfo] {.compiletime.} = 217 | ## Extract the PropertyInfo for a given node 218 | #[ 219 | Command 220 | BracketExpr 221 | Ident !"QtProperty" 222 | Ident !"string" 223 | Ident !"name" 224 | StmtList 225 | Asgn 226 | Ident !"read" 227 | Ident !"getName" 228 | Asgn 229 | Ident !"write" 230 | Ident !"setName" 231 | Asgn 232 | Ident !"notify" 233 | Ident !"nameChanged" 234 | ]# 235 | if node.kind != nnkCommand or 236 | node.len != 3 or 237 | node[0].kind != nnkBracketExpr or 238 | node[1].kind != nnkIdent or 239 | node[2].kind != nnkStmtList: 240 | return 241 | let bracketExpr = node[0] 242 | if bracketExpr.len != 2 or 243 | bracketExpr[0].kind != nnkIdent or 244 | bracketExpr[1].kind != nnkIdent or 245 | $(bracketExpr[0]) != "QtProperty": 246 | return 247 | let stmtList = node[2] 248 | if stmtList.len >= 1: 249 | if stmtList[0].kind != nnkAsgn or stmtList[0].len != 2 or 250 | stmtList[0][0].kind != nnkIdent or 251 | (stmtList[0][1].kind != nnkIdent and stmtList[0][1].kind != nnkAccQuoted): 252 | error("QtProperty parsing error") 253 | if stmtList.len >= 2: 254 | if stmtList[1].kind != nnkAsgn or stmtList[1].len != 2 or 255 | stmtList[1][0].kind != nnkIdent or 256 | (stmtList[1][1].kind != nnkIdent and stmtList[1][1].kind != nnkAccQuoted): 257 | error("QtProperty parsing error") 258 | if stmtList.len >= 3: 259 | if stmtList[2].kind != nnkAsgn or stmtList[2].len != 2 or 260 | stmtList[2][0].kind != nnkIdent or 261 | (stmtList[2][1].kind != nnkIdent and stmtList[2][1].kind != nnkAccQuoted): 262 | error("QtProperty parsing error") 263 | 264 | result.info.name = $(node[1]) 265 | result.info.typ = $(bracketExpr[1]) 266 | 267 | var 268 | readFound = false 269 | writeFound = false 270 | notifyFound = false 271 | 272 | result.info.read = "" 273 | result.info.write = "" 274 | result.info.notify = "" 275 | 276 | for c in stmtList: 277 | let accessorType = $(c[0]) 278 | let accessorName = c[1].repr 279 | if accessorType != "read" and accessorType != "write" and accessorType != "notify": 280 | error("Invalid property accessor. Use read, write or notify") 281 | if accessorType == "read" and readFound: 282 | error("Read slot already defined") 283 | if accessorType == "write" and writeFound: 284 | error("Write slot already defined") 285 | if accessorType == "notify" and notifyFound: 286 | error("Notify signal already defined") 287 | if accessorType == "read": 288 | readFound = true 289 | result.info.read = accessorName 290 | if accessorType == "write": 291 | writeFound = true 292 | result.info.write = accessorName 293 | if accessorType == "notify": 294 | notifyFound = true 295 | result.info.notify = accessorName 296 | 297 | result.ok = true 298 | 299 | 300 | proc isSlot(n: NimNode): bool {.compiletime.} = 301 | n.kind in {nnkProcDef, nnkMethodDef} and "slot" in n.getPragmas 302 | 303 | proc isSignal(n: NimNode): bool {.compiletime.} = 304 | n.kind in {nnkProcDef, nnkMethodDef} and "signal" in n.getPragmas 305 | 306 | proc isProperty(node: NimNode): bool {.compiletime.} = 307 | if node.kind != nnkCommand or 308 | node.len != 3 or 309 | node[0].kind != nnkBracketExpr or 310 | node[1].kind != nnkIdent or 311 | node[2].kind != nnkStmtList: 312 | return false 313 | let bracketExpr = node[0] 314 | if bracketExpr.len != 2 or 315 | bracketExpr[0].kind != nnkIdent or 316 | bracketExpr[1].kind != nnkIdent or 317 | $(bracketExpr[0]) != "QtProperty": 318 | return false 319 | return true 320 | 321 | proc extractQObjectInfo(node: NimNode): QObjectInfo {.compiletime.} = 322 | ## Extract the QObjectInfo for the given node 323 | let (typeNode, superTypeNode) = extractQObjectTypeDef(node) 324 | result.name = $typeNode 325 | result.superType = $superTypeNode 326 | result.slots = @[] 327 | result.signals = @[] 328 | result.properties = @[] 329 | 330 | # Extract slots and signals infos 331 | for c in node.children: 332 | # Extract slot 333 | if c.isSlot: 334 | var info = extractProcInfo(c) 335 | if info.parametersTypes.len == 0: 336 | error("Slot $1 must have at least an argument" % info.name) 337 | if info.parametersTypes[0] != $typeNode: 338 | error("Slot $1 first arguments must be $2" % [info.name, $typeNode]) 339 | info.parametersTypes.delete(0, 0) 340 | info.parametersNames.delete(0, 0) 341 | result.slots.add(info) 342 | # Extract signal 343 | if c.isSignal: 344 | var info = extractProcInfo(c) 345 | if info.parametersTypes.len == 0: 346 | error("Signal $1 must have at least an argument" % info.name) 347 | if info.parametersTypes[0] != $typeNode: 348 | error("Signal $1 first arguments must be $2" % [info.name, $typeNode]) 349 | info.parametersTypes.delete(0, 0) 350 | info.parametersNames.delete(0, 0) 351 | result.signals.add(info) 352 | 353 | # Extract properties infos and remove them 354 | var toRemove: seq[NimNode] = @[] 355 | for c in node: 356 | let (ok, info) = extractPropertyInfo(c) 357 | if not ok: continue 358 | toRemove.add(c) 359 | result.properties.add(info) 360 | 361 | for r in toRemove: 362 | if not node.removeChild(r): 363 | error("Failed to remove a child") 364 | 365 | 366 | proc generateMetaObjectSignalDefinitions(signals: seq[ProcInfo]): seq[string] {.compiletime.} = 367 | result = @[] 368 | for signal in signals: 369 | var parameters: seq[string] = @[] 370 | for i in 0.. 0: 446 | sequence.add("(") 447 | for i in 0.. 38 | vptr: DosQHashIntByteArray 39 | 40 | QModelIndex* = ref object of RootObj ## \ 41 | # A QModelIndex 42 | vptr: DosQModelIndex 43 | 44 | QResource* = ref object of RootObj ## \ 45 | # A QResource 46 | 47 | QSettings* = ref object of QObject ## \ 48 | 49 | QtItemFlag*{.pure, size: sizeof(cint).} = enum ## \ 50 | ## Item flags 51 | ## 52 | ## This enum mimic the Qt::itemFlag C++ enum 53 | None = 0.cint, 54 | IsSelectable = 1.cint, 55 | IsEditable = 2.cint, 56 | IsDragEnabled = 4.cint, 57 | IsDropEnabled = 8.cint, 58 | IsUserCheckable = 16.cint, 59 | IsEnabled = 32.cint, 60 | IsTristate = 64.cint, 61 | NeverHasChildren = 128.cint 62 | 63 | QtOrientation*{.pure, size: sizeof(cint).} = enum ## \ 64 | ## Define orientation 65 | ## 66 | ## This enum mimic the Qt::Orientation C++ enum 67 | Horizontal = 1.cint, 68 | Vertical = 2.cint 69 | 70 | QMetaType*{.pure, size: sizeof(cint).} = enum ## \ 71 | ## Qt metatypes values used for specifing the 72 | ## signals and slots argument and return types. 73 | ## 74 | ## This enum mimic the QMetaType::Type C++ enum 75 | UnknownType = 0.cint, 76 | Bool = 1.cint, 77 | Int = 2.cint, 78 | Double = 6.cint, 79 | QString = 10.cint, 80 | VoidStar = 31.cint, 81 | Float = 38.cint, 82 | QObjectStar = 39.cint, 83 | QVariant = 41.cint, 84 | Void = 43.cint 85 | 86 | ParameterDefinition* = object 87 | name*: string 88 | metaType*: QMetaType 89 | 90 | SignalDefinition* = object 91 | name*: string 92 | parameters*: seq[ParameterDefinition] 93 | 94 | SlotDefinition* = object 95 | name*: string 96 | returnMetaType*: QMetaType 97 | parameters*: seq[ParameterDefinition] 98 | 99 | PropertyDefinition* = object 100 | name*: string 101 | propertyMetaType*: QMetaType 102 | readSlot*: string 103 | writeSlot*: string 104 | notifySignal*: string 105 | 106 | QMetaObject* = ref object of RootObj 107 | vptr: DosQMetaObject 108 | signals: seq[SignalDefinition] 109 | slots: seq[SlotDefinition] 110 | properties: seq[PropertyDefinition] 111 | 112 | QUrl* = ref object of RootObj 113 | vptr: DosQUrl 114 | 115 | QNetworkConfigurationManager* = ref object of QObject 116 | 117 | QTimer* = ref object of QObject 118 | 119 | QNetworkAccessManagerFactory* = ref object of RootObj ## \ 120 | vptr: DosQQNetworkAccessManagerFactory 121 | 122 | QNetworkAccessManager* = ref object of QObject ## \ 123 | 124 | NetworkAccessibility*{.pure, size: sizeof(cint).} = enum ## \ 125 | UnknownAccessibility = -1.cint, 126 | NotAccessible = 0.cint, 127 | Accessible = 1.cint 128 | 129 | QUrlParsingMode*{.pure, size: sizeof(cint).} = enum 130 | Tolerant = 0.cint 131 | Strict = 1.cint 132 | 133 | Ownership {.pure.} = enum ## \ 134 | ## Specify the ownership of a pointer 135 | Take, # The ownership is passed to the wrapper 136 | Clone # The node should be cloned 137 | 138 | SingleInstance* = ref object of QObject 139 | 140 | StatusEvent* = ref object of QObject 141 | 142 | StatusOSNotification* = ref object of QObject 143 | 144 | StatusKeychainManager* = ref object of QObject 145 | 146 | const 147 | UserRole* = 0x100 148 | -------------------------------------------------------------------------------- /src/nimqml/private/qabstractitemmodel.nim: -------------------------------------------------------------------------------- 1 | import tables 2 | 3 | let qAbstractItemModelStaticMetaObjectInstance = newQAbstractItemModelMetaObject() 4 | 5 | proc staticMetaObject*(c: type QAbstractItemModel): QMetaObject = 6 | ## Return the metaObject of QAbstractItemModel 7 | qAbstractItemModelStaticMetaObjectInstance 8 | 9 | proc staticMetaObject*(self: QAbstractItemModel): QMetaObject = 10 | ## Return the metaObject of QAbstractItemModel 11 | qAbstractItemModelStaticMetaObjectInstance 12 | 13 | method metaObject*(self: QAbstractItemModel): QMetaObject = 14 | # Return the metaObject 15 | QAbstractItemModel.staticMetaObject 16 | 17 | method rowCount*(self: QAbstractItemModel, index: QModelIndex): int {.base.} = 18 | ## Return the model's row count 19 | 0 20 | 21 | proc rowCountCallback(modelPtr: pointer, rawIndex: DosQModelIndex, result: var cint) {.cdecl, exportc.} = 22 | debugMsg("QAbstractItemModel", "rowCountCallback") 23 | let model = cast[QAbstractItemModel](modelPtr) 24 | let index = newQModelIndex(rawIndex, Ownership.Clone) 25 | result = model.rowCount(index).cint 26 | 27 | method columnCount*(self: QAbstractItemModel, index: QModelIndex): int {.base.} = 28 | ## Return the model's column count 29 | 1 30 | 31 | proc columnCountCallback(modelPtr: pointer, rawIndex: DosQModelIndex, result: var cint) {.cdecl, exportc.} = 32 | debugMsg("QAbstractItemModel", "columnCountCallback") 33 | let model = cast[QAbstractItemModel](modelPtr) 34 | let index = newQModelIndex(rawIndex, Ownership.Clone) 35 | result = model.columnCount(index).cint 36 | 37 | method data*(self: QAbstractItemModel, index: QModelIndex, role: int): QVariant {.base.} = 38 | ## Return the data at the given model index and role 39 | nil 40 | 41 | proc dataCallback(modelPtr: pointer, rawIndex: DosQModelIndex, role: cint, result: DosQVariant) {.cdecl, exportc.} = 42 | debugMsg("QAbstractItemModel", "dataCallback") 43 | let model = cast[QAbstractItemModel](modelPtr) 44 | let index = newQModelIndex(rawIndex, Ownership.Clone) 45 | let variant = data(model, index, role.int) 46 | if variant != nil: 47 | dos_qvariant_assign(result, variant.vptr) 48 | variant.delete 49 | 50 | method setData*(self: QAbstractItemModel, index: QModelIndex, value: QVariant, role: int): bool {.base.} = 51 | ## Sets the data at the given index and role. Return true on success, false otherwise 52 | false 53 | 54 | proc setDataCallback(modelPtr: pointer, rawIndex: DosQModelIndex, rawQVariant: DosQVariant, role: cint, result: var bool) {.cdecl, exportc.} = 55 | debugMsg("QAbstractItemModel", "setDataCallback") 56 | let model = cast[QAbstractItemModel](modelPtr) 57 | let index = newQModelIndex(rawIndex, Ownership.Clone) 58 | let variant = newQVariant(rawQVariant, Ownership.Clone) 59 | result = model.setData(index, variant, role.int) 60 | 61 | method roleNames*(self: QAbstractItemModel): Table[int, string] {.base.} = 62 | ## Return the model role names 63 | nil 64 | 65 | proc roleNamesCallback(modelPtr: pointer, hash: DosQHashIntByteArray) {.cdecl, exportc.} = 66 | debugMsg("QAbstractItemModel", "roleNamesCallback") 67 | let model = cast[QAbstractItemModel](modelPtr) 68 | let table = model.roleNames() 69 | for key, val in table.pairs: 70 | dos_qhash_int_qbytearray_insert(hash, key.cint, val.cstring) 71 | 72 | method flags*(self: QAbstractItemModel, index: QModelIndex): QtItemFlag {.base.} = 73 | ## Return the item flags and the given index 74 | return QtItemFlag.None 75 | 76 | proc flagsCallback(modelPtr: pointer, rawIndex: DosQModelIndex, result: var cint) {.cdecl, exportc.} = 77 | debugMsg("QAbstractItemModel", "flagsCallback") 78 | let model = cast[QAbstractItemModel](modelPtr) 79 | let index = newQModelIndex(rawIndex, Ownership.Clone) 80 | result = model.flags(index).cint 81 | 82 | method headerData*(self: QAbstractItemModel, section: int, orientation: QtOrientation, role: int): QVariant {.base.} = 83 | ## Returns the data for the given role and section in the header with the specified orientation 84 | nil 85 | 86 | proc headerDataCallback(modelPtr: pointer, section: cint, orientation: cint, role: cint, result: DosQVariant) {.cdecl, exportc.} = 87 | debugMsg("QAbstractItemModel", "headerDataCallback") 88 | let model = cast[QAbstractItemModel](modelPtr) 89 | let variant = model.headerData(section.int, orientation.QtOrientation, role.int) 90 | if variant != nil: 91 | dos_qvariant_assign(result, variant.vptr) 92 | variant.delete 93 | 94 | proc createIndex*(self: QAbstractItemModel, row: int, column: int, data: pointer): QModelIndex = 95 | ## Create a new QModelIndex 96 | debugMsg("QAbstractItemModel", "createIndex") 97 | let index = dos_qabstractitemmodel_createIndex(self.vptr.DosQAbstractItemModel, row.cint, column.cint, data) 98 | result = newQModelIndex(index, Ownership.Take) 99 | 100 | method index*(self: QAbstractItemModel, row: int, column: int, parent: QModelIndex): QModelIndex {.base.} = 101 | doAssert(false, "QAbstractItemModel::index is pure virtual") 102 | 103 | proc indexCallback(modelPtr: pointer, row: cint, column: cint, parent: DosQModelIndex, result: DosQModelIndex) {.cdecl, exportc.} = 104 | debugMsg("QAbstractItemModel", "indexCallback") 105 | let model = cast[QAbstractItemModel](modelPtr) 106 | let index = model.index(row.int, column.int, newQModelIndex(parent, Ownership.Clone)) 107 | dos_qmodelindex_assign(result, index.vptr) 108 | 109 | method parent*(self: QAbstractItemModel, child: QModelIndex): QModelIndex {.base.} = 110 | doAssert(false, "QAbstractItemModel::parent is pure virtual") 111 | 112 | proc parentCallback(modelPtr: pointer, child: DosQModelIndex, result: DosQModelIndex) {.cdecl, exportc.} = 113 | debugMsg("QAbstractItemModel", "parentCallback") 114 | let model = cast[QAbstractItemModel](modelPtr) 115 | let index = model.parent(newQModelIndex(child, Ownership.Clone)) 116 | dos_qmodelindex_assign(result, index.vptr) 117 | 118 | method hasChildren*(self: QAbstractItemModel, parent: QModelIndex): bool {.base.} = 119 | return dos_qabstractitemmodel_hasChildren(self.vptr.DosQAbstractItemModel, parent.vptr.DosQModelIndex) 120 | 121 | proc hasChildrenCallback(modelPtr: pointer, parent: DosQModelIndex, result: var bool) {.cdecl, exportc.} = 122 | let model = cast[QAbstractItemModel](modelPtr) 123 | result = model.hasChildren(newQModelIndex(parent, Ownership.Clone)) 124 | 125 | method canFetchMore*(self: QAbstractItemModel, parent: QModelIndex): bool {.base.} = 126 | return dos_qabstractitemmodel_canFetchMore(self.vptr.DosQAbstractItemModel, parent.vptr.DosQModelIndex) 127 | 128 | proc canFetchMoreCallback(modelPtr: pointer, parent: DosQModelIndex, result: var bool) {.cdecl, exportc.} = 129 | let model = cast[QAbstractItemModel](modelPtr) 130 | result = model.canFetchMore(newQModelIndex(parent, Ownership.Clone)) 131 | 132 | method fetchMore*(self: QAbstractItemModel, parent: QModelIndex) {.base.} = 133 | dos_qabstractitemmodel_fetchMore(self.vptr.DosQAbstractItemModel, parent.vptr.DosQModelIndex) 134 | 135 | proc fetchMoreCallback(modelPtr: pointer, parent: DosQModelIndex) {.cdecl, exportc.} = 136 | let model = cast[QAbstractItemModel](modelPtr) 137 | model.fetchMore(newQModelIndex(parent, Ownership.Clone)) 138 | 139 | method onSlotCalled*(self: QAbstractItemModel, slotName: string, arguments: openarray[QVariant]) = 140 | ## Called from the dotherside library when a slot is called from Qml. 141 | discard 142 | 143 | proc setup*(self: QAbstractItemModel) = 144 | ## Setup a new QAbstractItemModel 145 | debugMsg("QAbstractItemModel", "setup") 146 | 147 | let qaimCallbacks = DosQAbstractItemModelCallbacks(rowCount: rowCountCallback, 148 | columnCount: columnCountCallback, 149 | data: dataCallback, 150 | setData: setDataCallback, 151 | roleNames: roleNamesCallback, 152 | flags: flagsCallback, 153 | headerData: headerDataCallback, 154 | index: indexCallback, 155 | parent: parentCallback, 156 | hasChildren: hasChildrenCallback, 157 | canFetchMore: canFetchMoreCallback, 158 | fetchMore: fetchMoreCallback) 159 | 160 | self.vptr = dos_qabstractitemmodel_create(addr(self[]), self.metaObject.vptr, 161 | qobjectCallback, qaimCallbacks).DosQObject 162 | 163 | proc delete*(self: QAbstractItemModel) = 164 | ## Delete the given QAbstractItemModel 165 | debugMsg("QAbstractItemModel", "delete") 166 | self.QObject.delete() 167 | 168 | proc newQAbstractItemModel*(): QAbstractItemModel = 169 | ## Return a new QAbstractItemModel 170 | debugMsg("QAbstractItemModel", "new") 171 | new(result, delete) 172 | result.setup() 173 | 174 | proc hasIndex*(self: QAbstractItemModel, row: int, column: int, parent: QModelIndex): bool = 175 | debugMsg("QAbstractItemModel", "hasIndex") 176 | dos_qabstractitemmodel_hasIndex(self.vptr.DosQAbstractItemModel, row.cint, column.cint, parent.vptr.DosQModelIndex) 177 | 178 | proc beginInsertRows*(self: QAbstractItemModel, parentIndex: QModelIndex, first: int, last: int) = 179 | ## Notify the view that the model is about to inserting the given number of rows 180 | debugMsg("QAbstractItemModel", "beginInsertRows") 181 | dos_qabstractitemmodel_beginInsertRows(self.vptr.DosQAbstractItemModel, parentIndex.vptr, first.cint, last.cint) 182 | 183 | proc endInsertRows*(self: QAbstractItemModel) = 184 | ## Notify the view that the rows have been inserted 185 | debugMsg("QAbstractItemModel", "endInsertRows") 186 | dos_qabstractitemmodel_endInsertRows(self.vptr.DosQAbstractItemModel) 187 | 188 | proc beginRemoveRows*(self: QAbstractItemModel, parentIndex: QModelIndex, first: int, last: int) = 189 | ## Notify the view that the model is about to remove the given number of rows 190 | debugMsg("QAbstractItemModel", "beginRemoveRows") 191 | dos_qabstractitemmodel_beginRemoveRows(self.vptr.DosQAbstractItemModel, parentIndex.vptr, first.cint, last.cint) 192 | 193 | proc endRemoveRows*(self: QAbstractItemModel) = 194 | ## Notify the view that the rows have been removed 195 | debugMsg("QAbstractItemModel", "endRemoveRows") 196 | dos_qabstractitemmodel_endRemoveRows(self.vptr.DosQAbstractItemModel) 197 | 198 | proc beginMoveRows*(self: QAbstractItemModel, sourceParentIndex: QModelIndex, sourceFirst: int, sourceLast: int, destParentIndex: QModelIndex, destinationChild: int) = 199 | ## Notify the view that the model is about to move rows 200 | debugMsg("QAbstractItemModel", "beginMoveRows") 201 | dos_qabstractitemmodel_beginMoveRows(self.vptr.DosQAbstractItemModel, sourceParentIndex.vptr, sourceFirst.cint, sourceLast.cint, destParentIndex.vptr, destinationChild.cint) 202 | 203 | proc endMoveRows*(self: QAbstractItemModel) = 204 | ## Notify the view that the rows have been moved 205 | debugMsg("QAbstractItemModel", "endMoveRows") 206 | dos_qabstractitemmodel_endMoveRows(self.vptr.DosQAbstractItemModel) 207 | 208 | proc beginInsertColumns*(self: QAbstractItemModel, parentIndex: QModelIndex, first: int, last: int) = 209 | ## Notify the view that the model is about to inserting the given number of columns 210 | debugMsg("QAbstractItemModel", "beginInsertColumns") 211 | dos_qabstractitemmodel_beginInsertColumns(self.vptr.DosQAbstractItemModel, parentIndex.vptr, first.cint, last.cint) 212 | 213 | proc endInsertColumns*(self: QAbstractItemModel) = 214 | ## Notify the view that the rows have been inserted 215 | debugMsg("QAbstractItemModel", "endInsertColumns") 216 | dos_qabstractitemmodel_endInsertColumns(self.vptr.DosQAbstractItemModel) 217 | 218 | proc beginRemoveColumns*(self: QAbstractItemModel, parentIndex: QModelIndex, first: int, last: int) = 219 | ## Notify the view that the model is about to remove the given number of columns 220 | debugMsg("QAbstractItemModel", "beginRemoveColumns") 221 | dos_qabstractitemmodel_beginRemoveColumns(self.vptr.DosQAbstractItemModel, parentIndex.vptr, first.cint, last.cint) 222 | 223 | proc endRemoveColumns*(self: QAbstractItemModel) = 224 | ## Notify the view that the columns have been removed 225 | debugMsg("QAbstractItemModel", "endRemoveColumns") 226 | dos_qabstractitemmodel_endRemoveColumns(self.vptr.DosQAbstractItemModel) 227 | 228 | proc beginResetModel*(self: QAbstractItemModel) = 229 | ## Notify the view that the model is about to resetting 230 | debugMsg("QAbstractItemModel", "beginResetModel") 231 | dos_qabstractitemmodel_beginResetModel(self.vptr.DosQAbstractItemModel) 232 | 233 | proc endResetModel*(self: QAbstractItemModel) = 234 | ## Notify the view that model has finished resetting 235 | debugMsg("QAbstractItemModel", "endResetModel") 236 | dos_qabstractitemmodel_endResetModel(self.vptr.DosQAbstractItemModel) 237 | 238 | proc dataChanged*(self: QAbstractItemModel, 239 | topLeft: QModelIndex, 240 | bottomRight: QModelIndex, 241 | roles: openArray[int] = []) = 242 | ## Notify the view that the model data changed 243 | debugMsg("QAbstractItemModel", "dataChanged") 244 | if roles.len == 0: 245 | dos_qabstractitemmodel_dataChanged(self.vptr.DosQAbstractItemModel, topLeft.vptr, 246 | bottomRight.vptr, nil, 0) 247 | else: 248 | var copy: seq[cint] 249 | for i in roles: 250 | copy.add(i.cint) 251 | dos_qabstractitemmodel_dataChanged(self.vptr.DosQAbstractItemModel, topLeft.vptr, 252 | bottomRight.vptr, copy[0].addr, copy.len.cint) 253 | -------------------------------------------------------------------------------- /src/nimqml/private/qabstractlistmodel.nim: -------------------------------------------------------------------------------- 1 | let qAbstractListModelStaticMetaObjectInstance = newQAbstractListModelMetaObject() 2 | 3 | proc staticMetaObject*(c: type QAbstractListModel): QMetaObject = 4 | ## Return the metaObject of QAbstractListModel 5 | qAbstractListModelStaticMetaObjectInstance 6 | 7 | proc staticMetaObject*(self: QAbstractListModel): QMetaObject = 8 | ## Return the metaObject of QAbstractListModel 9 | qAbstractListModelStaticMetaObjectInstance 10 | 11 | method metaObject*(self: QAbstractListModel): QMetaObject = 12 | # Return the metaObject 13 | QAbstractListModel.staticMetaObject 14 | 15 | proc setup*(self: QAbstractListModel) = 16 | ## Setup a new QAbstractListModel 17 | debugMsg("QAbstractListModel", "setup") 18 | 19 | let qaimCallbacks = DosQAbstractItemModelCallbacks(rowCount: rowCountCallback, 20 | columnCount: columnCountCallback, 21 | data: dataCallback, 22 | setData: setDataCallback, 23 | roleNames: roleNamesCallback, 24 | flags: flagsCallback, 25 | headerData: headerDataCallback, 26 | index: indexCallback, 27 | parent: parentCallback, 28 | hasChildren: hasChildrenCallback, 29 | canFetchMore: canFetchMoreCallback, 30 | fetchMore: fetchMoreCallback) 31 | 32 | self.vptr = dos_qabstractlistmodel_create(addr(self[]), self.metaObject.vptr, 33 | qobjectCallback, qaimCallbacks).DosQObject 34 | self.owner = true 35 | 36 | proc delete*(self: QAbstractListModel) = 37 | ## Delete the given QAbstractItemModel 38 | debugMsg("QAbstractItemModel", "delete") 39 | self.QObject.delete() 40 | 41 | proc newQAbstractListModel*(): QAbstractListModel = 42 | ## Return a new QAbstractListModel 43 | debugMsg("QAbstractListModel", "new") 44 | new(result, delete) 45 | result.setup() 46 | 47 | 48 | method columnCount(self: QAbstractListModel, index: QModelIndex): int = 49 | return dos_qabstractlistmodel_columnCount(self.vptr.DosQAbstractListModel, index.vptr.DosQModelIndex) 50 | 51 | method parent(self: QAbstractListModel, child: QModelIndex): QModelIndex = 52 | let indexPtr = dos_qabstractlistmodel_parent(self.vptr.DosQAbstractListModel, child.vptr.DosQModelIndex) 53 | result = newQModelIndex(indexPtr, Ownership.Take) 54 | 55 | method index*(self: QAbstractListModel, row: int, column: int, parent: QModelIndex): QModelIndex = 56 | let indexPtr = dos_qabstractlistmodel_index(self.vptr.DosQAbstractListModel, row.cint, column.cint, parent.vptr.DosQModelIndex) 57 | result = newQModelIndex(indexPtr, Ownership.Take) 58 | 59 | -------------------------------------------------------------------------------- /src/nimqml/private/qabstracttablemodel.nim: -------------------------------------------------------------------------------- 1 | let qAbstractTableModelStaticMetaObjectInstance = newQAbstractTableModelMetaObject() 2 | 3 | proc staticMetaObject*(c: type QAbstractTableModel): QMetaObject = 4 | ## Return the metaObject of QAbstractTableModel 5 | qAbstractTableModelStaticMetaObjectInstance 6 | 7 | proc staticMetaObject*(self: QAbstractTableModel): QMetaObject = 8 | ## Return the metaObject of QAbstractTableModel 9 | qAbstractTableModelStaticMetaObjectInstance 10 | 11 | method metaObject*(self: QAbstractTableModel): QMetaObject = 12 | # Return the metaObject 13 | QAbstractTableModel.staticMetaObject 14 | 15 | proc setup*(self: QAbstractTableModel) = 16 | ## Setup a new QAbstractTableModel 17 | debugMsg("QAbstractTableModel", "setup") 18 | 19 | let qaimCallbacks = DosQAbstractItemModelCallbacks(rowCount: rowCountCallback, 20 | columnCount: columnCountCallback, 21 | data: dataCallback, 22 | setData: setDataCallback, 23 | roleNames: roleNamesCallback, 24 | flags: flagsCallback, 25 | headerData: headerDataCallback, 26 | index: indexCallback, 27 | parent: parentCallback, 28 | hasChildren: hasChildrenCallback, 29 | canFetchMore: canFetchMoreCallback, 30 | fetchMore: fetchMoreCallback) 31 | 32 | self.vptr = dos_qabstracttablemodel_create(addr(self[]), self.metaObject.vptr, 33 | qobjectCallback, qaimCallbacks).DosQObject 34 | 35 | proc delete*(self: QAbstractTableModel) = 36 | ## Delete the given QAbstractItemModel 37 | debugMsg("QAbstractItemModel", "delete") 38 | self.QObject.delete() 39 | 40 | proc newQAbstractTableModel*(): QAbstractTableModel = 41 | ## Return a new QAbstractTableModel 42 | debugMsg("QAbstractTableModel", "new") 43 | new(result, delete) 44 | result.setup() 45 | 46 | method parent(self: QAbstractTableModel, child: QModelIndex): QModelIndex = 47 | let indexPtr = dos_qabstracttablemodel_parent(self.vptr.DosQAbstractTableModel, child.vptr.DosQModelIndex) 48 | result = newQModelIndex(indexPtr, Ownership.Take) 49 | 50 | method index*(self: QAbstractTableModel, row: int, column: int, parent: QModelIndex): QModelIndex = 51 | let indexPtr = dos_qabstracttablemodel_index(self.vptr.DosQAbstractTableModel, row.cint, column.cint, parent.vptr.DosQModelIndex) 52 | result = newQModelIndex(indexPtr, Ownership.Take) 53 | 54 | -------------------------------------------------------------------------------- /src/nimqml/private/qapplication.nim: -------------------------------------------------------------------------------- 1 | proc setup*(application: QApplication) = 2 | ## Setup a new QApplication 3 | dos_qapplication_create() 4 | application.deleted = false 5 | 6 | proc exec*(application: QApplication) = 7 | ## Start the Qt event loop 8 | dos_qapplication_exec() 9 | 10 | proc quit*(application: QApplication) = 11 | ## Quit the Qt event loop 12 | dos_qapplication_quit() 13 | 14 | proc icon*(application: QApplication, filename: string) = 15 | dos_qapplication_icon(filename.cstring) 16 | 17 | proc setClipboardText*(text: string = "") = 18 | dos_qapplication_clipboard_setText(text.cstring) 19 | 20 | proc installSelfSignedCertificate*(certificate: string) = 21 | dos_add_self_signed_certificate(certificate.cstring) 22 | 23 | proc installEventFilter*(application: QApplication, event: StatusEvent) = 24 | dos_qapplication_installEventFilter(event.vptr) 25 | 26 | proc setClipboardImage*(text: string = "") = 27 | dos_qapplication_clipboard_setImage(text.cstring) 28 | 29 | proc downloadImage*(imageSource: string = "", filePath = "") = 30 | dos_qapplication_download_image(imageSource.cstring, filePath.cstring) 31 | 32 | proc delete*(application: QApplication) = 33 | ## Delete the given QApplication 34 | if application.deleted: 35 | return 36 | debugMsg("QApplication", "delete") 37 | dos_qapplication_delete() 38 | application.deleted = true 39 | 40 | proc newQApplication*(): QApplication = 41 | ## Return a new QApplication 42 | new(result, delete) 43 | result.setup() 44 | -------------------------------------------------------------------------------- /src/nimqml/private/qdeclarative.nim: -------------------------------------------------------------------------------- 1 | import tables 2 | 3 | var ctorTable = initTable[cint, proc(): QObject]() 4 | 5 | proc creator(id: cint, wrapper: DosQObjectWrapper, nimQObject: var NimQObject, dosQObject: var DosQObject) {.cdecl.} = 6 | let qobject: QObject = ctorTable[id]() 7 | GC_ref(qobject) 8 | nimQObject = addr(qobject[]) 9 | dosQObject = qobject.vptr 10 | # Swap the dosQObject and 11 | qobject.vptr = wrapper.DosQObject 12 | qobject.owner = false 13 | 14 | proc deleter(id: cint, nimQObject: NimQObject) {.cdecl.} = 15 | let qobject = cast[QObject](nimQObject) 16 | GC_unref(qobject) 17 | 18 | proc qmlRegisterType*[T](uri: string, major: int, minor: int, qmlName: string, ctor: proc(): T): int = 19 | let metaObject: QMetaObject = T.staticMetaObject() 20 | var dosQmlRegisterType = DosQmlRegisterType(major: major.cint, minor: minor.cint, uri: uri.cstring, 21 | qml: qmlName.cstring, staticMetaObject: metaObject.vptr, 22 | createCallback: creator, deleteCallback: deleter) 23 | let id = dos_qdeclarative_qmlregistertype(dosQmlRegisterType.unsafeAddr) 24 | ctorTable[id] = proc(): QObject = ctor().QObject 25 | id.int 26 | 27 | proc qmlRegisterSingletonType*[T](uri: string, major: int, minor: int, qmlName: string, ctor: proc(): T): int = 28 | let metaObject: QMetaObject = T.staticMetaObject() 29 | var dosQmlRegisterType = DosQmlRegisterType(major: major.cint, minor: minor.cint, uri: uri.cstring, 30 | qml: qmlName.cstring, staticMetaObject: metaObject.vptr, 31 | createCallback: creator, deleteCallback: deleter) 32 | let id = dos_qdeclarative_qmlregistersingletontype(dosQmlRegisterType.unsafeAddr) 33 | ctorTable[id] = proc(): QObject = ctor().QObject 34 | id.int 35 | -------------------------------------------------------------------------------- /src/nimqml/private/qguiapplication.nim: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | proc setup*(self: QGuiApplication) = 4 | ## Setup a new QGuiApplication 5 | dos_qguiapplication_create() 6 | self.deleted = false 7 | 8 | proc delete*(self: QGuiApplication) = 9 | ## Delete the given QGuiApplication 10 | if self.deleted: 11 | return 12 | debugMsg("QGuiApplication", "delete") 13 | dos_qguiapplication_delete() 14 | self.deleted = true 15 | 16 | proc icon*(application: QGuiApplication, filename: string) = 17 | dos_qguiapplication_icon(filename.cstring) 18 | 19 | proc installEventFilter*(application: QGuiApplication, event: StatusEvent) = 20 | dos_qguiapplication_installEventFilter(event.vptr) 21 | 22 | proc newQGuiApplication*(): QGuiApplication = 23 | ## Return a new QGuiApplication 24 | new(result, delete) 25 | result.setup() 26 | 27 | proc exec*(self: QGuiApplication) = 28 | ## Start the Qt event loop 29 | dos_qguiapplication_exec() 30 | 31 | proc quit*(self: QGuiApplication) = 32 | ## Quit the Qt event loop 33 | dos_qguiapplication_quit() 34 | 35 | proc restartApplication*() = 36 | ## Restart the app 37 | dos_qguiapplication_restart() 38 | 39 | proc setClipboardText*(text: string = "") = 40 | dos_qguiapplication_clipboard_setText(text.cstring) 41 | 42 | proc getClipboardText*(): string = 43 | let str = dos_qguiapplication_clipboard_getText() 44 | result = $str 45 | dos_chararray_delete(str) 46 | 47 | proc installSelfSignedCertificate*(certificate: string) = 48 | dos_add_self_signed_certificate(certificate.cstring) 49 | 50 | proc setClipboardImage*(text: string = "") = 51 | dos_qguiapplication_clipboard_setImage(text.cstring) 52 | 53 | proc setClipboardImageByUrl*(url: string = "") = 54 | dos_qguiapplication_clipboard_setImageByUrl(url.cstring) 55 | 56 | proc downloadImage*(imageSource: string = "", filePath = "") = 57 | dos_qguiapplication_download_image(imageSource.cstring, filePath.cstring) 58 | 59 | proc downloadImageByUrl*(url: string = "", filePath = "") = 60 | dos_qguiapplication_download_imageByUrl(url.cstring, filePath.cstring) 61 | 62 | proc enableHDPI*(uiScaleFilePath: string) = 63 | dos_qguiapplication_enable_hdpi(uiScaleFilePath) 64 | 65 | proc initializeOpenGL*() = 66 | dos_qguiapplication_initialize_opengl() 67 | 68 | proc initializeWebView*() = 69 | dos_qtwebview_initialize() 70 | 71 | proc tryEnableThreadedRenderer*() = 72 | dos_qguiapplication_try_enable_threaded_renderer() 73 | 74 | proc applicationDirPath*(app: QGuiApplication): string = 75 | let str = dos_qguiapplication_application_dir_path() 76 | result = $str 77 | dos_chararray_delete(str) 78 | 79 | proc installMessageHandler*(handler: DosMessageHandler) = 80 | dos_installMessageHandler(handler) 81 | -------------------------------------------------------------------------------- /src/nimqml/private/qhashintbytearray.nim: -------------------------------------------------------------------------------- 1 | proc setup*(self: QHashIntByteArray) = 2 | ## Setup the QHash 3 | self.vptr = dos_qhash_int_qbytearray_create() 4 | 5 | proc delete*(self: QHashIntByteArray) = 6 | ## Delete the QHash 7 | if self.vptr.isNil: 8 | return 9 | debugMsg("QHashIntByteArray", "delete") 10 | dos_qhash_int_qbytearray_delete(self.vptr) 11 | self.vptr.resetToNil 12 | 13 | proc newQHashIntQByteArray*(): QHashIntByteArray = 14 | ## Create a new QHashIntQByteArray 15 | new(result, delete) 16 | result.setup() 17 | 18 | proc insert*(self: QHashIntByteArray, key: int, value: cstring) = 19 | ## Insert the value at the given key 20 | dos_qhash_int_qbytearray_insert(self.vptr, key, value) 21 | 22 | proc value*(self: QHashIntByteArray, key: int): string = 23 | ## Return the value associated at the given key 24 | let str = dos_qhash_int_qbytearray_value(self.vptr, key) 25 | result = $str 26 | dos_chararray_delete(str) 27 | -------------------------------------------------------------------------------- /src/nimqml/private/qmetaobject.nim: -------------------------------------------------------------------------------- 1 | proc delete*(metaObject: QMetaObject) = 2 | ## Delete a QMetaObject 3 | debugMsg("QMetaObject", "delete") 4 | if metaObject.vptr.isNil: 5 | return 6 | dos_qmetaobject_delete(metaObject.vptr) 7 | metaObject.vptr.resetToNil 8 | 9 | proc newQObjectMetaObject*(): QMetaObject = 10 | ## Create the QMetaObject of QObject 11 | debugMsg("QMetaObject", "newQObjectMetaObject") 12 | new(result, delete) 13 | result.vptr = dos_qobject_qmetaobject() 14 | 15 | proc newQAbstractItemModelMetaObject*(): QMetaObject = 16 | ## Create the QMetaObject of QAbstractItemModel 17 | debugMsg("QMetaObject", "newQAbstractItemModelMetaObject") 18 | new(result, delete) 19 | result.vptr = dos_qabstractitemmodel_qmetaobject() 20 | 21 | proc newQAbstractListModelMetaObject*(): QMetaObject = 22 | ## Create the QMetaObject of QAbstractListModel 23 | debugMsg("QMetaObject", "newQAbstractListModelMetaObject") 24 | new(result, delete) 25 | result.vptr = dos_qabstractlistmodel_qmetaobject() 26 | 27 | proc newQAbstractTableModelMetaObject*(): QMetaObject = 28 | ## Create the QMetaObject of QAbstractTableModel 29 | debugMsg("QMetaObject", "newQAbstractItemTableMetaObject") 30 | new(result, delete) 31 | result.vptr = dos_qabstracttablemodel_qmetaobject() 32 | 33 | proc newQMetaObject*(superClass: QMetaObject, className: string, 34 | signals: seq[SignalDefinition], 35 | slots: seq[SlotDefinition], 36 | properties: seq[PropertyDefinition]): QMetaObject = 37 | ## Create a new QMetaObject 38 | debugMsg("QMetaObject", "newQMetaObject") 39 | new(result, delete) 40 | result.signals = signals 41 | result.slots = slots 42 | result.properties = properties 43 | 44 | var dosParameters: seq[seq[DosParameterDefinition]] = @[] 45 | 46 | var dosSignals: seq[DosSignalDefinition] = @[] 47 | for i in 0.. 0: parameters[0].unsafeAddr else: nil) 55 | dosSignals.add(dosSignal) 56 | 57 | var dosSlots: seq[DosSlotDefinition] = @[] 58 | for i in 0.. 0: parameters[0].unsafeAddr else: nil) 68 | dosSlots.add(dosSlot) 69 | 70 | var dosProperties: seq[DosPropertyDefinition] = @[] 71 | for i in 0.. 0: dosSignals[0].unsafeAddr else: nil) 83 | let slots = DosSlotDefinitions(count: dosSlots.len.cint, definitions: if dosSlots.len > 0: dosSlots[0].unsafeAddr else: nil) 84 | let properties = DosPropertyDefinitions(count: dosProperties.len.cint, definitions: if dosProperties.len > 0: dosProperties[0].unsafeAddr else: nil) 85 | 86 | result.vptr = dos_qmetaobject_create(superClass.vptr, className.cstring, signals.unsafeAddr, slots.unsafeAddr, properties.unsafeAddr) 87 | -------------------------------------------------------------------------------- /src/nimqml/private/qmodelindex.nim: -------------------------------------------------------------------------------- 1 | proc setup*(self: QModelIndex) = 2 | ## Setup a new QModelIndex 3 | self.vptr = dos_qmodelindex_create() 4 | 5 | proc setup(self: QModelIndex, other: DosQModelIndex, takeOwnership: Ownership) = 6 | ## Setup a new QModelIndex 7 | self.vptr = if takeOwnership == Ownership.Take: other else: dos_qmodelindex_create_qmodelindex(other) 8 | 9 | proc delete*(self: QModelIndex) = 10 | ## Delete the given QModelIndex 11 | if self.vptr.isNil: 12 | return 13 | debugMsg("QModelIndex", "delete") 14 | dos_qmodelindex_delete(self.vptr) 15 | self.vptr.resetToNil 16 | 17 | proc newQModelIndex*(): QModelIndex = 18 | ## Return a new QModelIndex 19 | new(result, delete) 20 | result.setup() 21 | 22 | proc newQModelIndex(vptr: DosQModelIndex, takeOwnership: Ownership): QModelIndex = 23 | ## Return a new QModelIndex given a raw index 24 | new(result, delete) 25 | result.setup(vptr, takeOwnership) 26 | 27 | proc row*(self: QModelIndex): int = 28 | ## Return the index row 29 | dos_qmodelindex_row(self.vptr).int 30 | 31 | proc column*(self: QModelIndex): int = 32 | ## Return the index column 33 | dos_qmodelindex_column(self.vptr).int 34 | 35 | proc isValid*(self: QModelIndex): bool = 36 | ## Return true if the index is valid, false otherwise 37 | dos_qmodelindex_isValid(self.vptr) 38 | 39 | proc data*(self: QModelIndex, role: cint): QVariant = 40 | ## Return the model data associated to the given role 41 | newQVariant(dos_qmodelindex_data(self.vptr, role), Ownership.Take) 42 | 43 | proc parent*(self: QModelIndex): QModelIndex = 44 | ## Return the parent index 45 | newQModelIndex(dos_qmodelindex_parent(self.vptr), Ownership.Take) 46 | 47 | proc child*(self: QModelIndex, row: cint, column: cint): QModelIndex = 48 | ## Return the child index associated to the given row and column 49 | newQModelIndex(dos_qmodelindex_child(self.vptr, row, column), Ownership.Take) 50 | 51 | proc sibling*(self: QModelIndex, row: cint, column: cint): QModelIndex = 52 | ## Return the sibling index associated to the given row and column 53 | newQModelIndex(dos_qmodelindex_sibling(self.vptr, row, column), Ownership.Take) 54 | 55 | proc internalPointer(self: QModelIndex): pointer = 56 | ## Return the internal pointer 57 | dos_qmodelindex_internalPointer(self.vptr) 58 | -------------------------------------------------------------------------------- /src/nimqml/private/qnetworkconfigurationmanager.nim: -------------------------------------------------------------------------------- 1 | proc setup*(self: QNetworkConfigurationManager) = 2 | ## Setup a new QUrl 3 | self.vptr = dos_qncm_create() 4 | 5 | proc delete*(self: QNetworkConfigurationManager) = 6 | ## Delete a QUrl 7 | if self.vptr.isNil: 8 | return 9 | dos_qncm_delete(self.vptr) 10 | self.vptr.resetToNil 11 | 12 | proc newQNetworkConfigurationManager*(): QNetworkConfigurationManager = 13 | new(result, delete) 14 | result.setup() 15 | 16 | 17 | proc setup*(self: QNetworkAccessManagerFactory, tmpPath: string) = 18 | self.vptr = dos_qqmlnetworkaccessmanagerfactory_create(tmpPath.cstring) 19 | 20 | proc delete*(self: QNetworkAccessManagerFactory) = 21 | if self.vptr.isNil: 22 | return 23 | self.vptr.resetToNil 24 | 25 | proc newQNetworkAccessManagerFactory*(tmpPath: string): QNetworkAccessManagerFactory = 26 | new(result, delete) 27 | result.setup(tmpPath) 28 | 29 | proc setup*(self: QNetworkAccessManager, vptr: DosQQNetworkAccessManager) = 30 | self.vptr = DosQObject(vptr) 31 | 32 | proc delete*(self: QNetworkAccessManager) = 33 | if self.vptr.isNil: 34 | return 35 | self.vptr.resetToNil 36 | 37 | proc newQNetworkAccessManager*(vptr: DosQQNetworkAccessManager): QNetworkAccessManager = 38 | new(result, delete) 39 | result.setup(vptr) 40 | 41 | proc clearConnectionCache*(self: QNetworkAccessManager) = 42 | dos_qqmlnetworkaccessmanager_clearconnectioncache(DosQQNetworkAccessManager(self.vptr)) 43 | 44 | proc setNetworkAccessible*(self: QNetworkAccessManager, accessibility: NetworkAccessibility) = 45 | dos_qqmlnetworkaccessmanager_setnetworkaccessible(DosQQNetworkAccessManager(self.vptr), accessibility.cint) 46 | 47 | -------------------------------------------------------------------------------- /src/nimqml/private/qobject.nim: -------------------------------------------------------------------------------- 1 | let qObjectStaticMetaObjectInstance = newQObjectMetaObject() 2 | 3 | proc staticMetaObject*(c: type QObject): QMetaObject = 4 | ## Return the metaObject of QObject 5 | qObjectStaticMetaObjectInstance 6 | 7 | proc staticMetaObject*(self: QObject): QMetaObject = 8 | ## Return the metaObject of QObject 9 | qObjectStaticMetaObjectInstance 10 | 11 | proc objectName*(self: QObject): string = 12 | ## Return the QObject name 13 | var str = dos_qobject_objectName(self.vptr) 14 | result = $str 15 | dos_chararray_delete(str) 16 | 17 | proc `objectName=`*(self: QObject, name: string) = 18 | ## Sets the Qobject name 19 | dos_qobject_setObjectName(self.vptr, name.cstring) 20 | 21 | method metaObject*(self: QObject): QMetaObject {.base.} = 22 | ## Return the metaObject 23 | QObject.staticMetaObject 24 | 25 | proc emit*(qobject: QObject, signalName: string, arguments: openarray[QVariant] = []) = 26 | if qobject.vptr.isNil: 27 | return 28 | 29 | ## Emit the signal with the given name and values 30 | var dosArguments: seq[DosQVariant] = @[] 31 | for argument in arguments: 32 | dosArguments.add(argument.vptr) 33 | let dosNumArguments = dosArguments.len.cint 34 | let dosArgumentsPtr: ptr DosQVariant = if dosArguments.len > 0: dosArguments[0].unsafeAddr else: nil 35 | dos_qobject_signal_emit(qobject.vptr, signalName.cstring, dosNumArguments, cast[ptr DosQVariantArray](dosArgumentsPtr)) 36 | 37 | method onSlotCalled*(self: QObject, slotName: string, arguments: openarray[QVariant]) {.base.} = 38 | ## Called from the dotherside library when a slot is called from Qml. 39 | discard() 40 | 41 | proc qobjectCallback(qobjectPtr: pointer, slotNamePtr: DosQVariant, dosArgumentsLength: cint, dosArguments: ptr DosQVariantArray) {.cdecl, exportc.} = 42 | ## Called from the dotherside library for invoking a slot 43 | let qobject = cast[QObject](qobjectPtr) 44 | GC_ref(qobject) 45 | # Retrieve slot name 46 | let slotName = newQVariant(slotNamePtr, Ownership.Clone) # Don't take ownership but clone 47 | defer: slotName.delete 48 | # Retrieve arguments 49 | let arguments = toQVariantSequence(dosArguments, dosArgumentsLength, Ownership.Clone) # Don't take ownership but clone 50 | defer: arguments.delete 51 | # Forward to args to the slot 52 | qobject.onSlotCalled(slotName.stringVal, arguments) 53 | # Update the slot return value 54 | dos_qvariant_assign(dosArguments[0], arguments[0].vptr) 55 | GC_unref(qobject) 56 | 57 | proc setup*(self: QObject) = 58 | ## Initialize a new QObject 59 | self.owner = true 60 | self.vptr = dos_qobject_create(addr(self[]), self.metaObject.vptr, qobjectCallback) 61 | 62 | 63 | proc delete*(self: QObject) = 64 | ## Delete a QObject 65 | if not self.owner or self.vptr.isNil: 66 | return 67 | dos_qobject_delete(self.vptr) 68 | self.vptr.resetToNil 69 | 70 | proc newQObject*(): QObject = 71 | ## Create a new QObject 72 | new(result, delete) 73 | result.setup() 74 | 75 | proc vptr*(self: QObject): DosQObject = 76 | result = self.vptr 77 | 78 | proc signalConnect*(sender: QObject, signal: string, receiver: QObject, slot: string, signalType: int = 0) = 79 | dos_qobject_signal_connect(sender.vptr, ("2" & signal).cstring, receiver.vptr, ("1" & slot).cstring, signalType.cint) 80 | -------------------------------------------------------------------------------- /src/nimqml/private/qqmlapplicationengine.nim: -------------------------------------------------------------------------------- 1 | proc setup*(self: QQmlApplicationEngine) = 2 | ## Setup a QQmlApplicationEngine 3 | self.vptr = dos_qqmlapplicationengine_create() 4 | 5 | proc loadData*(self: QQmlApplicationEngine, data: string) = 6 | ## Load the given data 7 | dos_qqmlapplicationengine_load_data(self.vptr, data.cstring) 8 | 9 | proc load*(self: QQmlApplicationEngine, filename: string) = 10 | ## Load the given Qml file 11 | dos_qqmlapplicationengine_load(self.vptr, filename.cstring) 12 | 13 | proc load*(self: QQmlApplicationEngine, url: QUrl) = 14 | ## Load the given Qml file 15 | dos_qqmlapplicationengine_load_url(self.vptr, url.vptr) 16 | 17 | proc getNetworkAccessManager*(self: QQmlApplicationEngine): DosQQNetworkAccessManager = 18 | dos_qqmlapplicationengine_getNetworkAccessManager(self.vptr) 19 | 20 | proc setNetworkAccessManagerFactory*(self: QQmlApplicationEngine, factory: QNetworkAccessManagerFactory) = 21 | dos_qqmlapplicationengine_setNetworkAccessManagerFactory(self.vptr, factory.vptr) 22 | 23 | proc addImportPath*(self: QQmlApplicationEngine, path: string) = 24 | ## Add an import path 25 | dos_qqmlapplicationengine_add_import_path(self.vptr, path.cstring) 26 | 27 | proc setRootContextProperty*(self: QQmlApplicationEngine, name: string, value: QVariant) = 28 | ## Set a root context property 29 | let context = dos_qqmlapplicationengine_context(self.vptr) 30 | dos_qqmlcontext_setcontextproperty(context, name.cstring, value.vptr) 31 | 32 | proc setTranslationPackage*(self: QQmlApplicationEngine, packagePath: string, shouldRetranslate: bool = true) = 33 | dos_qguiapplication_load_translation(self.vptr, packagePath.cstring, shouldRetranslate) 34 | 35 | proc delete*(self: QQmlApplicationEngine) = 36 | ## Delete the given QQmlApplicationEngine 37 | debugMsg("QQmlApplicationEngine", "delete") 38 | if self.vptr.isNil: 39 | return 40 | dos_qqmlapplicationengine_delete(self.vptr) 41 | self.vptr.resetToNil 42 | 43 | proc newQQmlApplicationEngine*(): QQmlApplicationEngine = 44 | ## Return a new QQmlApplicationEngine 45 | new(result, delete) 46 | result.setup() 47 | -------------------------------------------------------------------------------- /src/nimqml/private/qquickview.nim: -------------------------------------------------------------------------------- 1 | proc setup*(self: QQuickView) = 2 | ## Setup a new QQuickView 3 | self.vptr = dos_qquickview_create() 4 | 5 | proc delete*(self: QQuickView) = 6 | ## Delete the given QQuickView 7 | if self.vptr.isNil: 8 | return 9 | debugMsg("QQuickView", "delete") 10 | dos_qquickview_delete(self.vptr) 11 | self.vptr.resetToNil 12 | 13 | proc newQQuickView*(): QQuickView = 14 | ## Return a new QQuickView 15 | new(result, delete) 16 | result.setup() 17 | 18 | proc source*(self: QQuickView): string = 19 | ## Return the source Qml file loaded by the view 20 | let str = dos_qquickview_source(self.vptr) 21 | result = $str 22 | dos_chararray_delete(str) 23 | 24 | proc `source=`*(self: QQuickView, filename: cstring) = 25 | ## Sets the source Qml file laoded by the view 26 | dos_qquickview_set_source(self.vptr, filename) 27 | 28 | proc show*(self: QQuickView) = 29 | ## Sets the view visible 30 | dos_qquickview_show(self.vptr) 31 | -------------------------------------------------------------------------------- /src/nimqml/private/qresource.nim: -------------------------------------------------------------------------------- 1 | proc registerResource*(c: type QResource, filename: string) = 2 | dos_qresource_register(filename.cstring) 3 | -------------------------------------------------------------------------------- /src/nimqml/private/qsettings.nim: -------------------------------------------------------------------------------- 1 | type 2 | QSettingsFormat* {.pure.} = enum 3 | NativeFormat = 0 4 | IniFormat 5 | 6 | proc setup(self: QSettings, fileName: string, format: int) = 7 | self.vptr = dos_qsettings_create(fileName, format) 8 | 9 | proc delete*(self: QSettings) = 10 | dos_qsettings_delete(self.vptr) 11 | self.vptr.resetToNil 12 | 13 | proc newQSettings*(fileName: string, 14 | format: QSettingsFormat = QSettingsFormat.NativeFormat): QSettings = 15 | ## Available values for format are: 16 | ## 0 - QSettings::NativeFormat 17 | ## 1 - QSettings::IniFormat 18 | ## any other value will be converted to 0 (QSettings::NativeFormat) 19 | new(result, delete) 20 | result.setup(fileName, format.int) 21 | 22 | proc value*(self: QSettings, key: string, defaultValue: QVariant = newQVariant()): 23 | QVariant = 24 | newQVariant(dos_qsettings_value(self.vptr, key, defaultValue.vptr), Ownership.Take) 25 | 26 | proc setValue*(self: QSettings, key: string, value: QVariant) = 27 | dos_qsettings_set_value(self.vptr, key, value.vptr) 28 | 29 | proc remove*(self: QSettings, key: string) = 30 | dos_qsettings_remove(self.vptr, key) 31 | 32 | proc beginGroup*(self: QSettings, group: string) = 33 | dos_qsettings_begin_group(self.vptr, group) 34 | 35 | proc endGroup*(self: QSettings) = 36 | dos_qsettings_end_group(self.vptr) -------------------------------------------------------------------------------- /src/nimqml/private/qtimer.nim: -------------------------------------------------------------------------------- 1 | proc delete*(self: QTimer) = 2 | dos_qtimer_delete(self.vptr) 3 | self.vptr.resetToNil 4 | 5 | proc setup*(self: QTimer) = 6 | self.vptr = dos_qtimer_create() 7 | 8 | proc newQTimer*() : QTimer = 9 | new(result, delete) 10 | result.setup() 11 | 12 | proc setInterval*(self: QTimer, interval: int) = 13 | dos_qtimer_set_interval(self.vptr, interval) 14 | 15 | proc interval*(self: QTimer): int = 16 | return dos_qtimer_interval(self.vptr) 17 | 18 | proc start*(self:QTimer) = 19 | dos_qtimer_start(self.vptr) 20 | 21 | proc stop*(self:QTimer) = 22 | dos_qtimer_stop(self.vptr) 23 | 24 | proc setSingleShot*(self:QTimer, singleShot: bool) = 25 | dos_qtimer_set_single_shot(self.vptr, singleShot) 26 | 27 | proc isSingleShot*(self:QTimer): bool = 28 | return dos_qtimer_is_single_shot(self.vptr) 29 | 30 | proc isActive*(self:QTimer): bool = 31 | return dos_qtimer_is_active(self.vptr) 32 | -------------------------------------------------------------------------------- /src/nimqml/private/qurl.nim: -------------------------------------------------------------------------------- 1 | proc setup*(self: QUrl, url: string, mode: QUrlParsingMode) = 2 | ## Setup a new QUrl 3 | self.vptr = dos_qurl_create(url.cstring, mode.cint) 4 | 5 | proc delete*(self: QUrl) = 6 | ## Delete a QUrl 7 | if self.vptr.isNil: 8 | return 9 | debugMsg("QUrl", "delete") 10 | dos_qurl_delete(self.vptr) 11 | self.vptr.resetToNil 12 | 13 | proc newQUrl*(url: string, mode: QUrlParsingMode = QUrlParsingMode.Tolerant): QUrl = 14 | ## Create a new QUrl 15 | new(result, delete) 16 | result.setup(url, mode) 17 | 18 | proc toString*(self: QUrl): string = 19 | ## Return the url string 20 | let str: cstring = dos_qurl_to_string(self.vptr) 21 | result = $str 22 | dos_chararray_delete(str) 23 | -------------------------------------------------------------------------------- /src/nimqml/private/qvariant.nim: -------------------------------------------------------------------------------- 1 | proc setup*(variant: QVariant) = 2 | ## Setup a new QVariant 3 | variant.vptr = dos_qvariant_create() 4 | 5 | proc setup*(variant: QVariant, value: int | int32 | int64) = 6 | ## Setup a new QVariant given a cint value 7 | variant.vptr = 8 | when sizeof(value) == sizeof(cint): 9 | dos_qvariant_create_int(value.cint) 10 | else: 11 | dos_qvariant_create_longlong(value.clonglong) 12 | 13 | proc setup*(variant: QVariant, value: uint | uint32 | uint64) = 14 | ## Setup a new QVariant given a cint value 15 | variant.vptr = 16 | when sizeof(value) == sizeof(cuint): 17 | dos_qvariant_create_uint(value.cuint) 18 | else: 19 | dos_qvariant_create_ulonglong(value.culonglong) 20 | 21 | proc setup*(variant: QVariant, value: bool) = 22 | ## Setup a new QVariant given a bool value 23 | variant.vptr = dos_qvariant_create_bool(value) 24 | 25 | proc setup*(variant: QVariant, value: string) = 26 | ## Setup a new QVariant given a string value 27 | variant.vptr = dos_qvariant_create_string(value.cstring) 28 | 29 | proc setup*(variant: QVariant, value: QObject) = 30 | ## Setup a new QVariant given a QObject 31 | variant.vptr = dos_qvariant_create_qobject(value.vptr) 32 | 33 | proc setup*(variant: QVariant, value: DosQVariant, takeOwnership: Ownership) = 34 | ## Setup a new QVariant given another QVariant. 35 | ## The inner value of the QVariant is copied 36 | variant.vptr = if takeOwnership == Ownership.Take: value else: dos_qvariant_create_qvariant(value) 37 | 38 | proc setup*(variant: QVariant, value: cfloat) = 39 | ## Setup a new QVariant given a cfloat value 40 | variant.vptr = dos_qvariant_create_float(value) 41 | 42 | proc setup*(variant: QVariant, value: cdouble) = 43 | ## Setup a new QVariant given a cdouble value 44 | variant.vptr = dos_qvariant_create_double(value) 45 | 46 | proc setup*(variant: QVariant, value: QVariant) = 47 | ## Setup a new QVariant given another QVariant. 48 | ## The inner value of the QVariant is copied 49 | setup(variant, value.vptr, Ownership.Clone) 50 | 51 | proc delete*(variant: QVariant) = 52 | ## Delete a QVariant 53 | if variant.vptr.isNil: 54 | return 55 | debugMsg("QVariant", "delete") 56 | dos_qvariant_delete(variant.vptr) 57 | variant.vptr.resetToNil 58 | 59 | proc newQVariant*(): QVariant = 60 | ## Return a new QVariant 61 | new(result, delete) 62 | result.setup() 63 | 64 | proc newQVariant*(value: int | int32 | int64 | uint | uint32 | uint64): QVariant = 65 | ## Return a new QVariant given a cint 66 | new(result, delete) 67 | result.setup(value) 68 | 69 | proc newQVariant*(value: bool): QVariant = 70 | ## Return a new QVariant given a bool 71 | new(result, delete) 72 | result.setup(value) 73 | 74 | proc newQVariant*(value: string): QVariant = 75 | ## Return a new QVariant given a string 76 | new(result, delete) 77 | result.setup(value) 78 | 79 | proc newQVariant*(value: QObject): QVariant = 80 | ## Return a new QVariant given a QObject 81 | new(result, delete) 82 | result.setup(value) 83 | 84 | proc newQVariant(value: DosQVariant, takeOwnership: Ownership): QVariant = 85 | ## Return a new QVariant given a raw QVariant pointer 86 | new(result, delete) 87 | result.setup(value, takeOwnership) 88 | 89 | proc newQVariant*(value: QVariant): QVariant = 90 | ## Return a new QVariant given another QVariant 91 | new(result, delete) 92 | result.setup(value) 93 | 94 | proc newQVariant*(value: float): QVariant = 95 | ## Return a new QVariant given a float 96 | new(result, delete) 97 | result.setup(value.cdouble) 98 | 99 | proc newQVariant*(value: float32): QVariant = 100 | ## Return a new QVariant given a float 101 | new(result, delete) 102 | result.setup(value.cfloat) 103 | 104 | proc isNull*(variant: QVariant): bool = 105 | ## Return true if the QVariant value is null, false otherwise 106 | dos_qvariant_isnull(variant.vptr) 107 | 108 | proc intVal*(variant: QVariant): int = 109 | ## Return the QVariant value as int 110 | when sizeof(result) == sizeof(cint): 111 | dos_qvariant_toInt(variant.vptr).int 112 | else: 113 | dos_qvariant_toLongLong(variant.vptr).int 114 | 115 | proc `intVal=`*(variant: QVariant, value: int) = 116 | ## Sets the QVariant value int value 117 | when sizeof(value) == sizeof(cint): 118 | dos_qvariant_setInt(variant.vptr, value.cint) 119 | else: 120 | dos_qvariant_setLongLong(variant.vptr, value.clonglong) 121 | 122 | proc int32Val*(variant: QVariant): int32 = 123 | ## Return the QVariant value as int 124 | dos_qvariant_toInt(variant.vptr).int32 125 | 126 | proc `int32Val=`*(variant: QVariant, value: int32) = 127 | ## Sets the QVariant value int value 128 | dos_qvariant_setInt(variant.vptr, value.cint) 129 | 130 | proc int64Val*(variant: QVariant): int64 = 131 | ## Return the QVariant value as int 132 | dos_qvariant_toLongLong(variant.vptr).int64 133 | 134 | proc `int64Val=`*(variant: QVariant, value: int64) = 135 | ## Sets the QVariant value int value 136 | dos_qvariant_setLongLong(variant.vptr, value.clonglong) 137 | 138 | proc uintVal*(variant: QVariant): uint = 139 | ## Return the QVariant value as int 140 | when sizeof(result) == sizeof(cuint): 141 | dos_qvariant_toUInt(variant.vptr).uint 142 | else: 143 | dos_qvariant_toULongLong(variant.vptr).uint 144 | 145 | proc `uintVal=`*(variant: QVariant, value: uint) = 146 | ## Sets the QVariant value uint value 147 | when sizeof(value) == sizeof(cuint): 148 | dos_qvariant_setUInt(variant.vptr, value.cuint) 149 | else: 150 | dos_qvariant_setULongLong(variant.vptr, value.culonglong) 151 | 152 | proc uint32Val*(variant: QVariant): uint32 = 153 | ## Return the QVariant value as int 154 | dos_qvariant_toUInt(variant.vptr).uint32 155 | 156 | proc `uint32Val=`*(variant: QVariant, value: uint32) = 157 | ## Sets the QVariant value int value 158 | var rawValue = value.culonglong 159 | dos_qvariant_setUInt(variant.vptr, value.cuint) 160 | 161 | proc uint64Val*(variant: QVariant): uint64 = 162 | ## Return the QVariant value as int 163 | dos_qvariant_toULongLong(variant.vptr).uint64 164 | 165 | proc `uint64Val=`*(variant: QVariant, value: uint64) = 166 | ## Sets the QVariant value int value 167 | dos_qvariant_setULongLong(variant.vptr, value.culonglong) 168 | 169 | proc boolVal*(variant: QVariant): bool = 170 | ## Return the QVariant value as bool 171 | dos_qvariant_toBool(variant.vptr) 172 | 173 | proc `boolVal=`*(variant: QVariant, value: bool) = 174 | ## Sets the QVariant bool value 175 | dos_qvariant_setBool(variant.vptr, value) 176 | 177 | proc floatVal*(variant: QVariant): float = 178 | ## Return the QVariant value as float 179 | dos_qvariant_toFloat(variant.vptr).float 180 | 181 | proc `floatVal=`*(variant: QVariant, value: float) = 182 | ## Sets the QVariant float value 183 | dos_qvariant_setFloat(variant.vptr, value.cfloat) 184 | 185 | proc doubleVal*(variant: QVariant): cdouble = 186 | ## Return the QVariant value as double 187 | dos_qvariant_toDouble(variant.vptr) 188 | 189 | proc `doubleVal=`*(variant: QVariant, value: cdouble) = 190 | ## Sets the QVariant double value 191 | dos_qvariant_setDouble(variant.vptr, value) 192 | 193 | proc stringVal*(variant: QVariant): string = 194 | ## Return the QVariant value as string 195 | var rawCString = dos_qvariant_toString(variant.vptr) 196 | result = $rawCString 197 | dos_chararray_delete(rawCString) 198 | 199 | proc `stringVal=`*(variant: QVariant, value: string) = 200 | ## Sets the QVariant string value 201 | dos_qvariant_setString(variant.vptr, value) 202 | 203 | proc `qobjectVal=`*(variant: QVariant, value: QObject) = 204 | ## Sets the QVariant qobject value 205 | dos_qvariant_setQObject(variant.vptr, value.vptr) 206 | 207 | proc assign*(leftValue: QVariant, rightValue: QVariant) = 208 | ## Assign a QVariant with another. The inner value of the QVariant is copied 209 | dos_qvariant_assign(leftValue.vptr, rightValue.vptr) 210 | 211 | proc toQVariantSequence(a: ptr DosQVariantArray, length: cint, takeOwnership: Ownership): seq[QVariant] = 212 | ## Convert an array of DosQVariant to a sequence of QVariant 213 | result = @[] 214 | for i in 0..