reflexion 0.1.12 → 0.1.13

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 (329) hide show
  1. checksums.yaml +5 -5
  2. data/.doc/ext/reflex/application.cpp +9 -5
  3. data/.doc/ext/reflex/capture_event.cpp +0 -4
  4. data/.doc/ext/reflex/contact_event.cpp +17 -10
  5. data/.doc/ext/reflex/draw_event.cpp +1 -5
  6. data/.doc/ext/reflex/ellipse_shape.cpp +51 -24
  7. data/.doc/ext/reflex/event.cpp +0 -4
  8. data/.doc/ext/reflex/filter.cpp +81 -0
  9. data/.doc/ext/reflex/focus_event.cpp +9 -13
  10. data/.doc/ext/reflex/frame_event.cpp +40 -6
  11. data/.doc/ext/reflex/image_view.cpp +1 -10
  12. data/.doc/ext/reflex/key_event.cpp +2 -6
  13. data/.doc/ext/reflex/line_shape.cpp +99 -0
  14. data/.doc/ext/reflex/motion_event.cpp +75 -0
  15. data/.doc/ext/reflex/native.cpp +18 -18
  16. data/.doc/ext/reflex/pointer_event.cpp +5 -11
  17. data/.doc/ext/reflex/polygon_shape.cpp +65 -0
  18. data/.doc/ext/reflex/rect_shape.cpp +102 -23
  19. data/.doc/ext/reflex/reflex.cpp +21 -2
  20. data/.doc/ext/reflex/scroll_event.cpp +0 -6
  21. data/.doc/ext/reflex/selector.cpp +43 -15
  22. data/.doc/ext/reflex/shape.cpp +211 -0
  23. data/.doc/ext/reflex/style.cpp +359 -185
  24. data/.doc/ext/reflex/style_length.cpp +163 -35
  25. data/.doc/ext/reflex/timer.cpp +101 -0
  26. data/.doc/ext/reflex/timer_event.cpp +123 -0
  27. data/.doc/ext/reflex/update_event.cpp +11 -6
  28. data/.doc/ext/reflex/view.cpp +548 -144
  29. data/.doc/ext/reflex/wheel_event.cpp +0 -22
  30. data/.doc/ext/reflex/window.cpp +7 -15
  31. data/README.md +1 -1
  32. data/Rakefile +14 -12
  33. data/VERSION +1 -1
  34. data/ext/reflex/application.cpp +10 -5
  35. data/ext/reflex/capture_event.cpp +1 -5
  36. data/ext/reflex/contact_event.cpp +19 -11
  37. data/ext/reflex/defs.h +5 -2
  38. data/ext/reflex/draw_event.cpp +2 -6
  39. data/ext/reflex/ellipse_shape.cpp +56 -25
  40. data/ext/reflex/event.cpp +0 -4
  41. data/ext/reflex/extconf.rb +1 -2
  42. data/ext/reflex/filter.cpp +86 -0
  43. data/ext/reflex/focus_event.cpp +11 -15
  44. data/ext/reflex/frame_event.cpp +46 -7
  45. data/ext/reflex/image_view.cpp +1 -10
  46. data/ext/reflex/key_event.cpp +3 -7
  47. data/ext/reflex/line_shape.cpp +104 -0
  48. data/ext/reflex/motion_event.cpp +79 -0
  49. data/ext/reflex/native.cpp +18 -18
  50. data/ext/reflex/pointer_event.cpp +6 -12
  51. data/ext/reflex/polygon_shape.cpp +68 -0
  52. data/ext/reflex/rect_shape.cpp +113 -24
  53. data/ext/reflex/reflex.cpp +21 -2
  54. data/ext/reflex/scroll_event.cpp +1 -7
  55. data/ext/reflex/selector.cpp +46 -16
  56. data/ext/reflex/selector.h +130 -0
  57. data/ext/reflex/shape.cpp +231 -0
  58. data/ext/reflex/style.cpp +363 -192
  59. data/ext/reflex/style_length.cpp +164 -37
  60. data/ext/reflex/timer.cpp +108 -0
  61. data/ext/reflex/timer_event.cpp +133 -0
  62. data/ext/reflex/update_event.cpp +13 -7
  63. data/ext/reflex/view.cpp +594 -150
  64. data/ext/reflex/wheel_event.cpp +1 -25
  65. data/ext/reflex/window.cpp +7 -15
  66. data/include/reflex/application.h +2 -0
  67. data/include/reflex/debug.h +22 -0
  68. data/include/reflex/defs.h +45 -0
  69. data/include/reflex/event.h +60 -16
  70. data/include/reflex/exception.h +9 -0
  71. data/include/reflex/filter.h +56 -0
  72. data/include/reflex/image_view.h +1 -1
  73. data/include/reflex/ruby/application.h +17 -9
  74. data/include/reflex/ruby/event.h +22 -0
  75. data/include/reflex/ruby/filter.h +69 -0
  76. data/include/reflex/ruby/selector.h +1 -1
  77. data/include/reflex/ruby/shape.h +140 -0
  78. data/include/reflex/ruby/style.h +1 -1
  79. data/include/reflex/ruby/timer.h +69 -0
  80. data/include/reflex/ruby/view.h +43 -76
  81. data/include/reflex/ruby/window.h +17 -32
  82. data/include/reflex/ruby.h +6 -4
  83. data/include/reflex/selector.h +54 -2
  84. data/include/reflex/shape.h +211 -0
  85. data/include/reflex/style.h +111 -77
  86. data/include/reflex/timer.h +73 -0
  87. data/include/reflex/view.h +181 -59
  88. data/include/reflex/window.h +4 -3
  89. data/include/reflex.h +5 -4
  90. data/lib/reflex/application.rb +6 -3
  91. data/lib/reflex/button.rb +2 -2
  92. data/lib/reflex/capture_event.rb +7 -6
  93. data/lib/reflex/contact_event.rb +10 -12
  94. data/lib/reflex/draw_event.rb +6 -1
  95. data/lib/reflex/ellipse_shape.rb +27 -0
  96. data/lib/reflex/filter.rb +18 -0
  97. data/lib/reflex/fixture.rb +4 -0
  98. data/lib/reflex/focus_event.rb +10 -12
  99. data/lib/reflex/frame_event.rb +1 -1
  100. data/lib/reflex/helper.rb +17 -29
  101. data/lib/reflex/key_event.rb +13 -11
  102. data/lib/reflex/line_shape.rb +18 -0
  103. data/lib/reflex/{texture.rb → matrix.rb} +2 -2
  104. data/lib/reflex/module.rb +4 -19
  105. data/lib/reflex/pointer_event.rb +26 -37
  106. data/lib/reflex/polygon.rb +14 -0
  107. data/lib/reflex/polygon_shape.rb +23 -0
  108. data/lib/reflex/polyline.rb +13 -0
  109. data/lib/reflex/rect_shape.rb +20 -0
  110. data/lib/reflex/reflex.rb +1 -3
  111. data/lib/reflex/scroll_event.rb +1 -1
  112. data/lib/reflex/selector.rb +2 -2
  113. data/lib/reflex/shape.rb +62 -0
  114. data/lib/reflex/style.rb +78 -11
  115. data/lib/reflex/style_length.rb +0 -11
  116. data/lib/reflex/text_view.rb +7 -24
  117. data/lib/reflex/timer.rb +30 -0
  118. data/lib/reflex/timer_event.rb +29 -0
  119. data/lib/reflex/update_event.rb +1 -1
  120. data/lib/reflex/view.rb +127 -32
  121. data/lib/reflex/wheel_event.rb +9 -1
  122. data/lib/reflex/window.rb +29 -9
  123. data/lib/reflex.rb +11 -5
  124. data/lib/reflexion.rb +23 -7
  125. data/reflex.gemspec +8 -10
  126. data/samples/bats.rb +4 -4
  127. data/samples/fans.rb +1 -1
  128. data/samples/fps.rb +5 -3
  129. data/samples/hello.rb +4 -6
  130. data/samples/image.rb +5 -4
  131. data/samples/ios/hello/hello.xcodeproj/project.pbxproj +0 -2
  132. data/samples/layout.rb +16 -7
  133. data/samples/model.rb +10 -7
  134. data/samples/physics.rb +22 -20
  135. data/samples/reflexion/breakout.rb +4 -5
  136. data/samples/reflexion/hello.rb +2 -2
  137. data/samples/reflexion/jump_action.rb +191 -0
  138. data/samples/reflexion/noise.rb +23 -0
  139. data/samples/reflexion/paint.rb +7 -6
  140. data/samples/reflexion/physics.rb +15 -8
  141. data/samples/reflexion/pulse.rb +24 -10
  142. data/samples/shader.rb +8 -6
  143. data/samples/shapes.rb +63 -14
  144. data/samples/tree.rb +9 -10
  145. data/samples/views.rb +3 -3
  146. data/samples/visuals.rb +2 -5
  147. data/src/body.cpp +146 -345
  148. data/src/body.h +91 -0
  149. data/src/event.cpp +66 -16
  150. data/src/exception.cpp +13 -3
  151. data/src/filter.cpp +76 -0
  152. data/src/fixture.cpp +164 -39
  153. data/src/fixture.h +85 -0
  154. data/src/image_view.cpp +4 -4
  155. data/src/ios/app_delegate.h +5 -10
  156. data/src/ios/app_delegate.mm +79 -41
  157. data/src/ios/application.h +32 -0
  158. data/src/ios/application.mm +35 -25
  159. data/src/ios/event.mm +8 -4
  160. data/src/ios/reflex.mm +0 -7
  161. data/src/ios/view_controller.h +33 -0
  162. data/src/ios/view_controller.mm +436 -0
  163. data/src/ios/window.h +40 -0
  164. data/src/ios/window.mm +59 -250
  165. data/src/osx/app_delegate.h +5 -10
  166. data/src/osx/app_delegate.mm +52 -55
  167. data/src/osx/application.h +32 -0
  168. data/src/osx/application.mm +44 -39
  169. data/src/osx/native_window.h +0 -15
  170. data/src/osx/native_window.mm +131 -115
  171. data/src/osx/opengl_view.h +0 -2
  172. data/src/osx/opengl_view.mm +12 -3
  173. data/src/osx/reflex.mm +0 -9
  174. data/src/osx/window.h +42 -0
  175. data/src/osx/window.mm +45 -252
  176. data/src/selector.cpp +232 -7
  177. data/src/selector.h +52 -0
  178. data/src/shape.cpp +1191 -0
  179. data/src/shape.h +61 -0
  180. data/src/style.cpp +571 -374
  181. data/src/style.h +39 -0
  182. data/src/timer.cpp +291 -0
  183. data/src/timer.h +55 -0
  184. data/src/view.cpp +1624 -984
  185. data/src/view.h +56 -0
  186. data/src/win32/window.cpp +3 -4
  187. data/src/window.cpp +275 -20
  188. data/src/window.h +92 -0
  189. data/src/world.cpp +112 -111
  190. data/src/world.h +34 -53
  191. data/task/box2d.rake +31 -10
  192. data/test/test_capture_event.rb +8 -6
  193. data/test/test_pointer_event.rb +85 -0
  194. data/test/test_selector.rb +1 -1
  195. data/test/test_shape.rb +71 -0
  196. data/test/test_style.rb +77 -11
  197. data/test/test_style_length.rb +42 -13
  198. data/test/test_view.rb +138 -14
  199. metadata +109 -210
  200. data/.doc/ext/reflex/arc_shape.cpp +0 -89
  201. data/.doc/ext/reflex/body.cpp +0 -299
  202. data/.doc/ext/reflex/fixture.cpp +0 -101
  203. data/.doc/ext/reflex/shape_view.cpp +0 -153
  204. data/ext/reflex/arc_shape.cpp +0 -94
  205. data/ext/reflex/body.cpp +0 -328
  206. data/ext/reflex/fixture.cpp +0 -108
  207. data/ext/reflex/shape_view.cpp +0 -161
  208. data/include/reflex/bitmap.h +0 -20
  209. data/include/reflex/body.h +0 -128
  210. data/include/reflex/bounds.h +0 -20
  211. data/include/reflex/color.h +0 -20
  212. data/include/reflex/color_space.h +0 -20
  213. data/include/reflex/fixture.h +0 -117
  214. data/include/reflex/font.h +0 -20
  215. data/include/reflex/image.h +0 -20
  216. data/include/reflex/matrix.h +0 -20
  217. data/include/reflex/painter.h +0 -20
  218. data/include/reflex/point.h +0 -24
  219. data/include/reflex/ruby/body.h +0 -41
  220. data/include/reflex/ruby/fixture.h +0 -41
  221. data/include/reflex/ruby/shape_view.h +0 -96
  222. data/include/reflex/shader.h +0 -20
  223. data/include/reflex/shape_view.h +0 -146
  224. data/include/reflex/texture.h +0 -20
  225. data/lib/reflex/body.rb +0 -22
  226. data/lib/reflex/flags.rb +0 -18
  227. data/lib/reflex/shape_view.rb +0 -25
  228. data/src/ios/application_data.h +0 -45
  229. data/src/ios/native_window.h +0 -39
  230. data/src/ios/native_window.mm +0 -224
  231. data/src/ios/opengl_view.h +0 -13
  232. data/src/ios/opengl_view.mm +0 -139
  233. data/src/ios/window_data.h +0 -75
  234. data/src/osx/application_data.h +0 -45
  235. data/src/osx/window_data.h +0 -75
  236. data/src/physics/Box2D/Box2D.h +0 -68
  237. data/src/physics/Box2D/Collision/Shapes/b2ChainShape.cpp +0 -193
  238. data/src/physics/Box2D/Collision/Shapes/b2ChainShape.h +0 -105
  239. data/src/physics/Box2D/Collision/Shapes/b2CircleShape.cpp +0 -99
  240. data/src/physics/Box2D/Collision/Shapes/b2CircleShape.h +0 -91
  241. data/src/physics/Box2D/Collision/Shapes/b2EdgeShape.cpp +0 -138
  242. data/src/physics/Box2D/Collision/Shapes/b2EdgeShape.h +0 -74
  243. data/src/physics/Box2D/Collision/Shapes/b2PolygonShape.cpp +0 -467
  244. data/src/physics/Box2D/Collision/Shapes/b2PolygonShape.h +0 -101
  245. data/src/physics/Box2D/Collision/Shapes/b2Shape.h +0 -101
  246. data/src/physics/Box2D/Collision/b2BroadPhase.cpp +0 -119
  247. data/src/physics/Box2D/Collision/b2BroadPhase.h +0 -257
  248. data/src/physics/Box2D/Collision/b2CollideCircle.cpp +0 -154
  249. data/src/physics/Box2D/Collision/b2CollideEdge.cpp +0 -698
  250. data/src/physics/Box2D/Collision/b2CollidePolygon.cpp +0 -239
  251. data/src/physics/Box2D/Collision/b2Collision.cpp +0 -252
  252. data/src/physics/Box2D/Collision/b2Collision.h +0 -277
  253. data/src/physics/Box2D/Collision/b2Distance.cpp +0 -603
  254. data/src/physics/Box2D/Collision/b2Distance.h +0 -141
  255. data/src/physics/Box2D/Collision/b2DynamicTree.cpp +0 -778
  256. data/src/physics/Box2D/Collision/b2DynamicTree.h +0 -289
  257. data/src/physics/Box2D/Collision/b2TimeOfImpact.cpp +0 -486
  258. data/src/physics/Box2D/Collision/b2TimeOfImpact.h +0 -58
  259. data/src/physics/Box2D/Common/b2BlockAllocator.cpp +0 -215
  260. data/src/physics/Box2D/Common/b2BlockAllocator.h +0 -62
  261. data/src/physics/Box2D/Common/b2Draw.cpp +0 -44
  262. data/src/physics/Box2D/Common/b2Draw.h +0 -86
  263. data/src/physics/Box2D/Common/b2GrowableStack.h +0 -85
  264. data/src/physics/Box2D/Common/b2Math.cpp +0 -94
  265. data/src/physics/Box2D/Common/b2Math.h +0 -720
  266. data/src/physics/Box2D/Common/b2Settings.cpp +0 -44
  267. data/src/physics/Box2D/Common/b2Settings.h +0 -151
  268. data/src/physics/Box2D/Common/b2StackAllocator.cpp +0 -83
  269. data/src/physics/Box2D/Common/b2StackAllocator.h +0 -60
  270. data/src/physics/Box2D/Common/b2Timer.cpp +0 -101
  271. data/src/physics/Box2D/Common/b2Timer.h +0 -50
  272. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp +0 -53
  273. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h +0 -39
  274. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp +0 -53
  275. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h +0 -39
  276. data/src/physics/Box2D/Dynamics/Contacts/b2CircleContact.cpp +0 -52
  277. data/src/physics/Box2D/Dynamics/Contacts/b2CircleContact.h +0 -39
  278. data/src/physics/Box2D/Dynamics/Contacts/b2Contact.cpp +0 -247
  279. data/src/physics/Box2D/Dynamics/Contacts/b2Contact.h +0 -349
  280. data/src/physics/Box2D/Dynamics/Contacts/b2ContactSolver.cpp +0 -838
  281. data/src/physics/Box2D/Dynamics/Contacts/b2ContactSolver.h +0 -95
  282. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp +0 -49
  283. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h +0 -39
  284. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp +0 -49
  285. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h +0 -39
  286. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp +0 -49
  287. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h +0 -38
  288. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonContact.cpp +0 -52
  289. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonContact.h +0 -39
  290. data/src/physics/Box2D/Dynamics/Joints/b2DistanceJoint.cpp +0 -260
  291. data/src/physics/Box2D/Dynamics/Joints/b2DistanceJoint.h +0 -169
  292. data/src/physics/Box2D/Dynamics/Joints/b2FrictionJoint.cpp +0 -251
  293. data/src/physics/Box2D/Dynamics/Joints/b2FrictionJoint.h +0 -119
  294. data/src/physics/Box2D/Dynamics/Joints/b2GearJoint.cpp +0 -419
  295. data/src/physics/Box2D/Dynamics/Joints/b2GearJoint.h +0 -125
  296. data/src/physics/Box2D/Dynamics/Joints/b2Joint.cpp +0 -211
  297. data/src/physics/Box2D/Dynamics/Joints/b2Joint.h +0 -226
  298. data/src/physics/Box2D/Dynamics/Joints/b2MotorJoint.cpp +0 -304
  299. data/src/physics/Box2D/Dynamics/Joints/b2MotorJoint.h +0 -133
  300. data/src/physics/Box2D/Dynamics/Joints/b2MouseJoint.cpp +0 -222
  301. data/src/physics/Box2D/Dynamics/Joints/b2MouseJoint.h +0 -129
  302. data/src/physics/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp +0 -629
  303. data/src/physics/Box2D/Dynamics/Joints/b2PrismaticJoint.h +0 -196
  304. data/src/physics/Box2D/Dynamics/Joints/b2PulleyJoint.cpp +0 -348
  305. data/src/physics/Box2D/Dynamics/Joints/b2PulleyJoint.h +0 -152
  306. data/src/physics/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp +0 -502
  307. data/src/physics/Box2D/Dynamics/Joints/b2RevoluteJoint.h +0 -204
  308. data/src/physics/Box2D/Dynamics/Joints/b2RopeJoint.cpp +0 -241
  309. data/src/physics/Box2D/Dynamics/Joints/b2RopeJoint.h +0 -114
  310. data/src/physics/Box2D/Dynamics/Joints/b2WeldJoint.cpp +0 -344
  311. data/src/physics/Box2D/Dynamics/Joints/b2WeldJoint.h +0 -126
  312. data/src/physics/Box2D/Dynamics/Joints/b2WheelJoint.cpp +0 -419
  313. data/src/physics/Box2D/Dynamics/Joints/b2WheelJoint.h +0 -210
  314. data/src/physics/Box2D/Dynamics/b2Body.cpp +0 -549
  315. data/src/physics/Box2D/Dynamics/b2Body.h +0 -860
  316. data/src/physics/Box2D/Dynamics/b2ContactManager.cpp +0 -296
  317. data/src/physics/Box2D/Dynamics/b2ContactManager.h +0 -52
  318. data/src/physics/Box2D/Dynamics/b2Fixture.cpp +0 -303
  319. data/src/physics/Box2D/Dynamics/b2Fixture.h +0 -345
  320. data/src/physics/Box2D/Dynamics/b2Island.cpp +0 -539
  321. data/src/physics/Box2D/Dynamics/b2Island.h +0 -93
  322. data/src/physics/Box2D/Dynamics/b2TimeStep.h +0 -70
  323. data/src/physics/Box2D/Dynamics/b2World.cpp +0 -1339
  324. data/src/physics/Box2D/Dynamics/b2World.h +0 -354
  325. data/src/physics/Box2D/Dynamics/b2WorldCallbacks.cpp +0 -36
  326. data/src/physics/Box2D/Dynamics/b2WorldCallbacks.h +0 -155
  327. data/src/physics/Box2D/Rope/b2Rope.cpp +0 -259
  328. data/src/physics/Box2D/Rope/b2Rope.h +0 -115
  329. data/src/shape_view.cpp +0 -306
data/src/view.cpp CHANGED
@@ -1,21 +1,28 @@
1
- #include "reflex/view.h"
1
+ #include "view.h"
2
2
 
3
3
 
4
4
  #include <assert.h>
5
+ #include <memory>
5
6
  #include <algorithm>
6
- #include <boost/scoped_ptr.hpp>
7
- #include <xot/util.h>
8
- #include "reflex/window.h"
9
- #include "reflex/body.h"
7
+ #include "reflex/timer.h"
8
+ #include "reflex/filter.h"
10
9
  #include "reflex/exception.h"
10
+ #include "reflex/debug.h"
11
+ #include "window.h"
12
+ #include "selector.h"
13
+ #include "timer.h"
14
+ #include "style.h"
15
+ #include "shape.h"
11
16
  #include "world.h"
17
+ #include "body.h"
18
+ #include "fixture.h"
12
19
 
13
20
 
14
21
  namespace Reflex
15
22
  {
16
23
 
17
24
 
18
- bool set_style_owner (Style* style, View* owner);
25
+ static const char* WALL_NAME = "__WALL__";
19
26
 
20
27
 
21
28
  struct View::Data
@@ -23,22 +30,26 @@ namespace Reflex
23
30
 
24
31
  typedef std::set<Selector> SelectorSet;
25
32
 
26
- enum Flags
33
+ enum Flag
27
34
  {
28
35
 
29
- ACTIVE = 0x1 << 0,
36
+ REDRAW = Xot::bit(1, FLAG_LAST),
30
37
 
31
- UPDATE_STYLE = 0x1 << 1,
38
+ APPLY_STYLE = Xot::bit(2, FLAG_LAST),
32
39
 
33
- UPDATE_LAYOUT = 0x1 << 2,
40
+ UPDATE_STYLE = Xot::bit(3, FLAG_LAST),
34
41
 
35
- UPDATING_WORLD = 0x1 << 3,
42
+ UPDATE_SHAPES = Xot::bit(4, FLAG_LAST),
36
43
 
37
- REMOVE_SELF = 0x1 << 4,
44
+ UPDATE_LAYOUT = Xot::bit(5, FLAG_LAST),
38
45
 
39
- DEFAULT_FLAGS = UPDATE_STYLE | UPDATE_LAYOUT
46
+ FIT_TO_CONTENT = Xot::bit(6, FLAG_LAST),
40
47
 
41
- };// Flags
48
+ HAS_VARIABLE_LENGTHS = Xot::bit(7, FLAG_LAST),
49
+
50
+ NO_SHAPE = Xot::bit(8, FLAG_LAST),
51
+
52
+ };// Flag
42
53
 
43
54
  Window* window;
44
55
 
@@ -54,25 +65,36 @@ namespace Reflex
54
65
 
55
66
  uint flags;
56
67
 
57
- boost::scoped_ptr<Selector> pselector;
68
+ std::unique_ptr<Point> pscroll;
69
+
70
+ SelectorPtr pselector;
71
+
72
+ std::unique_ptr<SelectorSet> pselectors_for_update;
58
73
 
59
- boost::scoped_ptr<SelectorSet> pselectors_for_update;
74
+ std::unique_ptr<Image> pcache_image;
60
75
 
61
- boost::scoped_ptr<Point> pscroll;
76
+ std::unique_ptr<Timers> ptimers;
62
77
 
63
- boost::scoped_ptr<ChildList> pchildren;
78
+ std::unique_ptr<Style> pstyle;
64
79
 
65
- boost::scoped_ptr<Style> pstyle;
80
+ std::unique_ptr<StyleList> pstyles;
66
81
 
67
- boost::scoped_ptr<StyleList> pstyles;
82
+ Shape::Ref pshape;
68
83
 
69
- boost::scoped_ptr<World> pworld;
84
+ std::unique_ptr<ShapeList> pshapes;
70
85
 
71
- boost::scoped_ptr<Body> pbody;
86
+ Filter::Ref pfilter;
87
+
88
+ std::unique_ptr<Body> pbody;
89
+
90
+ std::unique_ptr<World> pchild_world;
91
+
92
+ std::unique_ptr<ChildList> pchildren;
72
93
 
73
94
  Data ()
74
- : window(NULL), parent(NULL), zoom(1), angle(0),
75
- capture(CAPTURE_NONE), hide_count(0), flags(DEFAULT_FLAGS)
95
+ : window(NULL), parent(NULL),
96
+ zoom(1), angle(0), capture(CAPTURE_NONE), hide_count(0),
97
+ flags(FLAG_CLIP | FLAG_RESIZE_TO_FIT | REDRAW | UPDATE_LAYOUT | UPDATE_STYLE)
76
98
  {
77
99
  }
78
100
 
@@ -80,6 +102,12 @@ namespace Reflex
80
102
  {
81
103
  }
82
104
 
105
+ Point& scroll ()
106
+ {
107
+ if (!pscroll) pscroll.reset(new Point);
108
+ return *pscroll;
109
+ }
110
+
83
111
  Selector& selector ()
84
112
  {
85
113
  if (!pselector) pselector.reset(new Selector);
@@ -92,24 +120,18 @@ namespace Reflex
92
120
  return *pselectors_for_update;
93
121
  }
94
122
 
95
- Point& scroll ()
96
- {
97
- if (!pscroll) pscroll.reset(new Point);
98
- return *pscroll;
99
- }
100
-
101
- ChildList& children ()
123
+ Timers& timers ()
102
124
  {
103
- if (!pchildren) pchildren.reset(new ChildList);
104
- return *pchildren;
125
+ if (!ptimers) ptimers.reset(new Timers);
126
+ return *ptimers;
105
127
  }
106
128
 
107
- Style& style (View* this_)
129
+ Style& style (View* view)
108
130
  {
109
131
  if (!pstyle)
110
132
  {
111
133
  pstyle.reset(new Style);
112
- set_style_owner(pstyle.get(), this_);
134
+ Style_set_owner(pstyle.get(), view);
113
135
  }
114
136
  return *pstyle;
115
137
  }
@@ -120,164 +142,518 @@ namespace Reflex
120
142
  return *pstyles;
121
143
  }
122
144
 
123
- World* world (View* this_)
145
+ ShapeList& shapes ()
146
+ {
147
+ if (!pshapes) pshapes.reset(new ShapeList);
148
+ return *pshapes;
149
+ }
150
+
151
+ template <typename FUN>
152
+ void each_shape (FUN fun)
124
153
  {
125
- assert(this_);
154
+ if (pshape)
155
+ fun(pshape.get());
126
156
 
127
- if (!pworld)
157
+ if (pshapes)
128
158
  {
129
- pworld.reset(new World(this_));
130
- resize_world(this_);
159
+ for (auto& shape : *pshapes)
160
+ fun(shape.get());
131
161
  }
132
- return pworld.get();
133
162
  }
134
163
 
135
- World* parent_world ()
164
+ template <typename FUN>
165
+ void each_shape (FUN fun) const
136
166
  {
137
- if (!parent) return NULL;
138
- return parent->self->world(parent);
167
+ const_cast<Data*>(this)->each_shape(fun);
168
+ }
169
+
170
+ void update_shapes (bool force = false)
171
+ {
172
+ each_shape([=](Shape* shape)
173
+ {
174
+ Shape_update(shape, force);
175
+ });
176
+ }
177
+
178
+ void resize_shapes (FrameEvent* e)
179
+ {
180
+ each_shape([=](Shape* shape)
181
+ {
182
+ shape->on_resize(e);
183
+ });
139
184
  }
140
185
 
141
- Body* body (View* this_)
186
+ Body& body ()
142
187
  {
143
188
  if (!pbody)
144
189
  {
145
190
  World* world = parent_world();
146
- if (!world) return NULL;
147
- pbody.reset(world->create_body(this_, frame.position()));
148
- this_->make_body();
191
+ Body* b = world
192
+ ? new Body(world, frame.position(), angle)
193
+ : Body_create_temporary();
194
+ assert(b);
195
+
196
+ pbody.reset(b);
197
+ update_body_frame();
198
+ }
199
+ return *pbody;
200
+ }
201
+
202
+ void update_body_frame ()
203
+ {
204
+ if (!pbody) return;
205
+
206
+ pbody->set_transform(frame.x, frame.y, angle);
207
+ }
208
+
209
+ void update_body_and_shapes ()
210
+ {
211
+ std::unique_ptr<Body> old_body;
212
+ if (pbody)
213
+ {
214
+ old_body = std::move(pbody);
215
+ Body_copy_attributes(&body(), *old_body);
216
+ }
217
+
218
+ update_shapes(true);
219
+ }
220
+
221
+ World* parent_world (bool create = true)
222
+ {
223
+ if (!parent) return NULL;
224
+ return parent->self->child_world(parent, create);
225
+ }
226
+
227
+ World* child_world (View* view, bool create = true)
228
+ {
229
+ assert(view);
230
+
231
+ if (!pchild_world && create)
232
+ {
233
+ pchild_world.reset(new World());
234
+ create_walls(view);
149
235
  }
150
- return pbody.get();
236
+
237
+ return pchild_world.get();
151
238
  }
152
239
 
153
- void resize_world (View* this_)
240
+ void create_walls (View* view)
154
241
  {
155
- assert(this_);
242
+ assert(view);
156
243
 
157
- World* w = pworld.get();
158
- if (!w) return;
244
+ clear_walls(view);
159
245
 
160
- w->resize(frame.width, frame.height);
161
- this_->redraw();
246
+ View* wall = new View(WALL_NAME);
247
+ wall->add_shape(new WallShape(WallShape::ALL));
248
+ wall->set_static();
249
+
250
+ view->add_child(wall);
162
251
  }
163
252
 
164
- void update_body (View* this_)
253
+ void clear_walls (View* view)
165
254
  {
166
- assert(this_);
255
+ assert(view);
167
256
 
168
- Body* b = pbody.get();
169
- if (!b) return;
257
+ for (auto& wall : view->find_children(WALL_NAME))
258
+ view->remove_child(wall.get());
259
+ }
170
260
 
171
- b->set_transform(frame.x, frame.y, angle);
172
- this_->redraw();
261
+ ChildList& children ()
262
+ {
263
+ if (!pchildren) pchildren.reset(new ChildList);
264
+ return *pchildren;
173
265
  }
174
266
 
175
267
  void add_flag (uint flag)
176
268
  {
177
- flags |= flag;
269
+ Xot::add_flag(&flags, flag);
178
270
  }
179
271
 
180
272
  void remove_flag (uint flag)
181
273
  {
182
- flags &= ~flag;
274
+ Xot::remove_flag(&flags, flag);
183
275
  }
184
276
 
185
277
  bool has_flag (uint flag) const
186
278
  {
187
- return flags & flag;
279
+ return Xot::has_flag(flags, flag);
280
+ }
281
+
282
+ bool check_and_remove_flag (uint flag)
283
+ {
284
+ return Xot::check_and_remove_flag(&flags, flag);
188
285
  }
189
286
 
190
287
  };// View::Data
191
288
 
192
289
 
193
- void
194
- set_window (View* view, Window* window_)
290
+ class LayoutContext
195
291
  {
196
- assert(view);
197
292
 
198
- Window* current = view->self->window;
199
- if (current == window_) return;
293
+ public:
200
294
 
201
- if (current)
202
- {
203
- view->set_capture(View::CAPTURE_NONE);
295
+ LayoutContext (View* parent)
296
+ : parent(parent),
297
+ parent_style(View_get_style(parent)),
298
+ parent_frame(parent->self->frame)
299
+ {
300
+ Style::Flow flow_main, flow_sub;
301
+ parent_style.get_flow(&flow_main, &flow_sub);
302
+ get_flow_sign(&flow_main_h, &flow_main_v, flow_main);
303
+ get_flow_sign(&flow_sub_h, &flow_sub_v, flow_sub);
304
+ }
305
+
306
+ void place_children ()
307
+ {
308
+ View::ChildList* pchildren = parent->self->pchildren.get();
309
+ if (!pchildren || pchildren->empty())
310
+ return;
311
+
312
+ bool leftward = flow_main_h < 0 || flow_sub_h < 0;
313
+ bool upward = flow_main_v < 0 || flow_sub_v < 0;
314
+ Point start_position(
315
+ leftward ? parent_frame.width : 0,
316
+ upward ? parent_frame.height : 0);
317
+ Point position = start_position;
318
+
319
+ for (iterator begin = pchildren->begin(), end = pchildren->end(); true;)
320
+ {
321
+ iterator line_end;
322
+ coord main_fill_size = 0;
323
+ coord sub_size_max = 0;
324
+ calc_line(&line_end, &main_fill_size, &sub_size_max, begin, end);
325
+
326
+ for (iterator it = begin; it != line_end; ++it)
327
+ place_child(it->get(), &position, main_fill_size, sub_size_max);
328
+
329
+ if (line_end == end)
330
+ break;
331
+
332
+ flow_value(position.x, position.y, DIR_MAIN) =
333
+ flow_value(start_position.x, start_position.y, DIR_MAIN);
334
+
335
+ flow_value(position.x, position.y, DIR_SUB) +=
336
+ sub_size_max * flow_value(flow_sub_h, flow_sub_v, DIR_SUB);
337
+
338
+ begin = line_end;
339
+ }
340
+ }
341
+
342
+ private:
343
+
344
+ enum FlowDirection {DIR_MAIN, DIR_SUB};
345
+
346
+ typedef View::ChildList::iterator iterator;
347
+
348
+ View* parent;
349
+
350
+ const Style& parent_style;
351
+
352
+ const Bounds& parent_frame;
353
+
354
+ schar flow_main_h, flow_main_v, flow_sub_h, flow_sub_v;
355
+
356
+ static void get_flow_sign (schar* h, schar* v, Style::Flow flow)
357
+ {
358
+ assert(h && v);
359
+
360
+ switch (flow)
361
+ {
362
+ case Style::FLOW_RIGHT: *h = +1; *v = 0; break;
363
+ case Style::FLOW_DOWN: *h = 0; *v = +1; break;
364
+ case Style::FLOW_LEFT: *h = -1; *v = 0; break;
365
+ case Style::FLOW_UP: *h = 0; *v = -1; break;
366
+ default: *h = 0; *v = 0; break;
367
+ }
368
+ }
369
+
370
+ void calc_line (
371
+ iterator* line_end, coord* main_fill_size, coord* sub_size_max,
372
+ iterator begin, iterator end)
373
+ {
374
+ assert(line_end && main_fill_size && sub_size_max);
375
+
376
+ *line_end = end;
377
+ *main_fill_size = 0;
378
+ *sub_size_max = 0;
379
+
380
+ if (!has_flow())
381
+ return;
382
+
383
+ bool multiline = flow_sub_h != 0 || flow_sub_v != 0;
384
+ bool line_has_fill = false;
385
+ coord parent_size = flow_size(parent_frame, DIR_MAIN);
386
+ coord pos = 0;
387
+
388
+ for (iterator it = begin; it != end; ++it)
389
+ {
390
+ const View* child = it->get();
391
+ const Style* style = child->self->pstyle.get();
392
+ if (is_absolute(style))
393
+ continue;
394
+
395
+ const Bounds& frame = child->self->frame;
396
+ coord main_size = flow_size(frame, DIR_MAIN);
397
+ bool child_has_fill = has_fill_length(style, DIR_MAIN);
398
+
399
+ if (multiline && it != begin)
400
+ {
401
+ bool next_line = (pos + main_size) > parent_size;
402
+ bool double_fill = child_has_fill && line_has_fill;
403
+ if (next_line || double_fill)
404
+ {
405
+ *line_end = it;
406
+ break;
407
+ }
408
+ }
409
+
410
+ if (!child_has_fill)
411
+ pos += main_size;
412
+
413
+ if (!has_fill_length(style, DIR_SUB))
414
+ {
415
+ coord sub_size = flow_size(frame, DIR_SUB);
416
+ if (sub_size > *sub_size_max) *sub_size_max = sub_size;
417
+ }
418
+
419
+ line_has_fill |= child_has_fill;
420
+ }
421
+
422
+ *main_fill_size = parent_size - pos;
423
+ }
424
+
425
+ void place_child (
426
+ View* child, Point* position, coord main_fill_size, coord sub_size_max)
427
+ {
428
+ assert(child && position);
429
+
430
+ const Style* style = child->self->pstyle.get();
431
+ Bounds frame = child->frame();
432
+ bool update = false;
433
+
434
+ if (has_flow() && !is_absolute(style))
435
+ {
436
+ update |= fill_child(&frame, style, main_fill_size, sub_size_max);
437
+ update |= place_in_flow(&frame, position);
438
+ }
439
+
440
+ update |= place_position(&frame, style);
441
+
442
+ if (update)
443
+ View_set_frame(child, frame);
444
+ }
445
+
446
+ bool fill_child (
447
+ Bounds* frame,
448
+ const Style* style, coord main_fill_size, coord sub_size_max)
449
+ {
450
+ assert(frame);
451
+
452
+ bool update = false;
453
+
454
+ if (has_fill_length(style, DIR_MAIN))
455
+ update |= set_flow_size(frame, main_fill_size, DIR_MAIN);
456
+
457
+ if (has_fill_length(style, DIR_SUB))
458
+ update |= set_flow_size(frame, sub_size_max, DIR_SUB);
459
+
460
+ return update;
461
+ }
462
+
463
+ bool place_in_flow (Bounds* frame, Point* position)
464
+ {
465
+ assert(frame && position);
466
+
467
+ coord old_x = frame->x;
468
+ coord old_y = frame->y;
469
+
470
+ if (flow_main_h < 0) position->x -= frame->width;
471
+ if (flow_main_v < 0) position->y -= frame->height;
472
+
473
+ frame->x = position->x;
474
+ frame->y = position->y;
475
+
476
+ if (flow_main_h > 0) position->x += frame->width;
477
+ if (flow_main_v > 0) position->y += frame->height;
478
+
479
+ if (flow_sub_h < 0) frame->x -= frame->width;
480
+ if (flow_sub_v < 0) frame->y -= frame->height;
481
+
482
+ return frame->x != old_x || frame->y != old_y;
483
+ }
484
+
485
+ bool place_position (Bounds* frame, const Style* style)
486
+ {
487
+ assert(frame);
488
+
489
+ if (!style)
490
+ return false;
491
+
492
+ const StyleLength& l = style->left();
493
+ const StyleLength& t = style->top();
494
+ const StyleLength& r = style->right();
495
+ const StyleLength& b = style->bottom();
496
+ if (!l && !t && !r && !b)
497
+ return false;
498
+
499
+ bool update = false;
500
+
501
+ if (l && r)
502
+ {
503
+ coord ll, rr;
504
+ update |= StyleLength_get_pixel_length(&ll, l, parent_frame.w);
505
+ update |= StyleLength_get_pixel_length(&rr, r, parent_frame.w);
506
+ frame->x = ll;
507
+ frame->set_right(parent_frame.w - rr);
508
+ }
509
+ else if (l && !r)
510
+ update |= StyleLength_get_pixel_length(&frame->x, l, parent_frame.w);
511
+ else if (!l && r)
512
+ {
513
+ coord rr;
514
+ update |= StyleLength_get_pixel_length(&rr, r, parent_frame.w);
515
+ frame->x = parent_frame.w - (rr + frame->w);
516
+ }
517
+
518
+ if (t && b)
519
+ {
520
+ coord tt, bb;
521
+ update |= StyleLength_get_pixel_length(&tt, t, parent_frame.h);
522
+ update |= StyleLength_get_pixel_length(&bb, b, parent_frame.h);
523
+ frame->y = tt;
524
+ frame->set_bottom(parent_frame.h - bb);
525
+ }
526
+ else if (t && !b)
527
+ update |= StyleLength_get_pixel_length(&frame->y, t, parent_frame.h);
528
+ else if (!t && b)
529
+ {
530
+ coord bb;
531
+ update |= StyleLength_get_pixel_length(&bb, b, parent_frame.h);
532
+ frame->y = parent_frame.h - (bb + frame->h);
533
+ }
534
+
535
+ return update;
536
+ }
537
+
538
+ template <typename T>
539
+ T& flow_value (T& horizontal, T& vertical, FlowDirection dir) const
540
+ {
541
+ if (dir == DIR_MAIN)
542
+ return is_horizontal() ? horizontal : vertical;
543
+ else
544
+ return is_horizontal() ? vertical : horizontal;
545
+ }
546
+
547
+ bool set_flow_size (Bounds* frame, coord size, FlowDirection dir) const
548
+ {
549
+ assert(frame);
550
+
551
+ coord& value = flow_value(frame->width, frame->height, dir);
552
+ if (value == size) return false;
553
+
554
+ value = size;
555
+ return true;
556
+ }
557
+
558
+ const coord& flow_size (const Bounds& frame, FlowDirection dir) const
559
+ {
560
+ return flow_value(frame.width, frame.height, dir);
561
+ }
562
+
563
+ bool is_horizontal () const
564
+ {
565
+ return flow_main_h != 0;
566
+ }
204
567
 
568
+ bool is_absolute (const Style* style) const
569
+ {
570
+ if (!style) return false;
571
+
572
+ if (is_horizontal())
573
+ return style->top() || style->bottom();
574
+ else
575
+ return style->left() || style->right();
576
+ }
577
+
578
+ bool has_flow () const
579
+ {
580
+ return flow_main_h != 0 || flow_main_v != 0;
581
+ }
582
+
583
+ bool has_fill_length (const Style* style, FlowDirection dir) const
584
+ {
585
+ if (!style) return false;
586
+
587
+ const StyleLength& l = flow_value(style->width(), style->height(), dir);
588
+ return l.type() == StyleLength::FILL;
589
+ }
590
+
591
+ };// LayoutContext
592
+
593
+
594
+ void
595
+ View_set_window (View* view, Window* window)
596
+ {
597
+ if (!view)
598
+ argument_error(__FILE__, __LINE__);
599
+
600
+ if (view->self->window)
601
+ {
205
602
  Event e;
206
603
  view->on_detach(&e);
604
+ view->set_capture(View::CAPTURE_NONE);
207
605
  }
208
606
 
209
- view->self->window = window_;
607
+ view->self->window = window;
608
+ view->self->update_body_and_shapes();
210
609
 
211
- View::child_iterator end = view->child_end();
212
- for (View::child_iterator it = view->child_begin(); it != end; ++it)
213
- set_window(it->get(), window_);
610
+ View::ChildList* pchildren = view->self->pchildren.get();
611
+ if (pchildren)
612
+ {
613
+ for (auto& pchild : *pchildren)
614
+ View_set_window(pchild.get(), window);
615
+ }
214
616
 
215
617
  if (view->self->window)
216
618
  {
217
619
  Event e;
218
620
  view->on_attach(&e);
219
- view->resize_to_fit();
621
+ view->self->add_flag(View::Data::FIT_TO_CONTENT);
220
622
  }
221
623
  }
222
624
 
223
625
  static void
224
- set_parent (View* view, View* parent)
626
+ apply_style_to_children_have_variable_lengths (View* parent)
225
627
  {
226
- assert(view);
227
- View::Data* self = view->self.get();
628
+ assert(parent);
228
629
 
229
- View* current = self->parent;
230
- if (current == parent) return;
630
+ View::ChildList* pchildren = parent->self->pchildren.get();
631
+ if (!pchildren) return;
231
632
 
232
- if (current && parent)
633
+ for (auto& pchild : *pchildren)
233
634
  {
234
- reflex_error(__FILE__, __LINE__,
235
- "view '%s' already belongs to another parent '%s'.",
236
- view->name(), self->parent->name());
237
- }
238
-
239
- self->parent = parent;
240
- set_window(view, parent ? parent->window() : NULL);
241
- }
242
-
243
- bool
244
- is_view_active (View* view)
245
- {
246
- assert(view);
247
-
248
- return view->self->has_flag(View::Data::ACTIVE);
249
- }
250
-
251
- static bool
252
- remove_self (View* view)
253
- {
254
- assert(view);
255
- View::Data* self = view->self.get();
256
-
257
- if (!self->has_flag(View::Data::REMOVE_SELF) || !self->parent)
258
- return false;
635
+ assert(pchild);
259
636
 
260
- self->parent->remove_child(view);
261
- return true;
637
+ if (pchild->self->has_flag(View::Data::HAS_VARIABLE_LENGTHS))
638
+ pchild->self->add_flag(View::Data::APPLY_STYLE);
639
+ }
262
640
  }
263
641
 
264
642
  static void
265
- update_layout (View* view, bool update_parent = false)
643
+ update_view_layout (View* view, bool update_parent = false)
266
644
  {
267
645
  assert(view);
268
646
  View::Data* self = view->self.get();
269
647
 
270
- if (self->has_flag(View::Data::UPDATE_LAYOUT))
271
- return;
272
-
273
648
  self->add_flag(View::Data::UPDATE_LAYOUT);
274
649
 
275
650
  if (update_parent && self->parent)
276
- update_layout(self->parent, true);
651
+ update_view_layout(self->parent);
277
652
  }
278
653
 
279
654
  static void
280
- update_view_frame (View* view, const Bounds& frame, float angle, bool update_body)
655
+ update_view_frame (
656
+ View* view, const Bounds& frame, float angle, bool update_body)
281
657
  {
282
658
  assert(view);
283
659
  View::Data* self = view->self.get();
@@ -289,639 +665,565 @@ namespace Reflex
289
665
  self->frame = frame;
290
666
  self->angle = angle;
291
667
 
292
- bool move = event.is_move(), rotate = event.is_rotate();
668
+ bool move = event.is_move();
669
+ bool resize = event.is_resize();
670
+ bool rotate = event.is_rotate();
293
671
 
294
672
  if (move) view->on_move(&event);
673
+ if (resize) view->on_resize(&event);
295
674
  if (rotate) view->on_rotate(&event);
296
675
 
297
- if (update_body && (move || rotate))
298
- self->update_body(view);
299
-
300
- if (event.is_resize())
676
+ if (resize)
301
677
  {
302
- self->resize_world(view);
303
- view->on_resize(&event);
304
-
305
- update_layout(view, true);
678
+ view->self->resize_shapes(&event);
679
+ apply_style_to_children_have_variable_lengths(view);
680
+ update_view_layout(view, true);
306
681
  }
307
682
 
683
+ if (update_body && (move || rotate) && self->pbody)
684
+ self->update_body_frame();
685
+
686
+ if ((move || resize) && self->parent)
687
+ self->parent->self->add_flag(View::Data::FIT_TO_CONTENT);
688
+
308
689
  view->redraw();
309
690
  }
310
691
 
311
- static void
312
- update_view_world (View* view, float dt)
692
+ void
693
+ View_set_frame (View* view, const Bounds& frame)
313
694
  {
314
- assert(view);
315
- View::Data* self = view->self.get();
695
+ if (!view)
696
+ argument_error(__FILE__, __LINE__);
316
697
 
317
- World* world = self->pworld.get();
318
- if (world)
319
- {
320
- self->add_flag(View::Data::UPDATING_WORLD);
321
- world->step(dt);
322
- self->remove_flag(View::Data::UPDATING_WORLD);
323
- }
698
+ update_view_frame(view, frame, view->self->angle, true);
699
+ }
324
700
 
325
- Body* body = self->pbody.get();
326
- if (body)
327
- {
328
- Bounds b = view->frame();
329
- b.move_to(body->position());
330
- update_view_frame(view, b, body->angle(), false);
331
- }
701
+ const Style&
702
+ View_get_style (const View* view)
703
+ {
704
+ if (!view)
705
+ argument_error(__FILE__, __LINE__);
706
+
707
+ static const Style DEFAULT_STYLE;
708
+ return view->self->pstyle ? *view->self->pstyle : DEFAULT_STYLE;
332
709
  }
333
710
 
334
- void
335
- update_styles_for_selector (View* view, const Selector& selector)
711
+ Body*
712
+ View_get_body (View* view, bool create)
336
713
  {
337
- assert(view);
338
- View::Data* self = view->self.get();
714
+ if (!view) return NULL;
339
715
 
340
- if (selector.is_empty())
341
- self->add_flag(View::Data::UPDATE_STYLE);
342
- else
343
- self->selectors_for_update().insert(selector);
716
+ return create ? &view->self->body() : view->self->pbody.get();
344
717
  }
345
718
 
346
- static void
347
- update_views_for_selectors (View* view)
719
+ bool
720
+ View_is_active (const View& view)
348
721
  {
349
- assert(view);
350
- View::Data* self = view->self.get();
722
+ return view.self->window;
723
+ }
351
724
 
352
- View::Data::SelectorSet* sels = self->pselectors_for_update.get();
353
- if (!sels)
354
- return;
725
+ static void
726
+ find_all_children (
727
+ View::ChildList* result, const View* view, const Selector& selector,
728
+ bool recursive)
729
+ {
730
+ assert(result && view);
355
731
 
356
- Selector* view_sel = self->pselector.get();
357
- View::ChildList children;
732
+ View::ChildList* pchildren = view->self->pchildren.get();
733
+ if (!pchildren) return;
358
734
 
359
- View::Data::SelectorSet::iterator end = sels->end();
360
- for (View::Data::SelectorSet::iterator it = sels->begin(); it != end; ++it)
735
+ for (auto& pchild : *pchildren)
361
736
  {
362
- if (view_sel && view_sel->contains(*it))
363
- self->add_flag(View::Data::UPDATE_STYLE);
737
+ if (!pchild)
738
+ invalid_state_error(__FILE__, __LINE__);
364
739
 
365
- view->find_children(&children, *it, true);
366
- for (View::ChildList::iterator jt = children.begin(); jt != children.end(); ++jt)
367
- (*jt)->self->add_flag(View::Data::UPDATE_STYLE);
368
- }
740
+ if (pchild->selector().contains(selector))
741
+ result->push_back(pchild);
369
742
 
370
- sels->clear();
743
+ if (recursive)
744
+ find_all_children(result, pchild.get(), selector, true);
745
+ }
371
746
  }
372
747
 
373
748
  static void
374
749
  find_all_styles (
375
- View::StyleList* result, const View* view, const Selector& selector, bool recursive)
750
+ View::StyleList* result, const View* view, const Selector& selector,
751
+ bool recursive)
376
752
  {
377
- View::const_style_iterator end = view->style_end();
378
- for (View::const_style_iterator it = view->style_begin(); it != end; ++it)
753
+ assert(result && view);
754
+
755
+ View::StyleList* pstyles = view->self->pstyles.get();
756
+ if (pstyles)
379
757
  {
380
- if (selector.contains(it->selector()))
381
- result->push_back(*it);
758
+ for (auto& style : *pstyles)
759
+ {
760
+ if (selector.contains(style.selector()))
761
+ result->push_back(style);
762
+ }
382
763
  }
383
764
 
384
- if (recursive)
765
+ if (!recursive) return;
766
+
767
+ View::ChildList* pchildren = view->self->pchildren.get();
768
+ if (pchildren)
385
769
  {
386
- View::const_child_iterator end = view->child_end();
387
- for (View::const_child_iterator it = view->child_begin(); it != end; ++it)
388
- find_all_styles(result, it->get(), selector, true);
770
+ for (auto& pchild : *pchildren)
771
+ find_all_styles(result, pchild.get(), selector, true);
389
772
  }
390
773
  }
391
774
 
392
775
  static void
393
- get_styles_for_selector (
394
- View::StyleList* styles, View* view, const Selector& selector)
776
+ fire_timers (View* view, double now)
395
777
  {
396
- assert(styles);
778
+ assert(view);
397
779
 
398
- View* parent = view->parent();
399
- if (parent)
400
- get_styles_for_selector(styles, parent, selector);
780
+ Timers* timers = view->self->ptimers.get();
781
+ if (timers)
782
+ timers->fire(now);
783
+ }
784
+
785
+ static void
786
+ update_view_shapes (View* view)
787
+ {
788
+ assert(view);
789
+ View::Data* self = view->self.get();
401
790
 
402
- find_all_styles(styles, view, selector, false);
791
+ bool create_shape = self->pbody && !self->pshape;
792
+ if (create_shape)
793
+ view->shape();
794
+
795
+ bool update = self->check_and_remove_flag(View::Data::UPDATE_SHAPES);
796
+ if (update || create_shape)
797
+ self->update_shapes(create_shape);
403
798
  }
404
799
 
405
800
  static void
406
- get_styles_for_view (View::StyleList* styles, View* view)
801
+ update_view_body (View* view)
407
802
  {
408
- Selector* sel = view->self->pselector.get();
409
- if (!sel || sel->is_empty())
410
- return;
803
+ assert(view);
804
+
805
+ Body* body = view->self->pbody.get();
806
+ if (!body) return;
411
807
 
412
- get_styles_for_selector(styles, view, *sel);
808
+ Bounds frame = view->frame();
809
+ frame.move_to(body->position());
810
+ update_view_frame(view, frame, body->angle(), false);
413
811
  }
414
812
 
415
813
  static void
416
- update_view_style (View* view)
814
+ update_child_world (View* view, float dt)
417
815
  {
418
816
  assert(view);
419
817
  View::Data* self = view->self.get();
420
818
 
421
- if (!self->has_flag(View::Data::UPDATE_STYLE))
422
- return;
819
+ World* child_world = self->pchild_world.get();
820
+ if (!child_world) return;
423
821
 
424
- View::StyleList styles;
425
- get_styles_for_view(&styles, view);
822
+ child_world->on_update(dt);
426
823
 
427
- Style style;
428
- for (View::StyleList::iterator it = styles.begin(); it != styles.end(); ++it)
824
+ View::ChildList* pchildren = self->pchildren.get();
825
+ if (pchildren)
429
826
  {
430
- void override_style (Style*, const Style&);
431
- override_style(&style, *it);
827
+ for (auto& pchild : *pchildren)
828
+ update_view_body(pchild.get());
432
829
  }
433
-
434
- void apply_style (View*, const Style&);
435
- apply_style(view, style);
436
-
437
- self->remove_flag(View::Data::UPDATE_STYLE);
438
830
  }
439
831
 
440
- static void reflow_children (View* parent, const FrameEvent* event = NULL);
441
-
442
832
  static void
443
- update_view_layout (View* view)
833
+ update_views_for_selectors (View* view)
444
834
  {
445
835
  assert(view);
446
836
  View::Data* self = view->self.get();
447
837
 
448
- if (!self->has_flag(View::Data::UPDATE_LAYOUT))
838
+ View::Data::SelectorSet* sels = self->pselectors_for_update.get();
839
+ if (!sels)
449
840
  return;
450
841
 
451
- reflow_children(view);
452
- self->remove_flag(View::Data::UPDATE_LAYOUT);
842
+ Selector* view_sel = self->pselector.get();
843
+ View::ChildList children;
844
+
845
+ for (auto& sel : *sels)
846
+ {
847
+ if (view_sel && view_sel->contains(sel))
848
+ self->add_flag(View::Data::UPDATE_STYLE);
849
+
850
+ children.clear();
851
+ find_all_children(&children, view, sel, true);
852
+ for (auto& pchild : children)
853
+ pchild->self->add_flag(View::Data::UPDATE_STYLE);
854
+ }
855
+
856
+ sels->clear();
453
857
  }
454
858
 
455
- void
456
- update_view_tree (View* view, const UpdateEvent& event)
859
+ static void
860
+ get_styles_for_selector (
861
+ View::StyleList* result, View* view, const Selector& selector)
457
862
  {
458
- if (!view)
459
- argument_error(__FILE__, __LINE__);
863
+ assert(result);
460
864
 
461
- if (event.is_blocked() || remove_self(view))
462
- return;
865
+ View* parent = view->parent();
866
+ if (parent)
867
+ get_styles_for_selector(result, parent, selector);
463
868
 
464
- UpdateEvent e = event;
465
- update_view_world(view, e.dt);
466
- view->on_update(&e);
869
+ find_all_styles(result, view, selector, false);
870
+ }
467
871
 
468
- update_views_for_selectors(view);
469
- update_view_style(view);
872
+ static bool
873
+ get_styles_for_view (View::StyleList* result, View* view)
874
+ {
875
+ assert(result && view);
876
+
877
+ result->clear();
470
878
 
471
- View::child_iterator end = view->child_end();
472
- for (View::child_iterator it = view->child_begin(); it != end; ++it)
473
- update_view_tree(it->get(), e);
879
+ Selector* sel = view->self->pselector.get();
880
+ if (!sel || sel->is_empty())
881
+ return false;
474
882
 
475
- update_view_layout(view);
883
+ get_styles_for_selector(result, view, *sel);
884
+ return !result->empty();
476
885
  }
477
886
 
478
887
  static void
479
- draw_world (View* view, Painter* painter)
888
+ update_view_style (View* view)
480
889
  {
481
890
  assert(view);
891
+ View::Data* self = view->self.get();
482
892
 
483
- World* world = view->self->pworld.get();
484
- if (world) world->draw(painter);
485
- }
486
-
487
- void
488
- draw_view_tree (
489
- View* view, const DrawEvent& event, const Point& offset, const Bounds& clip)
490
- {
491
- if (!view)
492
- argument_error(__FILE__, __LINE__);
893
+ Style* pstyle = self->pstyle.get();
894
+ if (pstyle)
895
+ Style_clear_inherited_values(pstyle);
493
896
 
494
- if (event.is_blocked() || view->hidden())
495
- return;
897
+ View::StyleList styles;
898
+ if (get_styles_for_view(&styles, view))
899
+ {
900
+ if (!pstyle)
901
+ pstyle = &self->style(view);
496
902
 
497
- DrawEvent e = event;
498
- Painter* p = e.painter;
499
- Body* b = view->self->pbody.get();
903
+ for (auto& st : styles)
904
+ Style_override(pstyle, st);
905
+ }
500
906
 
501
- p->push_matrix();
502
- p->push_attr();
907
+ const Style& style = View_get_style(view);
908
+ if (Style_has_variable_lengths(style))
909
+ self->add_flag(View::Data::HAS_VARIABLE_LENGTHS);
910
+ else
911
+ self->remove_flag(View::Data::HAS_VARIABLE_LENGTHS);
503
912
 
504
- Bounds frame = view->frame();
505
- Point pos = frame.position() - view->scroll();
506
- p->translate(pos);
913
+ self->add_flag(View::Data::APPLY_STYLE);
914
+ }
507
915
 
508
- float angle = view->self->angle;
509
- if (angle != 0) p->rotate(angle);
916
+ static void
917
+ fit_view_to_content (View* view)
918
+ {
919
+ assert(view);
510
920
 
511
- float zoom = view->self->zoom;
512
- if (zoom != 1 && zoom > 0) p->scale(zoom, zoom);
921
+ Bounds bounds = view->content_bounds();
922
+ if (!bounds) return;
513
923
 
514
- pos += offset;
515
- Bounds clip2 = clip & frame.move_to(pos);
516
- if (b)
517
- p->no_clip();
924
+ if (view->self->has_flag(View::FLAG_SCROLL_TO_FIT))
925
+ view->scroll_to(-bounds.position());
518
926
  else
519
- p->set_clip(clip2);
927
+ bounds.size() += bounds.position();
520
928
 
521
- e.view = view;
522
- e.bounds = frame.move_to(0, 0, frame.z);
523
- view->on_draw(&e);
524
-
525
- View::child_iterator end = view->child_end();
526
- for (View::child_iterator it = view->child_begin(); it != end; ++it)
527
- draw_view_tree(it->get(), e, pos, clip2);
929
+ if (view->self->has_flag(View::FLAG_RESIZE_TO_FIT))
930
+ {
931
+ Bounds frame = view->frame();
528
932
 
529
- draw_world(view, p);
933
+ const Style* style = view->style(false);
934
+ if ((!style || !Style_has_width( *style))) frame.w = bounds.w;
935
+ if ((!style || !Style_has_height(*style))) frame.h = bounds.h;
936
+ frame.d = bounds.d;
530
937
 
531
- p->pop_attr();
532
- p->pop_matrix();
533
- }
534
- #if 0
535
- void
536
- get_all_margins (MarginList* margins, View* view)
537
- {
538
- if (!margins || !view)
539
- argument_error(__FILE__, __LINE__);
938
+ view->set_frame(frame);
939
+ }
540
940
  }
541
941
 
542
942
  void
543
- get_content_size (
544
- Point* size, View* view, const Point& parent_size, bool min_width, bool min_height)
943
+ View_update_tree (View* view, const UpdateEvent& event)
545
944
  {
546
- if (!size || !view)
945
+ if (!view)
547
946
  argument_error(__FILE__, __LINE__);
548
947
 
549
- const Style& style = view->style();
550
- const StyleLength4& pos = style.position();
551
- const StyleLength2& size = style.size();
552
- const StyleLength4& margin = style.margin();
553
- bool need_width = true, need_height = true;
554
- coord n;
555
-
556
- size->reset(0);
948
+ View::Data* self = view->self.get();
557
949
 
558
- if (pos.left && pos.right)
559
- {
560
- if (!pos.left.is_fixed())
561
- layout_error(__FILE__, __LINE__, "");
950
+ fire_timers(view, event.now);
562
951
 
563
- size->x += parent_size.x;
564
- need_width = false;
565
- }
566
- else if (size.width.get_pixel(&n, parent_size.x))
952
+ View::ChildList* pchildren = self->pchildren.get();
953
+ if (pchildren)
567
954
  {
568
- size->x += n;
569
- need_width = false;
955
+ for (auto& pchild : *pchildren)
956
+ View_update_tree(pchild.get(), event);
570
957
  }
571
958
 
572
- if (pos.top && pos.bottom)
573
- size->y += parent_size.y;
574
- else if (size.height.get_pixel(&n, parent_size.y))
575
- size->y += n;
576
- else
577
- need_height = true;
578
-
579
- if (need_width || need_height)
580
- {
581
- Point content_size = view->content_size();
582
- bool view_width = false, view_height = false;
583
-
584
- if (need_width && content_size.x >= 0)
585
- {
586
- size->x += content_size.x;
587
- need_width = false;
588
- }
589
-
590
- if (need_height && content_size.y >= 0)
591
- {
592
- size->y += content_size.y;
593
- need_height = false;
594
- }
595
-
596
- if (need_width || need_height)
597
- {
598
- View::child_iterator end = view->child_end();
599
- for (View::child_iterator it = view->child_begin(); it != end; ++it)
600
- {
601
- const View* child = it->get();
602
- Point child_size;
603
- get_content_size(&child_size, child, );
604
- const Bounds& b = it->frame();
605
- }
606
-
607
- for ()
608
- Point view_size;
609
- get_view_size(&view_size, );
610
- }
959
+ update_view_shapes(view);
960
+ update_child_world(view, event.dt);
611
961
 
612
- coord m;
613
- if (margin.left .get_pixel(&m, parent_size.x)) size->x += m;
614
- if (margin.top .get_pixel(&m, parent_size.y)) size->y += m;
615
- if (margin.right .get_pixel(&m, parent_size.x)) size->x += m;
616
- if (margin.bottom.get_pixel(&m, parent_size.y)) size->y += m;
617
- }
962
+ UpdateEvent e = event;
963
+ view->on_update(&e);
618
964
 
965
+ update_views_for_selectors(view);
619
966
 
967
+ if (self->check_and_remove_flag(View::Data::UPDATE_STYLE))
968
+ update_view_style(view);
620
969
 
970
+ if (self->check_and_remove_flag(View::Data::APPLY_STYLE))
971
+ Style_apply_to(View_get_style(view), view);
621
972
 
973
+ if (self->check_and_remove_flag(View::Data::UPDATE_LAYOUT))
974
+ view->update_layout();
622
975
 
976
+ if (self->check_and_remove_flag(View::Data::FIT_TO_CONTENT))
977
+ fit_view_to_content(view);
978
+ }
623
979
 
980
+ static bool
981
+ use_cache (View* view)
982
+ {
983
+ assert(view);
984
+ View::Data* self = view->self.get();
624
985
 
625
- const StyleLength4& margin = style.margin();
986
+ return
987
+ self->has_flag(View::FLAG_CACHE) ||
988
+ (self->pfilter && *self->pfilter);
989
+ }
626
990
 
627
- coord left, top, right, bottom;
628
- bool have_left = pos.left .get_pixel(&left, parent_width);
629
- bool have_top = pos.top .get_pixel(&top, parent_height);
630
- bool have_right = pos.right .get_pixel(&right, parent_width);
631
- bool have_bottom = pos.bottom.get_pixel(&bottom, parent_height);
991
+ static bool
992
+ reset_cache_image (View* view, const Painter& painter)
993
+ {
994
+ assert(view && use_cache(view));
995
+ View::Data* self = view->self.get();
632
996
 
633
- if (have_left && have_right)
997
+ Image* image = self->pcache_image.get();
998
+ int w = ceil(self->frame.width);
999
+ int h = ceil(self->frame.height);
1000
+ if (
1001
+ image &&
1002
+ image->width() == w &&
1003
+ image->height() == h &&
1004
+ image->pixel_density() == painter.pixel_density())
634
1005
  {
635
- s
1006
+ return false;
636
1007
  }
637
1008
 
638
- coord width, height;
639
- bool have_width = size.width .get_pixel(&width, parent_width);
640
- bool have_height = size.height.get_pixel(&height, parent_height);
641
- const StyleLength& w = style.width();
642
- switch (w.unit())
643
- {
644
- case StyleLength::PIXEL:
645
- case StyleLength::PERCENT:
646
- case StyleLength::NONE:
647
- default:
648
- }
1009
+ self->pcache_image.reset(
1010
+ new Image(w, h, Rays::RGBA, painter.pixel_density()));
1011
+ return true;
649
1012
  }
650
1013
 
651
1014
  static void
652
- get_flow_factor (int* h, int* v, Style::Flow flow)
1015
+ setup_painter (Painter* painter, const Color& fill, const Color& stroke)
653
1016
  {
654
- if (!h || !v)
655
- argument_error(__FILE__, __LINE__);
1017
+ assert(painter);
656
1018
 
657
- switch (flow)
658
- {
659
- case Style::FLOW_DOWN: *h = 0; *v = +1; break;
660
- case Style::FLOW_RIGHT: *h = +1; *v = 0; break;
661
- case Style::FLOW_UP: *h = 0; *v = -1; break;
662
- case Style::FLOW_LEFT: *h = -1; *v = 0; break;
663
- default: argument_error(__FILE__, __LINE__);
664
- }
1019
+ painter->set_fill(fill);
1020
+ painter->set_stroke(stroke);
665
1021
  }
666
1022
 
667
- struct Length4
1023
+ static void
1024
+ draw_default_shape (View* view, DrawEvent* event)
668
1025
  {
1026
+ assert(view && event && event->painter);
669
1027
 
670
- coord l, t, r, b;
671
-
672
- Length4 ()
673
- {
674
- }
1028
+ const Style& style = View_get_style(view);
1029
+ const Color& back_fill = style.background_fill();
1030
+ const Color& back_stroke = style.background_stroke();
675
1031
 
676
- Length4 (const StyleLength4& soruce)
1032
+ Shape* shape = view->shape(false);
1033
+ if (shape)
677
1034
  {
678
- reset(source);
1035
+ setup_painter(event->painter, back_fill, back_stroke);
1036
+ shape->on_draw(event);
679
1037
  }
680
-
681
- void reset (const StyleLength4& source)
1038
+ else if (back_fill || back_stroke)
682
1039
  {
683
- source.left .get_pixel(&l, 0);
684
- source.top .get_pixel(&t, 0);
685
- source.right .get_pixel(&r, 0);
686
- source.bottom.get_pixel(&b, 0);
1040
+ setup_painter(event->painter, back_fill, back_stroke);
1041
+ event->painter->rect(event->bounds);
687
1042
  }
1043
+ }
688
1044
 
689
- };// Length4
690
-
691
- struct ChildView
1045
+ static void
1046
+ draw_content (View* view, DrawEvent* event)
692
1047
  {
1048
+ assert(view && event && event->painter);
693
1049
 
694
- View* view;
695
-
696
- Point size;
697
-
698
- Length4 margin;
699
-
700
- ChildView (View* view) : view(view) {}
1050
+ draw_default_shape(view, event);
701
1051
 
702
- };// ChildView
1052
+ const Style& style = View_get_style(view);
1053
+ setup_painter(
1054
+ event->painter, style.foreground_fill(), style.foreground_stroke());
703
1055
 
704
- typedef std::vector<ChildView> ChildViewList;
1056
+ View::ShapeList* pshapes = view->self->pshapes.get();
1057
+ if (pshapes && !pshapes->empty())
1058
+ {
1059
+ for (auto& pshape : *pshapes)
1060
+ pshape->on_draw(event);
1061
+ }
705
1062
 
706
- static void reflow_view_tree (Point* size, Length4* margin, View* view);
1063
+ view->on_draw(event);
1064
+ }
707
1065
 
708
1066
  static void
709
- reflow_children (View* view, Point* size, const Style& style)
1067
+ draw_view (
1068
+ View* view, DrawEvent* event, const Point& offset, const Bounds& clip)
710
1069
  {
711
- assert(view && size);
712
-
713
- size_t nchildren = view->self->count_children();
714
- if (nchildren == 0) return;
715
-
716
- ChildViewList children;
717
- children.reserve(nchildren);
1070
+ assert(view && event && event->painter);
1071
+ View::Data* self = view->self.get();
718
1072
 
719
- View::child_iterator end = view->child_end();
720
- for (View::child_iterator it = view->child_begin(); it != end; ++it)
721
- {
722
- ChildView c(it->get());
723
- reflow_view_tree(&c.size, &c.margin, c.view);
724
- children.push_back(c);
725
- }
1073
+ Painter* p = event->painter;
1074
+ p->push_state();
726
1075
 
727
- assert(children.size() == nchildren)
728
- #if 0
729
- Flow flow_main, flow_sub;
730
- style.get_flow(&flow_main, &flow_sub);
731
-
732
- int main_h, main_v, sub_h, sub_v;
733
- get_flow_factor(&main_h, &main_v, flow_main);
734
- get_flow_factor(&sub_h, &sub_v, flow_sub);
735
- #endif
736
- coord x = 0, y = 0;
737
- coord parent_w = size->x, parent_h = size->y;
738
- coord height_max = 0;
739
- int child_count = 0;
740
- bool multiline = sub != Style::FLOW_NONE;
741
-
742
- for (size_t i = 0; i < nchildren; ++i)
743
- {
744
- const ChildView& child = children[i];
745
- Bounds& child_frame = child.view->self->frame;
1076
+ if (self->has_flag(View::FLAG_CLIP) && !self->pbody)
1077
+ p->set_clip(clip);
1078
+ else
1079
+ p->no_clip();
746
1080
 
747
- child_frame.x = x;
748
- child_frame.y = y;
749
- x += child.size.x;
1081
+ draw_content(view, event);
750
1082
 
751
- if (child.size.y > size_max)
752
- size_max = child.size.y;
1083
+ p->pop_state();
753
1084
 
754
- if (parent_w >= 0 && x > parent_w && view_count > 0)
1085
+ View::ChildList* pchildren = view->self->pchildren.get();
1086
+ if (pchildren)
1087
+ {
1088
+ for (auto& pchild : *pchildren)
755
1089
  {
756
- x = 0;
757
- y += size_max;
758
- size_max = 0;
759
- if (parent_h < 0 && y > size->y) size->y = y;
1090
+ if (event->bounds & pchild->self->frame)
1091
+ View_draw_tree(pchild.get(), *event, offset, clip);
760
1092
  }
1093
+ }
761
1094
 
762
- ++view_count;
1095
+ World* child_world = view->self->pchild_world.get();
1096
+ if (child_world)
1097
+ {
1098
+ p->push_state();
1099
+ child_world->on_draw(p);
1100
+ p->pop_state();
763
1101
  }
764
1102
  }
765
1103
 
766
1104
  static void
767
- reflow_view_tree (Point* size, Length4* margin, View* view)
1105
+ draw_view_to_cache (View* view, DrawEvent* event)
768
1106
  {
769
- if (!size || !margin || !view)
770
- argument_error(__FILE__, __LINE__);
771
-
772
- const Style& style = view->style();
1107
+ assert(view && event && event->painter && view->self->pcache_image);
773
1108
 
774
- *size = view->content_size();
775
- reflow_children(view, size, style);
1109
+ Painter* view_painter = event->painter;
1110
+ Painter cache_painter = view->self->pcache_image->painter();
1111
+ event->painter = &cache_painter;
776
1112
 
777
- Length4 padding(style.padding());
778
- size->x += padding.l + padding.r;
779
- size->y += padding.t + padding.b;
1113
+ cache_painter.begin();
1114
+ draw_view(view, event, 0, event->bounds);
1115
+ cache_painter.end();
780
1116
 
781
- Bounds& frame = view->self->frame;
782
- margin->reset(style.margin());
783
-
784
- frame.width = margin.l + size->x + margin.r;
785
- frame.height = margin.t + size->y + margin.b;
1117
+ event->painter = view_painter;
786
1118
  }
787
1119
 
788
- void
789
- get_fixed_content_size (Point* size, View* view)
1120
+ static bool
1121
+ draw_view_with_cache (View* view, DrawEvent* event, bool redraw)
790
1122
  {
791
- if (!size || !view)
792
- argument_error(__FILE__, __LINE__);
793
-
794
- const Style& style = view->style();
795
- const StyleLength2& size = style.size();
796
- bool need_width = true, need_height = true;
797
- coord n;
798
-
799
- size->reset(-1);
1123
+ assert(view && event && event->painter);
1124
+ View::Data* self = view->self.get();
800
1125
 
801
- if (size.width.is_fixed() && size.width.get_pixel(&n, parent_size.x))
1126
+ if (!use_cache(view))
802
1127
  {
803
- size->x += n;
804
- need_width = false;
1128
+ self->pcache_image.reset();
1129
+ return false;
805
1130
  }
806
1131
 
807
- if (size.height.get_pixel(&n, parent_size.y))
808
- {
809
- size->y += n;
810
- need_height = false;
811
- }
1132
+ Painter* painter = event->painter;
812
1133
 
813
- if (need_width || need_height)
1134
+ if (reset_cache_image(view, *painter) || redraw)
814
1135
  {
815
- Point content_size = view->content_size();
816
- bool view_width = false, view_height = false;
1136
+ if (!self->pcache_image)
1137
+ return false;
817
1138
 
818
- if (need_width && content_size.x >= 0)
819
- {
820
- size->x += content_size.x;
821
- need_width = false;
822
- }
1139
+ draw_view_to_cache(view, event);
1140
+ }
823
1141
 
824
- if (need_height && content_size.y >= 0)
825
- {
826
- size->y += content_size.y;
827
- need_height = false;
828
- }
1142
+ painter->push_state();
1143
+ painter->set_fill(1);
1144
+ painter->no_stroke();
1145
+ painter->no_shader();
829
1146
 
830
- if (need_width || need_height)
831
- {
832
- View::child_iterator end = view->child_end();
833
- for (View::child_iterator it = view->child_begin(); it != end; ++it)
834
- {
835
- const View* child = it->get();
836
- Point child_size;
837
- get_content_size(&child_size, child, );
838
- const Bounds& b = it->frame();
839
- }
1147
+ if (self->pfilter && *self->pfilter)
1148
+ self->pfilter->apply(painter, *self->pcache_image);
1149
+ else
1150
+ painter->image(*self->pcache_image, event->bounds);
840
1151
 
841
- for ()
842
- Point view_size;
843
- get_view_size(&view_size, );
844
- }
1152
+ painter->pop_state();
845
1153
 
846
- coord m;
847
- if (margin.left .get_pixel(&m, parent_size.x)) size->x += m;
848
- if (margin.top .get_pixel(&m, parent_size.y)) size->y += m;
849
- if (margin.right .get_pixel(&m, parent_size.x)) size->x += m;
850
- if (margin.bottom.get_pixel(&m, parent_size.y)) size->y += m;
851
- }
1154
+ return true;
852
1155
  }
853
- #endif
854
1156
 
855
- static bool
856
- get_style_flow (Style::Flow* main, Style::Flow* sub, const Style* style)
1157
+ void
1158
+ View_draw_tree (
1159
+ View* view, const DrawEvent& event, const Point& offset, const Bounds& clip)
857
1160
  {
858
- void get_default_flow (Style::Flow*, Style::Flow*);
1161
+ if (!view)
1162
+ argument_error(__FILE__, __LINE__);
859
1163
 
860
- assert(main && sub);
1164
+ View::Data* self = view->self.get();
861
1165
 
862
- if (style)
863
- style->get_flow(main, sub);
864
- else
865
- get_default_flow(main, sub);
1166
+ bool redraw = self->check_and_remove_flag(View::Data::REDRAW);
866
1167
 
867
- return *main != Style::FLOW_NONE;
868
- }
1168
+ if (event.is_blocked() || view->hidden())
1169
+ return;
869
1170
 
870
- static void
871
- reflow_children (View* parent, const FrameEvent* event)
872
- {
873
- assert(parent);
1171
+ if (self->frame.width <= 0 || self->frame.height <= 0)
1172
+ return;
874
1173
 
875
- View::ChildList* children = parent->self->pchildren.get();
876
- if (!children || children->empty()) return;
1174
+ Point pos = self->frame.position();
1175
+ Bounds clip2 = self->frame.dup().move_by(offset) & clip;
1176
+ DrawEvent e = event;
1177
+ e.view = view;
1178
+ e.bounds = self->frame;
1179
+ e.bounds.move_to(0, 0, e.bounds.z);
877
1180
 
878
- const Style* style = parent->style();
1181
+ if (self->pscroll)
1182
+ {
1183
+ pos .move_by( *self->pscroll);
1184
+ e.bounds.move_by(-*self->pscroll);
1185
+ }
879
1186
 
880
- Style::Flow flow_main, flow_sub;
881
- if (!get_style_flow(&flow_main, &flow_sub, style))
882
- return;
1187
+ Painter* p = event.painter;
1188
+ p->push_matrix();
1189
+ p->translate(pos);
883
1190
 
884
- #if 0
885
- int main_h, main_v, sub_h, sub_v;
886
- get_flow_factor(&main_h, &main_v, flow_main);
887
- get_flow_factor(&sub_h, &sub_v, flow_sub);
888
- #endif
1191
+ float angle = self->angle;
1192
+ if (angle != 0)
1193
+ p->rotate(angle);
889
1194
 
890
- const Bounds& parent_frame = parent->self->frame;
891
- coord x = 0, y = 0, size_max = 0;
892
- int child_count = 0;
893
- bool multiline = flow_sub != Style::FLOW_NONE;
1195
+ float zoom = self->zoom;
1196
+ if (zoom != 1 && zoom > 0)
1197
+ p->scale(zoom, zoom);
894
1198
 
895
- size_t nchildren = children->size();
896
- for (size_t i = 0; i < nchildren; ++i)
897
- {
898
- View* child = (*children)[i].get();
899
- Bounds child_frame = child->self->frame;
1199
+ pos += offset;
1200
+ if (!draw_view_with_cache(view, &e, redraw))
1201
+ draw_view(view, &e, pos, clip2);
900
1202
 
901
- if (
902
- (x + child_frame.width) > parent_frame.width &&
903
- child_count > 0 && multiline)
904
- {
905
- x = 0;
906
- y += size_max;
907
- size_max = 0;
908
- child_count = 0;
909
- }
1203
+ p->pop_matrix();
1204
+ }
910
1205
 
911
- child_frame.x = x;
912
- child_frame.y = y;
1206
+ void
1207
+ View_update_styles (View* view, const Selector& selector)
1208
+ {
1209
+ if (!view)
1210
+ argument_error(__FILE__, __LINE__);
913
1211
 
914
- x += child_frame.width;
1212
+ View::Data* self = view->self.get();
915
1213
 
916
- if (size_max < child_frame.height)
917
- size_max = child_frame.height;
1214
+ if (selector.is_empty())
1215
+ self->add_flag(View::Data::UPDATE_STYLE);
1216
+ else
1217
+ self->selectors_for_update().insert(selector);
1218
+ }
918
1219
 
919
- //if (y + size_max > parent_frame.height)
920
- // parent_frame.height = y + size_max;
1220
+ void
1221
+ View_update_shapes (View* view)
1222
+ {
1223
+ if (!view)
1224
+ argument_error(__FILE__, __LINE__);
921
1225
 
922
- ++child_count;
923
- child->set_frame(child_frame);
924
- }
1226
+ view->self->add_flag(View::Data::UPDATE_SHAPES);
925
1227
  }
926
1228
 
927
1229
  template <typename FUN, typename EVENT>
@@ -930,67 +1232,91 @@ namespace Reflex
930
1232
  {
931
1233
  assert(parent);
932
1234
 
933
- View::child_iterator end = parent->child_end();
934
- for (View::child_iterator it = parent->child_begin(); it != end; ++it)
935
- fun(it->get(), e);
1235
+ View::ChildList* pchildren = parent->self->pchildren.get();
1236
+ if (pchildren)
1237
+ {
1238
+ for (auto& pchild : *pchildren)
1239
+ fun(pchild.get(), e);
1240
+ }
936
1241
  }
937
1242
 
938
1243
  void
939
- call_key_event (View* child, const KeyEvent& event)
1244
+ View_call_key_event (View* view, const KeyEvent& event)
940
1245
  {
941
- if (!child)
1246
+ if (!view)
942
1247
  argument_error(__FILE__, __LINE__);
943
1248
 
944
- bool capturing = child->capture() & View::CAPTURE_KEY;
1249
+ bool capturing = view->capture() & View::CAPTURE_KEY;
945
1250
  if (capturing != event.capture) return;
946
1251
 
947
1252
  KeyEvent e = event;
948
- child->on_key(&e);
1253
+ view->on_key(&e);
1254
+
1255
+ switch (e.type)
1256
+ {
1257
+ case KeyEvent::DOWN: view->on_key_down(&e); break;
1258
+ case KeyEvent::UP: view->on_key_up(&e); break;
1259
+ case KeyEvent::NONE: break;
1260
+ }
1261
+ }
1262
+
1263
+ static void
1264
+ filter_pointer_event (
1265
+ PointerEvent* to, const PointerEvent& from, const Bounds& frame)
1266
+ {
1267
+ assert(to);
1268
+
1269
+ const Point& offset = frame.position();
1270
+
1271
+ to->size = 0;
1272
+ for (size_t i = 0; i < from.size; ++i) {
1273
+ const Point& pos = from.position(i);
1274
+ if (!frame.is_include(pos))
1275
+ continue;
1276
+
1277
+ to->positions[i] = pos - offset;
1278
+ ++to->size;
1279
+ }
949
1280
  }
950
1281
 
951
1282
  void
952
- call_pointer_event (View* child, const PointerEvent& event)
1283
+ View_call_pointer_event (View* view, const PointerEvent& event)
953
1284
  {
954
- if (!child)
1285
+ if (!view)
955
1286
  argument_error(__FILE__, __LINE__);
956
1287
 
957
- bool capturing = child->capture() & View::CAPTURE_POINTER;
1288
+ bool capturing = view->capture() & View::CAPTURE_POINTER;
958
1289
  if (capturing != event.capture) return;
959
1290
 
960
- const Bounds& frame = child->frame();
961
-
962
- if (!capturing)
963
- {
964
- bool include = false;
965
- for (size_t i = 0; i < event.size; ++i)
966
- {
967
- if (frame.is_include(event[i]))
968
- {
969
- include = true;
970
- break;
971
- }
972
- }
973
- if (!include) return;
974
- }
1291
+ const Bounds& frame = view->frame();
975
1292
 
976
1293
  PointerEvent e = event;
977
- Point offset = frame.position();
978
- for (size_t i = 0; i < e.size; ++i)
979
- e[i] -= offset;
1294
+ filter_pointer_event(&e, event, frame);
1295
+
1296
+ if (!capturing && e.size == 0)
1297
+ return;
1298
+
1299
+ view->on_pointer(&e);
980
1300
 
981
- child->on_pointer(&e);
1301
+ switch (e.type)
1302
+ {
1303
+ case PointerEvent::DOWN: view->on_pointer_down(&e); break;
1304
+ case PointerEvent::UP: view->on_pointer_up(&e); break;
1305
+ case PointerEvent::MOVE: view->on_pointer_move(&e); break;
1306
+ case PointerEvent::NONE: break;
1307
+ }
982
1308
 
983
1309
  if (!event.capture)
984
- call_children(child, call_pointer_event, e);
1310
+ call_children(view, View_call_pointer_event, e);
985
1311
  }
986
1312
 
987
1313
  void
988
- call_wheel_event (View* child, const WheelEvent& event)
1314
+ View_call_wheel_event (View* view, const WheelEvent& event)
989
1315
  {
990
- if (!child)
1316
+ if (!view)
991
1317
  argument_error(__FILE__, __LINE__);
992
1318
 
993
- const Bounds& frame = child->frame();
1319
+ const Bounds& frame = view->frame();
994
1320
 
995
1321
  if (!frame.is_include(event.x, event.y, event.z))
996
1322
  return;
@@ -998,24 +1324,45 @@ namespace Reflex
998
1324
  WheelEvent e = event;
999
1325
  e.position() -= frame.position();
1000
1326
 
1001
- child->on_wheel(&e);
1327
+ view->on_wheel(&e);
1002
1328
 
1003
- call_children(child, call_wheel_event, e);
1329
+ call_children(view, View_call_wheel_event, e);
1004
1330
  }
1005
1331
 
1006
-
1007
- View::View (const char* name)
1332
+ void
1333
+ View_call_contact_event (View* view, const ContactEvent& event)
1008
1334
  {
1009
- if (name) self->selector().set_name(name);
1335
+ if (!view)
1336
+ argument_error(__FILE__, __LINE__);
1337
+
1338
+ ContactEvent e = event;
1339
+ view->on_contact(&e);
1340
+
1341
+ switch (e.type)
1342
+ {
1343
+ case ContactEvent::BEGIN: view->on_contact_begin(&e); break;
1344
+ case ContactEvent::END: view->on_contact_end(&e); break;
1345
+ case ContactEvent::NONE: break;
1346
+ }
1347
+ }
1348
+
1349
+
1350
+ View::View (const char* name)
1351
+ {
1352
+ if (name) set_name(name);
1010
1353
  }
1011
1354
 
1012
1355
  View::~View ()
1013
1356
  {
1357
+ clear_children();// to delete child shapes before world.
1014
1358
  }
1015
1359
 
1016
1360
  void
1017
1361
  View::show ()
1018
1362
  {
1363
+ if (self->hide_count <= SHRT_MIN)
1364
+ invalid_state_error(__FILE__, __LINE__);
1365
+
1019
1366
  int new_count = self->hide_count - 1;
1020
1367
  if (new_count == 0)
1021
1368
  {
@@ -1032,6 +1379,9 @@ namespace Reflex
1032
1379
  void
1033
1380
  View::hide ()
1034
1381
  {
1382
+ if (self->hide_count >= SHRT_MAX)
1383
+ invalid_state_error(__FILE__, __LINE__);
1384
+
1035
1385
  int new_count = self->hide_count + 1;
1036
1386
  if (new_count == 1)
1037
1387
  {
@@ -1053,11 +1403,133 @@ namespace Reflex
1053
1403
 
1054
1404
  void
1055
1405
  View::redraw ()
1406
+ {
1407
+ if (self->has_flag(Data::REDRAW))
1408
+ return;
1409
+
1410
+ self->add_flag(Data::REDRAW);
1411
+
1412
+ if (self->parent)
1413
+ self->parent->redraw();
1414
+ else if (self->window)
1415
+ self->window->redraw();
1416
+ }
1417
+
1418
+ void
1419
+ View::focus (bool state)
1056
1420
  {
1057
1421
  Window* w = window();
1058
1422
  if (!w) return;
1059
1423
 
1060
- w->redraw();
1424
+ if (state)
1425
+ Window_set_focus(w, this);
1426
+ else if (w->focus() == this)
1427
+ Window_set_focus(w, NULL);
1428
+ }
1429
+
1430
+ void
1431
+ View::blur ()
1432
+ {
1433
+ focus(false);
1434
+ }
1435
+
1436
+ bool
1437
+ View::has_focus () const
1438
+ {
1439
+ const Window* w = window();
1440
+ return w && w->focus() == this;
1441
+ }
1442
+
1443
+ Timer*
1444
+ View::start_timer (float seconds, int count)
1445
+ {
1446
+ return self->timers().add(this, seconds, count);
1447
+ }
1448
+
1449
+ Timer*
1450
+ View::start_interval (float seconds)
1451
+ {
1452
+ return start_timer(seconds, -1);
1453
+ }
1454
+
1455
+ void
1456
+ View::update_layout ()
1457
+ {
1458
+ LayoutContext(this).place_children();
1459
+ redraw();
1460
+ }
1461
+
1462
+ Point
1463
+ View::from_parent (const Point& point) const
1464
+ {
1465
+ not_implemented_error(__FILE__, __LINE__);
1466
+ return 0;
1467
+ }
1468
+
1469
+ Point
1470
+ View::to_parent (const Point& point) const
1471
+ {
1472
+ not_implemented_error(__FILE__, __LINE__);
1473
+ return 0;
1474
+ }
1475
+
1476
+ Point
1477
+ View::from_window (const Point& point) const
1478
+ {
1479
+ Point p = point;
1480
+ for (const View* v = parent(); v; v = v->parent())
1481
+ p -= v->frame().position();
1482
+ return p;
1483
+ }
1484
+
1485
+ Point
1486
+ View::to_window (const Point& point) const
1487
+ {
1488
+ not_implemented_error(__FILE__, __LINE__);
1489
+ return 0;
1490
+ }
1491
+
1492
+ Point
1493
+ View::from_screen (const Point& point) const
1494
+ {
1495
+ not_implemented_error(__FILE__, __LINE__);
1496
+ return 0;
1497
+ }
1498
+
1499
+ Point
1500
+ View::to_screen (const Point& point) const
1501
+ {
1502
+ not_implemented_error(__FILE__, __LINE__);
1503
+ return 0;
1504
+ }
1505
+
1506
+ static void
1507
+ set_parent (View* view, View* parent)
1508
+ {
1509
+ assert(view);
1510
+ View::Data* self = view->self.get();
1511
+
1512
+ if (parent == self->parent) return;
1513
+
1514
+ self->parent = parent;
1515
+ View_set_window(view, parent ? parent->window() : NULL);
1516
+ }
1517
+
1518
+ static void
1519
+ erase_child_from_children (View* parent, View* child)
1520
+ {
1521
+ assert(parent && child);
1522
+
1523
+ View::ChildList* children = parent->self->pchildren.get();
1524
+ if (!children) return;
1525
+
1526
+ auto end = children->end();
1527
+ auto it = std::find(children->begin(), end, child);
1528
+ assert(it != end);
1529
+
1530
+ children->erase(it);
1531
+ if (children->empty())
1532
+ parent->self->pchildren.reset();
1061
1533
  }
1062
1534
 
1063
1535
  void
@@ -1073,12 +1545,15 @@ namespace Reflex
1073
1545
  else if (found != belong)
1074
1546
  invalid_state_error(__FILE__, __LINE__);
1075
1547
 
1076
- child->self->add_flag(View::Data::ACTIVE);
1077
-
1078
1548
  self->children().push_back(child);
1549
+
1550
+ View* prev_parent = child->parent();
1079
1551
  set_parent(child, this);
1080
1552
 
1081
- update_layout(this);
1553
+ if (prev_parent)
1554
+ erase_child_from_children(prev_parent, child);
1555
+
1556
+ update_view_layout(this);
1082
1557
  }
1083
1558
 
1084
1559
  void
@@ -1087,54 +1562,36 @@ namespace Reflex
1087
1562
  if (!child || child == this)
1088
1563
  argument_error(__FILE__, __LINE__);
1089
1564
 
1090
- if (!self->pchildren) return;
1091
-
1092
- child_iterator it = std::find(child_begin(), child_end(), child);
1093
- if (it == child_end()) return;
1094
-
1095
- child->self->remove_flag(View::Data::ACTIVE);
1096
-
1097
- if (self->has_flag(Data::UPDATING_WORLD))
1098
- {
1099
- child->self->add_flag(View::Data::REMOVE_SELF);
1565
+ bool found = std::find(child_begin(), child_end(), child) != child_end();
1566
+ bool belong = child->parent() == this;
1567
+ if (!found && !belong)
1100
1568
  return;
1101
- }
1102
-
1103
- if (child->parent() != this)
1569
+ else if (found != belong)
1104
1570
  invalid_state_error(__FILE__, __LINE__);
1105
1571
 
1106
- child->clear_body();
1107
-
1108
1572
  set_parent(child, NULL);
1109
- self->pchildren->erase(it);
1110
1573
 
1111
- update_layout(this);
1574
+ erase_child_from_children(this, child);
1575
+
1576
+ update_view_layout(this);
1112
1577
  }
1113
1578
 
1114
- static void
1115
- find_all_children (
1116
- View::ChildList* result, const View* view, const Selector& selector, bool recursive)
1579
+ void
1580
+ View::clear_children ()
1117
1581
  {
1118
- View::const_child_iterator end = view->child_end();
1119
- for (View::const_child_iterator it = view->child_begin(); it != end; ++it)
1120
- {
1121
- const View* child = it->get();
1122
- if (!child)
1123
- invalid_state_error(__FILE__, __LINE__);
1124
-
1125
- if (child->selector().contains(selector))
1126
- result->push_back(*it);
1582
+ if (!self->pchildren || self->pchildren->empty()) return;
1127
1583
 
1128
- if (recursive) find_all_children(result, child, selector, true);
1129
- }
1584
+ auto children = *self->pchildren;
1585
+ for (auto& child : children)
1586
+ remove_child(child);
1130
1587
  }
1131
1588
 
1132
- void
1133
- View::find_children (
1134
- ChildList* result, const Selector& selector, bool recursive) const
1589
+ View::ChildList
1590
+ View::find_children (const Selector& selector, bool recursive) const
1135
1591
  {
1136
- result->clear();
1137
- find_all_children(result, this, selector, recursive);
1592
+ ChildList result;
1593
+ find_all_children(&result, this, selector, recursive);
1594
+ return result;
1138
1595
  }
1139
1596
 
1140
1597
  static View::ChildList empty_children;
@@ -1182,14 +1639,14 @@ namespace Reflex
1182
1639
  static Style*
1183
1640
  add_view_style (View* view, Style style)
1184
1641
  {
1185
- assert(view && *view);
1642
+ assert(view);
1186
1643
 
1187
- if (!set_style_owner(&style, view))
1644
+ if (!Style_set_owner(&style, view))
1188
1645
  return NULL;
1189
1646
 
1190
- View::StyleList* styles = &view->self->styles();
1191
- styles->push_back(style);
1192
- return &styles->back();
1647
+ View::StyleList* pstyles = &view->self->styles();
1648
+ pstyles->push_back(style);
1649
+ return &pstyles->back();
1193
1650
  }
1194
1651
 
1195
1652
  void
@@ -1203,10 +1660,23 @@ namespace Reflex
1203
1660
  {
1204
1661
  if (!self->pstyles) return;
1205
1662
 
1206
- style_iterator it = std::find(style_begin(), style_end(), style);
1207
- if (it == style_end()) return;
1663
+ auto end = style_end();
1664
+ auto it = std::find(style_begin(), end, style);
1665
+ if (it == end) return;
1666
+
1667
+ if (!Style_set_owner(&*it, NULL))
1668
+ invalid_state_error(__FILE__, __LINE__);
1208
1669
 
1209
- self->styles().erase(it);
1670
+ self->pstyles->erase(it);
1671
+ if (self->pstyles->empty())
1672
+ self->pstyles.reset();
1673
+ }
1674
+
1675
+ void
1676
+ View::clear_styles ()
1677
+ {
1678
+ while (self->pstyles && !self->pstyles->empty())
1679
+ remove_style(*self->pstyles->begin());
1210
1680
  }
1211
1681
 
1212
1682
  Style*
@@ -1215,11 +1685,14 @@ namespace Reflex
1215
1685
  if (selector.is_empty())
1216
1686
  return style(create);
1217
1687
 
1218
- style_iterator end = style_end();
1219
- for (style_iterator it = style_begin(); it != end; ++it)
1688
+ StyleList* pstyles = self->pstyles.get();
1689
+ if (pstyles)
1220
1690
  {
1221
- if (selector == it->selector())
1222
- return &*it;
1691
+ for (auto& style : *pstyles)
1692
+ {
1693
+ if (selector == style.selector())
1694
+ return &style;
1695
+ }
1223
1696
  }
1224
1697
 
1225
1698
  if (create)
@@ -1238,11 +1711,12 @@ namespace Reflex
1238
1711
  return const_cast<View*>(this)->get_style(selector);
1239
1712
  }
1240
1713
 
1241
- void
1242
- View::find_styles (StyleList* result, const Selector& selector, bool recursive) const
1714
+ View::StyleList
1715
+ View::find_styles (const Selector& selector, bool recursive) const
1243
1716
  {
1244
- result->clear();
1245
- find_all_styles(result, this, selector, recursive);
1717
+ StyleList result;
1718
+ find_all_styles(&result, this, selector, recursive);
1719
+ return result;
1246
1720
  }
1247
1721
 
1248
1722
  static View::StyleList empty_styles;
@@ -1268,317 +1742,586 @@ namespace Reflex
1268
1742
  return self->pstyles->end();
1269
1743
  }
1270
1744
 
1271
- View::const_style_iterator
1272
- View::style_end () const
1745
+ View::const_style_iterator
1746
+ View::style_end () const
1747
+ {
1748
+ if (!self->pstyles) return empty_styles.end();
1749
+ return self->pstyles->end();
1750
+ }
1751
+
1752
+ void
1753
+ View::set_shape (Shape* shape)
1754
+ {
1755
+ if (!shape)
1756
+ self->add_flag(Data::NO_SHAPE);
1757
+ else
1758
+ self->remove_flag(Data::NO_SHAPE);
1759
+
1760
+ Shape::Ref& pshape = self->pshape;
1761
+ if (shape == pshape.get()) return;
1762
+
1763
+ if (pshape) Shape_set_owner(pshape, NULL);
1764
+ pshape.reset(shape);
1765
+ if (pshape) Shape_set_owner(pshape, this);
1766
+ }
1767
+
1768
+ Shape*
1769
+ View::shape (bool create)
1770
+ {
1771
+ if (create && !self->pshape && !self->has_flag(Data::NO_SHAPE))
1772
+ set_shape(new RectShape);
1773
+
1774
+ return self->pshape.get();
1775
+ }
1776
+
1777
+ const Shape*
1778
+ View::shape () const
1779
+ {
1780
+ return const_cast<View*>(this)->shape(false);
1781
+ }
1782
+
1783
+ void
1784
+ View::add_shape (Shape* shape)
1785
+ {
1786
+ if (!shape) return;
1787
+
1788
+ Shape_set_owner(shape, this);
1789
+ self->shapes().push_back(shape);
1790
+ }
1791
+
1792
+ void
1793
+ View::remove_shape (Shape* shape)
1794
+ {
1795
+ if (!shape || !self->pshapes)
1796
+ return;
1797
+
1798
+ auto end = shape_end();
1799
+ auto it = std::find(shape_begin(), end, shape);
1800
+ if (it == end) return;
1801
+
1802
+ Shape_set_owner(it->get(), NULL);
1803
+
1804
+ self->pshapes->erase(it);
1805
+ if (self->pshapes->empty())
1806
+ self->pshapes.reset();
1807
+ }
1808
+
1809
+ void
1810
+ View::clear_shapes ()
1811
+ {
1812
+ set_shape(NULL);
1813
+ while (self->pshapes && !self->pshapes->empty())
1814
+ remove_shape(self->pshapes->begin()->get());
1815
+ }
1816
+
1817
+ View::ShapeList
1818
+ View::find_shapes (const Selector& selector) const
1819
+ {
1820
+ ShapeList result;
1821
+ ShapeList* pshapes = self->pshapes.get();
1822
+ if (pshapes)
1823
+ {
1824
+ for (auto& shape : *pshapes)
1825
+ {
1826
+ if (selector.contains(shape->selector()))
1827
+ result.push_back(shape);
1828
+ }
1829
+ }
1830
+ return result;
1831
+ }
1832
+
1833
+ static View::ShapeList empty_shapes;
1834
+
1835
+ View::shape_iterator
1836
+ View::shape_begin ()
1837
+ {
1838
+ if (!self->pshapes) return empty_shapes.begin();
1839
+ return self->pshapes->begin();
1840
+ }
1841
+
1842
+ View::const_shape_iterator
1843
+ View::shape_begin () const
1844
+ {
1845
+ if (!self->pshapes) return empty_shapes.begin();
1846
+ return self->pshapes->begin();
1847
+ }
1848
+
1849
+ View::shape_iterator
1850
+ View::shape_end ()
1851
+ {
1852
+ if (!self->pshapes) return empty_shapes.end();
1853
+ return self->pshapes->end();
1854
+ }
1855
+
1856
+ View::const_shape_iterator
1857
+ View::shape_end () const
1858
+ {
1859
+ if (!self->pshapes) return empty_shapes.end();
1860
+ return self->pshapes->end();
1861
+ }
1862
+
1863
+ void
1864
+ View::set_filter (Filter* filter)
1865
+ {
1866
+ self->pfilter = filter;
1867
+ }
1868
+
1869
+ Filter*
1870
+ View::filter ()
1871
+ {
1872
+ return self->pfilter.get();
1873
+ }
1874
+
1875
+ const Filter*
1876
+ View::filter () const
1877
+ {
1878
+ return const_cast<View*>(this)->filter();
1879
+ }
1880
+
1881
+ void
1882
+ View::set_name (const char* name)
1883
+ {
1884
+ const char* current = this->name();
1885
+ if (name && current && strcmp(name, current) == 0)
1886
+ return;
1887
+
1888
+ HasSelector::set_name(name);
1889
+ self->add_flag(Data::UPDATE_STYLE);
1890
+ }
1891
+
1892
+ void
1893
+ View::add_tag (const char* tag)
1894
+ {
1895
+ if (has_tag(tag)) return;
1896
+
1897
+ HasSelector::add_tag(tag);
1898
+ self->add_flag(Data::UPDATE_STYLE);
1899
+ }
1900
+
1901
+ void
1902
+ View::remove_tag (const char* tag)
1903
+ {
1904
+ if (!has_tag(tag)) return;
1905
+
1906
+ HasSelector::remove_tag(tag);
1907
+ self->add_flag(Data::UPDATE_STYLE);
1908
+ }
1909
+
1910
+ void
1911
+ View::clear_tags ()
1912
+ {
1913
+ if (tag_begin() == tag_end()) return;
1914
+
1915
+ HasSelector::clear_tags();
1916
+ self->add_flag(Data::UPDATE_STYLE);
1917
+ }
1918
+
1919
+ void
1920
+ View::set_selector (const Selector& selector)
1921
+ {
1922
+ if (selector == this->selector()) return;
1923
+
1924
+ HasSelector::set_selector(selector);
1925
+ self->add_flag(Data::UPDATE_STYLE);
1926
+ }
1927
+
1928
+ void
1929
+ View::set_frame (coord x, coord y, coord width, coord height)
1930
+ {
1931
+ set_frame(Bounds(x, y, width, height));
1932
+ }
1933
+
1934
+ void
1935
+ View::set_frame (const Bounds& frame)
1936
+ {
1937
+ const Bounds& current = self->frame;
1938
+
1939
+ if (frame.w != current.w && !Style_has_width(*style()))
1940
+ style()->set_width(StyleLength::NONE);
1941
+
1942
+ if (frame.h != current.h && !Style_has_height(*style()))
1943
+ style()->set_height(StyleLength::NONE);
1944
+
1945
+ View_set_frame(this, frame);
1946
+ }
1947
+
1948
+ const Bounds&
1949
+ View::frame () const
1950
+ {
1951
+ return self->frame;
1952
+ }
1953
+
1954
+ Bounds
1955
+ View::content_bounds () const
1956
+ {
1957
+ Bounds bounds = Rays::invalid_bounds();
1958
+ self->each_shape([&](const Shape* shape)
1959
+ {
1960
+ if (!shape || !Shape_has_frame(*shape))
1961
+ return;
1962
+
1963
+ Bounds frame = shape->frame();
1964
+ if (frame) bounds |= frame;
1965
+ });
1966
+ return bounds;
1967
+ }
1968
+
1969
+ void
1970
+ View::fit_to_content ()
1971
+ {
1972
+ self->add_flag(View::Data::FIT_TO_CONTENT);
1973
+ }
1974
+
1975
+ void
1976
+ View::set_angle (float degree)
1977
+ {
1978
+ update_view_frame(this, self->frame, degree, true);
1979
+ }
1980
+
1981
+ float
1982
+ View::angle () const
1983
+ {
1984
+ return self->angle;
1985
+ }
1986
+
1987
+ static const Point ZERO_SCROLL;
1988
+
1989
+ void
1990
+ View::scroll_to (coord x, coord y, coord z)
1991
+ {
1992
+ Point old = self->scroll();
1993
+ self->scroll().reset(x, y, z);
1994
+ ScrollEvent e(x, y, z, x - old.x, y - old.y, z - old.z);
1995
+ on_scroll(&e);
1996
+
1997
+ redraw();
1998
+ }
1999
+
2000
+ void
2001
+ View::scroll_to (const Point& scroll)
2002
+ {
2003
+ scroll_to(scroll.x, scroll.y, scroll.z);
2004
+ }
2005
+
2006
+ void
2007
+ View::scroll_by (coord x, coord y, coord z)
2008
+ {
2009
+ const Point& p = scroll();
2010
+ scroll_to(p.x + x, p.y + y, p.z + z);
2011
+ }
2012
+
2013
+ void
2014
+ View::scroll_by (const Point& dscroll)
2015
+ {
2016
+ scroll_by(dscroll.x, dscroll.y, dscroll.z);
2017
+ }
2018
+
2019
+ const Point&
2020
+ View::scroll () const
2021
+ {
2022
+ if (self->pscroll)
2023
+ return self->scroll();
2024
+ else
2025
+ return ZERO_SCROLL;
2026
+ }
2027
+
2028
+ void
2029
+ View::set_zoom (float zoom)
2030
+ {
2031
+ self->zoom = zoom;
2032
+ redraw();
2033
+ }
2034
+
2035
+ float
2036
+ View::zoom () const
2037
+ {
2038
+ return self->zoom;
2039
+ }
2040
+
2041
+ void
2042
+ View::set_capture (uint types)
2043
+ {
2044
+ if (types == self->capture) return;
2045
+
2046
+ uint old = self->capture;
2047
+ self->capture = types;
2048
+
2049
+ bool registered = old != CAPTURE_NONE;
2050
+ bool capture = types != CAPTURE_NONE;
2051
+
2052
+ if (capture && !registered)
2053
+ View_register_capture(this);
2054
+ else if (!capture && registered)
2055
+ View_unregister_capture(this);
2056
+
2057
+ CaptureEvent e(~old & types, old & ~types);
2058
+ on_capture(&e);
2059
+ }
2060
+
2061
+ uint
2062
+ View::capture () const
1273
2063
  {
1274
- if (!self->pstyles) return empty_styles.end();
1275
- return self->pstyles->end();
2064
+ return self->capture;
1276
2065
  }
1277
2066
 
1278
2067
  void
1279
- View::focus (bool state)
2068
+ View::add_flag (uint flags)
1280
2069
  {
1281
- Window* w = window();
1282
- if (!w) return;
1283
-
1284
- void set_focus (Window*, View*);
1285
- if (state)
1286
- set_focus(w, this);
1287
- else if (w->focus() == this)
1288
- set_focus(w, NULL);
2070
+ self->add_flag(flags);
1289
2071
  }
1290
2072
 
1291
2073
  void
1292
- View::blur ()
2074
+ View::remove_flag (uint flags)
1293
2075
  {
1294
- focus(false);
2076
+ self->remove_flag(flags);
1295
2077
  }
1296
2078
 
1297
2079
  bool
1298
- View::has_focus () const
2080
+ View::has_flag (uint flags) const
1299
2081
  {
1300
- const Window* w = window();
1301
- return w && w->focus() == this;
2082
+ return self->has_flag(flags);
1302
2083
  }
1303
2084
 
1304
- void
1305
- View::resize_to_fit ()
2085
+ View*
2086
+ View::parent ()
1306
2087
  {
1307
- Point size = content_size();
1308
- if (size.x < 0 && size.y < 0 && size.z <= 0) return;
1309
-
1310
- const Style* st = style();
1311
-
1312
- Bounds b = frame();
1313
- if ((!st || !st->width()) && size.x >= 0) b.width = size.x;
1314
- if ((!st || !st->height()) && size.y >= 0) b.height = size.y;
1315
- if ( size.z >= 0) b.depth = size.z;
1316
- set_frame(b);
2088
+ return self->parent;
1317
2089
  }
1318
2090
 
1319
- Point
1320
- View::content_size () const
2091
+ const View*
2092
+ View::parent () const
1321
2093
  {
1322
- return -1;
2094
+ return const_cast<This*>(this)->parent();
1323
2095
  }
1324
2096
 
1325
- void
1326
- View::make_body ()
2097
+ Window*
2098
+ View::window ()
1327
2099
  {
1328
- Body* b = body();
1329
- if (!b) return;
1330
-
1331
- b->clear_fixtures();
1332
-
1333
- const Point& size = frame().size();
1334
- b->add_box(size.x, size.y);
2100
+ return self->window;
1335
2101
  }
1336
2102
 
1337
- void
1338
- View::clear_body ()
2103
+ const Window*
2104
+ View::window () const
1339
2105
  {
1340
- Body* body = self->pbody.get();
1341
- if (!body) return;
1342
-
1343
- World* world = self->parent_world();
1344
- if (!world)
1345
- invalid_state_error(__FILE__, __LINE__);
1346
-
1347
- world->destroy_body(body);
1348
- self->pbody.reset();
2106
+ return const_cast<View*>(this)->window();
1349
2107
  }
1350
2108
 
1351
2109
  void
1352
- View::set_name (const char* name)
2110
+ View::apply_force (coord x, coord y)
1353
2111
  {
1354
- self->selector().set_name(name);
2112
+ self->body().apply_force(x, y);
1355
2113
  }
1356
2114
 
1357
- const char*
1358
- View::name () const
2115
+ void
2116
+ View::apply_force (const Point& force)
1359
2117
  {
1360
- const Selector* sel = self->pselector.get();
1361
- return sel ? sel->name() : "";
2118
+ self->body().apply_force(force);
1362
2119
  }
1363
2120
 
1364
2121
  void
1365
- View::add_tag (const char* tag)
2122
+ View::apply_torque (float torque)
1366
2123
  {
1367
- self->selector().add_tag(tag);
2124
+ self->body().apply_torque(torque);
1368
2125
  }
1369
2126
 
1370
2127
  void
1371
- View::remove_tag (const char* tag)
2128
+ View::apply_linear_impulse (coord x, coord y)
1372
2129
  {
1373
- Selector* sel = self->pselector.get();
1374
- if (!sel) return;
1375
-
1376
- sel->remove_tag(tag);
2130
+ self->body().apply_linear_impulse(x, y);
1377
2131
  }
1378
2132
 
1379
- static Selector::TagSet empty_tags;
1380
-
1381
- View::tag_iterator
1382
- View::tag_begin ()
2133
+ void
2134
+ View::apply_linear_impulse (const Point& impulse)
1383
2135
  {
1384
- Selector* sel = self->pselector.get();
1385
- return sel ? sel->begin() : empty_tags.begin();
2136
+ self->body().apply_linear_impulse(impulse);
1386
2137
  }
1387
2138
 
1388
- View::const_tag_iterator
1389
- View::tag_begin () const
2139
+ void
2140
+ View::apply_angular_impulse (float impulse)
1390
2141
  {
1391
- const Selector* sel = self->pselector.get();
1392
- return sel ? sel->begin() : empty_tags.begin();
2142
+ self->body().apply_angular_impulse(impulse);
1393
2143
  }
1394
2144
 
1395
- View::tag_iterator
1396
- View::tag_end ()
2145
+ void
2146
+ View::set_static (bool state)
1397
2147
  {
1398
- Selector* sel = self->pselector.get();
1399
- return sel ? sel->end() : empty_tags.end();
2148
+ set_dynamic(!state);
1400
2149
  }
1401
2150
 
1402
- View::const_tag_iterator
1403
- View::tag_end () const
2151
+ bool
2152
+ View::is_static () const
1404
2153
  {
1405
- const Selector* sel = self->pselector.get();
1406
- return sel ? sel->end() : empty_tags.end();
2154
+ return self->pbody ? !self->pbody->is_dynamic() : false;
1407
2155
  }
1408
2156
 
1409
2157
  void
1410
- View::set_selector (const Selector& selector)
2158
+ View::set_dynamic (bool state)
1411
2159
  {
1412
- self->selector() = selector;
2160
+ Body& b = self->body();
2161
+ if (state == b.is_dynamic())
2162
+ return;
2163
+
2164
+ b.set_dynamic(state);
1413
2165
  }
1414
2166
 
1415
- Selector&
1416
- View::selector ()
2167
+ bool
2168
+ View::is_dynamic () const
1417
2169
  {
1418
- return self->selector();
2170
+ return self->pbody ? self->pbody->is_dynamic() : false;
1419
2171
  }
1420
2172
 
1421
- const Selector&
1422
- View::selector () const
2173
+ void
2174
+ View::set_density (float density)
1423
2175
  {
1424
- static const Selector EMPTY;
2176
+ Shape* s = shape();
2177
+ if (!s)
2178
+ invalid_state_error(__FILE__, __LINE__, "view has no shape.");
1425
2179
 
1426
- const Selector* sel = self->pselector.get();
1427
- return sel ? *sel : EMPTY;
2180
+ s->set_density(density);
1428
2181
  }
1429
2182
 
1430
- void
1431
- View::set_frame (coord x, coord y, coord width, coord height)
2183
+ float
2184
+ View::density () const
1432
2185
  {
1433
- set_frame(Bounds(x, y, width, height));
2186
+ const Shape* s = self->pshape.get();
2187
+ return s ? s->density() : 0;
1434
2188
  }
1435
2189
 
1436
2190
  void
1437
- View::set_frame (const Bounds& frame)
2191
+ View::set_friction (float friction)
1438
2192
  {
1439
- update_view_frame(this, frame, self->angle, true);
2193
+ Shape* s = shape();
2194
+ if (!s)
2195
+ invalid_state_error(__FILE__, __LINE__, "view has no shape.");
2196
+
2197
+ s->set_friction(friction);
1440
2198
  }
1441
2199
 
1442
- const Bounds&
1443
- View::frame () const
2200
+ float
2201
+ View::friction () const
1444
2202
  {
1445
- return self->frame;
2203
+ const Shape* s = self->pshape.get();
2204
+ return s ? s->friction() : 0;
1446
2205
  }
1447
2206
 
1448
2207
  void
1449
- View::set_zoom (float zoom)
2208
+ View::set_restitution (float restitution)
1450
2209
  {
1451
- self->zoom = zoom;
1452
- redraw();
2210
+ Shape* s = shape();
2211
+ if (!s)
2212
+ invalid_state_error(__FILE__, __LINE__, "view has no shape.");
2213
+
2214
+ s->set_restitution(restitution);
1453
2215
  }
1454
2216
 
1455
2217
  float
1456
- View::zoom () const
2218
+ View::restitution () const
1457
2219
  {
1458
- return self->zoom;
2220
+ const Shape* s = self->pshape.get();
2221
+ return s ? s->restitution() : 0;
1459
2222
  }
1460
2223
 
1461
- #if 0
1462
2224
  void
1463
- View::set_angle (float degree)
2225
+ View::set_sensor (bool state)
1464
2226
  {
1465
- update_view_frame(this, self->frame, degree, true);
2227
+ Shape* s = shape();
2228
+ if (!s)
2229
+ invalid_state_error(__FILE__, __LINE__, "view has no shape.");
2230
+
2231
+ s->set_sensor(state);
1466
2232
  }
1467
- #endif
1468
2233
 
1469
- float
1470
- View::angle () const
2234
+ bool
2235
+ View::is_sensor () const
1471
2236
  {
1472
- return self->angle;
2237
+ const Shape* s = self->pshape.get();
2238
+ return s ? s->is_sensor() : false;
1473
2239
  }
1474
2240
 
1475
- static const Point ZERO_SCROLL;
1476
-
1477
2241
  void
1478
- View::scroll_to (coord x, coord y, coord z)
2242
+ View::set_category_bits (uint bits)
1479
2243
  {
1480
- Point old = self->scroll();
1481
- self->scroll().reset(x, y, z);
1482
- ScrollEvent e(x, y, z, x - old.x, y - old.y, z - old.z);
1483
- on_scroll(&e);
2244
+ Shape* s = shape();
2245
+ if (!s)
2246
+ invalid_state_error(__FILE__, __LINE__, "view has no shape.");
1484
2247
 
1485
- redraw();
2248
+ s->set_category_bits(bits);
1486
2249
  }
1487
2250
 
1488
- void
1489
- View::scroll_to (const Point& scroll)
2251
+ uint
2252
+ View::category_bits () const
1490
2253
  {
1491
- scroll_to(scroll.x, scroll.y, scroll.z);
2254
+ const Shape* s = self->pshape.get();
2255
+ return s ? s->category_bits() : 0x1;
1492
2256
  }
1493
2257
 
1494
2258
  void
1495
- View::scroll_by (coord x, coord y, coord z)
2259
+ View::set_collision_mask (uint mask)
1496
2260
  {
1497
- const Point& p = scroll();
1498
- scroll_to(p.x + x, p.y + y, p.z + z);
1499
- }
2261
+ Shape* s = shape();
2262
+ if (!s)
2263
+ invalid_state_error(__FILE__, __LINE__, "view has no shape.");
1500
2264
 
1501
- void
1502
- View::scroll_by (const Point& dscroll)
1503
- {
1504
- scroll_by(dscroll.x, dscroll.y, dscroll.z);
2265
+ s->set_collision_mask(mask);
1505
2266
  }
1506
2267
 
1507
- const Point&
1508
- View::scroll () const
2268
+ uint
2269
+ View::collision_mask () const
1509
2270
  {
1510
- if (self->pscroll)
1511
- return self->scroll();
1512
- else
1513
- return ZERO_SCROLL;
2271
+ const Shape* s = self->pshape.get();
2272
+ return s ? s->collision_mask() : 0xffff;
1514
2273
  }
1515
2274
 
1516
2275
  void
1517
- View::set_capture (uint types)
2276
+ View::set_linear_velocity (coord x, coord y)
1518
2277
  {
1519
- if (types == self->capture) return;
1520
-
1521
- uint old = self->capture;
1522
- self->capture = types;
1523
-
1524
- bool registered = old != CAPTURE_NONE;
1525
- bool capture = types != CAPTURE_NONE;
1526
-
1527
- if (capture && !registered)
1528
- {
1529
- void register_capture (View*);
1530
- register_capture(this);
1531
- }
1532
- else if (!capture && registered)
1533
- {
1534
- void unregister_capture (View*);
1535
- unregister_capture(this);
1536
- }
1537
-
1538
- CaptureEvent e(~old & types, old & ~types);
1539
- on_capture(&e);
2278
+ self->body().set_linear_velocity(x, y);
1540
2279
  }
1541
2280
 
1542
- uint
1543
- View::capture () const
2281
+ void
2282
+ View::set_linear_velocity (const Point& velocity)
1544
2283
  {
1545
- return self->capture;
2284
+ self->body().set_linear_velocity(velocity);
1546
2285
  }
1547
2286
 
1548
- View*
1549
- View::parent ()
2287
+ Point
2288
+ View::linear_velocity () const
1550
2289
  {
1551
- return self->parent;
2290
+ const Body* b = self->pbody.get();
2291
+ return b ? b->linear_velocity() : 0;
1552
2292
  }
1553
2293
 
1554
- const View*
1555
- View::parent () const
2294
+ void
2295
+ View::set_angular_velocity (float velocity)
1556
2296
  {
1557
- return const_cast<This*>(this)->parent();
2297
+ self->body().set_angular_velocity(velocity);
1558
2298
  }
1559
2299
 
1560
- Window*
1561
- View::window ()
2300
+ float
2301
+ View::angular_velocity () const
1562
2302
  {
1563
- return self->window;
2303
+ const Body* b = self->pbody.get();
2304
+ return b ? b->angular_velocity() : 0;
1564
2305
  }
1565
2306
 
1566
- const Window*
1567
- View::window () const
2307
+ void
2308
+ View::set_gravity_scale (float scale)
1568
2309
  {
1569
- return const_cast<View*>(this)->window();
2310
+ self->body().set_gravity_scale(scale);
1570
2311
  }
1571
2312
 
1572
- Body*
1573
- View::body ()
2313
+ float
2314
+ View::gravity_scale () const
1574
2315
  {
1575
- return self->body(this);
2316
+ const Body* b = self->pbody.get();
2317
+ return b ? b->gravity_scale() : 1;
1576
2318
  }
1577
2319
 
1578
- const Body*
1579
- View::body () const
2320
+ void
2321
+ View::update_physics (float duration)
1580
2322
  {
1581
- return const_cast<View*>(this)->body();
2323
+ World* w = self->pchild_world.get();
2324
+ if (w) w->update(duration);
1582
2325
  }
1583
2326
 
1584
2327
  float
@@ -1588,27 +2331,22 @@ namespace Reflex
1588
2331
  if (body)
1589
2332
  return body->meter2pixel(meter);
1590
2333
 
1591
- World* world = self->pworld.get();
1592
- if (world)
1593
- return world->meter2pixel(meter);
2334
+ World* child_world = self->pchild_world.get();
2335
+ if (child_world)
2336
+ return child_world->meter2pixel(meter);
1594
2337
 
1595
- View* parent_ = NULL;
1596
- World* parent_world = NULL;
1597
- if (
1598
- (parent_ = parent()) &&
1599
- (parent_world = parent_->self->pworld.get()))
1600
- {
2338
+ World* parent_world = self->parent_world(false);
2339
+ if (parent_world)
1601
2340
  return parent_world->meter2pixel(meter);
1602
- }
1603
2341
 
1604
2342
  if (!create_world)
1605
2343
  invalid_state_error(__FILE__, __LINE__);
1606
2344
 
1607
- World* new_world = self->world(this);
1608
- if (!new_world)
2345
+ child_world = self->child_world(this);
2346
+ if (!child_world)
1609
2347
  invalid_state_error(__FILE__, __LINE__);
1610
2348
 
1611
- return new_world->meter2pixel(meter);
2349
+ return child_world->meter2pixel(meter);
1612
2350
  }
1613
2351
 
1614
2352
  float
@@ -1626,283 +2364,179 @@ namespace Reflex
1626
2364
  void
1627
2365
  View::set_gravity (const Point& vector)
1628
2366
  {
1629
- World* w = self->world(this);
1630
- if (!w)
1631
- invalid_state_error(__FILE__, __LINE__);
1632
-
1633
- w->set_gravity(vector);
2367
+ self->child_world(this)->set_gravity(vector);
1634
2368
  }
1635
2369
 
1636
2370
  Point
1637
2371
  View::gravity () const
1638
2372
  {
1639
- World* w = self->pworld.get();
2373
+ World* w = self->pchild_world.get();
1640
2374
  return w ? w->gravity() : 0;
1641
2375
  }
1642
2376
 
1643
- Body*
1644
- View::wall ()
1645
- {
1646
- return self->world(this)->wall();
1647
- }
1648
-
1649
- const Body*
1650
- View::wall () const
1651
- {
1652
- return const_cast<View*>(this)->wall();
1653
- }
1654
-
1655
2377
  void
1656
- View::set_debug (bool state)
2378
+ View::set_time_scale (float scale)
1657
2379
  {
1658
- World* w = self->world(this);
1659
- if (!w)
1660
- invalid_state_error(__FILE__, __LINE__);
1661
-
1662
- w->set_debug(state);
2380
+ self->child_world(this)->set_time_scale(scale);
1663
2381
  }
1664
2382
 
1665
- bool
1666
- View::debugging () const
2383
+ float
2384
+ View::time_scale () const
1667
2385
  {
1668
- World* w = self->pworld.get();
1669
- return w ? w->debugging() : false;
2386
+ World* w = self->pchild_world.get();
2387
+ return w ? w->time_scale() : 1;
1670
2388
  }
1671
2389
 
1672
- Point
1673
- View::from_parent (const Point& point) const
2390
+ View*
2391
+ View::wall ()
1674
2392
  {
1675
- not_implemented_error(__FILE__, __LINE__);
1676
- return 0;
1677
- }
2393
+ self->child_world(this);
1678
2394
 
1679
- Point
1680
- View::to_parent (const Point& point) const
1681
- {
1682
- not_implemented_error(__FILE__, __LINE__);
1683
- return 0;
1684
- }
2395
+ ChildList children = find_children(WALL_NAME);
2396
+ if (children.empty()) return NULL;
1685
2397
 
1686
- Point
1687
- View::from_window (const Point& point) const
1688
- {
1689
- Point p = point;
1690
- for (const View* v = parent(); v; v = v->parent())
1691
- p -= v->frame().position();
1692
- return p;
2398
+ return children[0].get();
1693
2399
  }
1694
2400
 
1695
- Point
1696
- View::to_window (const Point& point) const
2401
+ const View*
2402
+ View::wall () const
1697
2403
  {
1698
- not_implemented_error(__FILE__, __LINE__);
1699
- return 0;
2404
+ return const_cast<View*>(this)->wall();
1700
2405
  }
1701
2406
 
1702
- Point
1703
- View::from_screen (const Point& point) const
2407
+ void
2408
+ View::set_debug (bool state)
1704
2409
  {
1705
- not_implemented_error(__FILE__, __LINE__);
1706
- return 0;
2410
+ World* w = self->child_world(this);
2411
+ if (w) w->set_debug(state);
1707
2412
  }
1708
2413
 
1709
- Point
1710
- View::to_screen (const Point& point) const
2414
+ bool
2415
+ View::debug () const
1711
2416
  {
1712
- not_implemented_error(__FILE__, __LINE__);
1713
- return 0;
2417
+ World* w = self->pchild_world.get();
2418
+ return w ? w->debug() : false;
1714
2419
  }
1715
2420
 
1716
2421
  void
1717
2422
  View::on_attach (Event* e)
1718
2423
  {
1719
- if (!e)
1720
- argument_error(__FILE__, __LINE__);
1721
2424
  }
1722
2425
 
1723
2426
  void
1724
2427
  View::on_detach (Event* e)
1725
2428
  {
1726
- if (!e)
1727
- argument_error(__FILE__, __LINE__);
1728
2429
  }
1729
2430
 
1730
2431
  void
1731
2432
  View::on_show (Event* e)
1732
2433
  {
1733
- if (!e)
1734
- argument_error(__FILE__, __LINE__);
1735
2434
  }
1736
2435
 
1737
2436
  void
1738
2437
  View::on_hide (Event* e)
1739
2438
  {
1740
- if (!e)
1741
- argument_error(__FILE__, __LINE__);
1742
2439
  }
1743
2440
 
1744
2441
  void
1745
2442
  View::on_update (UpdateEvent* e)
1746
2443
  {
1747
- if (!e)
1748
- argument_error(__FILE__, __LINE__);
1749
2444
  }
1750
2445
 
1751
2446
  void
1752
2447
  View::on_draw (DrawEvent* e)
1753
2448
  {
1754
- if (!e)
1755
- argument_error(__FILE__, __LINE__);
1756
2449
  }
1757
2450
 
1758
2451
  void
1759
2452
  View::on_move (FrameEvent* e)
1760
2453
  {
1761
- if (!e)
1762
- argument_error(__FILE__, __LINE__);
1763
2454
  }
1764
2455
 
1765
2456
  void
1766
2457
  View::on_resize (FrameEvent* e)
1767
2458
  {
1768
- if (!e)
1769
- argument_error(__FILE__, __LINE__);
1770
2459
  }
1771
2460
 
1772
2461
  void
1773
2462
  View::on_rotate (FrameEvent* e)
1774
2463
  {
1775
- if (!e)
1776
- argument_error(__FILE__, __LINE__);
1777
2464
  }
1778
2465
 
1779
2466
  void
1780
2467
  View::on_scroll (ScrollEvent* e)
1781
2468
  {
1782
- if (!e)
1783
- argument_error(__FILE__, __LINE__);
1784
2469
  }
1785
2470
 
1786
2471
  void
1787
2472
  View::on_focus (FocusEvent* e)
1788
2473
  {
1789
- if (!e)
1790
- argument_error(__FILE__, __LINE__);
1791
- }
1792
-
1793
- void
1794
- View::on_blur (FocusEvent* e)
1795
- {
1796
- if (!e)
1797
- argument_error(__FILE__, __LINE__);
1798
2474
  }
1799
2475
 
1800
2476
  void
1801
2477
  View::on_key (KeyEvent* e)
1802
2478
  {
1803
- if (!e)
1804
- argument_error(__FILE__, __LINE__);
1805
-
1806
- switch (e->type)
1807
- {
1808
- case KeyEvent::DOWN: on_key_down(e); break;
1809
- case KeyEvent::UP: on_key_up(e); break;
1810
- case KeyEvent::NONE: break;
1811
- }
1812
2479
  }
1813
2480
 
1814
2481
  void
1815
2482
  View::on_key_down (KeyEvent* e)
1816
2483
  {
1817
- if (!e)
1818
- argument_error(__FILE__, __LINE__);
1819
2484
  }
1820
2485
 
1821
2486
  void
1822
2487
  View::on_key_up (KeyEvent* e)
1823
2488
  {
1824
- if (!e)
1825
- argument_error(__FILE__, __LINE__);
1826
2489
  }
1827
2490
 
1828
2491
  void
1829
2492
  View::on_pointer (PointerEvent* e)
1830
2493
  {
1831
- if (!e)
1832
- argument_error(__FILE__, __LINE__);
1833
-
1834
- switch (e->type)
1835
- {
1836
- case PointerEvent::DOWN: on_pointer_down(e); break;
1837
- case PointerEvent::UP: on_pointer_up(e); break;
1838
- case PointerEvent::MOVE: on_pointer_move(e); break;
1839
- case PointerEvent::NONE: break;
1840
- }
1841
2494
  }
1842
2495
 
1843
2496
  void
1844
2497
  View::on_pointer_down (PointerEvent* e)
1845
2498
  {
1846
- if (!e)
1847
- argument_error(__FILE__, __LINE__);
1848
2499
  }
1849
2500
 
1850
2501
  void
1851
2502
  View::on_pointer_up (PointerEvent* e)
1852
2503
  {
1853
- if (!e)
1854
- argument_error(__FILE__, __LINE__);
1855
2504
  }
1856
2505
 
1857
2506
  void
1858
2507
  View::on_pointer_move (PointerEvent* e)
1859
2508
  {
1860
- if (!e)
1861
- argument_error(__FILE__, __LINE__);
1862
2509
  }
1863
2510
 
1864
2511
  void
1865
2512
  View::on_wheel (WheelEvent* e)
1866
2513
  {
1867
- if (!e)
1868
- argument_error(__FILE__, __LINE__);
1869
-
1870
2514
  //scroll_by(e->dx, e->dy, e->dz);
1871
2515
  }
1872
2516
 
1873
2517
  void
1874
2518
  View::on_capture (CaptureEvent* e)
1875
2519
  {
1876
- if (!e)
1877
- argument_error(__FILE__, __LINE__);
1878
2520
  }
1879
2521
 
1880
2522
  void
1881
- View::on_contact (ContactEvent* e)
2523
+ View::on_timer (TimerEvent* e)
1882
2524
  {
1883
- if (!e)
1884
- argument_error(__FILE__, __LINE__);
2525
+ }
1885
2526
 
1886
- switch (e->type)
1887
- {
1888
- case ContactEvent::BEGIN: on_contact_begin(e); break;
1889
- case ContactEvent::END: on_contact_end(e); break;
1890
- case ContactEvent::NONE: break;
1891
- }
2527
+ void
2528
+ View::on_contact (ContactEvent* e)
2529
+ {
1892
2530
  }
1893
2531
 
1894
2532
  void
1895
2533
  View::on_contact_begin (ContactEvent* e)
1896
2534
  {
1897
- if (!e)
1898
- argument_error(__FILE__, __LINE__);
1899
2535
  }
1900
2536
 
1901
2537
  void
1902
2538
  View::on_contact_end (ContactEvent* e)
1903
2539
  {
1904
- if (!e)
1905
- argument_error(__FILE__, __LINE__);
1906
2540
  }
1907
2541
 
1908
2542
  View::operator bool () const
@@ -1916,5 +2550,11 @@ namespace Reflex
1916
2550
  return !operator bool();
1917
2551
  }
1918
2552
 
2553
+ SelectorPtr*
2554
+ View::get_selector_ptr ()
2555
+ {
2556
+ return &self->pselector;
2557
+ }
2558
+
1919
2559
 
1920
2560
  }// Reflex