reflexion 0.1.11 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (333) hide show
  1. checksums.yaml +5 -5
  2. data/.doc/ext/reflex/application.cpp +9 -5
  3. data/.doc/ext/reflex/capture_event.cpp +4 -9
  4. data/.doc/ext/reflex/contact_event.cpp +17 -13
  5. data/.doc/ext/reflex/draw_event.cpp +3 -8
  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 +47 -14
  11. data/.doc/ext/reflex/image_view.cpp +1 -10
  12. data/.doc/ext/reflex/key_event.cpp +9 -14
  13. data/.doc/ext/reflex/line_shape.cpp +99 -0
  14. data/.doc/ext/reflex/motion_event.cpp +73 -0
  15. data/.doc/ext/reflex/native.cpp +18 -18
  16. data/.doc/ext/reflex/pointer_event.cpp +27 -25
  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 +24 -3
  20. data/.doc/ext/reflex/scroll_event.cpp +8 -15
  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 +12 -8
  28. data/.doc/ext/reflex/view.cpp +548 -144
  29. data/.doc/ext/reflex/wheel_event.cpp +5 -28
  30. data/.doc/ext/reflex/window.cpp +7 -15
  31. data/LICENSE +21 -0
  32. data/README.md +1 -1
  33. data/Rakefile +14 -12
  34. data/VERSION +1 -1
  35. data/ext/reflex/application.cpp +10 -5
  36. data/ext/reflex/capture_event.cpp +4 -9
  37. data/ext/reflex/contact_event.cpp +18 -13
  38. data/ext/reflex/defs.h +5 -2
  39. data/ext/reflex/draw_event.cpp +3 -8
  40. data/ext/reflex/ellipse_shape.cpp +56 -25
  41. data/ext/reflex/event.cpp +0 -4
  42. data/ext/reflex/extconf.rb +1 -2
  43. data/ext/reflex/filter.cpp +86 -0
  44. data/ext/reflex/focus_event.cpp +11 -15
  45. data/ext/reflex/frame_event.cpp +52 -14
  46. data/ext/reflex/image_view.cpp +1 -10
  47. data/ext/reflex/key_event.cpp +9 -14
  48. data/ext/reflex/line_shape.cpp +104 -0
  49. data/ext/reflex/motion_event.cpp +77 -0
  50. data/ext/reflex/native.cpp +18 -18
  51. data/ext/reflex/pointer_event.cpp +27 -25
  52. data/ext/reflex/polygon_shape.cpp +68 -0
  53. data/ext/reflex/rect_shape.cpp +113 -24
  54. data/ext/reflex/reflex.cpp +24 -3
  55. data/ext/reflex/scroll_event.cpp +8 -15
  56. data/ext/reflex/selector.cpp +46 -16
  57. data/ext/reflex/selector.h +130 -0
  58. data/ext/reflex/shape.cpp +231 -0
  59. data/ext/reflex/style.cpp +363 -192
  60. data/ext/reflex/style_length.cpp +164 -37
  61. data/ext/reflex/timer.cpp +108 -0
  62. data/ext/reflex/timer_event.cpp +133 -0
  63. data/ext/reflex/update_event.cpp +13 -8
  64. data/ext/reflex/view.cpp +594 -150
  65. data/ext/reflex/wheel_event.cpp +5 -30
  66. data/ext/reflex/window.cpp +7 -15
  67. data/include/reflex.h +5 -4
  68. data/include/reflex/application.h +2 -0
  69. data/include/reflex/debug.h +22 -0
  70. data/include/reflex/defs.h +45 -2
  71. data/include/reflex/event.h +55 -11
  72. data/include/reflex/exception.h +17 -2
  73. data/include/reflex/filter.h +56 -0
  74. data/include/reflex/image_view.h +1 -1
  75. data/include/reflex/ruby.h +6 -4
  76. data/include/reflex/ruby/application.h +17 -9
  77. data/include/reflex/ruby/event.h +22 -0
  78. data/include/reflex/ruby/filter.h +69 -0
  79. data/include/reflex/ruby/reflex.h +1 -0
  80. data/include/reflex/ruby/selector.h +1 -1
  81. data/include/reflex/ruby/shape.h +140 -0
  82. data/include/reflex/ruby/style.h +1 -1
  83. data/include/reflex/ruby/timer.h +69 -0
  84. data/include/reflex/ruby/view.h +43 -76
  85. data/include/reflex/ruby/window.h +17 -32
  86. data/include/reflex/selector.h +54 -2
  87. data/include/reflex/shape.h +211 -0
  88. data/include/reflex/style.h +136 -76
  89. data/include/reflex/timer.h +73 -0
  90. data/include/reflex/view.h +181 -59
  91. data/include/reflex/window.h +4 -3
  92. data/lib/reflex.rb +13 -6
  93. data/lib/reflex/application.rb +6 -3
  94. data/lib/reflex/button.rb +2 -2
  95. data/lib/reflex/{texture.rb → camera.rb} +2 -2
  96. data/lib/reflex/capture_event.rb +7 -6
  97. data/lib/reflex/contact_event.rb +10 -12
  98. data/lib/reflex/draw_event.rb +6 -1
  99. data/lib/reflex/ellipse_shape.rb +27 -0
  100. data/lib/reflex/filter.rb +18 -0
  101. data/lib/reflex/fixture.rb +4 -0
  102. data/lib/reflex/focus_event.rb +10 -12
  103. data/lib/reflex/frame_event.rb +1 -1
  104. data/lib/reflex/helper.rb +17 -29
  105. data/lib/reflex/key_event.rb +13 -11
  106. data/lib/reflex/line_shape.rb +18 -0
  107. data/lib/reflex/matrix.rb +13 -0
  108. data/lib/reflex/module.rb +4 -19
  109. data/lib/reflex/pointer_event.rb +28 -35
  110. data/lib/reflex/polygon.rb +14 -0
  111. data/lib/reflex/polygon_shape.rb +23 -0
  112. data/lib/reflex/polyline.rb +13 -0
  113. data/lib/reflex/rect_shape.rb +20 -0
  114. data/lib/reflex/reflex.rb +1 -3
  115. data/lib/reflex/scroll_event.rb +1 -1
  116. data/lib/reflex/selector.rb +2 -2
  117. data/lib/reflex/shape.rb +62 -0
  118. data/lib/reflex/style.rb +78 -11
  119. data/lib/reflex/style_length.rb +0 -11
  120. data/lib/reflex/text_view.rb +7 -24
  121. data/lib/reflex/timer.rb +30 -0
  122. data/lib/reflex/timer_event.rb +29 -0
  123. data/lib/reflex/update_event.rb +1 -1
  124. data/lib/reflex/view.rb +127 -32
  125. data/lib/reflex/wheel_event.rb +9 -1
  126. data/lib/reflex/window.rb +29 -9
  127. data/lib/reflexion.rb +23 -7
  128. data/reflex.gemspec +7 -8
  129. data/samples/bats.rb +4 -4
  130. data/samples/camera.rb +32 -0
  131. data/samples/fans.rb +1 -1
  132. data/samples/fps.rb +5 -3
  133. data/samples/hello.rb +4 -6
  134. data/samples/image.rb +5 -4
  135. data/samples/ios/hello/hello.xcodeproj/project.pbxproj +0 -2
  136. data/samples/layout.rb +16 -7
  137. data/samples/model.rb +10 -7
  138. data/samples/physics.rb +22 -20
  139. data/samples/reflexion/breakout.rb +4 -5
  140. data/samples/reflexion/hello.rb +2 -2
  141. data/samples/reflexion/jump_action.rb +191 -0
  142. data/samples/reflexion/noise.rb +23 -0
  143. data/samples/reflexion/paint.rb +7 -6
  144. data/samples/reflexion/physics.rb +15 -8
  145. data/samples/reflexion/pulse.rb +24 -10
  146. data/samples/shader.rb +8 -6
  147. data/samples/shapes.rb +79 -14
  148. data/samples/tree.rb +9 -10
  149. data/samples/views.rb +3 -3
  150. data/samples/visuals.rb +2 -5
  151. data/src/body.cpp +146 -345
  152. data/src/body.h +91 -0
  153. data/src/event.cpp +65 -15
  154. data/src/exception.cpp +13 -3
  155. data/src/filter.cpp +76 -0
  156. data/src/fixture.cpp +164 -39
  157. data/src/fixture.h +85 -0
  158. data/src/image_view.cpp +4 -4
  159. data/src/ios/app_delegate.h +5 -10
  160. data/src/ios/app_delegate.mm +79 -41
  161. data/src/ios/application.h +32 -0
  162. data/src/ios/application.mm +35 -25
  163. data/src/ios/event.mm +8 -4
  164. data/src/ios/reflex.mm +0 -7
  165. data/src/ios/view_controller.h +37 -0
  166. data/src/ios/view_controller.mm +424 -0
  167. data/src/ios/window.h +40 -0
  168. data/src/ios/window.mm +59 -250
  169. data/src/osx/app_delegate.h +5 -10
  170. data/src/osx/app_delegate.mm +52 -55
  171. data/src/osx/application.h +32 -0
  172. data/src/osx/application.mm +44 -39
  173. data/src/osx/native_window.h +0 -15
  174. data/src/osx/native_window.mm +127 -127
  175. data/src/osx/opengl_view.h +0 -2
  176. data/src/osx/opengl_view.mm +12 -3
  177. data/src/osx/reflex.mm +0 -9
  178. data/src/osx/window.h +42 -0
  179. data/src/osx/window.mm +45 -252
  180. data/src/selector.cpp +232 -7
  181. data/src/selector.h +52 -0
  182. data/src/shape.cpp +1191 -0
  183. data/src/shape.h +61 -0
  184. data/src/style.cpp +573 -376
  185. data/src/style.h +39 -0
  186. data/src/timer.cpp +288 -0
  187. data/src/timer.h +55 -0
  188. data/src/view.cpp +1624 -984
  189. data/src/view.h +56 -0
  190. data/src/win32/window.cpp +3 -4
  191. data/src/window.cpp +302 -20
  192. data/src/window.h +94 -0
  193. data/src/world.cpp +112 -111
  194. data/src/world.h +34 -53
  195. data/task/box2d.rake +31 -10
  196. data/test/test_capture_event.rb +8 -6
  197. data/test/test_pointer_event.rb +130 -0
  198. data/test/test_selector.rb +1 -1
  199. data/test/test_shape.rb +71 -0
  200. data/test/test_style.rb +77 -11
  201. data/test/test_style_length.rb +42 -13
  202. data/test/test_view.rb +138 -14
  203. metadata +118 -202
  204. data/.doc/ext/reflex/arc_shape.cpp +0 -89
  205. data/.doc/ext/reflex/body.cpp +0 -299
  206. data/.doc/ext/reflex/fixture.cpp +0 -101
  207. data/.doc/ext/reflex/shape_view.cpp +0 -153
  208. data/ext/reflex/arc_shape.cpp +0 -94
  209. data/ext/reflex/body.cpp +0 -328
  210. data/ext/reflex/fixture.cpp +0 -108
  211. data/ext/reflex/shape_view.cpp +0 -161
  212. data/include/reflex/bitmap.h +0 -20
  213. data/include/reflex/body.h +0 -128
  214. data/include/reflex/bounds.h +0 -20
  215. data/include/reflex/color.h +0 -20
  216. data/include/reflex/color_space.h +0 -20
  217. data/include/reflex/fixture.h +0 -117
  218. data/include/reflex/font.h +0 -20
  219. data/include/reflex/image.h +0 -20
  220. data/include/reflex/matrix.h +0 -20
  221. data/include/reflex/painter.h +0 -20
  222. data/include/reflex/point.h +0 -24
  223. data/include/reflex/ruby/body.h +0 -41
  224. data/include/reflex/ruby/fixture.h +0 -41
  225. data/include/reflex/ruby/shape_view.h +0 -96
  226. data/include/reflex/shader.h +0 -20
  227. data/include/reflex/shape_view.h +0 -146
  228. data/include/reflex/texture.h +0 -20
  229. data/lib/reflex/body.rb +0 -22
  230. data/lib/reflex/flags.rb +0 -18
  231. data/lib/reflex/shape_view.rb +0 -25
  232. data/src/ios/application_data.h +0 -45
  233. data/src/ios/native_window.h +0 -39
  234. data/src/ios/native_window.mm +0 -224
  235. data/src/ios/opengl_view.h +0 -13
  236. data/src/ios/opengl_view.mm +0 -139
  237. data/src/ios/window_data.h +0 -75
  238. data/src/osx/application_data.h +0 -45
  239. data/src/osx/window_data.h +0 -75
  240. data/src/physics/Box2D/Box2D.h +0 -68
  241. data/src/physics/Box2D/Collision/Shapes/b2ChainShape.cpp +0 -193
  242. data/src/physics/Box2D/Collision/Shapes/b2ChainShape.h +0 -105
  243. data/src/physics/Box2D/Collision/Shapes/b2CircleShape.cpp +0 -99
  244. data/src/physics/Box2D/Collision/Shapes/b2CircleShape.h +0 -91
  245. data/src/physics/Box2D/Collision/Shapes/b2EdgeShape.cpp +0 -138
  246. data/src/physics/Box2D/Collision/Shapes/b2EdgeShape.h +0 -74
  247. data/src/physics/Box2D/Collision/Shapes/b2PolygonShape.cpp +0 -467
  248. data/src/physics/Box2D/Collision/Shapes/b2PolygonShape.h +0 -101
  249. data/src/physics/Box2D/Collision/Shapes/b2Shape.h +0 -101
  250. data/src/physics/Box2D/Collision/b2BroadPhase.cpp +0 -119
  251. data/src/physics/Box2D/Collision/b2BroadPhase.h +0 -257
  252. data/src/physics/Box2D/Collision/b2CollideCircle.cpp +0 -154
  253. data/src/physics/Box2D/Collision/b2CollideEdge.cpp +0 -698
  254. data/src/physics/Box2D/Collision/b2CollidePolygon.cpp +0 -239
  255. data/src/physics/Box2D/Collision/b2Collision.cpp +0 -252
  256. data/src/physics/Box2D/Collision/b2Collision.h +0 -277
  257. data/src/physics/Box2D/Collision/b2Distance.cpp +0 -603
  258. data/src/physics/Box2D/Collision/b2Distance.h +0 -141
  259. data/src/physics/Box2D/Collision/b2DynamicTree.cpp +0 -778
  260. data/src/physics/Box2D/Collision/b2DynamicTree.h +0 -289
  261. data/src/physics/Box2D/Collision/b2TimeOfImpact.cpp +0 -486
  262. data/src/physics/Box2D/Collision/b2TimeOfImpact.h +0 -58
  263. data/src/physics/Box2D/Common/b2BlockAllocator.cpp +0 -215
  264. data/src/physics/Box2D/Common/b2BlockAllocator.h +0 -62
  265. data/src/physics/Box2D/Common/b2Draw.cpp +0 -44
  266. data/src/physics/Box2D/Common/b2Draw.h +0 -86
  267. data/src/physics/Box2D/Common/b2GrowableStack.h +0 -85
  268. data/src/physics/Box2D/Common/b2Math.cpp +0 -94
  269. data/src/physics/Box2D/Common/b2Math.h +0 -720
  270. data/src/physics/Box2D/Common/b2Settings.cpp +0 -44
  271. data/src/physics/Box2D/Common/b2Settings.h +0 -151
  272. data/src/physics/Box2D/Common/b2StackAllocator.cpp +0 -83
  273. data/src/physics/Box2D/Common/b2StackAllocator.h +0 -60
  274. data/src/physics/Box2D/Common/b2Timer.cpp +0 -101
  275. data/src/physics/Box2D/Common/b2Timer.h +0 -50
  276. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp +0 -53
  277. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h +0 -39
  278. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp +0 -53
  279. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h +0 -39
  280. data/src/physics/Box2D/Dynamics/Contacts/b2CircleContact.cpp +0 -52
  281. data/src/physics/Box2D/Dynamics/Contacts/b2CircleContact.h +0 -39
  282. data/src/physics/Box2D/Dynamics/Contacts/b2Contact.cpp +0 -247
  283. data/src/physics/Box2D/Dynamics/Contacts/b2Contact.h +0 -349
  284. data/src/physics/Box2D/Dynamics/Contacts/b2ContactSolver.cpp +0 -838
  285. data/src/physics/Box2D/Dynamics/Contacts/b2ContactSolver.h +0 -95
  286. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp +0 -49
  287. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h +0 -39
  288. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp +0 -49
  289. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h +0 -39
  290. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp +0 -49
  291. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h +0 -38
  292. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonContact.cpp +0 -52
  293. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonContact.h +0 -39
  294. data/src/physics/Box2D/Dynamics/Joints/b2DistanceJoint.cpp +0 -260
  295. data/src/physics/Box2D/Dynamics/Joints/b2DistanceJoint.h +0 -169
  296. data/src/physics/Box2D/Dynamics/Joints/b2FrictionJoint.cpp +0 -251
  297. data/src/physics/Box2D/Dynamics/Joints/b2FrictionJoint.h +0 -119
  298. data/src/physics/Box2D/Dynamics/Joints/b2GearJoint.cpp +0 -419
  299. data/src/physics/Box2D/Dynamics/Joints/b2GearJoint.h +0 -125
  300. data/src/physics/Box2D/Dynamics/Joints/b2Joint.cpp +0 -211
  301. data/src/physics/Box2D/Dynamics/Joints/b2Joint.h +0 -226
  302. data/src/physics/Box2D/Dynamics/Joints/b2MotorJoint.cpp +0 -304
  303. data/src/physics/Box2D/Dynamics/Joints/b2MotorJoint.h +0 -133
  304. data/src/physics/Box2D/Dynamics/Joints/b2MouseJoint.cpp +0 -222
  305. data/src/physics/Box2D/Dynamics/Joints/b2MouseJoint.h +0 -129
  306. data/src/physics/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp +0 -629
  307. data/src/physics/Box2D/Dynamics/Joints/b2PrismaticJoint.h +0 -196
  308. data/src/physics/Box2D/Dynamics/Joints/b2PulleyJoint.cpp +0 -348
  309. data/src/physics/Box2D/Dynamics/Joints/b2PulleyJoint.h +0 -152
  310. data/src/physics/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp +0 -502
  311. data/src/physics/Box2D/Dynamics/Joints/b2RevoluteJoint.h +0 -204
  312. data/src/physics/Box2D/Dynamics/Joints/b2RopeJoint.cpp +0 -241
  313. data/src/physics/Box2D/Dynamics/Joints/b2RopeJoint.h +0 -114
  314. data/src/physics/Box2D/Dynamics/Joints/b2WeldJoint.cpp +0 -344
  315. data/src/physics/Box2D/Dynamics/Joints/b2WeldJoint.h +0 -126
  316. data/src/physics/Box2D/Dynamics/Joints/b2WheelJoint.cpp +0 -419
  317. data/src/physics/Box2D/Dynamics/Joints/b2WheelJoint.h +0 -210
  318. data/src/physics/Box2D/Dynamics/b2Body.cpp +0 -549
  319. data/src/physics/Box2D/Dynamics/b2Body.h +0 -860
  320. data/src/physics/Box2D/Dynamics/b2ContactManager.cpp +0 -296
  321. data/src/physics/Box2D/Dynamics/b2ContactManager.h +0 -52
  322. data/src/physics/Box2D/Dynamics/b2Fixture.cpp +0 -303
  323. data/src/physics/Box2D/Dynamics/b2Fixture.h +0 -345
  324. data/src/physics/Box2D/Dynamics/b2Island.cpp +0 -539
  325. data/src/physics/Box2D/Dynamics/b2Island.h +0 -93
  326. data/src/physics/Box2D/Dynamics/b2TimeStep.h +0 -70
  327. data/src/physics/Box2D/Dynamics/b2World.cpp +0 -1339
  328. data/src/physics/Box2D/Dynamics/b2World.h +0 -354
  329. data/src/physics/Box2D/Dynamics/b2WorldCallbacks.cpp +0 -36
  330. data/src/physics/Box2D/Dynamics/b2WorldCallbacks.h +0 -155
  331. data/src/physics/Box2D/Rope/b2Rope.cpp +0 -259
  332. data/src/physics/Box2D/Rope/b2Rope.h +0 -115
  333. data/src/shape_view.cpp +0 -306
@@ -0,0 +1,39 @@
1
+ // -*- c++ -*-
2
+ #pragma once
3
+ #ifndef __REFLEX_SRC_STYLE_H__
4
+ #define __REFLEX_SRC_STYLE_H__
5
+
6
+
7
+ #include <reflex/style.h>
8
+
9
+
10
+ namespace Reflex
11
+ {
12
+
13
+
14
+ class View;
15
+
16
+
17
+ bool StyleLength_get_pixel_length (
18
+ coord* pixel_length, const StyleLength& style_length, coord parent_size);
19
+
20
+
21
+ bool Style_set_owner (Style* style, View* owner);
22
+
23
+ bool Style_has_variable_lengths (const Style& style);
24
+
25
+ void Style_clear_inherited_values (Style* style);
26
+
27
+ void Style_override (Style* overridden, const Style& overrides);
28
+
29
+ void Style_apply_to (const Style& style, View* view);
30
+
31
+ bool Style_has_width (const Style& style);
32
+
33
+ bool Style_has_height (const Style& style);
34
+
35
+
36
+ }// Reflex
37
+
38
+
39
+ #endif//EOH
@@ -0,0 +1,288 @@
1
+ #include "reflex/timer.h"
2
+ #include "timer.h"
3
+
4
+
5
+ #include "reflex/view.h"
6
+ #include "reflex/event.h"
7
+ #include "reflex/exception.h"
8
+ #include "selector.h"
9
+
10
+
11
+ namespace Reflex
12
+ {
13
+
14
+
15
+ struct Timer::Data
16
+ {
17
+
18
+ View* owner;
19
+
20
+ int id, count;
21
+
22
+ float interval;
23
+
24
+ double next_time;
25
+
26
+ SelectorPtr pselector;
27
+
28
+ Data ()
29
+ : owner(NULL), id(ID_INVALID), count(1), interval(-1), next_time(-1)
30
+ {
31
+ }
32
+
33
+ Selector& selector ()
34
+ {
35
+ if (!pselector) pselector.reset(new Selector);
36
+ return *pselector;
37
+ }
38
+
39
+ };// Data
40
+
41
+
42
+ namespace global
43
+ {
44
+
45
+ static Timer_CreateFun create_fun = NULL;
46
+
47
+ }// global
48
+
49
+ void
50
+ Timer_set_create_fun (Timer_CreateFun fun)
51
+ {
52
+ global::create_fun = fun;
53
+ }
54
+
55
+ static Timer*
56
+ Timer_create ()
57
+ {
58
+ return global::create_fun
59
+ ? global::create_fun()
60
+ : new Timer();
61
+ }
62
+
63
+
64
+ Timer::Timer ()
65
+ {
66
+ }
67
+
68
+ Timer::~Timer ()
69
+ {
70
+ }
71
+
72
+ void
73
+ Timer::fire ()
74
+ {
75
+ if (!*this)
76
+ invalid_state_error(__FILE__, __LINE__);
77
+
78
+ TimerEvent e(this);
79
+ self->owner->on_timer(&e);
80
+ }
81
+
82
+ void
83
+ Timer::stop ()
84
+ {
85
+ set_count(0);
86
+ }
87
+
88
+ View*
89
+ Timer::owner () const
90
+ {
91
+ return self->owner;
92
+ }
93
+
94
+ int
95
+ Timer::id () const
96
+ {
97
+ return self->id;
98
+ }
99
+
100
+ float
101
+ Timer::interval () const
102
+ {
103
+ return self->interval;
104
+ }
105
+
106
+ void
107
+ Timer::set_count (int count)
108
+ {
109
+ self->count = count;
110
+ }
111
+
112
+ int
113
+ Timer::count () const
114
+ {
115
+ return self->count;
116
+ }
117
+
118
+ bool
119
+ Timer::is_finished () const
120
+ {
121
+ return self->count == 0;
122
+ }
123
+
124
+ Timer::operator bool () const
125
+ {
126
+ const Data* p = self.get();
127
+ return p->owner && p->id != ID_INVALID && p->interval >= 0;
128
+ }
129
+
130
+ bool
131
+ Timer::operator ! () const
132
+ {
133
+ return !operator bool();
134
+ }
135
+
136
+ bool
137
+ operator == (const Timer& lhs, const Timer& rhs)
138
+ {
139
+ return lhs.self.get() == rhs.self.get();
140
+ }
141
+
142
+ bool
143
+ operator != (const Timer& lhs, const Timer& rhs)
144
+ {
145
+ return !operator==(lhs, rhs);
146
+ }
147
+
148
+ SelectorPtr*
149
+ Timer::get_selector_ptr ()
150
+ {
151
+ return &self->pselector;
152
+ }
153
+
154
+
155
+ Timers::Timers ()
156
+ : next_id(Timer::ID_FIRST)
157
+ {
158
+ }
159
+
160
+ void
161
+ Timers::add (Timer* timer)
162
+ {
163
+ assert(timer && *timer);
164
+
165
+ for (auto it = timers.begin(), end = timers.end(); it != end; ++it)
166
+ {
167
+ if (timer->self->next_time < (*it)->self->next_time)
168
+ {
169
+ timers.insert(it, timer);
170
+ return;
171
+ }
172
+ }
173
+
174
+ timers.push_back(timer);
175
+ }
176
+
177
+ static void
178
+ update_next_time (Timer* timer)
179
+ {
180
+ assert(timer && *timer);
181
+
182
+ timer->self->next_time = Xot::time() + timer->self->interval;
183
+ }
184
+
185
+ static void
186
+ setup_timer (Timer* timer, View* owner, int id, float interval, int count)
187
+ {
188
+ assert(timer);
189
+
190
+ Timer::Data* self = timer->self.get();
191
+
192
+ self->owner = owner;
193
+ self->id = id;
194
+ self->interval = interval;
195
+ self->count = count;
196
+
197
+ update_next_time(timer);
198
+ }
199
+
200
+ Timer*
201
+ Timers::add (View* owner, float interval, int count)
202
+ {
203
+ if (!owner)
204
+ argument_error(__FILE__, __LINE__);
205
+
206
+ Timer* timer = Timer_create();
207
+ if (!timer)
208
+ reflex_error(__FILE__, __LINE__, "failed to create timer.");
209
+
210
+ setup_timer(timer, owner, next_id++, interval, count);
211
+ add(timer);
212
+ return timer;
213
+ }
214
+
215
+ void
216
+ Timers::remove (Timer* timer)
217
+ {
218
+ if (!timer)
219
+ argument_error(__FILE__, __LINE__);
220
+
221
+ for (auto it = timers.begin(), end = timers.end(); it != end; ++it)
222
+ {
223
+ if (timer->id() == (*it)->id())
224
+ timers.erase(it);
225
+ }
226
+ }
227
+
228
+ static bool
229
+ is_time_to_fire (Timer* timer, double now)
230
+ {
231
+ assert(timer);
232
+
233
+ return now >= timer->self->next_time;
234
+ }
235
+
236
+ static void
237
+ fire_timer (Timer* timer)
238
+ {
239
+ assert(timer);
240
+
241
+ if (timer->is_finished())
242
+ return;
243
+
244
+ if (timer->self->count > 0)
245
+ --timer->self->count;
246
+
247
+ timer->fire();
248
+
249
+ if (!timer->is_finished())
250
+ update_next_time(timer);
251
+ }
252
+
253
+ static bool
254
+ compare_timer (const Timer::Ref& lhs, const Timer::Ref& rhs)
255
+ {
256
+ return lhs->is_finished() || lhs->self->next_time < rhs->self->next_time;
257
+ }
258
+
259
+ void
260
+ Timers::fire (double now)
261
+ {
262
+ for (auto it = timers.begin(), end = timers.end(); it != end; ++it)
263
+ {
264
+ Timer* timer = it->get();
265
+ if (!is_time_to_fire(timer, now))
266
+ break;
267
+
268
+ fire_timer(timer);
269
+ }
270
+
271
+ timers.sort(compare_timer);
272
+
273
+ while (!timers.empty() && timers.front()->is_finished())
274
+ timers.pop_front();
275
+ }
276
+
277
+ void
278
+ Timers::find_timers (
279
+ TimerList* result, const Selector& selector, bool recursive) const
280
+ {
281
+ if (!result)
282
+ argument_error(__FILE__, __LINE__);
283
+
284
+ not_implemented_error(__FILE__, __LINE__);
285
+ }
286
+
287
+
288
+ }// Reflex
@@ -0,0 +1,55 @@
1
+ // -*- c++ -*-
2
+ #pragma once
3
+ #ifndef __REFLEX_SRC_TIMER_H__
4
+ #define __REFLEX_SRC_TIMER_H__
5
+
6
+
7
+ #include <vector>
8
+ #include <list>
9
+ #include <reflex/timer.h>
10
+
11
+
12
+ namespace Reflex
13
+ {
14
+
15
+
16
+ class Timers
17
+ {
18
+
19
+ public:
20
+
21
+ typedef std::vector<Timer::Ref> TimerList;
22
+
23
+ Timers ();
24
+
25
+ Timer* add (View* owner, float interval, int count = 1);
26
+
27
+ void remove (Timer* timer);
28
+
29
+ void fire (double now);
30
+
31
+ void find_timers (
32
+ TimerList* result, const Selector& selector, bool recuesive = false) const;
33
+
34
+ private:
35
+
36
+ typedef std::list<Timer::Ref> List;
37
+
38
+ List timers;
39
+
40
+ int next_id;
41
+
42
+ void add (Timer* timer);
43
+
44
+ };// Timers
45
+
46
+
47
+ typedef Timer* (*Timer_CreateFun) ();
48
+
49
+ void Timer_set_create_fun (Timer_CreateFun fun);
50
+
51
+
52
+ }// Reflex
53
+
54
+
55
+ #endif//EOH
@@ -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