reflexion 0.1.10 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/reflex/body.cpp +53 -0
  3. data/.doc/ext/reflex/native.cpp +0 -4
  4. data/.doc/ext/reflex/selector.cpp +3 -3
  5. data/.doc/ext/reflex/style.cpp +390 -30
  6. data/.doc/ext/reflex/style_length.cpp +1 -1
  7. data/.doc/ext/reflex/view.cpp +24 -6
  8. data/VERSION +1 -1
  9. data/ext/reflex/body.cpp +59 -0
  10. data/ext/reflex/native.cpp +0 -4
  11. data/ext/reflex/selector.cpp +3 -3
  12. data/ext/reflex/style.cpp +432 -32
  13. data/ext/reflex/style_length.cpp +1 -1
  14. data/ext/reflex/view.cpp +25 -5
  15. data/include/reflex/body.h +16 -0
  16. data/include/reflex/ruby.h +5 -3
  17. data/include/reflex/ruby/style.h +11 -0
  18. data/include/reflex/selector.h +7 -1
  19. data/include/reflex/style.h +93 -27
  20. data/include/reflex/view.h +8 -4
  21. data/lib/reflex.rb +0 -2
  22. data/lib/reflex/body.rb +1 -0
  23. data/lib/reflex/button.rb +1 -0
  24. data/lib/reflex/selector.rb +10 -1
  25. data/lib/reflex/style.rb +15 -0
  26. data/lib/reflex/style_length.rb +1 -1
  27. data/lib/reflex/view.rb +5 -2
  28. data/lib/reflex/window.rb +2 -2
  29. data/samples/reflexion/breakout.rb +4 -9
  30. data/src/body.cpp +61 -0
  31. data/src/ios/event.mm +1 -3
  32. data/src/ios/native_window.mm +3 -20
  33. data/src/ios/opengl_view.mm +1 -1
  34. data/src/ios/window.mm +7 -0
  35. data/src/selector.cpp +38 -16
  36. data/src/style.cpp +515 -161
  37. data/src/view.cpp +371 -242
  38. data/src/world.cpp +8 -0
  39. data/test/test_selector.rb +14 -12
  40. data/test/test_style.rb +11 -6
  41. data/test/test_style_length.rb +5 -6
  42. data/test/test_view.rb +8 -7
  43. metadata +2 -17
  44. data/.doc/ext/reflex/style_length2.cpp +0 -149
  45. data/.doc/ext/reflex/style_length4.cpp +0 -192
  46. data/ext/reflex/style_length2.cpp +0 -157
  47. data/ext/reflex/style_length4.cpp +0 -204
  48. data/include/reflex/ruby/style_length.h +0 -63
  49. data/include/reflex/style_length.h +0 -147
  50. data/lib/reflex/style_length2.rb +0 -34
  51. data/lib/reflex/style_length4.rb +0 -38
  52. data/src/style_length.cpp +0 -341
  53. data/test/test_style_length2.rb +0 -50
  54. data/test/test_style_length4.rb +0 -56
data/src/view.cpp CHANGED
@@ -15,37 +15,38 @@ namespace Reflex
15
15
  {
16
16
 
17
17
 
18
- void set_focus (Window* window, View* view);
19
-
20
- void register_capture (View* view);
21
-
22
- void unregister_capture (View* view);
18
+ bool set_style_owner (Style* style, View* owner);
23
19
 
24
20
 
25
21
  struct View::Data
26
22
  {
27
23
 
28
- Window* window;
24
+ typedef std::set<Selector> SelectorSet;
29
25
 
30
- View* parent;
26
+ enum Flags
27
+ {
31
28
 
32
- Bounds frame;
29
+ ACTIVE = 0x1 << 0,
33
30
 
34
- float angle, scale;
31
+ UPDATE_STYLE = 0x1 << 1,
35
32
 
36
- boost::scoped_ptr<Selector> pselector;
33
+ UPDATE_LAYOUT = 0x1 << 2,
37
34
 
38
- boost::scoped_ptr<Point> pscroll;
35
+ UPDATING_WORLD = 0x1 << 3,
39
36
 
40
- boost::scoped_ptr<ChildList> pchildren;
37
+ REMOVE_SELF = 0x1 << 4,
41
38
 
42
- boost::scoped_ptr<StyleList> pstyles;
39
+ DEFAULT_FLAGS = UPDATE_STYLE | UPDATE_LAYOUT
43
40
 
44
- boost::scoped_ptr<World> pworld;
41
+ };// Flags
45
42
 
46
- boost::scoped_ptr<Body> pbody;
43
+ Window* window;
47
44
 
48
- Style style;
45
+ View* parent;
46
+
47
+ Bounds frame;
48
+
49
+ float zoom, angle;
49
50
 
50
51
  ushort capture;
51
52
 
@@ -53,9 +54,25 @@ namespace Reflex
53
54
 
54
55
  uint flags;
55
56
 
57
+ boost::scoped_ptr<Selector> pselector;
58
+
59
+ boost::scoped_ptr<SelectorSet> pselectors_for_update;
60
+
61
+ boost::scoped_ptr<Point> pscroll;
62
+
63
+ boost::scoped_ptr<ChildList> pchildren;
64
+
65
+ boost::scoped_ptr<Style> pstyle;
66
+
67
+ boost::scoped_ptr<StyleList> pstyles;
68
+
69
+ boost::scoped_ptr<World> pworld;
70
+
71
+ boost::scoped_ptr<Body> pbody;
72
+
56
73
  Data ()
57
- : window(NULL), parent(NULL), angle(0), scale(1),
58
- capture(CAPTURE_NONE), hide_count(0), flags(0)
74
+ : window(NULL), parent(NULL), zoom(1), angle(0),
75
+ capture(CAPTURE_NONE), hide_count(0), flags(DEFAULT_FLAGS)
59
76
  {
60
77
  }
61
78
 
@@ -69,6 +86,12 @@ namespace Reflex
69
86
  return *pselector;
70
87
  }
71
88
 
89
+ SelectorSet& selectors_for_update ()
90
+ {
91
+ if (!pselectors_for_update) pselectors_for_update.reset(new SelectorSet);
92
+ return *pselectors_for_update;
93
+ }
94
+
72
95
  Point& scroll ()
73
96
  {
74
97
  if (!pscroll) pscroll.reset(new Point);
@@ -81,6 +104,16 @@ namespace Reflex
81
104
  return *pchildren;
82
105
  }
83
106
 
107
+ Style& style (View* this_)
108
+ {
109
+ if (!pstyle)
110
+ {
111
+ pstyle.reset(new Style);
112
+ set_style_owner(pstyle.get(), this_);
113
+ }
114
+ return *pstyle;
115
+ }
116
+
84
117
  StyleList& styles ()
85
118
  {
86
119
  if (!pstyles) pstyles.reset(new StyleList);
@@ -139,73 +172,118 @@ namespace Reflex
139
172
  this_->redraw();
140
173
  }
141
174
 
175
+ void add_flag (uint flag)
176
+ {
177
+ flags |= flag;
178
+ }
179
+
180
+ void remove_flag (uint flag)
181
+ {
182
+ flags &= ~flag;
183
+ }
184
+
185
+ bool has_flag (uint flag) const
186
+ {
187
+ return flags & flag;
188
+ }
189
+
142
190
  };// View::Data
143
191
 
144
192
 
145
193
  void
146
- set_window (View* this_, Window* window_)
194
+ set_window (View* view, Window* window_)
147
195
  {
148
- if (!this_)
149
- argument_error(__FILE__, __LINE__);
196
+ assert(view);
150
197
 
151
- Window* current = this_->self->window;
198
+ Window* current = view->self->window;
152
199
  if (current == window_) return;
153
200
 
154
201
  if (current)
155
202
  {
156
- this_->set_capture(View::CAPTURE_NONE);
203
+ view->set_capture(View::CAPTURE_NONE);
157
204
 
158
205
  Event e;
159
- this_->on_detach(&e);
206
+ view->on_detach(&e);
160
207
  }
161
208
 
162
- this_->self->window = window_;
209
+ view->self->window = window_;
163
210
 
164
- View::child_iterator end = this_->child_end();
165
- for (View::child_iterator it = this_->child_begin(); it != end; ++it)
211
+ View::child_iterator end = view->child_end();
212
+ for (View::child_iterator it = view->child_begin(); it != end; ++it)
166
213
  set_window(it->get(), window_);
167
214
 
168
- if (this_->self->window)
215
+ if (view->self->window)
169
216
  {
170
217
  Event e;
171
- this_->on_attach(&e);
172
- this_->resize_to_fit();
218
+ view->on_attach(&e);
219
+ view->resize_to_fit();
173
220
  }
174
221
  }
175
222
 
176
223
  static void
177
- set_parent (View* this_, View* parent_)
224
+ set_parent (View* view, View* parent)
178
225
  {
179
- if (!this_)
180
- argument_error(__FILE__, __LINE__);
226
+ assert(view);
227
+ View::Data* self = view->self.get();
181
228
 
182
- View* current = this_->self->parent;
183
- if (current == parent_) return;
229
+ View* current = self->parent;
230
+ if (current == parent) return;
184
231
 
185
- if (current && parent_)
232
+ if (current && parent)
186
233
  {
187
234
  reflex_error(__FILE__, __LINE__,
188
235
  "view '%s' already belongs to another parent '%s'.",
189
- this_->name(), this_->self->parent->name());
236
+ view->name(), self->parent->name());
190
237
  }
191
238
 
192
- this_->self->parent = parent_;
193
- set_window(this_, parent_ ? parent_->window() : NULL);
239
+ self->parent = parent;
240
+ set_window(view, parent ? parent->window() : NULL);
194
241
  }
195
242
 
196
- static void reflow_children (View* parent, const FrameEvent* event = NULL);
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;
259
+
260
+ self->parent->remove_child(view);
261
+ return true;
262
+ }
197
263
 
198
264
  static void
199
- update_view_frame (View* view, const Bounds& frame, float angle, bool update_body)
265
+ update_layout (View* view, bool update_parent = false)
200
266
  {
201
- if (!view)
202
- argument_error(__FILE__, __LINE__);
267
+ assert(view);
268
+ View::Data* self = view->self.get();
203
269
 
204
- if (!*view)
205
- invalid_state_error(__FILE__, __LINE__);
270
+ if (self->has_flag(View::Data::UPDATE_LAYOUT))
271
+ return;
206
272
 
273
+ self->add_flag(View::Data::UPDATE_LAYOUT);
274
+
275
+ if (update_parent && self->parent)
276
+ update_layout(self->parent, true);
277
+ }
278
+
279
+ static void
280
+ update_view_frame (View* view, const Bounds& frame, float angle, bool update_body)
281
+ {
282
+ assert(view);
207
283
  View::Data* self = view->self.get();
208
- if (frame == self->frame && angle == self->angle) return;
284
+
285
+ if (frame == self->frame && angle == self->angle)
286
+ return;
209
287
 
210
288
  FrameEvent event(frame, self->frame, angle, self->angle);
211
289
  self->frame = frame;
@@ -224,19 +302,27 @@ namespace Reflex
224
302
  self->resize_world(view);
225
303
  view->on_resize(&event);
226
304
 
227
- reflow_children(view, &event);
305
+ update_layout(view, true);
228
306
  }
229
307
 
230
308
  view->redraw();
231
309
  }
232
310
 
233
311
  static void
234
- update_world (View* view, float dt)
312
+ update_view_world (View* view, float dt)
235
313
  {
236
- World* world = view->self->pworld.get();
237
- if (world) world->step(dt);
314
+ assert(view);
315
+ View::Data* self = view->self.get();
238
316
 
239
- Body* body = view->self->pbody.get();
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
+ }
324
+
325
+ Body* body = self->pbody.get();
240
326
  if (body)
241
327
  {
242
328
  Bounds b = view->frame();
@@ -245,24 +331,155 @@ namespace Reflex
245
331
  }
246
332
  }
247
333
 
334
+ void
335
+ update_styles_for_selector (View* view, const Selector& selector)
336
+ {
337
+ assert(view);
338
+ View::Data* self = view->self.get();
339
+
340
+ if (selector.is_empty())
341
+ self->add_flag(View::Data::UPDATE_STYLE);
342
+ else
343
+ self->selectors_for_update().insert(selector);
344
+ }
345
+
346
+ static void
347
+ update_views_for_selectors (View* view)
348
+ {
349
+ assert(view);
350
+ View::Data* self = view->self.get();
351
+
352
+ View::Data::SelectorSet* sels = self->pselectors_for_update.get();
353
+ if (!sels)
354
+ return;
355
+
356
+ Selector* view_sel = self->pselector.get();
357
+ View::ChildList children;
358
+
359
+ View::Data::SelectorSet::iterator end = sels->end();
360
+ for (View::Data::SelectorSet::iterator it = sels->begin(); it != end; ++it)
361
+ {
362
+ if (view_sel && view_sel->contains(*it))
363
+ self->add_flag(View::Data::UPDATE_STYLE);
364
+
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
+ }
369
+
370
+ sels->clear();
371
+ }
372
+
373
+ static void
374
+ find_all_styles (
375
+ View::StyleList* result, const View* view, const Selector& selector, bool recursive)
376
+ {
377
+ View::const_style_iterator end = view->style_end();
378
+ for (View::const_style_iterator it = view->style_begin(); it != end; ++it)
379
+ {
380
+ if (selector.contains(it->selector()))
381
+ result->push_back(*it);
382
+ }
383
+
384
+ if (recursive)
385
+ {
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);
389
+ }
390
+ }
391
+
392
+ static void
393
+ get_styles_for_selector (
394
+ View::StyleList* styles, View* view, const Selector& selector)
395
+ {
396
+ assert(styles);
397
+
398
+ View* parent = view->parent();
399
+ if (parent)
400
+ get_styles_for_selector(styles, parent, selector);
401
+
402
+ find_all_styles(styles, view, selector, false);
403
+ }
404
+
405
+ static void
406
+ get_styles_for_view (View::StyleList* styles, View* view)
407
+ {
408
+ Selector* sel = view->self->pselector.get();
409
+ if (!sel || sel->is_empty())
410
+ return;
411
+
412
+ get_styles_for_selector(styles, view, *sel);
413
+ }
414
+
415
+ static void
416
+ update_view_style (View* view)
417
+ {
418
+ assert(view);
419
+ View::Data* self = view->self.get();
420
+
421
+ if (!self->has_flag(View::Data::UPDATE_STYLE))
422
+ return;
423
+
424
+ View::StyleList styles;
425
+ get_styles_for_view(&styles, view);
426
+
427
+ Style style;
428
+ for (View::StyleList::iterator it = styles.begin(); it != styles.end(); ++it)
429
+ {
430
+ void override_style (Style*, const Style&);
431
+ override_style(&style, *it);
432
+ }
433
+
434
+ void apply_style (View*, const Style&);
435
+ apply_style(view, style);
436
+
437
+ self->remove_flag(View::Data::UPDATE_STYLE);
438
+ }
439
+
440
+ static void reflow_children (View* parent, const FrameEvent* event = NULL);
441
+
442
+ static void
443
+ update_view_layout (View* view)
444
+ {
445
+ assert(view);
446
+ View::Data* self = view->self.get();
447
+
448
+ if (!self->has_flag(View::Data::UPDATE_LAYOUT))
449
+ return;
450
+
451
+ reflow_children(view);
452
+ self->remove_flag(View::Data::UPDATE_LAYOUT);
453
+ }
454
+
248
455
  void
249
456
  update_view_tree (View* view, const UpdateEvent& event)
250
457
  {
251
458
  if (!view)
252
459
  argument_error(__FILE__, __LINE__);
253
460
 
461
+ if (event.is_blocked() || remove_self(view))
462
+ return;
463
+
254
464
  UpdateEvent e = event;
255
- update_world(view, e.dt);
465
+ update_view_world(view, e.dt);
256
466
  view->on_update(&e);
257
467
 
468
+ update_views_for_selectors(view);
469
+ update_view_style(view);
470
+
258
471
  View::child_iterator end = view->child_end();
259
472
  for (View::child_iterator it = view->child_begin(); it != end; ++it)
260
473
  update_view_tree(it->get(), e);
474
+
475
+ update_view_layout(view);
261
476
  }
262
477
 
263
478
  static void
264
479
  draw_world (View* view, Painter* painter)
265
480
  {
481
+ assert(view);
482
+
266
483
  World* world = view->self->pworld.get();
267
484
  if (world) world->draw(painter);
268
485
  }
@@ -274,7 +491,8 @@ namespace Reflex
274
491
  if (!view)
275
492
  argument_error(__FILE__, __LINE__);
276
493
 
277
- if (view->hidden()) return;
494
+ if (event.is_blocked() || view->hidden())
495
+ return;
278
496
 
279
497
  DrawEvent e = event;
280
498
  Painter* p = e.painter;
@@ -290,8 +508,8 @@ namespace Reflex
290
508
  float angle = view->self->angle;
291
509
  if (angle != 0) p->rotate(angle);
292
510
 
293
- float scale = view->self->scale;
294
- if (scale != 1) p->scale(scale);
511
+ float zoom = view->self->zoom;
512
+ if (zoom != 1 && zoom > 0) p->scale(zoom, zoom);
295
513
 
296
514
  pos += offset;
297
515
  Bounds clip2 = clip & frame.move_to(pos);
@@ -633,16 +851,35 @@ namespace Reflex
633
851
  }
634
852
  }
635
853
  #endif
854
+
855
+ static bool
856
+ get_style_flow (Style::Flow* main, Style::Flow* sub, const Style* style)
857
+ {
858
+ void get_default_flow (Style::Flow*, Style::Flow*);
859
+
860
+ assert(main && sub);
861
+
862
+ if (style)
863
+ style->get_flow(main, sub);
864
+ else
865
+ get_default_flow(main, sub);
866
+
867
+ return *main != Style::FLOW_NONE;
868
+ }
869
+
636
870
  static void
637
871
  reflow_children (View* parent, const FrameEvent* event)
638
872
  {
639
- if (!parent)
640
- argument_error(__FILE__, __LINE__);
873
+ assert(parent);
641
874
 
642
- if (!parent->self->pchildren) return;
875
+ View::ChildList* children = parent->self->pchildren.get();
876
+ if (!children || children->empty()) return;
643
877
 
644
- View::ChildList& children = *parent->self->pchildren;
645
- if (children.empty()) return;
878
+ const Style* style = parent->style();
879
+
880
+ Style::Flow flow_main, flow_sub;
881
+ if (!get_style_flow(&flow_main, &flow_sub, style))
882
+ return;
646
883
 
647
884
  #if 0
648
885
  int main_h, main_v, sub_h, sub_v;
@@ -650,25 +887,20 @@ namespace Reflex
650
887
  get_flow_factor(&sub_h, &sub_v, flow_sub);
651
888
  #endif
652
889
 
653
- const Style& style = parent->style();
654
-
655
- Style::Flow flow_main, flow_sub;
656
- style.get_flow(&flow_main, &flow_sub);
657
-
658
890
  const Bounds& parent_frame = parent->self->frame;
659
891
  coord x = 0, y = 0, size_max = 0;
660
892
  int child_count = 0;
661
893
  bool multiline = flow_sub != Style::FLOW_NONE;
662
894
 
663
- size_t nchildren = children.size();
895
+ size_t nchildren = children->size();
664
896
  for (size_t i = 0; i < nchildren; ++i)
665
897
  {
666
- View* child = children[i].get();
898
+ View* child = (*children)[i].get();
667
899
  Bounds child_frame = child->self->frame;
668
900
 
669
901
  if (
670
902
  (x + child_frame.width) > parent_frame.width &&
671
- child_count > 0)// && multiline)
903
+ child_count > 0 && multiline)
672
904
  {
673
905
  x = 0;
674
906
  y += size_max;
@@ -784,9 +1016,6 @@ namespace Reflex
784
1016
  void
785
1017
  View::show ()
786
1018
  {
787
- if (!*this)
788
- invalid_state_error(__FILE__, __LINE__);
789
-
790
1019
  int new_count = self->hide_count - 1;
791
1020
  if (new_count == 0)
792
1021
  {
@@ -803,9 +1032,6 @@ namespace Reflex
803
1032
  void
804
1033
  View::hide ()
805
1034
  {
806
- if (!*this)
807
- invalid_state_error(__FILE__, __LINE__);
808
-
809
1035
  int new_count = self->hide_count + 1;
810
1036
  if (new_count == 1)
811
1037
  {
@@ -822,18 +1048,12 @@ namespace Reflex
822
1048
  bool
823
1049
  View::hidden () const
824
1050
  {
825
- if (!*this)
826
- invalid_state_error(__FILE__, __LINE__);
827
-
828
1051
  return self->hide_count > 0;
829
1052
  }
830
1053
 
831
1054
  void
832
1055
  View::redraw ()
833
1056
  {
834
- if (!*this)
835
- invalid_state_error(__FILE__, __LINE__);
836
-
837
1057
  Window* w = window();
838
1058
  if (!w) return;
839
1059
 
@@ -846,9 +1066,6 @@ namespace Reflex
846
1066
  if (!child || child == this)
847
1067
  argument_error(__FILE__, __LINE__);
848
1068
 
849
- if (!*this)
850
- invalid_state_error(__FILE__, __LINE__);
851
-
852
1069
  bool found = std::find(child_begin(), child_end(), child) != child_end();
853
1070
  bool belong = child->parent() == this;
854
1071
  if (found && belong)
@@ -856,8 +1073,12 @@ namespace Reflex
856
1073
  else if (found != belong)
857
1074
  invalid_state_error(__FILE__, __LINE__);
858
1075
 
1076
+ child->self->add_flag(View::Data::ACTIVE);
1077
+
859
1078
  self->children().push_back(child);
860
1079
  set_parent(child, this);
1080
+
1081
+ update_layout(this);
861
1082
  }
862
1083
 
863
1084
  void
@@ -866,14 +1087,19 @@ namespace Reflex
866
1087
  if (!child || child == this)
867
1088
  argument_error(__FILE__, __LINE__);
868
1089
 
869
- if (!*this)
870
- invalid_state_error(__FILE__, __LINE__);
871
-
872
1090
  if (!self->pchildren) return;
873
1091
 
874
1092
  child_iterator it = std::find(child_begin(), child_end(), child);
875
1093
  if (it == child_end()) return;
876
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);
1100
+ return;
1101
+ }
1102
+
877
1103
  if (child->parent() != this)
878
1104
  invalid_state_error(__FILE__, __LINE__);
879
1105
 
@@ -881,6 +1107,8 @@ namespace Reflex
881
1107
 
882
1108
  set_parent(child, NULL);
883
1109
  self->pchildren->erase(it);
1110
+
1111
+ update_layout(this);
884
1112
  }
885
1113
 
886
1114
  static void
@@ -894,7 +1122,7 @@ namespace Reflex
894
1122
  if (!child)
895
1123
  invalid_state_error(__FILE__, __LINE__);
896
1124
 
897
- if (selector.match(child->selector()))
1125
+ if (child->selector().contains(selector))
898
1126
  result->push_back(*it);
899
1127
 
900
1128
  if (recursive) find_all_children(result, child, selector, true);
@@ -905,9 +1133,6 @@ namespace Reflex
905
1133
  View::find_children (
906
1134
  ChildList* result, const Selector& selector, bool recursive) const
907
1135
  {
908
- if (!*this)
909
- invalid_state_error(__FILE__, __LINE__);
910
-
911
1136
  result->clear();
912
1137
  find_all_children(result, this, selector, recursive);
913
1138
  }
@@ -917,9 +1142,6 @@ namespace Reflex
917
1142
  View::child_iterator
918
1143
  View::child_begin ()
919
1144
  {
920
- if (!*this)
921
- invalid_state_error(__FILE__, __LINE__);
922
-
923
1145
  if (!self->pchildren) return empty_children.begin();
924
1146
  return self->pchildren->begin();
925
1147
  }
@@ -927,9 +1149,6 @@ namespace Reflex
927
1149
  View::const_child_iterator
928
1150
  View::child_begin () const
929
1151
  {
930
- if (!*this)
931
- invalid_state_error(__FILE__, __LINE__);
932
-
933
1152
  if (!self->pchildren) return empty_children.begin();
934
1153
  return self->pchildren->begin();
935
1154
  }
@@ -937,9 +1156,6 @@ namespace Reflex
937
1156
  View::child_iterator
938
1157
  View::child_end ()
939
1158
  {
940
- if (!*this)
941
- invalid_state_error(__FILE__, __LINE__);
942
-
943
1159
  if (!self->pchildren) return empty_children.end();
944
1160
  return self->pchildren->end();
945
1161
  }
@@ -947,43 +1163,44 @@ namespace Reflex
947
1163
  View::const_child_iterator
948
1164
  View::child_end () const
949
1165
  {
950
- if (!*this)
951
- invalid_state_error(__FILE__, __LINE__);
952
-
953
1166
  if (!self->pchildren) return empty_children.end();
954
1167
  return self->pchildren->end();
955
1168
  }
956
1169
 
957
- Style&
958
- View::style ()
1170
+ Style*
1171
+ View::style (bool create)
959
1172
  {
960
- if (!*this)
961
- invalid_state_error(__FILE__, __LINE__);
962
-
963
- return self->style;
1173
+ return create ? &self->style(this) : self->pstyle.get();
964
1174
  }
965
1175
 
966
- const Style&
1176
+ const Style*
967
1177
  View::style () const
968
1178
  {
969
- return const_cast<View*>(this)->style();
1179
+ return const_cast<View*>(this)->style(false);
1180
+ }
1181
+
1182
+ static Style*
1183
+ add_view_style (View* view, Style style)
1184
+ {
1185
+ assert(view && *view);
1186
+
1187
+ if (!set_style_owner(&style, view))
1188
+ return NULL;
1189
+
1190
+ View::StyleList* styles = &view->self->styles();
1191
+ styles->push_back(style);
1192
+ return &styles->back();
970
1193
  }
971
1194
 
972
1195
  void
973
1196
  View::add_style (const Style& style)
974
1197
  {
975
- if (!*this)
976
- invalid_state_error(__FILE__, __LINE__);
977
-
978
- self->styles().push_back(style);
1198
+ add_view_style(this, style);
979
1199
  }
980
1200
 
981
1201
  void
982
1202
  View::remove_style (const Style& style)
983
1203
  {
984
- if (!*this)
985
- invalid_state_error(__FILE__, __LINE__);
986
-
987
1204
  if (!self->pstyles) return;
988
1205
 
989
1206
  style_iterator it = std::find(style_begin(), style_end(), style);
@@ -993,10 +1210,10 @@ namespace Reflex
993
1210
  }
994
1211
 
995
1212
  Style*
996
- View::get_style (const Selector& selector)
1213
+ View::get_style (const Selector& selector, bool create)
997
1214
  {
998
- if (!*this)
999
- invalid_state_error(__FILE__, __LINE__);
1215
+ if (selector.is_empty())
1216
+ return style(create);
1000
1217
 
1001
1218
  style_iterator end = style_end();
1002
1219
  for (style_iterator it = style_begin(); it != end; ++it)
@@ -1005,6 +1222,13 @@ namespace Reflex
1005
1222
  return &*it;
1006
1223
  }
1007
1224
 
1225
+ if (create)
1226
+ {
1227
+ Style s;
1228
+ s.set_selector(selector);
1229
+ return add_view_style(this, s);
1230
+ }
1231
+
1008
1232
  return NULL;
1009
1233
  }
1010
1234
 
@@ -1014,31 +1238,9 @@ namespace Reflex
1014
1238
  return const_cast<View*>(this)->get_style(selector);
1015
1239
  }
1016
1240
 
1017
- static void
1018
- find_all_styles (
1019
- View::StyleList* result, const View* view, const Selector& selector, bool recursive)
1020
- {
1021
- View::const_style_iterator end = view->style_end();
1022
- for (View::const_style_iterator it = view->style_begin(); it != end; ++it)
1023
- {
1024
- if (selector.match(it->selector()))
1025
- result->push_back(*it);
1026
- }
1027
-
1028
- if (recursive)
1029
- {
1030
- View::const_child_iterator end = view->child_end();
1031
- for (View::const_child_iterator it = view->child_begin(); it != end; ++it)
1032
- find_all_styles(result, it->get(), selector, true);
1033
- }
1034
- }
1035
-
1036
1241
  void
1037
1242
  View::find_styles (StyleList* result, const Selector& selector, bool recursive) const
1038
1243
  {
1039
- if (!*this)
1040
- invalid_state_error(__FILE__, __LINE__);
1041
-
1042
1244
  result->clear();
1043
1245
  find_all_styles(result, this, selector, recursive);
1044
1246
  }
@@ -1048,9 +1250,6 @@ namespace Reflex
1048
1250
  View::style_iterator
1049
1251
  View::style_begin ()
1050
1252
  {
1051
- if (!*this)
1052
- invalid_state_error(__FILE__, __LINE__);
1053
-
1054
1253
  if (!self->pstyles) return empty_styles.begin();
1055
1254
  return self->pstyles->begin();
1056
1255
  }
@@ -1058,9 +1257,6 @@ namespace Reflex
1058
1257
  View::const_style_iterator
1059
1258
  View::style_begin () const
1060
1259
  {
1061
- if (!*this)
1062
- invalid_state_error(__FILE__, __LINE__);
1063
-
1064
1260
  if (!self->pstyles) return empty_styles.begin();
1065
1261
  return self->pstyles->begin();
1066
1262
  }
@@ -1068,9 +1264,6 @@ namespace Reflex
1068
1264
  View::style_iterator
1069
1265
  View::style_end ()
1070
1266
  {
1071
- if (!*this)
1072
- invalid_state_error(__FILE__, __LINE__);
1073
-
1074
1267
  if (!self->pstyles) return empty_styles.end();
1075
1268
  return self->pstyles->end();
1076
1269
  }
@@ -1078,9 +1271,6 @@ namespace Reflex
1078
1271
  View::const_style_iterator
1079
1272
  View::style_end () const
1080
1273
  {
1081
- if (!*this)
1082
- invalid_state_error(__FILE__, __LINE__);
1083
-
1084
1274
  if (!self->pstyles) return empty_styles.end();
1085
1275
  return self->pstyles->end();
1086
1276
  }
@@ -1091,6 +1281,7 @@ namespace Reflex
1091
1281
  Window* w = window();
1092
1282
  if (!w) return;
1093
1283
 
1284
+ void set_focus (Window*, View*);
1094
1285
  if (state)
1095
1286
  set_focus(w, this);
1096
1287
  else if (w->focus() == this)
@@ -1113,25 +1304,21 @@ namespace Reflex
1113
1304
  void
1114
1305
  View::resize_to_fit ()
1115
1306
  {
1116
- if (!*this)
1117
- invalid_state_error(__FILE__, __LINE__);
1118
-
1119
1307
  Point size = content_size();
1120
1308
  if (size.x < 0 && size.y < 0 && size.z <= 0) return;
1121
1309
 
1310
+ const Style* st = style();
1311
+
1122
1312
  Bounds b = frame();
1123
- if (size.x >= 0) b.width = size.x;
1124
- if (size.y >= 0) b.height = size.y;
1125
- if (size.z >= 0) b.depth = size.z;
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;
1126
1316
  set_frame(b);
1127
1317
  }
1128
1318
 
1129
1319
  Point
1130
1320
  View::content_size () const
1131
1321
  {
1132
- if (!*this)
1133
- invalid_state_error(__FILE__, __LINE__);
1134
-
1135
1322
  return -1;
1136
1323
  }
1137
1324
 
@@ -1164,37 +1351,25 @@ namespace Reflex
1164
1351
  void
1165
1352
  View::set_name (const char* name)
1166
1353
  {
1167
- if (!*this)
1168
- invalid_state_error(__FILE__, __LINE__);
1169
-
1170
1354
  self->selector().set_name(name);
1171
1355
  }
1172
1356
 
1173
1357
  const char*
1174
1358
  View::name () const
1175
1359
  {
1176
- if (!*this)
1177
- invalid_state_error(__FILE__, __LINE__);
1178
-
1179
1360
  const Selector* sel = self->pselector.get();
1180
- return sel ? sel->name() : NULL;
1361
+ return sel ? sel->name() : "";
1181
1362
  }
1182
1363
 
1183
1364
  void
1184
1365
  View::add_tag (const char* tag)
1185
1366
  {
1186
- if (!*this)
1187
- invalid_state_error(__FILE__, __LINE__);
1188
-
1189
1367
  self->selector().add_tag(tag);
1190
1368
  }
1191
1369
 
1192
1370
  void
1193
1371
  View::remove_tag (const char* tag)
1194
1372
  {
1195
- if (!*this)
1196
- invalid_state_error(__FILE__, __LINE__);
1197
-
1198
1373
  Selector* sel = self->pselector.get();
1199
1374
  if (!sel) return;
1200
1375
 
@@ -1206,9 +1381,6 @@ namespace Reflex
1206
1381
  View::tag_iterator
1207
1382
  View::tag_begin ()
1208
1383
  {
1209
- if (!*this)
1210
- invalid_state_error(__FILE__, __LINE__);
1211
-
1212
1384
  Selector* sel = self->pselector.get();
1213
1385
  return sel ? sel->begin() : empty_tags.begin();
1214
1386
  }
@@ -1216,9 +1388,6 @@ namespace Reflex
1216
1388
  View::const_tag_iterator
1217
1389
  View::tag_begin () const
1218
1390
  {
1219
- if (!*this)
1220
- invalid_state_error(__FILE__, __LINE__);
1221
-
1222
1391
  const Selector* sel = self->pselector.get();
1223
1392
  return sel ? sel->begin() : empty_tags.begin();
1224
1393
  }
@@ -1226,9 +1395,6 @@ namespace Reflex
1226
1395
  View::tag_iterator
1227
1396
  View::tag_end ()
1228
1397
  {
1229
- if (!*this)
1230
- invalid_state_error(__FILE__, __LINE__);
1231
-
1232
1398
  Selector* sel = self->pselector.get();
1233
1399
  return sel ? sel->end() : empty_tags.end();
1234
1400
  }
@@ -1236,9 +1402,6 @@ namespace Reflex
1236
1402
  View::const_tag_iterator
1237
1403
  View::tag_end () const
1238
1404
  {
1239
- if (!*this)
1240
- invalid_state_error(__FILE__, __LINE__);
1241
-
1242
1405
  const Selector* sel = self->pselector.get();
1243
1406
  return sel ? sel->end() : empty_tags.end();
1244
1407
  }
@@ -1246,18 +1409,12 @@ namespace Reflex
1246
1409
  void
1247
1410
  View::set_selector (const Selector& selector)
1248
1411
  {
1249
- if (!*this)
1250
- invalid_state_error(__FILE__, __LINE__);
1251
-
1252
1412
  self->selector() = selector;
1253
1413
  }
1254
1414
 
1255
1415
  Selector&
1256
1416
  View::selector ()
1257
1417
  {
1258
- if (!*this)
1259
- invalid_state_error(__FILE__, __LINE__);
1260
-
1261
1418
  return self->selector();
1262
1419
  }
1263
1420
 
@@ -1266,9 +1423,6 @@ namespace Reflex
1266
1423
  {
1267
1424
  static const Selector EMPTY;
1268
1425
 
1269
- if (!*this)
1270
- invalid_state_error(__FILE__, __LINE__);
1271
-
1272
1426
  const Selector* sel = self->pselector.get();
1273
1427
  return sel ? *sel : EMPTY;
1274
1428
  }
@@ -1288,12 +1442,22 @@ namespace Reflex
1288
1442
  const Bounds&
1289
1443
  View::frame () const
1290
1444
  {
1291
- if (!*this)
1292
- invalid_state_error(__FILE__, __LINE__);
1293
-
1294
1445
  return self->frame;
1295
1446
  }
1296
1447
 
1448
+ void
1449
+ View::set_zoom (float zoom)
1450
+ {
1451
+ self->zoom = zoom;
1452
+ redraw();
1453
+ }
1454
+
1455
+ float
1456
+ View::zoom () const
1457
+ {
1458
+ return self->zoom;
1459
+ }
1460
+
1297
1461
  #if 0
1298
1462
  void
1299
1463
  View::set_angle (float degree)
@@ -1305,9 +1469,6 @@ namespace Reflex
1305
1469
  float
1306
1470
  View::angle () const
1307
1471
  {
1308
- if (!*this)
1309
- invalid_state_error(__FILE__, __LINE__);
1310
-
1311
1472
  return self->angle;
1312
1473
  }
1313
1474
 
@@ -1316,13 +1477,11 @@ namespace Reflex
1316
1477
  void
1317
1478
  View::scroll_to (coord x, coord y, coord z)
1318
1479
  {
1319
- if (!*this)
1320
- invalid_state_error(__FILE__, __LINE__);
1321
-
1322
1480
  Point old = self->scroll();
1323
1481
  self->scroll().reset(x, y, z);
1324
1482
  ScrollEvent e(x, y, z, x - old.x, y - old.y, z - old.z);
1325
1483
  on_scroll(&e);
1484
+
1326
1485
  redraw();
1327
1486
  }
1328
1487
 
@@ -1348,9 +1507,6 @@ namespace Reflex
1348
1507
  const Point&
1349
1508
  View::scroll () const
1350
1509
  {
1351
- if (!*this)
1352
- invalid_state_error(__FILE__, __LINE__);
1353
-
1354
1510
  if (self->pscroll)
1355
1511
  return self->scroll();
1356
1512
  else
@@ -1360,9 +1516,6 @@ namespace Reflex
1360
1516
  void
1361
1517
  View::set_capture (uint types)
1362
1518
  {
1363
- if (!*this)
1364
- invalid_state_error(__FILE__, __LINE__);
1365
-
1366
1519
  if (types == self->capture) return;
1367
1520
 
1368
1521
  uint old = self->capture;
@@ -1372,9 +1525,15 @@ namespace Reflex
1372
1525
  bool capture = types != CAPTURE_NONE;
1373
1526
 
1374
1527
  if (capture && !registered)
1528
+ {
1529
+ void register_capture (View*);
1375
1530
  register_capture(this);
1531
+ }
1376
1532
  else if (!capture && registered)
1533
+ {
1534
+ void unregister_capture (View*);
1377
1535
  unregister_capture(this);
1536
+ }
1378
1537
 
1379
1538
  CaptureEvent e(~old & types, old & ~types);
1380
1539
  on_capture(&e);
@@ -1383,18 +1542,12 @@ namespace Reflex
1383
1542
  uint
1384
1543
  View::capture () const
1385
1544
  {
1386
- if (!*this)
1387
- invalid_state_error(__FILE__, __LINE__);
1388
-
1389
1545
  return self->capture;
1390
1546
  }
1391
1547
 
1392
1548
  View*
1393
1549
  View::parent ()
1394
1550
  {
1395
- if (!*this)
1396
- invalid_state_error(__FILE__, __LINE__);
1397
-
1398
1551
  return self->parent;
1399
1552
  }
1400
1553
 
@@ -1407,9 +1560,6 @@ namespace Reflex
1407
1560
  Window*
1408
1561
  View::window ()
1409
1562
  {
1410
- if (!*this)
1411
- invalid_state_error(__FILE__, __LINE__);
1412
-
1413
1563
  return self->window;
1414
1564
  }
1415
1565
 
@@ -1422,9 +1572,6 @@ namespace Reflex
1422
1572
  Body*
1423
1573
  View::body ()
1424
1574
  {
1425
- if (!*this)
1426
- invalid_state_error(__FILE__, __LINE__);
1427
-
1428
1575
  return self->body(this);
1429
1576
  }
1430
1577
 
@@ -1437,9 +1584,6 @@ namespace Reflex
1437
1584
  float
1438
1585
  View::meter2pixel (float meter, bool create_world)
1439
1586
  {
1440
- if (!*this)
1441
- invalid_state_error(__FILE__, __LINE__);
1442
-
1443
1587
  Body* body = self->pbody.get();
1444
1588
  if (body)
1445
1589
  return body->meter2pixel(meter);
@@ -1482,9 +1626,6 @@ namespace Reflex
1482
1626
  void
1483
1627
  View::set_gravity (const Point& vector)
1484
1628
  {
1485
- if (!*this)
1486
- invalid_state_error(__FILE__, __LINE__);
1487
-
1488
1629
  World* w = self->world(this);
1489
1630
  if (!w)
1490
1631
  invalid_state_error(__FILE__, __LINE__);
@@ -1495,9 +1636,6 @@ namespace Reflex
1495
1636
  Point
1496
1637
  View::gravity () const
1497
1638
  {
1498
- if (!*this)
1499
- invalid_state_error(__FILE__, __LINE__);
1500
-
1501
1639
  World* w = self->pworld.get();
1502
1640
  return w ? w->gravity() : 0;
1503
1641
  }
@@ -1505,9 +1643,6 @@ namespace Reflex
1505
1643
  Body*
1506
1644
  View::wall ()
1507
1645
  {
1508
- if (!*this)
1509
- invalid_state_error(__FILE__, __LINE__);
1510
-
1511
1646
  return self->world(this)->wall();
1512
1647
  }
1513
1648
 
@@ -1520,9 +1655,6 @@ namespace Reflex
1520
1655
  void
1521
1656
  View::set_debug (bool state)
1522
1657
  {
1523
- if (!*this)
1524
- invalid_state_error(__FILE__, __LINE__);
1525
-
1526
1658
  World* w = self->world(this);
1527
1659
  if (!w)
1528
1660
  invalid_state_error(__FILE__, __LINE__);
@@ -1533,9 +1665,6 @@ namespace Reflex
1533
1665
  bool
1534
1666
  View::debugging () const
1535
1667
  {
1536
- if (!*this)
1537
- invalid_state_error(__FILE__, __LINE__);
1538
-
1539
1668
  World* w = self->pworld.get();
1540
1669
  return w ? w->debugging() : false;
1541
1670
  }