reflexion 0.5.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/reflex/application.cpp +19 -1
  3. data/.doc/ext/reflex/chase_constraint.cpp +84 -0
  4. data/.doc/ext/reflex/clipboard.cpp +65 -0
  5. data/.doc/ext/reflex/constraint.cpp +135 -0
  6. data/.doc/ext/reflex/key_event.cpp +6 -6
  7. data/.doc/ext/reflex/link_constraint.cpp +178 -0
  8. data/.doc/ext/reflex/menu.cpp +302 -0
  9. data/.doc/ext/reflex/native.cpp +22 -4
  10. data/.doc/ext/reflex/pin.cpp +156 -0
  11. data/.doc/ext/reflex/pointer.cpp +2 -0
  12. data/.doc/ext/reflex/pointer_event.cpp +1 -1
  13. data/.doc/ext/reflex/reflex.cpp +42 -7
  14. data/.doc/ext/reflex/selector.cpp +4 -4
  15. data/.doc/ext/reflex/snap_constraint.cpp +125 -0
  16. data/.doc/ext/reflex/style_length.cpp +3 -2
  17. data/.doc/ext/reflex/view.cpp +96 -23
  18. data/.doc/ext/reflex/wheel_constraint.cpp +142 -0
  19. data/.doc/ext/reflex/window.cpp +59 -17
  20. data/.github/workflows/release-gem.yml +10 -1
  21. data/.github/workflows/test.yml +9 -0
  22. data/ChangeLog.md +30 -0
  23. data/README.md +1 -0
  24. data/VERSION +1 -1
  25. data/ext/reflex/application.cpp +21 -1
  26. data/ext/reflex/chase_constraint.cpp +89 -0
  27. data/ext/reflex/clipboard.cpp +69 -0
  28. data/ext/reflex/constraint.cpp +146 -0
  29. data/ext/reflex/key_event.cpp +6 -6
  30. data/ext/reflex/link_constraint.cpp +194 -0
  31. data/ext/reflex/menu.cpp +330 -0
  32. data/ext/reflex/native.cpp +22 -4
  33. data/ext/reflex/pin.cpp +165 -0
  34. data/ext/reflex/pointer.cpp +2 -0
  35. data/ext/reflex/pointer_event.cpp +1 -1
  36. data/ext/reflex/reflex.cpp +42 -7
  37. data/ext/reflex/selector.cpp +4 -4
  38. data/ext/reflex/selector.h +1 -1
  39. data/ext/reflex/snap_constraint.cpp +135 -0
  40. data/ext/reflex/style_length.cpp +3 -2
  41. data/ext/reflex/view.cpp +117 -37
  42. data/ext/reflex/wheel_constraint.cpp +154 -0
  43. data/ext/reflex/window.cpp +65 -18
  44. data/include/reflex/application.h +9 -0
  45. data/include/reflex/clipboard.h +53 -0
  46. data/include/reflex/constraint.h +275 -0
  47. data/include/reflex/defs.h +204 -195
  48. data/include/reflex/event.h +2 -0
  49. data/include/reflex/menu.h +120 -0
  50. data/include/reflex/pin.h +68 -0
  51. data/include/reflex/pointer.h +4 -0
  52. data/include/reflex/ruby/clipboard.h +23 -0
  53. data/include/reflex/ruby/constraint.h +94 -0
  54. data/include/reflex/ruby/menu.h +103 -0
  55. data/include/reflex/ruby/pin.h +40 -0
  56. data/include/reflex/ruby/view.h +36 -0
  57. data/include/reflex/ruby/window.h +36 -18
  58. data/include/reflex/view.h +39 -12
  59. data/include/reflex/window.h +17 -4
  60. data/include/reflex.h +5 -0
  61. data/lib/reflex/chase_constraint.rb +15 -0
  62. data/lib/reflex/clipboard.rb +19 -0
  63. data/lib/reflex/constraint.rb +29 -0
  64. data/lib/reflex/extension.rb +1 -1
  65. data/lib/reflex/helper.rb +28 -0
  66. data/lib/reflex/key_event.rb +7 -12
  67. data/lib/reflex/link_constraint.rb +31 -0
  68. data/lib/reflex/menu.rb +76 -0
  69. data/lib/reflex/pin.rb +39 -0
  70. data/lib/reflex/pointer.rb +18 -0
  71. data/lib/reflex/pointer_event.rb +1 -1
  72. data/lib/reflex/snap_constraint.rb +28 -0
  73. data/lib/reflex/view.rb +56 -4
  74. data/lib/reflex/wheel_constraint.rb +28 -0
  75. data/lib/reflex/wheel_event.rb +9 -0
  76. data/lib/reflex.rb +15 -6
  77. data/pod.rake +4 -2
  78. data/reflex.gemspec +3 -3
  79. data/samples/constraint.rb +152 -0
  80. data/samples/menu.rb +29 -0
  81. data/src/application.cpp +21 -2
  82. data/src/application.h +5 -0
  83. data/src/clipboard.cpp +81 -0
  84. data/src/constraint.cpp +1662 -0
  85. data/src/constraint.h +64 -0
  86. data/src/event.cpp +7 -1
  87. data/src/event.h +1 -2
  88. data/src/ios/application.mm +5 -0
  89. data/src/ios/clipboard.mm +44 -0
  90. data/src/ios/event.h +6 -2
  91. data/src/ios/event.mm +31 -12
  92. data/src/ios/menu.mm +36 -0
  93. data/src/ios/view_controller.mm +45 -12
  94. data/src/ios/window.mm +6 -0
  95. data/src/menu.cpp +325 -0
  96. data/src/menu.h +65 -0
  97. data/src/osx/app_delegate.mm +74 -125
  98. data/src/osx/application.mm +16 -0
  99. data/src/osx/clipboard.mm +45 -0
  100. data/src/osx/event.mm +40 -10
  101. data/src/osx/menu.h +25 -0
  102. data/src/osx/menu.mm +372 -0
  103. data/src/osx/native_window.mm +27 -0
  104. data/src/osx/opengl_view.mm +51 -0
  105. data/src/osx/window.mm +11 -0
  106. data/src/pin.cpp +137 -0
  107. data/src/pointer.cpp +27 -16
  108. data/src/pointer.h +6 -0
  109. data/src/sdl/application.cpp +5 -0
  110. data/src/sdl/clipboard.cpp +39 -0
  111. data/src/sdl/event.cpp +20 -3
  112. data/src/sdl/event.h +6 -3
  113. data/src/sdl/menu.cpp +35 -0
  114. data/src/sdl/window.cpp +26 -8
  115. data/src/view.cpp +313 -52
  116. data/src/view.h +18 -2
  117. data/src/win32/application.cpp +5 -0
  118. data/src/win32/clipboard.cpp +210 -0
  119. data/src/win32/event.cpp +11 -1
  120. data/src/win32/event.h +2 -0
  121. data/src/win32/menu.cpp +352 -0
  122. data/src/win32/menu.h +27 -0
  123. data/src/win32/window.cpp +62 -0
  124. data/src/win32/window.h +3 -0
  125. data/src/window.cpp +235 -22
  126. data/src/window.h +13 -2
  127. data/src/world.cpp +77 -14
  128. data/src/world.h +9 -2
  129. data/test/helper.rb +7 -0
  130. data/test/test_application.rb +11 -0
  131. data/test/test_chase_constraint.rb +124 -0
  132. data/test/test_clipboard.rb +54 -0
  133. data/test/test_constraint.rb +186 -0
  134. data/test/test_key_event.rb +6 -0
  135. data/test/test_link_constraint.rb +239 -0
  136. data/test/test_menu.rb +207 -0
  137. data/test/test_pin.rb +65 -0
  138. data/test/test_pointer.rb +23 -9
  139. data/test/test_pointer_event.rb +1 -1
  140. data/test/test_snap_constraint.rb +142 -0
  141. data/test/test_view.rb +113 -23
  142. data/test/test_wheel_constraint.rb +127 -0
  143. data/test/test_wheel_event.rb +15 -9
  144. data/test/test_window.rb +10 -0
  145. metadata +82 -8
data/src/view.cpp CHANGED
@@ -20,6 +20,7 @@
20
20
  #include "world.h"
21
21
  #include "body.h"
22
22
  #include "fixture.h"
23
+ #include "constraint.h"
23
24
 
24
25
 
25
26
  namespace Reflex
@@ -84,35 +85,37 @@ namespace Reflex
84
85
  uint flags =
85
86
  FLAG_CLIP | FLAG_RESIZE_TO_FIT | REDRAW | UPDATE_LAYOUT | UPDATE_STYLE;
86
87
 
87
- std::unique_ptr<Point> ppivot;
88
+ std::unique_ptr<Point> ppivot;
88
89
 
89
- std::unique_ptr<Point> pscroll;
90
+ std::unique_ptr<Point> pscroll;
90
91
 
91
- SelectorPtr pselector;
92
+ SelectorPtr pselector;
92
93
 
93
- std::unique_ptr<SelectorSet> pselectors_for_update;
94
+ std::unique_ptr<SelectorSet> pselectors_for_update;
94
95
 
95
- std::unique_ptr<Image> pcache_image;
96
+ std::unique_ptr<Image> pcache_image;
96
97
 
97
- std::unique_ptr<Timers> ptimers;
98
+ std::unique_ptr<Timers> ptimers;
98
99
 
99
- std::unique_ptr<Style> pstyle;
100
+ std::unique_ptr<Style> pstyle;
100
101
 
101
- std::unique_ptr<StyleList> pstyles;
102
+ std::unique_ptr<StyleList> pstyles;
102
103
 
103
- Shape::Ref pshape;
104
+ Shape::Ref pshape;
104
105
 
105
- std::unique_ptr<ShapeList> pshapes;
106
+ std::unique_ptr<ShapeList> pshapes;
106
107
 
107
- Filter::Ref pfilter;
108
+ Filter::Ref pfilter;
108
109
 
109
- std::unique_ptr<Body> pbody;
110
+ std::unique_ptr<Body> pbody;
110
111
 
111
- std::unique_ptr<World> pchild_world;
112
+ std::unique_ptr<ConstraintList> pconstraints;
112
113
 
113
- std::unique_ptr<ChildList> pchildren;
114
+ std::unique_ptr<World> pchild_world;
114
115
 
115
- std::unique_ptr<ChildList> pchildren_sorted;
116
+ std::unique_ptr<ChildList> pchildren;
117
+
118
+ std::unique_ptr<ChildList> pchildren_sorted;
116
119
 
117
120
  Point& pivot ()
118
121
  {
@@ -176,6 +179,24 @@ namespace Reflex
176
179
  return *pshapes;
177
180
  }
178
181
 
182
+ ConstraintList& constraints ()
183
+ {
184
+ if (!pconstraints) pconstraints.reset(new ConstraintList);
185
+ return *pconstraints;
186
+ }
187
+
188
+ void sever_constraints ()
189
+ {
190
+ if (!pconstraints) return;
191
+
192
+ ConstraintList list;
193
+ list.swap(*pconstraints);
194
+ for (auto& constraint : list)
195
+ Constraint_sever(constraint.get());
196
+
197
+ pconstraints.reset();
198
+ }
199
+
179
200
  template <typename FUN>
180
201
  void each_shape (FUN fun)
181
202
  {
@@ -203,6 +224,17 @@ namespace Reflex
203
224
  });
204
225
  }
205
226
 
227
+ void update_constraints ()
228
+ {
229
+ if (!pconstraints) return;
230
+
231
+ for (auto& constraint : *pconstraints)
232
+ {
233
+ Constraint_deactivate(constraint.get());
234
+ Constraint_activate(constraint.get());
235
+ }
236
+ }
237
+
206
238
  void resize_shapes (FrameEvent* e)
207
239
  {
208
240
  each_shape([=](Shape* shape)
@@ -287,6 +319,7 @@ namespace Reflex
287
319
  }
288
320
 
289
321
  update_shapes(true);
322
+ update_constraints();
290
323
  }
291
324
 
292
325
  World* parent_world (bool create = true)
@@ -706,8 +739,21 @@ namespace Reflex
706
739
  };// LayoutContext
707
740
 
708
741
 
709
- void
710
- View_set_window (View* view, Window* window)
742
+ static void
743
+ call_children (View* parent, std::function<bool(View*)> fun, bool sort = true)
744
+ {
745
+ auto* children = parent->self->children(false, sort);
746
+ if (!children) return;
747
+
748
+ for (auto it = children->rbegin(), end = children->rend(); it != end; ++it)
749
+ {
750
+ if (!fun(it->get()))
751
+ break;
752
+ }
753
+ }
754
+
755
+ static void
756
+ set_window (View* view, Window* window)
711
757
  {
712
758
  if (!view)
713
759
  argument_error(__FILE__, __LINE__);
@@ -726,7 +772,7 @@ namespace Reflex
726
772
  if (children)
727
773
  {
728
774
  for (auto& child : *children)
729
- View_set_window(child.get(), window);
775
+ set_window(child.get(), window);
730
776
  }
731
777
 
732
778
  if (view->self->window)
@@ -737,6 +783,28 @@ namespace Reflex
737
783
  }
738
784
  }
739
785
 
786
+ void
787
+ View_set_window (View* view, Window* window)
788
+ {
789
+ if (!view)
790
+ argument_error(__FILE__, __LINE__);
791
+
792
+ Window* old = view->self->window;
793
+ if (old && old->active())
794
+ {
795
+ Event e;
796
+ View_deactivate_tree(view, &e);
797
+ }
798
+
799
+ set_window(view, window);
800
+
801
+ if (window && window->active())
802
+ {
803
+ Event e;
804
+ View_activate_tree(view, &e);
805
+ }
806
+ }
807
+
740
808
  static void
741
809
  apply_style_to_children_have_variable_lengths (View* parent)
742
810
  {
@@ -832,18 +900,103 @@ namespace Reflex
832
900
  return create ? &view->self->body() : view->self->pbody.get();
833
901
  }
834
902
 
903
+ const Body*
904
+ View_get_body (const View* view)
905
+ {
906
+ return View_get_body(const_cast<View*>(view), false);
907
+ }
908
+
909
+ void
910
+ View_add_constraint (View* view, Constraint* constraint)
911
+ {
912
+ if (!view || !constraint)
913
+ argument_error(__FILE__, __LINE__);
914
+
915
+ if (constraint->is_removed())
916
+ invalid_state_error(__FILE__, __LINE__, "constraint is already removed");
917
+
918
+ if (constraint->view(0) != view)
919
+ argument_error(__FILE__, __LINE__, "the constraint does not belong to this view");
920
+
921
+ auto& list = view->self->constraints();
922
+ if (std::find(list.begin(), list.end(), constraint) != list.end())
923
+ invalid_state_error(__FILE__, __LINE__, "the constraint is already added");
924
+
925
+ // the mismatch is not detectable before activation because
926
+ // activating is what creates the missing bodies
927
+ if (
928
+ !Constraint_activate(constraint) &&
929
+ Constraint_has_world_mismatch(constraint))
930
+ {
931
+ physics_error(__FILE__, __LINE__, "the views belong to different worlds");
932
+ }
933
+
934
+ list.push_back(constraint);
935
+ View* view1 = constraint->view(1);
936
+ if (view1) view1->self->constraints().push_back(constraint);
937
+ }
938
+
939
+ void
940
+ View_remove_constraint (View* view, Constraint* constraint)
941
+ {
942
+ if (!view || !constraint)
943
+ argument_error(__FILE__, __LINE__);
944
+
945
+ auto* list = view->self->pconstraints.get();
946
+ if (!list) return;
947
+
948
+ auto it = std::find(list->begin(), list->end(), constraint);
949
+ if (it != list->end()) list->erase(it);
950
+
951
+ if (list->empty()) view->self->pconstraints.reset();
952
+ }
953
+
835
954
  bool
836
955
  View_is_active (const View& view)
837
956
  {
838
957
  return view.self->window;
839
958
  }
840
959
 
960
+ void
961
+ View_activate_tree (View* view, Event* event)
962
+ {
963
+ if (!view)
964
+ argument_error(__FILE__, __LINE__);
965
+
966
+ Event e = event->dup();
967
+ view->on_activate(&e);
968
+ if (e.is_blocked()) return;
969
+
970
+ call_children(view, [&](View* child) {
971
+ View_activate_tree(child, &e);
972
+ return !e.is_blocked();
973
+ }, false);
974
+ }
975
+
976
+ void
977
+ View_deactivate_tree (View* view, Event* event)
978
+ {
979
+ if (!view)
980
+ argument_error(__FILE__, __LINE__);
981
+
982
+ Event e = event->dup();
983
+
984
+ call_children(view, [&](View* child) {
985
+ View_deactivate_tree(child, &e);
986
+ return !e.is_blocked();
987
+ }, false);
988
+
989
+ if (e.is_blocked()) return;
990
+
991
+ view->on_deactivate(&e);
992
+ }
993
+
841
994
  static void
842
995
  find_all_children (
843
996
  View::ChildList* result, const View* view, const Selector& selector,
844
997
  bool recursive)
845
998
  {
846
- View::ChildList* children = view->self->children();
999
+ auto* children = view->self->children();
847
1000
  if (!children) return;
848
1001
 
849
1002
  for (auto& child : *children)
@@ -869,7 +1022,7 @@ namespace Reflex
869
1022
  {
870
1023
  for (auto& style : *pstyles)
871
1024
  {
872
- if (selector.contains(style.selector()))
1025
+ if (style.selector().contains(selector))
873
1026
  result->push_back(style);
874
1027
  }
875
1028
  }
@@ -933,14 +1086,14 @@ namespace Reflex
933
1086
  }
934
1087
 
935
1088
  static void
936
- update_child_world (View* view, float dt)
1089
+ update_child_world (View* view)
937
1090
  {
938
1091
  View::Data* self = view->self.get();
939
1092
 
940
1093
  World* child_world = self->pchild_world.get();
941
1094
  if (!child_world) return;
942
1095
 
943
- child_world->on_update(dt);
1096
+ child_world->on_update();
944
1097
 
945
1098
  View::ChildList* children = self->children();
946
1099
  if (children)
@@ -1087,7 +1240,7 @@ namespace Reflex
1087
1240
  }
1088
1241
 
1089
1242
  update_view_shapes(view);
1090
- update_child_world(view, event.dt());
1243
+ update_child_world(view);
1091
1244
 
1092
1245
  UpdateEvent e = event.dup();
1093
1246
  view->on_update(&e);
@@ -1194,7 +1347,7 @@ namespace Reflex
1194
1347
 
1195
1348
  static void
1196
1349
  draw_view (
1197
- View* view, DrawEvent* event, const Point& offset, const Bounds& clip)
1350
+ View* view, DrawEvent* event, const Point& offset, const Bounds& clip, float scale)
1198
1351
  {
1199
1352
  View::Data* self = view->self.get();
1200
1353
 
@@ -1218,7 +1371,7 @@ namespace Reflex
1218
1371
  for (auto& child : *children)
1219
1372
  {
1220
1373
  if (event->bounds() & child->self->frame)
1221
- View_draw_tree(child.get(), event, offset, clip);
1374
+ View_draw_tree(child.get(), event, offset, clip, scale);
1222
1375
  }
1223
1376
  }
1224
1377
 
@@ -1240,7 +1393,7 @@ namespace Reflex
1240
1393
  DrawEvent_set_painter(event, &cache_painter);
1241
1394
 
1242
1395
  cache_painter.begin();
1243
- draw_view(view, event, 0, event->bounds());
1396
+ draw_view(view, event, 0, event->bounds(), 1);
1244
1397
  cache_painter.end();
1245
1398
 
1246
1399
  DrawEvent_set_painter(event, view_painter);
@@ -1284,7 +1437,7 @@ namespace Reflex
1284
1437
 
1285
1438
  void
1286
1439
  View_draw_tree (
1287
- View* view, DrawEvent* event, const Point& offset, const Bounds& clip)
1440
+ View* view, DrawEvent* event, const Point& offset, Bounds clip, float scale)
1288
1441
  {
1289
1442
  if (!view)
1290
1443
  argument_error(__FILE__, __LINE__);
@@ -1300,9 +1453,17 @@ namespace Reflex
1300
1453
  return;
1301
1454
 
1302
1455
  Bounds bounds = self->frame;
1303
- Point pos = bounds.position();
1304
- Bounds clip2 = bounds.dup().move_by(offset) & clip;
1456
+ if (clip)
1457
+ {
1458
+ // clipping is applied via glScissor which ignores the painter matrix,
1459
+ // so track the frame in screen space: ancestor zooms are accumulated
1460
+ // in 'scale' and ancestor positions in 'offset'
1461
+ clip &= Bounds(
1462
+ bounds.x * scale + offset.x, bounds.y * scale + offset.y,
1463
+ bounds.w * scale, bounds.h * scale);
1464
+ }
1305
1465
 
1466
+ Point pos = bounds.position();
1306
1467
  bounds.set_position(0, 0, bounds.z);
1307
1468
  if (self->pscroll)
1308
1469
  {
@@ -1320,6 +1481,10 @@ namespace Reflex
1320
1481
  if (pivot) p->translate( pivot->x * bounds.w, pivot->y * bounds.h);
1321
1482
  p->rotate(self->angle);
1322
1483
  if (pivot) p->translate(-pivot->x * bounds.w, -pivot->y * bounds.h);
1484
+
1485
+ // a rotated frame can not be represented as a screen-space
1486
+ // scissor rect, so give up clipping from here on down
1487
+ clip.reset(-1);
1323
1488
  }
1324
1489
 
1325
1490
  float zoom = self->zoom;
@@ -1332,8 +1497,9 @@ namespace Reflex
1332
1497
 
1333
1498
  if (!draw_view_with_cache(view, &e, redraw))
1334
1499
  {
1335
- pos += offset;
1336
- draw_view(view, &e, pos, clip2);
1500
+ draw_view(
1501
+ view, &e, Point(pos.x * scale + offset.x, pos.y * scale + offset.y),
1502
+ clip, zoom > 0 ? scale * zoom : scale);
1337
1503
  }
1338
1504
 
1339
1505
  p->pop_matrix();
@@ -1362,6 +1528,26 @@ namespace Reflex
1362
1528
  view->self->add_flag(View::Data::UPDATE_SHAPES);
1363
1529
  }
1364
1530
 
1531
+ void
1532
+ View_get_hovered_views (ViewList* result, View* view, const Point& position)
1533
+ {
1534
+ if (!result)
1535
+ argument_error(__FILE__, __LINE__);
1536
+ if (!view)
1537
+ argument_error(__FILE__, __LINE__);
1538
+
1539
+ if (view->hidden() || !view->frame().is_include(position))
1540
+ return;
1541
+
1542
+ result->emplace_back(view);
1543
+
1544
+ Point pos = view->from_parent(position);
1545
+ call_children(view, [&](View* child) {
1546
+ View_get_hovered_views(result, child, pos);
1547
+ return true;
1548
+ });
1549
+ }
1550
+
1365
1551
  void
1366
1552
  View_call_key_event (View* view, KeyEvent* event)
1367
1553
  {
@@ -1384,19 +1570,6 @@ namespace Reflex
1384
1570
  }
1385
1571
  }
1386
1572
 
1387
- static void
1388
- call_children (View* parent, std::function<bool(View*)> fun, bool sort = true)
1389
- {
1390
- auto* children = parent->self->children(false, sort);
1391
- if (!children) return;
1392
-
1393
- for (auto it = children->rbegin(), end = children->rend(); it != end; ++it)
1394
- {
1395
- if (!fun(it->get()))
1396
- break;
1397
- }
1398
- }
1399
-
1400
1573
  static void
1401
1574
  call_pointer_events_for_each_child (View* parent, PointerEvent* event)
1402
1575
  {
@@ -1423,6 +1596,8 @@ namespace Reflex
1423
1596
  case Pointer::UP: view->on_pointer_up(event); break;
1424
1597
  case Pointer::MOVE: view->on_pointer_move(event); break;
1425
1598
  case Pointer::CANCEL: view->on_pointer_cancel(event); break;
1599
+ case Pointer::ENTER: view->on_pointer_enter(event); break;
1600
+ case Pointer::LEAVE: view->on_pointer_leave(event); break;
1426
1601
  default: break;
1427
1602
  }
1428
1603
  }
@@ -1469,6 +1644,10 @@ namespace Reflex
1469
1644
 
1470
1645
  PointerEvent e = event->dup();
1471
1646
 
1647
+ auto action = e[0].action();
1648
+ if (action == Pointer::ENTER || action == Pointer::LEAVE)
1649
+ return call_pointer_events(view, &e);
1650
+
1472
1651
  if (!e.is_captured())
1473
1652
  call_pointer_events_for_each_child(view, &e);
1474
1653
 
@@ -1586,6 +1765,8 @@ namespace Reflex
1586
1765
 
1587
1766
  View::~View ()
1588
1767
  {
1768
+ self->sever_constraints();
1769
+
1589
1770
  clear_children();// to delete child shapes before world.
1590
1771
  }
1591
1772
 
@@ -1831,7 +2012,7 @@ namespace Reflex
1831
2012
  }
1832
2013
 
1833
2014
  void
1834
- View::add_child (View* child)
2015
+ View::add_child (View* child, int index)
1835
2016
  {
1836
2017
  if (!child)
1837
2018
  argument_error(__FILE__, __LINE__);
@@ -1845,7 +2026,11 @@ namespace Reflex
1845
2026
  else if (found != belong)
1846
2027
  invalid_state_error(__FILE__, __LINE__);
1847
2028
 
1848
- self->children(true)->push_back(child);
2029
+ auto* children = self->children(true);
2030
+ if (index < 0 || (int) children->size() < index)
2031
+ children->push_back(child);
2032
+ else
2033
+ children->insert(children->begin() + (size_t) index, child);
1849
2034
 
1850
2035
  View* prev_parent = child->parent();
1851
2036
  set_parent(child, this);
@@ -2089,12 +2274,17 @@ namespace Reflex
2089
2274
  }
2090
2275
 
2091
2276
  void
2092
- View::add_shape (Shape* shape)
2277
+ View::add_shape (Shape* shape, int index)
2093
2278
  {
2094
2279
  if (!shape) return;
2095
2280
 
2096
2281
  Shape_set_owner(shape, this);
2097
- self->shapes().push_back(shape);
2282
+
2283
+ auto& shapes = self->shapes();
2284
+ if (index < 0 || (int) shapes.size() < index)
2285
+ shapes.push_back(shape);
2286
+ else
2287
+ shapes.insert(shapes.begin() + (size_t) index, shape);
2098
2288
  }
2099
2289
 
2100
2290
  void
@@ -2131,7 +2321,7 @@ namespace Reflex
2131
2321
  {
2132
2322
  for (auto& shape : *pshapes)
2133
2323
  {
2134
- if (selector.contains(shape->selector()))
2324
+ if (shape->selector().contains(selector))
2135
2325
  result.push_back(shape);
2136
2326
  }
2137
2327
  }
@@ -2168,6 +2358,58 @@ namespace Reflex
2168
2358
  return self->pshapes->end();
2169
2359
  }
2170
2360
 
2361
+ void
2362
+ View::clear_constraints ()
2363
+ {
2364
+ self->sever_constraints();
2365
+ }
2366
+
2367
+ View::ConstraintList
2368
+ View::find_constraints (const Selector& selector) const
2369
+ {
2370
+ ConstraintList result;
2371
+ ConstraintList* pconstraints = self->pconstraints.get();
2372
+ if (pconstraints)
2373
+ {
2374
+ for (auto& constraint : *pconstraints)
2375
+ {
2376
+ if (constraint->selector().contains(selector))
2377
+ result.push_back(constraint);
2378
+ }
2379
+ }
2380
+ return result;
2381
+ }
2382
+
2383
+ static View::ConstraintList empty_constraints;
2384
+
2385
+ View::constraint_iterator
2386
+ View::constraint_begin ()
2387
+ {
2388
+ if (!self->pconstraints) return empty_constraints.begin();
2389
+ return self->pconstraints->begin();
2390
+ }
2391
+
2392
+ View::const_constraint_iterator
2393
+ View::constraint_begin () const
2394
+ {
2395
+ if (!self->pconstraints) return empty_constraints.begin();
2396
+ return self->pconstraints->begin();
2397
+ }
2398
+
2399
+ View::constraint_iterator
2400
+ View::constraint_end ()
2401
+ {
2402
+ if (!self->pconstraints) return empty_constraints.end();
2403
+ return self->pconstraints->end();
2404
+ }
2405
+
2406
+ View::const_constraint_iterator
2407
+ View::constraint_end () const
2408
+ {
2409
+ if (!self->pconstraints) return empty_constraints.end();
2410
+ return self->pconstraints->end();
2411
+ }
2412
+
2171
2413
  void
2172
2414
  View::set_filter (Filter* filter)
2173
2415
  {
@@ -2626,10 +2868,9 @@ namespace Reflex
2626
2868
  }
2627
2869
 
2628
2870
  void
2629
- View::update_world (float duration)
2871
+ View::update_world ()
2630
2872
  {
2631
- World* w = self->pchild_world.get();
2632
- if (w) w->update(duration);
2873
+ update_child_world(this);
2633
2874
  }
2634
2875
 
2635
2876
  float
@@ -2736,6 +2977,16 @@ namespace Reflex
2736
2977
  {
2737
2978
  }
2738
2979
 
2980
+ void
2981
+ View::on_activate (Event* e)
2982
+ {
2983
+ }
2984
+
2985
+ void
2986
+ View::on_deactivate (Event* e)
2987
+ {
2988
+ }
2989
+
2739
2990
  void
2740
2991
  View::on_show (Event* e)
2741
2992
  {
@@ -2826,6 +3077,16 @@ namespace Reflex
2826
3077
  {
2827
3078
  }
2828
3079
 
3080
+ void
3081
+ View::on_pointer_enter (PointerEvent* e)
3082
+ {
3083
+ }
3084
+
3085
+ void
3086
+ View::on_pointer_leave (PointerEvent* e)
3087
+ {
3088
+ }
3089
+
2829
3090
  void
2830
3091
  View::on_wheel (WheelEvent* e)
2831
3092
  {
data/src/view.h CHANGED
@@ -11,10 +11,14 @@ namespace Reflex
11
11
  {
12
12
 
13
13
 
14
+ typedef std::vector<View::Ref> ViewList;
15
+
16
+
14
17
  constexpr const char* VIEW_TAG_ROOT = "ROOT";
15
18
 
16
19
 
17
20
  class Body;
21
+ class Constraint;
18
22
 
19
23
 
20
24
  void View_set_window (View* view, Window* window);
@@ -23,19 +27,31 @@ namespace Reflex
23
27
 
24
28
  const Style& View_get_style (const View* view);
25
29
 
26
- Body* View_get_body (View* view, bool create = true);
30
+ Body* View_get_body ( View* view, bool create = true);
31
+
32
+ const Body* View_get_body (const View* view);
33
+
34
+ void View_add_constraint (View* view, Constraint* constraint);
35
+
36
+ void View_remove_constraint (View* view, Constraint* constraint);
27
37
 
28
38
  bool View_is_active (const View& view);
29
39
 
40
+ void View_activate_tree (View* view, Event* event);
41
+
42
+ void View_deactivate_tree (View* view, Event* event);
43
+
30
44
  void View_update_tree (View* view, const UpdateEvent& event);
31
45
 
32
46
  void View_draw_tree (
33
- View* view, DrawEvent* event, const Point& offset, const Bounds& clip);
47
+ View* view, DrawEvent* event, const Point& offset, Bounds clip, float scale = 1);
34
48
 
35
49
  void View_update_styles (View* view, const Selector& selector);
36
50
 
37
51
  void View_update_shapes (View* view);
38
52
 
53
+ void View_get_hovered_views (ViewList* result, View* view, const Point& position);
54
+
39
55
  void View_call_key_event (View* view, KeyEvent* event);
40
56
 
41
57
  void View_call_pointer_event (View* view, PointerEvent* event);
@@ -16,6 +16,11 @@ namespace Reflex
16
16
  return new Application::Data();
17
17
  }
18
18
 
19
+ void
20
+ Application_set_menu (Application* app, Menu* menu)
21
+ {
22
+ }
23
+
19
24
 
20
25
  static double
21
26
  get_time ()