reflexion 0.1.10 → 0.1.11

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 (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/lib/reflex/style.rb CHANGED
@@ -29,6 +29,21 @@ module Reflex
29
29
  get_flow.map {|n| flow2sym n}
30
30
  end
31
31
 
32
+ def inspect ()
33
+ attrs = {
34
+ selector: selector,
35
+ flow: flow,
36
+ size: size,
37
+ position: position,
38
+ offset: offset,
39
+ margin: margin,
40
+ padding: padding,
41
+ background_color: background_color,
42
+ background_image: background_image
43
+ }
44
+ "#<Reflex::Style #{attrs.map {|k, v| %(#{k}:#{v.to_s})}.join ' '}>"
45
+ end
46
+
32
47
  private
33
48
 
34
49
  SYM2FLOW = {
@@ -21,7 +21,7 @@ module Reflex
21
21
  end
22
22
 
23
23
  def inspect ()
24
- "#<Reflex::StyleLength #{value}#{unit}>"
24
+ "#<#{self.class.name} #{to_s}>"
25
25
  end
26
26
 
27
27
  end# StyleLength
data/lib/reflex/view.rb CHANGED
@@ -26,7 +26,10 @@ module Reflex
26
26
  :static=, :static?, :dynamic=, :dynamic?,
27
27
  :velocity=, :linear_velocity=, :angular_velocity=,
28
28
  :velocity, :linear_velocity, :angular_velocity,
29
- :density=, :density, :friction=, :friction, :restitution=, :restitution
29
+ :apply_force, :apply_torque, :apply_impulse,
30
+ :apply_linear_impulse, :apply_angular_impulse,
31
+ :density=, :density, :friction=, :friction, :restitution=, :restitution,
32
+ :gravity_scale=, :gravity_scale
30
33
 
31
34
  alias add add_child
32
35
  alias remove remove_child
@@ -48,7 +51,7 @@ module Reflex
48
51
  end
49
52
 
50
53
  def style (*args, &block)
51
- s = get_style *args
54
+ s = get_style args.empty? ? nil : Selector.selector(*args)
52
55
  Xot::BlockUtil.instance_eval_or_block_call s, &block if block
53
56
  s
54
57
  end
data/lib/reflex/window.rb CHANGED
@@ -20,8 +20,8 @@ module Reflex
20
20
  extend Forwardable
21
21
 
22
22
  def_delegators :root,
23
- :add_child, :remove_child, :find_children, :style, :meter2pixel, :meter,
24
- :gravity=, :gravity, :wall, :debug=, :debug?
23
+ :add_child, :remove_child, :find_children, :style, :styles,
24
+ :meter2pixel, :meter, :gravity=, :gravity, :wall, :debug=, :debug?
25
25
 
26
26
  def_delegators :wall,
27
27
  :friction=, :friction, :restitution=, :restitution
@@ -9,7 +9,6 @@ require 'reflexion/include'
9
9
 
10
10
 
11
11
  $hit, $bang = [880, 440].map {|n| Sound.new SineWave.new(freq: n), 0.1}
12
- $garbages = []
13
12
 
14
13
  def add_shape (klass: RectShape, frame: [0, 0, 100, 100], color: :white, type: :static)
15
14
  window.add klass.new {
@@ -18,27 +17,23 @@ def add_shape (klass: RectShape, frame: [0, 0, 100, 100], color: :white, type: :
18
17
  end
19
18
 
20
19
  setup do
20
+ style.flow = :none
21
21
  set size: [600, 400], friction: 0
22
22
  5.times do |y|
23
23
  10.times do |x|
24
24
  shape = add_shape frame: [(x + 1) * 50, (y + 1) * 20, 30, 10], color: [:white, :red, :green, :blue, :yellow][y]
25
- shape.on(:contact) {$hit.play; $garbages << shape}
25
+ shape.on(:contact) {$hit.play; shape.parent.remove shape}
26
26
  end
27
27
  end
28
28
  $bar = add_shape frame: [0, 350, 100, 20], color: :blue
29
29
  bottom = add_shape frame: [0, window.h - 1, window.w, 1]
30
- bottom.on(:contact) {|e| $bang.play; $garbages << e.view}
30
+ bottom.on(:contact) {|e| $bang.play; e.view.parent.remove e.view}
31
31
  end
32
32
 
33
33
  pointer do |e|
34
34
  $bar.x = e.x - $bar.w / 2
35
35
  if e.down?
36
- ball = add_shape klass: [EllipseShape, RectShape].sample, frame: [e.x, $bar.y - 20, 20, 20], type: :dynamic
36
+ ball = add_shape klass: [EllipseShape, RectShape].sample, frame: [e.x, $bar.y - 20, 20, 20], type: :dynamic
37
37
  ball.velocity = Point.new(rand(-1.0..1.0), -1).normal * 500
38
38
  end
39
39
  end
40
-
41
- update do
42
- $garbages.uniq.each {|o| o.parent.remove o}
43
- $garbages.clear
44
- end
data/src/body.cpp CHANGED
@@ -314,6 +314,51 @@ namespace Reflex
314
314
  return Xot::rad2deg(PTR->GetAngularVelocity());
315
315
  }
316
316
 
317
+ void
318
+ Body::apply_force (coord x, coord y)
319
+ {
320
+ apply_force(Point(x, y));
321
+ }
322
+
323
+ void
324
+ Body::apply_force (const Point& force)
325
+ {
326
+ assert(PTR);
327
+
328
+ PTR->ApplyForceToCenter(to_b2vec2(force, ppm), true);
329
+ }
330
+
331
+ void
332
+ Body::apply_torque (float torque)
333
+ {
334
+ assert(PTR);
335
+
336
+ PTR->ApplyTorque(torque, true);
337
+ }
338
+
339
+ void
340
+ Body::apply_linear_impulse (coord x, coord y)
341
+ {
342
+ apply_linear_impulse(Point(x, y));
343
+ }
344
+
345
+ void
346
+ Body::apply_linear_impulse (const Point& impulse)
347
+ {
348
+ assert(PTR);
349
+
350
+ PTR->ApplyLinearImpulse(
351
+ to_b2vec2(impulse, ppm), PTR->GetWorldCenter(), true);
352
+ }
353
+
354
+ void
355
+ Body::apply_angular_impulse (float impulse)
356
+ {
357
+ assert(PTR);
358
+
359
+ PTR->ApplyAngularImpulse(impulse, true);
360
+ }
361
+
317
362
  void
318
363
  Body::set_density (float density)
319
364
  {
@@ -398,6 +443,22 @@ namespace Reflex
398
443
  return val;
399
444
  }
400
445
 
446
+ void
447
+ Body::set_gravity_scale (float scale)
448
+ {
449
+ assert(PTR);
450
+
451
+ return PTR->SetGravityScale(scale);
452
+ }
453
+
454
+ float
455
+ Body::gravity_scale () const
456
+ {
457
+ assert(PTR);
458
+
459
+ return PTR->GetGravityScale();
460
+ }
461
+
401
462
  Body::iterator
402
463
  Body::begin ()
403
464
  {
data/src/ios/event.mm CHANGED
@@ -13,9 +13,7 @@ namespace Reflex
13
13
  correct_point (UIView* view, UITouch* touch)
14
14
  {
15
15
  assert(view && touch);
16
- CGPoint p = [touch locationInView: view];
17
- p.y = [view bounds].size.height - p.y;
18
- return p;
16
+ return [touch locationInView: view];
19
17
  }
20
18
 
21
19
 
@@ -24,26 +24,11 @@ namespace Reflex
24
24
  }// Reflex
25
25
 
26
26
 
27
- static CGRect device_frame ()
28
- {
29
- UIScreen* screen = [UIScreen mainScreen];
30
- CGRect rect = screen.applicationFrame;
31
- CGFloat scale = screen.scale;
32
-
33
- rect.origin.x = 0;
34
- rect.origin.y = 0;
35
- rect.size.width *= scale;
36
- rect.size.height *= scale;
37
-
38
- return rect;
39
- }
40
-
41
-
42
27
  @implementation NativeWindow
43
28
 
44
29
  - (id) init
45
30
  {
46
- self = [super initWithFrame: device_frame()];
31
+ self = [super initWithFrame: UIScreen.mainScreen.bounds];
47
32
  if (!self) return nil;
48
33
 
49
34
  pref = new Reflex::Window::Ref;
@@ -106,8 +91,7 @@ static CGRect device_frame ()
106
91
  REF->self->prev_time_update = now;
107
92
 
108
93
  REF->on_update(&e);
109
- if (!e.is_blocked())
110
- Reflex::update_view_tree(REF->root(), e);
94
+ Reflex::update_view_tree(REF->root(), e);
111
95
  }
112
96
 
113
97
  - (void) draw
@@ -139,8 +123,7 @@ static CGRect device_frame ()
139
123
  e.painter->clear();
140
124
 
141
125
  REF->on_draw(&e);
142
- if (!e.is_blocked())
143
- draw_view_tree(REF->root(), e, 0, REF->frame().dup().move_to(0));
126
+ draw_view_tree(REF->root(), e, 0, REF->frame().dup().move_to(0));
144
127
 
145
128
  e.painter->end();
146
129
  }
@@ -24,7 +24,7 @@
24
24
  GLKView* view = (GLKView*) self.view;
25
25
  view.context = context;
26
26
  view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
27
- view.drawableMultisample = GLKViewDrawableMultisample4X;
27
+ //view.drawableMultisample = GLKViewDrawableMultisample4X;
28
28
 
29
29
  self.preferredFramesPerSecond = 60;
30
30
 
data/src/ios/window.mm CHANGED
@@ -8,6 +8,12 @@
8
8
  #import "native_window.h"
9
9
 
10
10
 
11
+ namespace Rays
12
+ {
13
+ void set_painter_scale_factor(Painter*, float);
14
+ };
15
+
16
+
11
17
  namespace Reflex
12
18
  {
13
19
 
@@ -94,6 +100,7 @@ namespace Reflex
94
100
 
95
101
  set_window(self->root.get(), this);
96
102
 
103
+ Rays::set_painter_scale_factor(&self->painter, UIScreen.mainScreen.scale);
97
104
  self->painter.canvas(0, 0, 1, 1);
98
105
  }
99
106
 
data/src/selector.cpp CHANGED
@@ -15,9 +15,9 @@ namespace Reflex
15
15
 
16
16
  TagSet tags;
17
17
 
18
- bool operator == (const Data& rhs)
18
+ friend bool operator == (const Data& lhs, const Data& rhs)
19
19
  {
20
- return name == rhs.name && tags == rhs.tags;
20
+ return lhs.name == rhs.name && lhs.tags == rhs.tags;
21
21
  }
22
22
 
23
23
  };// Selector::Data
@@ -28,6 +28,31 @@ namespace Reflex
28
28
  if (name) set_name(name);
29
29
  }
30
30
 
31
+ Selector
32
+ Selector::copy () const
33
+ {
34
+ Selector t;
35
+ *t.self = *self;
36
+ return t;
37
+ }
38
+
39
+ bool
40
+ Selector::contains (const This& selector) const
41
+ {
42
+ if (self->name.empty() && self->tags.empty())
43
+ return false;
44
+
45
+ const TagSet& tags = self->tags;
46
+ const_iterator tags_end = tags.end();
47
+
48
+ iterator end = selector.end();
49
+ for (iterator tag = selector.begin(); tag != end; ++tag)
50
+ if (tags.find(*tag) == tags_end)
51
+ return false;
52
+
53
+ return selector.self->name.empty() || selector.self->name == self->name;
54
+ }
55
+
31
56
  void
32
57
  Selector::set_name (const char* name)
33
58
  {
@@ -37,7 +62,7 @@ namespace Reflex
37
62
  const char*
38
63
  Selector::name () const
39
64
  {
40
- return self->name.empty() ? NULL : self->name.c_str();
65
+ return self->name.c_str();
41
66
  }
42
67
 
43
68
  void
@@ -89,20 +114,9 @@ namespace Reflex
89
114
  }
90
115
 
91
116
  bool
92
- Selector::match (const This& obj) const
117
+ Selector::is_empty () const
93
118
  {
94
- if (self->name.empty() && self->tags.empty())
95
- return false;
96
-
97
- const TagSet& obj_tags = obj.self->tags;
98
- const_iterator obj_end = obj_tags.end();
99
-
100
- iterator end = this->end();
101
- for (iterator it = begin(); it != end; ++it)
102
- if (obj_tags.find(*it) == obj_end)
103
- return false;
104
-
105
- return self->name.empty() || self->name == obj.self->name;
119
+ return self->name.empty() && self->tags.empty();
106
120
  }
107
121
 
108
122
  bool
@@ -117,5 +131,13 @@ namespace Reflex
117
131
  return !operator==(lhs, rhs);
118
132
  }
119
133
 
134
+ bool
135
+ operator < (const Selector& lhs, const Selector& rhs)
136
+ {
137
+ Selector::Data* l = lhs.self.get();
138
+ Selector::Data* r = rhs.self.get();
139
+ return l->name < r->name || l->tags < r->tags;
140
+ }
141
+
120
142
 
121
143
  }// Reflex
data/src/style.cpp CHANGED
@@ -85,22 +85,37 @@ namespace Reflex
85
85
  Wrapper* p = pointer();
86
86
  if (!p)
87
87
  {
88
- if (create)
89
- p = reset(new Wrapper());
90
- else
88
+ if (!create)
91
89
  invalid_state_error(__FILE__, __LINE__);
90
+
91
+ p = reset(new Wrapper());
92
92
  }
93
93
  return p->get();
94
94
  }
95
95
 
96
- const Value& value (bool create = false) const
96
+ const Value& get (const Value& defval) const
97
97
  {
98
- return const_cast<This*>(this)->value(create);
98
+ Wrapper* p = pointer();
99
+ return p ? p->get() : defval;
99
100
  }
100
101
 
101
- void set_inherited (bool state = true)
102
+ bool set (const Value& val)
102
103
  {
103
- if (pointer()) pwrapper = Xot::set_pointer_flag(pwrapper, state);
104
+ Value& current = value(true);
105
+ if (current == val)
106
+ return false;
107
+
108
+ current = val;
109
+ return true;
110
+ }
111
+
112
+ void override (const This& value)
113
+ {
114
+ if (!value || (*this && !is_inherited()))
115
+ return;
116
+
117
+ reset(value.pointer());
118
+ set_inherited();
104
119
  }
105
120
 
106
121
  bool is_inherited () const
@@ -128,101 +143,295 @@ namespace Reflex
128
143
  return p;
129
144
  }
130
145
 
131
- Wrapper* pointer () {return Xot::set_pointer_flag(pwrapper, false);}
146
+ void set_inherited (bool state = true)
147
+ {
148
+ if (pwrapper)
149
+ pwrapper = Xot::set_pointer_flag(pwrapper, state);
150
+ }
132
151
 
133
- const Wrapper* pointer () const {return const_cast<StyleValue*>(this)->pointer();}
152
+ Wrapper* pointer () const {return Xot::set_pointer_flag(pwrapper, false);}
134
153
 
135
154
  };// StyleValue
136
155
 
137
156
 
138
- struct Style::Data : public Xot::RefCountable<>
157
+ struct StyleLength::Data
139
158
  {
140
159
 
141
- typedef StyleValue<bool> Bool;
142
-
143
- typedef StyleValue<int> Int;
160
+ Value value;
144
161
 
145
- typedef StyleValue<double> Float;
162
+ Unit unit;
146
163
 
147
- typedef StyleValue<StyleLength> Length;
164
+ Data () : value(0), unit(NONE) {}
148
165
 
149
- typedef StyleValue<StyleLength2> Length2;
166
+ friend bool operator == (const Data& lhs, const Data& rhs)
167
+ {
168
+ return lhs.value == rhs.value && lhs.unit == rhs.unit;
169
+ }
150
170
 
151
- typedef StyleValue<StyleLength4> Length4;
171
+ };// StyleLength::Data
152
172
 
153
- typedef StyleValue<Color> Color;
154
173
 
155
- typedef StyleValue<Image> Image;
174
+ StyleLength::StyleLength ()
175
+ {
176
+ }
156
177
 
157
- View* owner;
178
+ StyleLength::StyleLength (Value value, Unit unit)
179
+ {
180
+ reset(value, unit);
181
+ }
158
182
 
159
- Selector selector;
183
+ StyleLength::StyleLength (const char* str)
184
+ {
185
+ reset(str);
186
+ }
160
187
 
161
- Int flow_main, flow_sub;
188
+ StyleLength
189
+ StyleLength::copy () const
190
+ {
191
+ return StyleLength(value(), unit());
192
+ }
162
193
 
163
- Length2 size;
194
+ void
195
+ StyleLength::reset (Value value, Unit unit)
196
+ {
197
+ if (unit < NONE || UNIT_LAST <= unit)
198
+ argument_error(__FILE__, __LINE__);
164
199
 
165
- Length4 position, offset, margin, padding;
200
+ self->value = value;
201
+ self->unit = unit;
202
+ }
166
203
 
167
- Color background_color;
204
+ static StyleLength::Unit
205
+ str2unit (const char* s)
206
+ {
207
+ if (strcasecmp(s, "px") == 0) return StyleLength::PIXEL;
208
+ else if (strcasecmp(s, "%") == 0) return StyleLength::PERCENT;
209
+ else return StyleLength::NONE;
210
+ }
168
211
 
169
- Image background_image;
212
+ static const char*
213
+ unit2str (StyleLength::Unit unit)
214
+ {
215
+ switch (unit)
216
+ {
217
+ case StyleLength::PIXEL: return "px";
218
+ case StyleLength::PERCENT: return "%";
219
+ default: return NULL;
220
+ }
221
+ }
170
222
 
171
- Data () : owner(NULL) {}
223
+ void
224
+ StyleLength::reset (const char* str)
225
+ {
226
+ Value num;
227
+ char suffix[256];
228
+ int count = sscanf(str, "%f%s", &num, suffix);
229
+ if (count != 2)
230
+ argument_error(__FILE__, __LINE__);
172
231
 
173
- };// Style::Data
232
+ reset(num, str2unit(suffix));
233
+ }
174
234
 
235
+ StyleLength::Value
236
+ StyleLength::value () const
237
+ {
238
+ return self->value;
239
+ }
175
240
 
176
- namespace Zero
241
+ StyleLength::Unit
242
+ StyleLength::unit () const
177
243
  {
244
+ return self->unit;
245
+ }
178
246
 
179
- static const StyleLength length;
247
+ String
248
+ StyleLength::to_s () const
249
+ {
250
+ if (!*this)
251
+ return "";
180
252
 
181
- static const StyleLength2 length2;
253
+ String num;
254
+ if (fmod(self->value, 1) == 0)
255
+ num = Xot::stringf("%d", (long) self->value);
256
+ else
257
+ num = Xot::stringf("%g", self->value);
182
258
 
183
- static const StyleLength4 length4;
259
+ const char* suffix = unit2str(self->unit);;
260
+ if (!suffix)
261
+ invalid_state_error(__FILE__, __LINE__);
184
262
 
185
- static const Color color(0);
263
+ return num + suffix;
264
+ }
186
265
 
187
- static const Image image;
266
+ StyleLength::operator bool () const
267
+ {
268
+ return NONE < self->unit && self->unit < UNIT_LAST;
269
+ }
188
270
 
189
- }// Zero
271
+ bool
272
+ StyleLength::operator ! () const
273
+ {
274
+ return !operator bool();
275
+ }
190
276
 
277
+ bool
278
+ operator == (const StyleLength& lhs, const StyleLength& rhs)
279
+ {
280
+ return (!lhs && !rhs) || *lhs.self == *rhs.self;
281
+ }
191
282
 
192
- static Style::Data*
193
- get_data (Style* this_, bool create = false)
283
+ bool
284
+ operator != (const StyleLength& lhs, const StyleLength& rhs)
194
285
  {
195
- if (!this_)
196
- argument_error(__FILE__, __LINE__);
286
+ return !operator ==(lhs, rhs);
287
+ }
197
288
 
198
- if (create && !this_->ref)
199
- this_->ref.reset(new Style::Data());
200
289
 
201
- return this_->ref.get();
290
+ void
291
+ get_default_flow (Style::Flow* main, Style::Flow* sub)
292
+ {
293
+ assert(main || sub);
294
+
295
+ if (main) *main = Style::FLOW_RIGHT;
296
+ if (sub) *sub = Style::FLOW_DOWN;
202
297
  }
203
298
 
204
- static const Style::Data*
205
- get_data (const Style* this_)
299
+
300
+ struct Style::Data
206
301
  {
207
- return get_data(const_cast<Style*>(this_));
208
- }
209
302
 
303
+ typedef StyleValue<bool> Bool;
210
304
 
211
- Style::Style (const char* name)
305
+ typedef StyleValue<int> Int;
306
+
307
+ typedef StyleValue<double> Float;
308
+
309
+ typedef StyleValue<Color> Color;
310
+
311
+ typedef StyleValue<Image> Image;
312
+
313
+ typedef StyleValue<StyleLength> Length;
314
+
315
+ View* owner;
316
+
317
+ Selector selector;
318
+
319
+ Int flow;
320
+
321
+ Length width, height;
322
+
323
+ Length left, top, right, bottom;
324
+
325
+ Length offset_left, offset_top, offset_right, offset_bottom;
326
+
327
+ Length margin_left, margin_top, margin_right, margin_bottom;
328
+
329
+ Length padding_left, padding_top, padding_right, padding_bottom;
330
+
331
+ Color fill, stroke;
332
+
333
+ Image image;
334
+
335
+ Data ()
336
+ : owner(NULL)
337
+ {
338
+ }
339
+
340
+ enum FlowOffset {FLOW_MASK = 0xffff, FLOW_SHIFT = 16};
341
+
342
+ bool set_flow (Flow main, Flow sub)
343
+ {
344
+ return flow.set((main & FLOW_MASK) | ((sub & FLOW_MASK) << FLOW_SHIFT));
345
+ }
346
+
347
+ Flow flow_main () const
348
+ {
349
+ Flow defval = FLOW_NONE;
350
+ get_default_flow(&defval, NULL);
351
+ return (Flow) (flow.get(defval) & FLOW_MASK);
352
+ }
353
+
354
+ Flow flow_sub () const
355
+ {
356
+ Flow defval = FLOW_NONE;
357
+ get_default_flow(NULL, &defval);
358
+ return (Flow) ((flow.get(defval << FLOW_SHIFT) >> FLOW_SHIFT) & FLOW_MASK);
359
+ }
360
+
361
+ };// Data
362
+
363
+
364
+ namespace Zero
212
365
  {
213
- if (name) set_name(name);
366
+
367
+ static const Color color;
368
+
369
+ static const Image image;
370
+
371
+ static const StyleLength length;
372
+
373
+ }// Zero
374
+
375
+
376
+ bool
377
+ set_style_owner (Style* style, View* owner)
378
+ {
379
+ assert(style);
380
+
381
+ if (style->self->owner)
382
+ return false;
383
+
384
+ style->self->owner = owner;
385
+ return true;
214
386
  }
215
387
 
216
- Style::Style (const This& obj)
217
- : ref(obj.ref)
388
+ static void
389
+ update_owner (const Style& style)
218
390
  {
391
+ View* owner = style.self->owner;
392
+ if (!owner) return;
393
+
394
+ void update_styles_for_selector (View*, const Selector&);
395
+ update_styles_for_selector(owner, style.self->selector);
219
396
  }
220
397
 
221
- Style&
222
- Style::operator = (const This& obj)
398
+ void
399
+ override_style (Style* overridden, const Style& overrides)
400
+ {
401
+ assert(overridden);
402
+
403
+ Style::Data* from = overrides.self.get();
404
+ Style::Data* to = overridden->self.get();
405
+ if (!from || !to) return;
406
+
407
+ to->flow .override(from->flow);
408
+ to->width .override(from->width);
409
+ to->height .override(from->height);
410
+ to->left .override(from->left);
411
+ to->top .override(from->top);
412
+ to->right .override(from->right);
413
+ to->bottom .override(from->bottom);
414
+ to->offset_left .override(from->offset_left);
415
+ to->offset_top .override(from->offset_top);
416
+ to->offset_right .override(from->offset_right);
417
+ to->offset_bottom .override(from->offset_bottom);
418
+ to->margin_left .override(from->margin_left);
419
+ to->margin_top .override(from->margin_top);
420
+ to->margin_right .override(from->margin_right);
421
+ to->margin_bottom .override(from->margin_bottom);
422
+ to->padding_left .override(from->padding_left);
423
+ to->padding_top .override(from->padding_top);
424
+ to->padding_right .override(from->padding_right);
425
+ to->padding_bottom.override(from->padding_bottom);
426
+ to->fill .override(from->fill);
427
+ to->stroke .override(from->stroke);
428
+ to->image .override(from->image);
429
+ }
430
+
431
+
432
+ Style::Style (const char* name)
223
433
  {
224
- if (&obj != this) ref = obj.ref;
225
- return *this;
434
+ if (name) set_name(name);
226
435
  }
227
436
 
228
437
  Style::~Style ()
@@ -232,80 +441,83 @@ namespace Reflex
232
441
  void
233
442
  Style::set_name (const char* name)
234
443
  {
235
- get_data(this, true)->selector.set_name(name);
444
+ update_owner(*this);
445
+
446
+ self->selector.set_name(name);
447
+
448
+ update_owner(*this);
236
449
  }
237
450
 
238
451
  const char*
239
452
  Style::name () const
240
453
  {
241
- const Data* data = get_data(this);
242
- return data ? data->selector.name() : NULL;
454
+ return self->selector.name();
243
455
  }
244
456
 
245
457
  void
246
458
  Style::add_tag (const char* tag)
247
459
  {
248
- get_data(this, true)->selector.add_tag(tag);
460
+ update_owner(*this);
461
+
462
+ self->selector.add_tag(tag);
463
+
464
+ update_owner(*this);
249
465
  }
250
466
 
251
467
  void
252
468
  Style::remove_tag (const char* tag)
253
469
  {
254
- Data* data = get_data(this);
255
- if (!data) return;
470
+ update_owner(*this);
256
471
 
257
- data->selector.remove_tag(tag);
258
- }
472
+ self->selector.remove_tag(tag);
259
473
 
260
- static Selector::TagSet empty_tags;
474
+ update_owner(*this);
475
+ }
261
476
 
262
477
  Selector::iterator
263
478
  Style::tag_begin ()
264
479
  {
265
- Data* data = get_data(this);
266
- return data ? data->selector.begin() : empty_tags.begin();
480
+ return self->selector.begin();
267
481
  }
268
482
 
269
483
  Selector::const_iterator
270
484
  Style::tag_begin () const
271
485
  {
272
- const Data* data = get_data(this);
273
- return data ? data->selector.begin() : empty_tags.begin();
486
+ return self->selector.begin();
274
487
  }
275
488
 
276
489
  Selector::iterator
277
490
  Style::tag_end ()
278
491
  {
279
- Data* data = get_data(this);
280
- return data ? data->selector.end() : empty_tags.end();
492
+ return self->selector.end();
281
493
  }
282
494
 
283
495
  Selector::const_iterator
284
496
  Style::tag_end () const
285
497
  {
286
- const Data* data = get_data(this);
287
- return data ? data->selector.end() : empty_tags.end();
498
+ return self->selector.end();
288
499
  }
289
500
 
290
501
  void
291
502
  Style::set_selector (const Selector& selector)
292
503
  {
293
- get_data(this, true)->selector = selector;
504
+ update_owner(*this);
505
+
506
+ self->selector = selector;
507
+
508
+ update_owner(*this);
294
509
  }
295
510
 
296
511
  Selector&
297
512
  Style::selector ()
298
513
  {
299
- return get_data(this, true)->selector;
514
+ return self->selector;
300
515
  }
301
516
 
302
517
  const Selector&
303
518
  Style::selector () const
304
519
  {
305
- static const Selector EMPTY;
306
-
307
- const Data* data = get_data(this);
308
- return data ? data->selector : EMPTY;
520
+ return self->selector;
309
521
  }
310
522
 
311
523
  enum FlowDir {FLOW_INVALID = 0, FLOW_H, FLOW_V};
@@ -319,8 +531,8 @@ namespace Reflex
319
531
  case Style::FLOW_RIGHT: return FLOW_H;
320
532
  case Style::FLOW_UP:
321
533
  case Style::FLOW_DOWN: return FLOW_V;
534
+ default: return FLOW_INVALID;
322
535
  }
323
- return FLOW_INVALID;
324
536
  }
325
537
 
326
538
  void
@@ -335,9 +547,9 @@ namespace Reflex
335
547
  argument_error(__FILE__, __LINE__);
336
548
  }
337
549
 
338
- Data* data = get_data(this, true);
339
- data->flow_main = main;
340
- data->flow_sub = sub;
550
+ self->set_flow(main, sub);
551
+
552
+ update_owner(*this);
341
553
  }
342
554
 
343
555
  void
@@ -346,224 +558,287 @@ namespace Reflex
346
558
  if (!main && !sub)
347
559
  argument_error(__FILE__, __LINE__);
348
560
 
349
- const Data* data = get_data(this);
350
- if (!data || (!data->flow_main && !data->flow_sub))
351
- {
352
- if (main) *main = FLOW_DOWN;
353
- if (sub) *sub = FLOW_NONE;
354
- }
355
- else if (data->flow_main && data->flow_sub)
356
- {
357
- if (main) *main = (Flow) data->flow_main.value();
358
- if (sub) *sub = (Flow) data->flow_sub.value();
359
- }
360
- else
361
- invalid_state_error(__FILE__, __LINE__);
362
- }
363
-
364
- void
365
- Style::set_size (const StyleLength2& size)
366
- {
367
- get_data(this, true)->size = size;
561
+ if (main) *main = self->flow_main();
562
+ if (sub) *sub = self->flow_sub();
368
563
  }
369
564
 
370
565
  void
371
566
  Style::set_width (const StyleLength& width)
372
567
  {
373
- get_data(this, true)->size.value(true).set_width(width);
568
+ if (self->width.set(width))
569
+ update_owner(*this);
374
570
  }
375
571
 
376
572
  void
377
573
  Style::set_height (const StyleLength& height)
378
574
  {
379
- get_data(this, true)->size.value(true).set_height(height);
575
+ if (self->height.set(height))
576
+ update_owner(*this);
380
577
  }
381
578
 
382
- const StyleLength2&
383
- Style::size () const
579
+ const StyleLength&
580
+ Style::width () const
384
581
  {
385
- const Data* data = get_data(this);
386
- return data && data->size ? data->size.value() : Zero::length2;
582
+ return self->width.get(Zero::length);
387
583
  }
388
584
 
389
- void
390
- Style::set_position (const StyleLength4& position)
585
+ const StyleLength&
586
+ Style::height () const
391
587
  {
392
- get_data(this, true)->position = position;
588
+ return self->height.get(Zero::length);
393
589
  }
394
590
 
395
591
  void
396
592
  Style::set_left (const StyleLength& left)
397
593
  {
398
- get_data(this, true)->position.value(true).set_left(left);
594
+ if (self->left.set(left))
595
+ update_owner(*this);
399
596
  }
400
597
 
401
598
  void
402
599
  Style::set_top (const StyleLength& top)
403
600
  {
404
- get_data(this, true)->position.value(true).set_top(top);
601
+ if (self->top.set(top))
602
+ update_owner(*this);
405
603
  }
406
604
 
407
605
  void
408
606
  Style::set_right (const StyleLength& right)
409
607
  {
410
- get_data(this, true)->position.value(true).set_right(right);
608
+ if (self->right.set(right))
609
+ update_owner(*this);
411
610
  }
412
611
 
413
612
  void
414
613
  Style::set_bottom (const StyleLength& bottom)
415
614
  {
416
- get_data(this, true)->position.value(true).set_bottom(bottom);
615
+ if (self->bottom.set(bottom))
616
+ update_owner(*this);
417
617
  }
418
618
 
419
- const StyleLength4&
420
- Style::position () const
619
+ const StyleLength&
620
+ Style::left () const
421
621
  {
422
- const Data* data = get_data(this);
423
- return data && data->position ? data->position.value() : Zero::length4;
622
+ return self->left.get(Zero::length);
424
623
  }
425
624
 
426
- void
427
- Style::set_offset (const StyleLength4& offset)
625
+ const StyleLength&
626
+ Style::top () const
627
+ {
628
+ return self->top.get(Zero::length);
629
+ }
630
+
631
+ const StyleLength&
632
+ Style::right () const
633
+ {
634
+ return self->right.get(Zero::length);
635
+ }
636
+
637
+ const StyleLength&
638
+ Style::bottom () const
428
639
  {
429
- get_data(this, true)->offset = offset;
640
+ return self->bottom.get(Zero::length);
430
641
  }
431
642
 
432
643
  void
433
644
  Style::set_offset_left (const StyleLength& left)
434
645
  {
435
- get_data(this, true)->offset.value(true).set_left(left);
646
+ if (self->offset_left.set(left))
647
+ update_owner(*this);
436
648
  }
437
649
 
438
650
  void
439
651
  Style::set_offset_top (const StyleLength& top)
440
652
  {
441
- get_data(this, true)->offset.value(true).set_top(top);
653
+ if (self->offset_top.set(top))
654
+ update_owner(*this);
442
655
  }
443
656
 
444
657
  void
445
658
  Style::set_offset_right (const StyleLength& right)
446
659
  {
447
- get_data(this, true)->offset.value(true).set_right(right);
660
+ if (self->offset_right.set(right))
661
+ update_owner(*this);
448
662
  }
449
663
 
450
664
  void
451
665
  Style::set_offset_bottom (const StyleLength& bottom)
452
666
  {
453
- get_data(this, true)->offset.value(true).set_bottom(bottom);
667
+ if (self->offset_bottom.set(bottom))
668
+ update_owner(*this);
454
669
  }
455
670
 
456
- const StyleLength4&
457
- Style::offset () const
671
+ const StyleLength&
672
+ Style::offset_left () const
458
673
  {
459
- const Data* data = get_data(this);
460
- return data && data->offset ? data->offset.value() : Zero::length4;
674
+ return self->offset_left.get(Zero::length);
461
675
  }
462
676
 
463
- void
464
- Style::set_margin (const StyleLength4& margin)
677
+ const StyleLength&
678
+ Style::offset_top () const
465
679
  {
466
- get_data(this, true)->margin = margin;
680
+ return self->offset_top.get(Zero::length);
681
+ }
682
+
683
+ const StyleLength&
684
+ Style::offset_right () const
685
+ {
686
+ return self->offset_right.get(Zero::length);
687
+ }
688
+
689
+ const StyleLength&
690
+ Style::offset_bottom () const
691
+ {
692
+ return self->offset_bottom.get(Zero::length);
467
693
  }
468
694
 
469
695
  void
470
696
  Style::set_margin_left (const StyleLength& left)
471
697
  {
472
- get_data(this, true)->margin.value(true).set_left(left);
698
+ if (self->margin_left.set(left))
699
+ update_owner(*this);
473
700
  }
474
701
 
475
702
  void
476
703
  Style::set_margin_top (const StyleLength& top)
477
704
  {
478
- get_data(this, true)->margin.value(true).set_top(top);
705
+ if (self->margin_top.set(top))
706
+ update_owner(*this);
479
707
  }
480
708
 
481
709
  void
482
710
  Style::set_margin_right (const StyleLength& right)
483
711
  {
484
- get_data(this, true)->margin.value(true).set_right(right);
712
+ if (self->margin_right.set(right))
713
+ update_owner(*this);
485
714
  }
486
715
 
487
716
  void
488
717
  Style::set_margin_bottom (const StyleLength& bottom)
489
718
  {
490
- get_data(this, true)->margin.value(true).set_bottom(bottom);
719
+ if (self->margin_bottom.set(bottom))
720
+ update_owner(*this);
491
721
  }
492
722
 
493
- const StyleLength4&
494
- Style::margin () const
723
+ const StyleLength&
724
+ Style::margin_left () const
495
725
  {
496
- const Data* data = get_data(this);
497
- return data && data->margin ? data->margin.value() : Zero::length4;
726
+ return self->margin_left.get(Zero::length);
498
727
  }
499
728
 
500
- void
501
- Style::set_padding (const StyleLength4& padding)
729
+ const StyleLength&
730
+ Style::margin_top () const
731
+ {
732
+ return self->margin_top.get(Zero::length);
733
+ }
734
+
735
+ const StyleLength&
736
+ Style::margin_right () const
502
737
  {
503
- get_data(this, true)->padding = padding;
738
+ return self->margin_right.get(Zero::length);
739
+ }
740
+
741
+ const StyleLength&
742
+ Style::margin_bottom () const
743
+ {
744
+ return self->margin_bottom.get(Zero::length);
504
745
  }
505
746
 
506
747
  void
507
748
  Style::set_padding_left (const StyleLength& left)
508
749
  {
509
- get_data(this, true)->padding.value(true).set_left(left);
750
+ if (self->padding_left.set(left))
751
+ update_owner(*this);
510
752
  }
511
753
 
512
754
  void
513
755
  Style::set_padding_top (const StyleLength& top)
514
756
  {
515
- get_data(this, true)->padding.value(true).set_top(top);
757
+ if (self->padding_top.set(top))
758
+ update_owner(*this);
516
759
  }
517
760
 
518
761
  void
519
762
  Style::set_padding_right (const StyleLength& right)
520
763
  {
521
- get_data(this, true)->padding.value(true).set_right(right);
764
+ if (self->padding_right.set(right))
765
+ update_owner(*this);
522
766
  }
523
767
 
524
768
  void
525
769
  Style::set_padding_bottom (const StyleLength& bottom)
526
770
  {
527
- get_data(this, true)->padding.value(true).set_bottom(bottom);
771
+ if (self->padding_bottom.set(bottom))
772
+ update_owner(*this);
773
+ }
774
+
775
+ const StyleLength&
776
+ Style::padding_left () const
777
+ {
778
+ return self->padding_left.get(Zero::length);
779
+ }
780
+
781
+ const StyleLength&
782
+ Style::padding_top () const
783
+ {
784
+ return self->padding_top.get(Zero::length);
785
+ }
786
+
787
+ const StyleLength&
788
+ Style::padding_right () const
789
+ {
790
+ return self->padding_right.get(Zero::length);
791
+ }
792
+
793
+ const StyleLength&
794
+ Style::padding_bottom () const
795
+ {
796
+ return self->padding_bottom.get(Zero::length);
528
797
  }
529
798
 
530
- const StyleLength4&
531
- Style::padding () const
799
+ void
800
+ Style::set_fill (const Color& fill)
532
801
  {
533
- const Data* data = get_data(this);
534
- return data && data->padding ? data->padding.value() : Zero::length4;
802
+ if (self->fill.set(fill))
803
+ update_owner(*this);
804
+ }
805
+
806
+ const Color&
807
+ Style::fill () const
808
+ {
809
+ return self->fill.get(Zero::color);
535
810
  }
536
811
 
537
812
  void
538
- Style::set_background_color (const Color& value)
813
+ Style::set_stroke (const Color& stroke)
539
814
  {
540
- get_data(this, true)->background_color = value;
815
+ if (self->stroke.set(stroke))
816
+ update_owner(*this);
541
817
  }
542
818
 
543
819
  const Color&
544
- Style::background_color () const
820
+ Style::stroke () const
545
821
  {
546
- const Data* data = get_data(this);
547
- return data && data->background_color ? data->background_color.value() : Zero::color;
822
+ return self->stroke.get(Zero::color);
548
823
  }
549
824
 
550
825
  void
551
- Style::set_background_image (const Image& value)
826
+ Style::set_image (const Image& image)
552
827
  {
553
- get_data(this, true)->background_image = value;
828
+ if (self->image.set(image))
829
+ update_owner(*this);
554
830
  }
555
831
 
556
832
  const Image&
557
- Style::background_image () const
833
+ Style::image () const
558
834
  {
559
- const Data* data = get_data(this);
560
- return data && data->background_image ? data->background_image.value() : Zero::image;
835
+ return self->image.get(Zero::image);
561
836
  }
562
837
 
563
838
  bool
564
839
  operator == (const Style& lhs, const Style& rhs)
565
840
  {
566
- return lhs.ref == rhs.ref;
841
+ return lhs.self.get() == rhs.self.get();
567
842
  }
568
843
 
569
844
  bool
@@ -573,4 +848,83 @@ namespace Reflex
573
848
  }
574
849
 
575
850
 
851
+ static bool
852
+ get_pixel_length (
853
+ coord* pixel_length,
854
+ const StyleLength& style_length, const coord* parent_size)
855
+ {
856
+ if (!pixel_length)
857
+ argument_error(__FILE__, __LINE__);
858
+
859
+ if (!style_length)
860
+ return false;
861
+
862
+ coord length = 0;
863
+ StyleLength::Value value = style_length.value();
864
+ switch (style_length.unit())
865
+ {
866
+ case StyleLength::PIXEL:
867
+ length = value;
868
+ break;
869
+
870
+ case StyleLength::PERCENT:
871
+ {
872
+ if (!parent_size)
873
+ argument_error(__FILE__, __LINE__);
874
+
875
+ length = (value == 100) ?
876
+ *parent_size : floor(*parent_size * value / 100);
877
+ break;
878
+ }
879
+
880
+ default:
881
+ invalid_state_error(__FILE__, __LINE__);
882
+ }
883
+
884
+ if (length == *pixel_length)
885
+ return false;
886
+
887
+ *pixel_length = length;
888
+ return true;
889
+ }
890
+
891
+ static void
892
+ update_frame (View* view, const Style& style)
893
+ {
894
+ assert(view);
895
+ Style::Data* s = style.self.get();
896
+
897
+ Bounds frame = view->frame();
898
+ View* parent_view = view->parent();
899
+ const Bounds* parent = parent_view ? &parent_view->frame() : NULL;
900
+ bool update = false;
901
+
902
+ if (s->width)
903
+ {
904
+ update |= get_pixel_length(
905
+ &frame.width, s->width.value(), parent ? &parent->width : NULL);
906
+ }
907
+
908
+ if (s->height) {
909
+ update |= get_pixel_length(
910
+ &frame.height, s->height.value(), parent ? &parent->height : NULL);
911
+ }
912
+
913
+ if (update)
914
+ view->set_frame(frame);
915
+ }
916
+
917
+ void
918
+ apply_style (View* view, const Style& style)
919
+ {
920
+ if (!view)
921
+ argument_error(__FILE__, __LINE__);
922
+
923
+ //update_margin(view, values);
924
+ //update_padding(view, values);
925
+ update_frame(view, style);
926
+ //update_background(view, values);
927
+ }
928
+
929
+
576
930
  }// Reflex