qml 0.0.7 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +3 -0
  3. data/.travis.yml +5 -9
  4. data/LICENSE.txt +1 -1
  5. data/README.md +84 -114
  6. data/changes.md +5 -0
  7. data/examples/fizzbuzz/fizzbuzz.rb +3 -4
  8. data/examples/todo_array/todo_array.rb +4 -4
  9. data/examples/todo_sequel/todo_sequel.rb +7 -7
  10. data/examples/twitter/twitter.rb +5 -3
  11. data/ext/qml/application.c +88 -0
  12. data/ext/qml/application.h +9 -0
  13. data/ext/qml/component.c +89 -0
  14. data/ext/qml/component.h +10 -0
  15. data/ext/qml/conversion.c +60 -0
  16. data/ext/qml/conversion.h +8 -0
  17. data/ext/qml/dispatcher.c +31 -0
  18. data/ext/qml/dispatcher.h +7 -0
  19. data/ext/qml/engine.c +135 -0
  20. data/ext/qml/engine.h +10 -0
  21. data/ext/qml/exporter.c +93 -0
  22. data/ext/qml/exporter.h +7 -0
  23. data/ext/qml/extconf.rb +38 -97
  24. data/ext/qml/interface.c +156 -0
  25. data/ext/qml/interface.h +11 -0
  26. data/ext/qml/js_array.c +47 -0
  27. data/ext/qml/js_array.h +7 -0
  28. data/ext/qml/js_function.c +109 -0
  29. data/ext/qml/js_function.h +7 -0
  30. data/ext/qml/js_object.c +284 -0
  31. data/ext/qml/js_object.h +19 -0
  32. data/ext/qml/js_wrapper.c +19 -0
  33. data/ext/qml/js_wrapper.h +7 -0
  34. data/ext/qml/lib/libqmlbind/.gitignore +38 -0
  35. data/ext/qml/lib/libqmlbind/.gitmodules +3 -0
  36. data/ext/qml/lib/libqmlbind/.travis.yml +14 -0
  37. data/ext/qml/lib/libqmlbind/LICENSE.txt +22 -0
  38. data/ext/qml/lib/libqmlbind/libqmlbind.pro +3 -0
  39. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind.h +14 -0
  40. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/application.h +18 -0
  41. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/component.h +21 -0
  42. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/engine.h +34 -0
  43. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/exporter.h +37 -0
  44. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/interface.h +16 -0
  45. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/iterator.h +19 -0
  46. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/metaobject.h +13 -0
  47. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/plugin.h +17 -0
  48. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/qmlbind_global.h +78 -0
  49. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/register.h +17 -0
  50. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/signal_emitter.h +15 -0
  51. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/string.h +15 -0
  52. data/ext/qml/lib/libqmlbind/qmlbind/include/qmlbind/value.h +100 -0
  53. data/ext/qml/lib/libqmlbind/qmlbind/qmlbind.pro +62 -0
  54. data/ext/qml/lib/libqmlbind/qmlbind/src/api_application.cpp +103 -0
  55. data/ext/qml/lib/libqmlbind/qmlbind/src/api_component.cpp +54 -0
  56. data/ext/qml/lib/libqmlbind/qmlbind/src/api_engine.cpp +65 -0
  57. data/ext/qml/lib/libqmlbind/qmlbind/src/api_exporter.cpp +52 -0
  58. data/ext/qml/lib/libqmlbind/qmlbind/src/api_interface.cpp +19 -0
  59. data/ext/qml/lib/libqmlbind/qmlbind/src/api_iterator.cpp +32 -0
  60. data/ext/qml/lib/libqmlbind/qmlbind/src/api_metaobject.cpp +19 -0
  61. data/ext/qml/lib/libqmlbind/qmlbind/src/api_plugin.cpp +27 -0
  62. data/ext/qml/lib/libqmlbind/qmlbind/src/api_register.cpp +17 -0
  63. data/ext/qml/lib/libqmlbind/qmlbind/src/api_signal_emitter.cpp +27 -0
  64. data/ext/qml/lib/libqmlbind/qmlbind/src/api_string.cpp +22 -0
  65. data/ext/qml/lib/libqmlbind/qmlbind/src/api_value.cpp +215 -0
  66. data/ext/qml/lib/libqmlbind/qmlbind/src/backref.cpp +54 -0
  67. data/ext/qml/lib/libqmlbind/qmlbind/src/backref.h +29 -0
  68. data/ext/qml/lib/libqmlbind/qmlbind/src/engine.cpp +32 -0
  69. data/ext/qml/lib/libqmlbind/qmlbind/src/engine.h +27 -0
  70. data/ext/qml/lib/libqmlbind/qmlbind/src/exporter.cpp +73 -0
  71. data/ext/qml/lib/libqmlbind/qmlbind/src/exporter.h +46 -0
  72. data/ext/qml/lib/libqmlbind/qmlbind/src/interface.cpp +75 -0
  73. data/ext/qml/lib/libqmlbind/qmlbind/src/interface.h +37 -0
  74. data/ext/qml/lib/libqmlbind/qmlbind/src/metaobject.cpp +101 -0
  75. data/ext/qml/lib/libqmlbind/qmlbind/src/metaobject.h +29 -0
  76. data/ext/qml/lib/libqmlbind/qmlbind/src/signalemitter.cpp +33 -0
  77. data/ext/qml/lib/libqmlbind/qmlbind/src/signalemitter.h +25 -0
  78. data/ext/qml/lib/libqmlbind/qmlbind/src/ticktimer.cpp +15 -0
  79. data/ext/qml/lib/libqmlbind/qmlbind/src/ticktimer.h +19 -0
  80. data/ext/qml/lib/libqmlbind/qmlbind/src/typeregisterer.cpp +112 -0
  81. data/ext/qml/lib/libqmlbind/qmlbind/src/typeregisterer.h +28 -0
  82. data/ext/qml/lib/libqmlbind/qmlbind/src/util.h +13 -0
  83. data/ext/qml/lib/libqmlbind/qmlbind/src/wrapper.cpp +23 -0
  84. data/ext/qml/lib/libqmlbind/qmlbind/src/wrapper.h +29 -0
  85. data/ext/qml/lib/libqmlbind/readme.md +14 -0
  86. data/ext/qml/lib/libqmlbind/test/api.c +1 -0
  87. data/ext/qml/lib/libqmlbind/test/application_test.cpp +16 -0
  88. data/ext/qml/lib/libqmlbind/test/component_test.cpp +57 -0
  89. data/ext/qml/lib/libqmlbind/test/engine_test.cpp +94 -0
  90. data/ext/qml/lib/libqmlbind/test/exporter_test.cpp +312 -0
  91. data/ext/qml/lib/libqmlbind/test/fixtures/emptyhandlers.cpp +36 -0
  92. data/ext/qml/lib/libqmlbind/test/fixtures/emptyhandlers.h +6 -0
  93. data/ext/qml/lib/libqmlbind/test/fixtures/test.qml +5 -0
  94. data/ext/qml/lib/libqmlbind/test/fixtures/testmodule/qmldir +2 -0
  95. data/ext/qml/lib/libqmlbind/test/fixtures/testmodule/test.qml +5 -0
  96. data/ext/qml/lib/libqmlbind/test/iterator_test.cpp +37 -0
  97. data/ext/qml/lib/libqmlbind/test/main.cpp +11 -0
  98. data/ext/qml/lib/libqmlbind/test/plugin_test.cpp +41 -0
  99. data/ext/qml/lib/libqmlbind/test/test.pro +26 -0
  100. data/ext/qml/lib/libqmlbind/test/test_helper.h +20 -0
  101. data/ext/qml/lib/libqmlbind/test/value_test.cpp +252 -0
  102. data/ext/qml/lib/libqmlbind/testplugin/testplugin.cpp +11 -0
  103. data/ext/qml/lib/libqmlbind/testplugin/testplugin.h +21 -0
  104. data/ext/qml/lib/libqmlbind/testplugin/testplugin.json +3 -0
  105. data/ext/qml/lib/libqmlbind/testplugin/testplugin.pro +21 -0
  106. data/ext/qml/meta_object.c +81 -0
  107. data/ext/qml/meta_object.h +8 -0
  108. data/ext/qml/plugin_loader.c +71 -0
  109. data/ext/qml/plugin_loader.h +7 -0
  110. data/ext/qml/qml.c +95 -0
  111. data/ext/qml/qml.h +10 -0
  112. data/ext/qml/rubyqml-plugin/listmodel.cpp +102 -0
  113. data/ext/qml/rubyqml-plugin/listmodel.h +37 -0
  114. data/ext/qml/rubyqml-plugin/rubyqml-plugin.pro +19 -0
  115. data/ext/qml/rubyqml-plugin/rubyqmlplugin.cpp +25 -0
  116. data/ext/qml/rubyqml-plugin/rubyqmlplugin.h +19 -0
  117. data/ext/qml/signal_emitter.c +71 -0
  118. data/ext/qml/signal_emitter.h +9 -0
  119. data/lib/qml.rb +11 -10
  120. data/lib/qml/access.rb +64 -86
  121. data/lib/qml/application.rb +20 -71
  122. data/lib/qml/component.rb +41 -33
  123. data/lib/qml/core_ext.rb +1 -0
  124. data/lib/qml/core_ext/to_qml.rb +70 -0
  125. data/lib/qml/data.rb +1 -0
  126. data/lib/qml/data/array_model.rb +99 -101
  127. data/lib/qml/data/list_model.rb +107 -131
  128. data/lib/qml/data/list_model_access.rb +44 -0
  129. data/lib/qml/data/query_model.rb +45 -47
  130. data/lib/qml/dispatcher.rb +5 -13
  131. data/lib/qml/engine.rb +9 -58
  132. data/lib/qml/errors.rb +0 -21
  133. data/lib/qml/interface.rb +21 -0
  134. data/lib/qml/js_array.rb +8 -0
  135. data/lib/qml/js_object.rb +69 -0
  136. data/lib/qml/js_util.rb +18 -0
  137. data/lib/qml/plugin_loader.rb +1 -13
  138. data/lib/qml/plugins.rb +3 -17
  139. data/lib/qml/proc_access.rb +28 -0
  140. data/lib/qml/qt.rb +21 -3
  141. data/lib/qml/reactive.rb +147 -8
  142. data/lib/qml/signal.rb +67 -0
  143. data/lib/qml/version.rb +1 -1
  144. data/qml.gemspec +8 -2
  145. data/spec/qml/access_spec.rb +33 -120
  146. data/spec/qml/application_spec.rb +11 -24
  147. data/spec/qml/component_spec.rb +4 -4
  148. data/spec/qml/data/array_model_spec.rb +2 -2
  149. data/spec/qml/data/list_model_spec.rb +2 -2
  150. data/spec/qml/data/query_model_spec.rb +4 -4
  151. data/spec/qml/engine_spec.rb +23 -21
  152. data/spec/qml/interface_spec.rb +20 -0
  153. data/spec/qml/js_array_spec.rb +29 -0
  154. data/spec/qml/js_function_spec.rb +32 -0
  155. data/spec/qml/js_object_spec.rb +113 -0
  156. data/spec/qml/plugin_loader_spec.rb +9 -11
  157. data/spec/qml/qt_spec.rb +9 -0
  158. data/spec/qml/reactive_spec.rb +37 -0
  159. data/spec/qml/signal_connect_spec.rb +27 -0
  160. data/spec/qml/signal_spec.rb +73 -0
  161. data/spec/qml/to_qml_spec.rb +76 -0
  162. data/spec/shared/qml/access_example.rb +21 -0
  163. data/spec/shared/qml/data/list_model.rb +12 -13
  164. data/spec/spec_helper.rb +2 -3
  165. metadata +141 -166
  166. data/examples/imageprovider/imageprovider.rb +0 -57
  167. data/examples/imageprovider/main.qml +0 -51
  168. data/ext/qml/accessclass.cpp +0 -65
  169. data/ext/qml/accessclass.h +0 -19
  170. data/ext/qml/accessobject.cpp +0 -30
  171. data/ext/qml/accessobject.h +0 -22
  172. data/ext/qml/common.h +0 -18
  173. data/ext/qml/conversionerror.h +0 -14
  174. data/ext/qml/ext_accesswrapperfactory.cpp +0 -75
  175. data/ext/qml/ext_accesswrapperfactory.h +0 -39
  176. data/ext/qml/ext_anywrapper.cpp +0 -34
  177. data/ext/qml/ext_anywrapper.h +0 -23
  178. data/ext/qml/ext_kernel.cpp +0 -81
  179. data/ext/qml/ext_kernel.h +0 -9
  180. data/ext/qml/ext_metaobject.cpp +0 -399
  181. data/ext/qml/ext_metaobject.h +0 -60
  182. data/ext/qml/ext_pluginloader.cpp +0 -53
  183. data/ext/qml/ext_pluginloader.h +0 -30
  184. data/ext/qml/ext_pointer.cpp +0 -132
  185. data/ext/qml/ext_pointer.h +0 -41
  186. data/ext/qml/ext_testutil.cpp +0 -40
  187. data/ext/qml/ext_testutil.h +0 -9
  188. data/ext/qml/foreignclass.cpp +0 -72
  189. data/ext/qml/foreignclass.h +0 -88
  190. data/ext/qml/foreignmetaobject.cpp +0 -345
  191. data/ext/qml/foreignmetaobject.h +0 -46
  192. data/ext/qml/foreignobject.cpp +0 -22
  193. data/ext/qml/foreignobject.h +0 -21
  194. data/ext/qml/functioninfo.h +0 -16
  195. data/ext/qml/init.cpp +0 -67
  196. data/ext/qml/kernel.cpp +0 -39
  197. data/ext/qml/kernel.h +0 -32
  198. data/ext/qml/listmodel.cpp +0 -137
  199. data/ext/qml/listmodel.h +0 -45
  200. data/ext/qml/markable.h +0 -12
  201. data/ext/qml/objectdata.cpp +0 -26
  202. data/ext/qml/objectdata.h +0 -20
  203. data/ext/qml/objectgc.cpp +0 -69
  204. data/ext/qml/objectgc.h +0 -28
  205. data/ext/qml/plugins/core/applicationextension.cpp +0 -29
  206. data/ext/qml/plugins/core/applicationextension.h +0 -25
  207. data/ext/qml/plugins/core/componentextension.cpp +0 -41
  208. data/ext/qml/plugins/core/componentextension.h +0 -28
  209. data/ext/qml/plugins/core/contextextension.cpp +0 -39
  210. data/ext/qml/plugins/core/contextextension.h +0 -29
  211. data/ext/qml/plugins/core/core.pro +0 -29
  212. data/ext/qml/plugins/core/coreplugin.cpp +0 -87
  213. data/ext/qml/plugins/core/coreplugin.h +0 -49
  214. data/ext/qml/plugins/core/engineextension.cpp +0 -43
  215. data/ext/qml/plugins/core/engineextension.h +0 -31
  216. data/ext/qml/plugins/core/imageprovider.cpp +0 -38
  217. data/ext/qml/plugins/core/imageprovider.h +0 -18
  218. data/ext/qml/plugins/core/imagerequestpromise.cpp +0 -19
  219. data/ext/qml/plugins/core/imagerequestpromise.h +0 -21
  220. data/ext/qml/plugins/core/qmlexception.cpp +0 -11
  221. data/ext/qml/plugins/core/qmlexception.h +0 -17
  222. data/ext/qml/plugins/testutil/imageprovidertest.cpp +0 -40
  223. data/ext/qml/plugins/testutil/imageprovidertest.h +0 -17
  224. data/ext/qml/plugins/testutil/objectlifechecker.cpp +0 -17
  225. data/ext/qml/plugins/testutil/objectlifechecker.h +0 -24
  226. data/ext/qml/plugins/testutil/ownershiptest.cpp +0 -26
  227. data/ext/qml/plugins/testutil/ownershiptest.h +0 -30
  228. data/ext/qml/plugins/testutil/testobject.cpp +0 -6
  229. data/ext/qml/plugins/testutil/testobject.h +0 -108
  230. data/ext/qml/plugins/testutil/testobjectsubclass.cpp +0 -10
  231. data/ext/qml/plugins/testutil/testobjectsubclass.h +0 -19
  232. data/ext/qml/plugins/testutil/testutil.pro +0 -22
  233. data/ext/qml/plugins/testutil/testutilplugin.cpp +0 -55
  234. data/ext/qml/plugins/testutil/testutilplugin.h +0 -36
  235. data/ext/qml/qmltyperegisterer.cpp +0 -74
  236. data/ext/qml/qmltyperegisterer.h +0 -30
  237. data/ext/qml/rubyclass.cpp +0 -82
  238. data/ext/qml/rubyclass.h +0 -230
  239. data/ext/qml/rubyvalue.cpp +0 -656
  240. data/ext/qml/rubyvalue.h +0 -224
  241. data/ext/qml/signalforwarder.cpp +0 -64
  242. data/ext/qml/signalforwarder.h +0 -29
  243. data/ext/qml/util.cpp +0 -112
  244. data/ext/qml/util.h +0 -82
  245. data/ext/qml/valuereference.cpp +0 -50
  246. data/ext/qml/valuereference.h +0 -22
  247. data/ext/qml/weakvaluereference.cpp +0 -51
  248. data/ext/qml/weakvaluereference.h +0 -21
  249. data/lib/qml/context.rb +0 -71
  250. data/lib/qml/data/error.rb +0 -5
  251. data/lib/qml/dispatchable.rb +0 -34
  252. data/lib/qml/error_converter.rb +0 -16
  253. data/lib/qml/geometry.rb +0 -3
  254. data/lib/qml/geometry/point.rb +0 -5
  255. data/lib/qml/geometry/rectangle.rb +0 -5
  256. data/lib/qml/geometry/size.rb +0 -5
  257. data/lib/qml/image_provider.rb +0 -87
  258. data/lib/qml/init.rb +0 -29
  259. data/lib/qml/meta_object.rb +0 -20
  260. data/lib/qml/models.rb +0 -1
  261. data/lib/qml/qt_classes.rb +0 -9
  262. data/lib/qml/qt_object_base.rb +0 -233
  263. data/lib/qml/reactive/bindable.rb +0 -79
  264. data/lib/qml/reactive/chained_signal.rb +0 -25
  265. data/lib/qml/reactive/error.rb +0 -5
  266. data/lib/qml/reactive/object.rb +0 -293
  267. data/lib/qml/reactive/property.rb +0 -19
  268. data/lib/qml/reactive/signal.rb +0 -115
  269. data/lib/qml/reactive/signal_spy.rb +0 -27
  270. data/lib/qml/reactive/signals/map_signal.rb +0 -21
  271. data/lib/qml/reactive/signals/merge_signal.rb +0 -21
  272. data/lib/qml/reactive/signals/select_signal.rb +0 -21
  273. data/lib/qml/reactive/simple_property.rb +0 -17
  274. data/lib/qml/reactive/unbound_property.rb +0 -42
  275. data/lib/qml/reactive/unbound_signal.rb +0 -51
  276. data/lib/qml/test_util.rb +0 -1
  277. data/lib/qml/test_util/object_life_checker.rb +0 -17
  278. data/lib/qml/wrappable.rb +0 -9
  279. data/spec/qml/context_spec.rb +0 -43
  280. data/spec/qml/conversion_spec.rb +0 -60
  281. data/spec/qml/dispatchable_spec.rb +0 -26
  282. data/spec/qml/dispatcher_spec.rb +0 -71
  283. data/spec/qml/geometry/point_spec.rb +0 -4
  284. data/spec/qml/geometry/rectangle_spec.rb +0 -4
  285. data/spec/qml/geometry/size_spec.rb +0 -4
  286. data/spec/qml/image_provider_spec.rb +0 -33
  287. data/spec/qml/qt_object_base_spec.rb +0 -119
  288. data/spec/qml/reactive/object_spec.rb +0 -249
  289. data/spec/qml/reactive/property_spec.rb +0 -70
  290. data/spec/qml/reactive/signal_spec.rb +0 -191
  291. data/spec/qml/reactive/signal_spy_spec.rb +0 -26
  292. data/spec/qml/reactive/unbound_property_spec.rb +0 -40
  293. data/spec/qml/reactive/unbound_signal_spec.rb +0 -70
  294. data/spec/qml/test_object_spec.rb +0 -186
  295. data/spec/qml/wrappable_spec.rb +0 -10
  296. data/spec/shared/qml/reactive/object.rb +0 -39
@@ -1 +0,0 @@
1
- require 'qml/models/array_model'
@@ -1,9 +0,0 @@
1
- require 'qml/plugins'
2
-
3
- module QML
4
- Application = Kernel.application_meta_object.build_class
5
- Engine = Kernel.engine_meta_object.build_class
6
- Context = Plugins.core.metaObjects['QQmlContext'].build_class
7
- Component = Plugins.core.metaObjects['QQmlComponent'].build_class
8
- Qt = Plugins.core.metaObjects['Qt'].build_class
9
- end
@@ -1,233 +0,0 @@
1
- require 'qml/dispatchable'
2
- require 'qml/name_helper'
3
-
4
- module QML
5
-
6
- class QtPropertyBase
7
- attr_reader :changed
8
-
9
- def initialize(metaobj, objptr, name)
10
- super()
11
- @metaobj = metaobj
12
- @objptr = objptr
13
- @name = name
14
- @changed = QtSignal.new(metaobj, objptr, @metaobj.notify_signal(@name))
15
- end
16
-
17
- def value=(newval)
18
- @metaobj.set_property(@objptr, @name, newval)
19
- end
20
-
21
- def value
22
- @metaobj.get_property(@objptr, @name)
23
- end
24
- end
25
-
26
- class QtProperty < QtPropertyBase
27
- include Reactive::Bindable
28
- end
29
-
30
- class QtSignal < Reactive::Signal
31
- def initialize(metaobj, objptr, name)
32
- super(nil)
33
- @objptr = objptr
34
- @metaobj = metaobj
35
- @name = name
36
- @initialized = false
37
- end
38
-
39
- private
40
-
41
- def connected(block)
42
- return if @initialized
43
- @metaobj.connect_signal(@objptr, @name, method(:emit))
44
- @initialized = true
45
- end
46
- end
47
-
48
- # {QtObjectBase} is the base class for Qt object wrappers.
49
- #
50
- # In ruby-qml you can access the followings of Qt objects in Ruby.
51
- #
52
- # * Properties as {Reactive::Property}
53
- # * Signals as {Reactive::Signal}
54
- # * Q_INVOKABLE methods, slots and QML methods as Ruby methods
55
- #
56
- # Properties and signals support is provided by {Reactive::Object}.
57
- #
58
- # While their names are camelCase in Qt, ruby-qml aliases them as underscore_case.
59
- #
60
- # @example
61
- # # QML::Application is actually a wrapper for QApplication
62
- # app = QML.application
63
- #
64
- # # set property
65
- # app.applicationName = "Test"
66
- # app.application_name = "Test" # aliased version
67
- #
68
- # # connect to signal
69
- # app.aboutToQuit.connect do # "about_to_quit" is also OK
70
- # puts "quitting..."
71
- # end
72
- #
73
- # # call slot
74
- # app.quit
75
- class QtObjectBase
76
- include Dispatchable
77
- include Reactive::Object
78
-
79
- # @api private
80
- class SubclassBuilder
81
-
82
- attr_reader :subclass
83
-
84
- def initialize(metaobj, klass)
85
- @metaobj = metaobj
86
- @subclass = klass
87
- end
88
-
89
- def build
90
- create unless @subclass
91
- return if @subclass.meta_object == @metaobj
92
-
93
- @metaobj.method_names.reject { |name| @metaobj.signal?(name) }.each do |name|
94
- define_method(name)
95
- end
96
- @metaobj.method_names.select { |name| @metaobj.signal?(name) }.each do |name|
97
- define_signal(name)
98
- end
99
- @metaobj.property_names.each do |name|
100
- define_property(name)
101
- end
102
- @metaobj.enumerators.each do |k, v|
103
- define_enum(k, v)
104
- end
105
- @subclass.__send__ :meta_object=, @metaobj
106
-
107
- self
108
- end
109
-
110
- private
111
-
112
- def create
113
- super_metaobj = @metaobj.super_class
114
- @subclass = Class.new(super_metaobj ? super_metaobj.build_class : QtObjectBase)
115
- end
116
-
117
- def define_method(name)
118
- metaobj = @metaobj
119
- return if metaobj.private?(name)
120
- underscore = NameHelper.to_underscore(name)
121
-
122
- @subclass.class_eval do
123
- define_method name do |*args|
124
- metaobj.invoke_method(@pointer, name, args)
125
- end
126
- private name if metaobj.protected?(name)
127
- alias_method underscore, name unless underscore == name
128
- end
129
- end
130
-
131
- def define_signal(name)
132
- metaobj = @metaobj
133
- underscore = NameHelper.to_underscore(name)
134
- @subclass.class_eval do
135
- variadic_signal name, signal: -> { QtSignal.new(metaobj, @pointer, name) }
136
- alias_signal underscore, name unless underscore == name
137
- end
138
- end
139
-
140
- def define_property(name)
141
- metaobj = @metaobj
142
- underscore = NameHelper.to_underscore(name)
143
- @subclass.class_eval do
144
- property name, nil, property: -> { QtProperty.new(metaobj, @pointer, name) }
145
- alias_property underscore, name unless underscore == name
146
- end
147
- end
148
-
149
- def define_enum(name, hash)
150
- define_const(name, hash.values.sort)
151
- hash.each do |k, v|
152
- define_const(k, v)
153
- end
154
- end
155
-
156
- def define_const(name, value)
157
- name = (name[0].capitalize + name[1..-1]).to_sym
158
- underscore = NameHelper.to_upper_underscore(name)
159
- @subclass.class_eval do
160
- const_set name, value
161
- const_set underscore, value unless underscore == name
162
- end
163
- end
164
- end
165
-
166
- class << self
167
- attr_accessor :meta_object
168
- private :meta_object=
169
- end
170
-
171
- attr_accessor :pointer
172
- private :pointer=
173
-
174
- # Evaluates a JavaScript expression on the QML context of the object.
175
- # Fails with {QMLError} when the object is not created by QML and does not belong to any context.
176
- # @param [String] str
177
- # @return the result.
178
- # @example
179
- # component = QML::Component.new data: <<-EOS
180
- # import QtQuick 2.0
181
- # QtObject {
182
- # property string foo: 'foo'
183
- # property string bar: 'bar'
184
- # }
185
- # EOS
186
- # obj = component.create
187
- # obj.qml_eval("foo + bar") #=> "foobar"
188
- def qml_eval(str)
189
- context = Context.for_object(self)
190
- fail QMLError, 'belongs to no context' unless context
191
- context.eval(self, str)
192
- end
193
-
194
- def inspect
195
- klass = self.class
196
- property_inspect = klass.instance_properties.sort
197
- .reject { |name| klass.instance_property(name).alias? }
198
- .map do |name|
199
- "#{name}=" +
200
- begin
201
- property(name).value.inspect
202
- rescue ConversionError
203
- "<unsupported type>"
204
- end
205
- end
206
- .join(' ')
207
- classname = klass.name || "[class for #{klass.meta_object.name}]"
208
- "#<#{classname}:#{__id__} #{property_inspect}>"
209
- end
210
-
211
- alias_method :to_s, :inspect
212
-
213
- # @return whether the object is managed by Ruby and QML and garbage collected when no longer used.
214
- def managed?
215
- pointer.managed?
216
- end
217
-
218
- # Sets the management status of the object.
219
- # @param [Boolean] managed
220
- # @return [Boolean]
221
- def managed=(managed)
222
- pointer.managed = managed
223
- end
224
-
225
- # Sets the management status of the object in safer way.
226
- # Objects that are created by QML will remain managed and objects that have parents will remain unmanaged.
227
- # @param [Boolean] managed
228
- # @return [Boolean]
229
- def prefer_managed(managed)
230
- pointer.prefer_managed managed
231
- end
232
- end
233
- end
@@ -1,79 +0,0 @@
1
- module QML
2
- module Reactive
3
- module Bindable
4
-
5
- def initialize(*args, &block)
6
- super
7
- @connections = []
8
- end
9
-
10
- # Sets a new value.
11
- # The old property binding is discarded.
12
- # @param new_value new value
13
- def value=(new_value, unbind = true)
14
- self.unbind if unbind
15
- unless value == new_value
16
- super(new_value)
17
- changed.emit(new_value)
18
- end
19
- new_value
20
- end
21
-
22
- alias_method :set_value, :value=
23
-
24
- # @return The property value
25
- def value
26
- touch
27
- super
28
- end
29
-
30
- # @api private
31
- module Resolver
32
- @sources_stack = []
33
- class << self
34
- def eval_and_resolve(&block)
35
- @sources_stack.push([])
36
- ret = block.call
37
- [ret, @sources_stack.pop]
38
- end
39
-
40
- def add(property)
41
- current = @sources_stack.last
42
- current && current << property
43
- end
44
- end
45
- end
46
-
47
- # Sets a property binding.
48
- # The block is re-evaluated when any of other properties used in it is updated
49
- # and the result is used as the new property value.
50
- # @yield
51
- # @example
52
- # p1 = Property.new
53
- # p2 = Property.new
54
- # p1.bind { p2.value + 1 }
55
- # p2.value = 10
56
- # p1.value #=> 11
57
- # @return The property value
58
- def bind(&block)
59
- unbind
60
- value, sources = Resolver.eval_and_resolve(&block)
61
- set_value(value, false)
62
- @connections = sources.map do |source|
63
- fail Error, 'Recursive binding' if source == self
64
- source.changed.connect { set_value(block.call, false) }
65
- end
66
- end
67
-
68
- def unbind
69
- @connections.each(&:disconnect)
70
- end
71
-
72
- private
73
-
74
- def touch
75
- Resolver.add(self)
76
- end
77
- end
78
- end
79
- end
@@ -1,25 +0,0 @@
1
- require 'qml/reactive/signal'
2
-
3
- module QML
4
- module Reactive
5
- class ChainedSignal < Signal
6
- private
7
- def connected(listener)
8
- if connection_count == 1
9
- @connections = Array(connect_to_sources)
10
- end
11
- end
12
-
13
- def disconnected(listener)
14
- if connection_count == 0
15
- @connections.each(&:disconnect)
16
- @connections = nil
17
- end
18
- end
19
-
20
- def connect_to_sources
21
- fail NotImplementedError
22
- end
23
- end
24
- end
25
- end
@@ -1,5 +0,0 @@
1
- module QML
2
- module Reactive
3
- class Error < ::StandardError; end
4
- end
5
- end
@@ -1,293 +0,0 @@
1
- require 'qml/reactive/unbound_signal'
2
- require 'qml/reactive/unbound_property'
3
-
4
- module QML
5
- module Reactive
6
-
7
- # {Object} is used to define signals and properties within class definition.
8
- # Signals and properties will be inherited by and can be overridden in subclasses.
9
- # @note Currently {Object} can be included only by classes, not modules.
10
- # @see Object::ClassMethods
11
- module Object
12
-
13
- # When {Object} is included by a class, the class extends {ClassMethods} to add the common class methods.
14
- def self.included(derived)
15
- fail Error, "#{Object} must be included in a class" unless derived.is_a? ::Class
16
- derived.extend(ClassMethods)
17
- end
18
-
19
- def initialize(*args, &block)
20
- # prepare properties
21
- properties = self.class.instance_property_hash
22
- .values
23
- .map { |property| self.class.instance_property(property.original) }
24
- .uniq
25
- properties.each do |property|
26
- instance_variable_set("@_property_#{property.name}", property.bind(self))
27
- end
28
-
29
- # prepare signals
30
- signals = self.class.instance_signal_hash
31
- .values
32
- .map { |signal| self.class.instance_signal(signal.original) }
33
- .uniq
34
- signals.each do |signal|
35
- instance_variable_set("@_signal_#{signal.name}", signal.bind(self))
36
- end
37
-
38
- # prepare signal connections
39
- self.class.send(:initial_connections_hash).each do |name, blocks|
40
- blocks.each do |block|
41
- signal(name).connect do |*args|
42
- instance_exec(*args, &block)
43
- end
44
- end
45
- end
46
-
47
- super
48
- end
49
-
50
- # @!method signal(name)
51
- # Returns a signal.
52
- # @param name [Symbol] The signal name
53
- # @return [QML::Reactive::Signal]
54
-
55
- # @!method signals
56
- # Returns all signal names.
57
- # @return [Array<Symbol>]
58
-
59
- # @!method property(name)
60
- # Returns a property.
61
- # @param name [Symbol] The property name
62
- # @return [QML::Reactive::Property]
63
-
64
- # @!method properties
65
- # Returns all property names.
66
- # @return [Array<Symbol>]
67
-
68
- [%w{signal signals}, %w{property properties}].each do |singular, plural|
69
- class_eval <<-EOS, __FILE__, __LINE__ + 1
70
- def #{singular}(name)
71
- name = self.class.instance_#{singular}(name).original
72
- instance_variable_get(:"@_#{singular}_\#{name}") or
73
- fail ::NameError, "undefined #{singular} '\#{name}' for class '\#{self.class}'"
74
- end
75
-
76
- def #{plural}
77
- self.class.instance_#{plural}
78
- end
79
- EOS
80
- end
81
-
82
- # @!parse extend ClassMethods
83
-
84
- module ClassMethods
85
-
86
- # @!method instance_signals(include_super = true)
87
- # Returns all signal names for the class.
88
- # @param include_super [true|false]
89
- # @return [Array<Symbol>]
90
-
91
- # @!method instance_signal(name)
92
- # Returns an unbound signal.
93
- # @param name [Symbol] The signal name
94
- # @return [QML::Reactive::UnboundSignal]
95
-
96
- # @!method instance_properties(include_super = true)
97
- # Returns all property names for the class.
98
- # @param include_super [true|false]
99
- # @return [Array<Symbol>]
100
-
101
- # @!method instance_property(name)
102
- # Returns an unbound property.
103
- # @param name [Symbol] The property name
104
- # @return [QML::Reactive::UnboundProperty]
105
- [%w{signal signals}, %w{property properties}].each do |singular, plural|
106
- class_eval <<-EOS, __FILE__, __LINE__ + 1
107
- def instance_#{singular}_hash(include_super = true)
108
- if include_super && superclass.include?(Object)
109
- superclass.instance_#{singular}_hash.merge instance_#{singular}_hash(false)
110
- else
111
- @instance_#{singular}_hash ||= {}
112
- end
113
- end
114
-
115
- def instance_#{plural}(include_super = true)
116
- instance_#{singular}_hash(include_super).keys
117
- end
118
-
119
- def instance_#{singular}(name)
120
- instance_#{singular}_hash[name] or fail ::NameError, "undefined #{singular} '\#{name}' for class '\#{self}'"
121
- end
122
- EOS
123
- end
124
-
125
- # Defines a signal for the class.
126
- # The signal will be variadic if args == nil.
127
- # @param name [#to_sym] The signal name
128
- # @param params [Array<#to_sym>, nil] The signal parameter names
129
- # @param opts [Hash]
130
- # @option opts [Proc] :signal (nil)
131
- # @return [Symbol] The signal name
132
- # @example
133
- # class Button
134
- # include QML::Reactive::Object
135
- # signal :pressed, [:pos]
136
- # def press(pos)
137
- # pressed.emit(pos)
138
- # end
139
- # end
140
- #
141
- # button = Button.new
142
- # button.pressed.connect { |pos| puts "Pressed at #{pos}" }
143
- # button.press([10, 20])
144
- #
145
- # class ColorButton < Button
146
- # signal :pressed, [:pos, :color]
147
- # end
148
- #
149
- # color_button = ColorButton.new
150
- # color_button.pressed.connect { |pos, color| "#{color} button pressed at #{pos}" }
151
- # color_button.press([10, 20], 'red')
152
- def signal(name, params, opts = {})
153
- name.to_sym.tap do |name|
154
- params = params.map(&:to_sym)
155
- add_signal(UnboundSignal.new(name, params, false, self, opts[:signal]))
156
- end
157
- end
158
-
159
- # Defines a variadic signal.
160
- # Variadic signals do not restrict the number of arguments.
161
- # @param opts [Hash]
162
- # @option opts [Proc] :signal (nil)
163
- # @see #signal
164
- def variadic_signal(name, opts = {})
165
- name.to_sym.tap do |name|
166
- add_signal(UnboundSignal.new(name, nil, true, self, opts[:signal]))
167
- end
168
- end
169
-
170
- # Aliases a signal.
171
- # @param name [#to_sym]
172
- # @param original_name [#to_sym]
173
- # @return [Symbol] The new name
174
- def alias_signal(name, original_name)
175
- name.to_sym.tap do |name|
176
- original_name = original_name.to_sym
177
- add_signal(instance_signal(original_name).alias(name))
178
- end
179
- end
180
-
181
- # Defines a property for the class.
182
- # @param name [#to_sym] The name of the property
183
- # @param init_value The initial value (optional)
184
- # @param opts [Hash]
185
- # @option opts [Proc] :property (nil)
186
- # @yield The initial property binding (optional)
187
- # @return [Symbol] The name
188
- # @example
189
- # class Foo
190
- # include QML::Reactive::Object
191
- # property(:name) { 'hogehoge' }
192
- # ...
193
- # end
194
- # Foo.new.name #=> 'hogehoge'
195
- # Foo.new.name = 'foobar'
196
- # Foo.new.name #=> 'foobar'
197
- # Foo.new.name_changed.connect do |new_name|
198
- # ...
199
- #
200
- # class Bar < Foo
201
- # property(:name) { 'piyopiyo' }
202
- # end
203
- # Bar.new.name #=> 'piyopiyo'
204
- def property(name, init_value = nil, opts = {}, &init_binding)
205
- name.to_sym.tap do |name|
206
- add_property(UnboundProperty.new(name, init_value, init_binding, self, opts[:property]))
207
- signal("#{name}_changed", [:new_value], signal: -> { property(name).changed })
208
- end
209
- end
210
-
211
- # Aliases a property.
212
- # @param name [#to_sym]
213
- # @param original_name [#to_sym]
214
- # @return [Symbol] The new name
215
- def alias_property(name, original_name)
216
- name.to_sym.tap do |name|
217
- original_name = original_name.to_sym
218
- add_property(instance_property(original_name).alias(name))
219
- alias_signal("#{name}_changed", "#{original_name}_changed")
220
- end
221
- end
222
-
223
- # Adds a signal handler.
224
- # @param signal_name The name of the signal
225
- # @yield The block that is connected to the signal during object initialization
226
- def on(signal_name, &block)
227
- # just for check
228
- instance_signal(signal_name)
229
- @initial_connections_hash ||= {}
230
- @initial_connections_hash[signal_name] ||= []
231
- @initial_connections_hash[signal_name] << block
232
- end
233
-
234
- # Adds a handler to a property change signal.
235
- # @param property_name The name of the property
236
- # @yield The block that is connected to the property change signal during object initialization
237
- # @example
238
- # class Foo
239
- # property :bar, ''
240
- # on_changed :bar do
241
- # some_action
242
- # end
243
- # def some_action
244
- # ...
245
- # end
246
- # end
247
- # @see #on
248
- def on_changed(property_name, &block)
249
- on(:"#{property_name}_changed", &block)
250
- end
251
-
252
- private
253
-
254
- def add_signal(signal)
255
- instance_signal_hash(false)[signal.name] = signal
256
-
257
- class_eval <<-EOS, __FILE__, __LINE__ + 1
258
- def #{signal.name}
259
- @_signal_#{signal.original}
260
- end
261
- EOS
262
- end
263
-
264
- def add_property(property)
265
- instance_property_hash(false)[property.name] = property
266
-
267
- class_eval <<-EOS, __FILE__, __LINE__ + 1
268
- def #{property.name}(&block)
269
- @_property_#{property.original}.value(&block)
270
- end
271
- def #{property.name}=(new_value)
272
- @_property_#{property.original}.value = new_value
273
- end
274
- EOS
275
- end
276
-
277
- def initial_connections_hash(include_super = true)
278
- if include_super && superclass.include?(Object)
279
- superclass.send(:initial_connections_hash).dup.tap do |hash|
280
- initial_connections_hash(false).each do |key, blocks|
281
- hash[key] ||= []
282
- hash[key] += blocks
283
- end
284
- end
285
- else
286
- @initial_connections_hash ||= {}
287
- end
288
- end
289
- end
290
- end
291
- end
292
- end
293
-