qml 0.0.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
-