├── .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..