reflexion 0.1.6 → 0.1.7

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 (225) hide show
  1. checksums.yaml +7 -0
  2. data/.doc/ext/reflex/application.cpp +54 -39
  3. data/.doc/ext/reflex/capture_event.cpp +87 -0
  4. data/.doc/ext/reflex/draw_event.cpp +103 -0
  5. data/.doc/ext/reflex/event.cpp +73 -0
  6. data/.doc/ext/reflex/focus_event.cpp +98 -0
  7. data/.doc/ext/reflex/frame_event.cpp +133 -0
  8. data/.doc/ext/reflex/image_view.cpp +74 -0
  9. data/.doc/ext/reflex/key_event.cpp +124 -0
  10. data/.doc/ext/reflex/native.cpp +45 -6
  11. data/.doc/ext/reflex/pointer_event.cpp +181 -0
  12. data/.doc/ext/reflex/reflex.cpp +17 -41
  13. data/.doc/ext/reflex/scroll_event.cpp +141 -0
  14. data/.doc/ext/reflex/selector.cpp +135 -0
  15. data/.doc/ext/reflex/style.cpp +253 -0
  16. data/.doc/ext/reflex/style_length.cpp +133 -0
  17. data/.doc/ext/reflex/style_length2.cpp +149 -0
  18. data/.doc/ext/reflex/style_length4.cpp +192 -0
  19. data/.doc/ext/reflex/update_event.cpp +77 -0
  20. data/.doc/ext/reflex/view.cpp +408 -88
  21. data/.doc/ext/reflex/wheel_event.cpp +146 -0
  22. data/.doc/ext/reflex/window.cpp +95 -92
  23. data/Rakefile +6 -5
  24. data/VERSION +1 -1
  25. data/ext/reflex/application.cpp +67 -49
  26. data/ext/reflex/capture_event.cpp +92 -0
  27. data/ext/reflex/draw_event.cpp +110 -0
  28. data/ext/reflex/event.cpp +77 -0
  29. data/ext/reflex/extconf.rb +18 -68
  30. data/ext/reflex/focus_event.cpp +104 -0
  31. data/ext/reflex/frame_event.cpp +143 -0
  32. data/ext/reflex/image_view.cpp +77 -0
  33. data/ext/reflex/key_event.cpp +133 -0
  34. data/ext/reflex/native.cpp +45 -6
  35. data/ext/reflex/pointer_event.cpp +195 -0
  36. data/ext/reflex/reflex.cpp +21 -47
  37. data/ext/reflex/scroll_event.cpp +152 -0
  38. data/ext/reflex/selector.cpp +144 -0
  39. data/ext/reflex/style.cpp +277 -0
  40. data/ext/reflex/style_length.cpp +140 -0
  41. data/ext/reflex/style_length2.cpp +157 -0
  42. data/ext/reflex/style_length4.cpp +204 -0
  43. data/ext/reflex/update_event.cpp +81 -0
  44. data/ext/reflex/view.cpp +469 -114
  45. data/ext/reflex/wheel_event.cpp +158 -0
  46. data/ext/reflex/window.cpp +130 -123
  47. data/include/reflex/application.h +12 -7
  48. data/include/reflex/defs.h +13 -89
  49. data/include/reflex/event.h +260 -0
  50. data/include/reflex/exception.h +17 -11
  51. data/include/reflex/image_view.h +45 -0
  52. data/include/reflex/reflex.h +2 -6
  53. data/include/reflex/ruby/application.h +40 -13
  54. data/include/reflex/ruby/event.h +72 -0
  55. data/include/reflex/ruby/image_view.h +25 -0
  56. data/include/reflex/ruby/selector.h +27 -0
  57. data/include/reflex/ruby/style.h +27 -0
  58. data/include/reflex/ruby/style_length.h +37 -0
  59. data/include/reflex/ruby/view.h +193 -38
  60. data/include/reflex/ruby/window.h +123 -39
  61. data/include/reflex/ruby.h +3 -2
  62. data/include/reflex/selector.h +64 -0
  63. data/include/reflex/style.h +144 -0
  64. data/include/reflex/style_length.h +147 -0
  65. data/include/reflex/view.h +182 -19
  66. data/include/reflex/window.h +35 -19
  67. data/include/reflex.h +7 -0
  68. data/lib/reflex/application.rb +14 -5
  69. data/lib/reflex/arc_shape.rb +20 -0
  70. data/lib/reflex/button.rb +75 -0
  71. data/lib/reflex/capture_event.rb +37 -0
  72. data/lib/reflex/color.rb +13 -0
  73. data/lib/reflex/color_space.rb +13 -0
  74. data/lib/reflex/draw_event.rb +19 -0
  75. data/lib/reflex/ellipse_shape.rb +20 -0
  76. data/lib/reflex/ext.rb +1 -1
  77. data/lib/reflex/flags.rb +18 -0
  78. data/lib/reflex/focus_event.rb +38 -0
  79. data/lib/reflex/font.rb +13 -0
  80. data/lib/reflex/frame_event.rb +42 -0
  81. data/lib/reflex/helper.rb +87 -30
  82. data/lib/reflex/image_view.rb +25 -0
  83. data/lib/reflex/key_event.rb +38 -0
  84. data/lib/reflex/line_shape.rb +20 -0
  85. data/lib/reflex/list_view.rb +15 -0
  86. data/lib/reflex/model.rb +149 -0
  87. data/lib/reflex/model_owner.rb +57 -0
  88. data/lib/reflex/model_view.rb +22 -0
  89. data/lib/reflex/module.rb +11 -7
  90. data/lib/reflex/pointer_event.rb +85 -0
  91. data/lib/reflex/rect_shape.rb +20 -0
  92. data/lib/reflex/reflex.rb +13 -2
  93. data/lib/reflex/scroll_event.rb +19 -0
  94. data/lib/reflex/selector.rb +31 -0
  95. data/lib/reflex/shader.rb +13 -0
  96. data/lib/reflex/shape.rb +34 -0
  97. data/lib/reflex/style.rb +55 -0
  98. data/lib/reflex/style_length.rb +30 -0
  99. data/lib/reflex/style_length2.rb +34 -0
  100. data/lib/reflex/style_length4.rb +38 -0
  101. data/lib/reflex/text_view.rb +55 -0
  102. data/lib/reflex/update_event.rb +19 -0
  103. data/lib/reflex/view.rb +38 -4
  104. data/lib/reflex/wheel_event.rb +19 -0
  105. data/lib/reflex/window.rb +7 -5
  106. data/lib/reflex.rb +38 -1
  107. data/lib/reflexion/include.rb +5 -0
  108. data/lib/reflexion.rb +100 -0
  109. data/reflex.gemspec +3 -4
  110. data/samples/app.rb +13 -0
  111. data/samples/bats.rb +91 -0
  112. data/samples/checker.rb +36 -0
  113. data/{examples/ruby/shapes.rb → samples/fans.rb} +12 -16
  114. data/samples/fps.rb +46 -0
  115. data/samples/grid.rb +60 -0
  116. data/{examples/ruby → samples}/hello.rb +14 -16
  117. data/samples/image.rb +44 -0
  118. data/samples/ios/hello/hello/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
  119. data/samples/ios/hello/hello/Images.xcassets/LaunchImage.launchimage/Contents.json +51 -0
  120. data/samples/ios/hello/hello/en.lproj/InfoPlist.strings +2 -0
  121. data/samples/ios/hello/hello/hello-Info.plist +47 -0
  122. data/samples/ios/hello/hello/hello-Prefix.pch +10 -0
  123. data/samples/ios/hello/hello/main.cpp +79 -0
  124. data/samples/ios/hello/hello.xcodeproj/project.pbxproj +725 -0
  125. data/{examples/ruby → samples}/key.rb +11 -14
  126. data/samples/layout.rb +89 -0
  127. data/samples/model.rb +86 -0
  128. data/samples/osx/hello/hello/Images.xcassets/AppIcon.appiconset/Contents.json +58 -0
  129. data/samples/osx/hello/hello/en.lproj/Credits.rtf +29 -0
  130. data/samples/osx/hello/hello/en.lproj/InfoPlist.strings +2 -0
  131. data/samples/osx/hello/hello/hello-Info.plist +32 -0
  132. data/samples/osx/hello/hello/hello-Prefix.pch +3 -0
  133. data/samples/osx/hello/hello/main.cpp +79 -0
  134. data/samples/osx/hello/hello.xcodeproj/project.pbxproj +725 -0
  135. data/samples/reflexion/hello.rb +24 -0
  136. data/samples/reflexion/paint.rb +40 -0
  137. data/samples/reflexion/pulse.rb +34 -0
  138. data/samples/repl.rb +69 -0
  139. data/samples/shader.rb +41 -0
  140. data/samples/shapes.rb +30 -0
  141. data/{examples/ruby → samples}/text.rb +7 -8
  142. data/samples/tree.rb +71 -0
  143. data/samples/views.rb +41 -0
  144. data/samples/visuals.rb +22 -0
  145. data/src/event.cpp +225 -0
  146. data/src/exception.cpp +24 -15
  147. data/src/image_view.cpp +70 -0
  148. data/src/ios/app_delegate.h +17 -0
  149. data/src/ios/app_delegate.mm +120 -0
  150. data/src/ios/application.mm +116 -0
  151. data/src/{cocoa/applicationdata.h → ios/application_data.h} +6 -6
  152. data/src/ios/event.h +26 -0
  153. data/src/ios/event.mm +31 -0
  154. data/src/ios/native_window.h +37 -0
  155. data/src/ios/native_window.mm +220 -0
  156. data/src/ios/opengl_view.h +13 -0
  157. data/src/ios/opengl_view.mm +131 -0
  158. data/src/{cocoa → ios}/reflex.mm +8 -12
  159. data/src/ios/window.mm +303 -0
  160. data/src/ios/window_data.h +75 -0
  161. data/src/osx/app_delegate.h +17 -0
  162. data/src/{cocoa/cocoaapplication.mm → osx/app_delegate.mm} +90 -48
  163. data/src/osx/application.mm +132 -0
  164. data/src/osx/application_data.h +45 -0
  165. data/src/osx/event.h +42 -0
  166. data/src/osx/event.mm +112 -0
  167. data/src/osx/native_window.h +26 -0
  168. data/src/osx/native_window.mm +322 -0
  169. data/src/{cocoa/openglview.h → osx/opengl_view.h} +0 -4
  170. data/src/{cocoa/openglview.mm → osx/opengl_view.mm} +66 -23
  171. data/src/osx/reflex.mm +50 -0
  172. data/src/osx/window.mm +308 -0
  173. data/src/osx/window_data.h +75 -0
  174. data/src/selector.cpp +121 -0
  175. data/src/style.cpp +576 -0
  176. data/src/style_length.cpp +341 -0
  177. data/src/view.cpp +1228 -129
  178. data/src/win32/application.cpp +1 -1
  179. data/src/window.cpp +54 -26
  180. data/test/helper.rb +8 -4
  181. data/test/test_capture_event.rb +41 -0
  182. data/test/test_event.rb +20 -0
  183. data/test/test_has_frame.rb +45 -0
  184. data/test/test_model.rb +9 -0
  185. data/test/test_model_owner.rb +9 -0
  186. data/test/test_selector.rb +75 -0
  187. data/test/test_style.rb +70 -0
  188. data/test/test_style_length.rb +38 -0
  189. data/test/test_style_length2.rb +50 -0
  190. data/test/test_style_length4.rb +56 -0
  191. data/test/test_view.rb +97 -23
  192. data/test/test_window.rb +54 -46
  193. metadata +205 -84
  194. data/.doc/ext/reflex/defs.cpp +0 -8
  195. data/.doc/ext/reflex/key.cpp +0 -122
  196. data/.doc/ext/reflex/points.cpp +0 -151
  197. data/.gitignore +0 -14
  198. data/ChangeLog +0 -8
  199. data/examples/hello/.gitignore +0 -2
  200. data/examples/hello/Rakefile +0 -41
  201. data/examples/hello/main.cpp +0 -18
  202. data/examples/ruby/app.rb +0 -13
  203. data/examples/ruby/checker.rb +0 -41
  204. data/examples/ruby/fps.rb +0 -49
  205. data/examples/ruby/grid.rb +0 -65
  206. data/examples/ruby/views.rb +0 -88
  207. data/examples/ruby/visuals.rb +0 -27
  208. data/ext/reflex/defs.cpp +0 -8
  209. data/ext/reflex/key.cpp +0 -129
  210. data/ext/reflex/points.cpp +0 -161
  211. data/include/reflex/ruby/key.h +0 -39
  212. data/include/reflex/ruby/points.h +0 -39
  213. data/lib/reflex/visuals/string.rb +0 -53
  214. data/src/cocoa/application.mm +0 -101
  215. data/src/cocoa/cocoaapplication.h +0 -21
  216. data/src/cocoa/cocoawindow.h +0 -46
  217. data/src/cocoa/cocoawindow.mm +0 -230
  218. data/src/cocoa/defs.h +0 -34
  219. data/src/cocoa/defs.mm +0 -87
  220. data/src/cocoa/window.mm +0 -148
  221. data/src/cocoa/windowdata.h +0 -56
  222. data/src/defs.cpp +0 -47
  223. data/src/helper.h +0 -12
  224. data/src/reflex.cpp +0 -43
  225. /data/{README → README.md} +0 -0
data/src/view.cpp CHANGED
@@ -1,275 +1,1205 @@
1
1
  #include "reflex/view.h"
2
2
 
3
3
 
4
- #include <string.h>
4
+ #include <assert.h>
5
+ #include <algorithm>
6
+ #include <boost/scoped_ptr.hpp>
5
7
  #include <rays/bounds.h>
6
8
  #include <rays/painter.h>
7
- #include <reflex/window.h>
9
+ #include "reflex/window.h"
10
+ #include "reflex/exception.h"
8
11
 
9
12
 
10
13
  namespace Reflex
11
14
  {
12
15
 
13
16
 
14
- typedef std::vector<View::Ref> ViewList;
17
+ void set_focus (Window* window, View* view);
15
18
 
16
- static ViewList empty_list;
19
+ void register_capture (View* view);
20
+
21
+ void unregister_capture (View* view);
17
22
 
18
23
 
19
24
  struct View::Data
20
25
  {
21
26
 
22
- typedef ViewList:: iterator iterator;
27
+ Window* window;
23
28
 
24
- typedef ViewList::const_iterator const_iterator;
29
+ View* parent;
25
30
 
26
- String name;
31
+ Bounds frame;
27
32
 
28
- Bounds bounds;
33
+ boost::scoped_ptr<Selector> pselector;
29
34
 
30
- int hidecount;
35
+ boost::scoped_ptr<Point> pscroll;
31
36
 
32
- View* parent;
37
+ boost::scoped_ptr<ChildList> pchildren;
33
38
 
34
- Window* window;
39
+ boost::scoped_ptr<StyleList> pstyles;
40
+
41
+ Style style;
42
+
43
+ ushort capture;
44
+
45
+ short hide_count;
35
46
 
36
- ViewList* pchildren_;
47
+ uint flags;
37
48
 
38
49
  Data ()
39
- : hidecount(0), parent(NULL), pchildren_(NULL)
50
+ : window(NULL), parent(NULL),
51
+ capture(CAPTURE_NONE), hide_count(0), flags(0)
40
52
  {
41
53
  }
42
54
 
43
55
  ~Data ()
44
56
  {
45
- delete pchildren_;
46
57
  }
47
58
 
48
- bool set_parent (View* parent_)
59
+ Selector& selector ()
49
60
  {
50
- if (parent_ && parent) return false;
61
+ if (!pselector) pselector.reset(new Selector);
62
+ return *pselector;
63
+ }
51
64
 
52
- parent = parent_;
53
- window = parent_ ? parent_->window() : NULL;
54
- return true;
65
+ Point& scroll ()
66
+ {
67
+ if (!pscroll) pscroll.reset(new Point);
68
+ return *pscroll;
55
69
  }
56
70
 
57
- ViewList* children ()
71
+ ChildList& children ()
58
72
  {
59
- if (pchildren_ == NULL) pchildren_ = new ViewList();
60
- return pchildren_;
73
+ if (!pchildren) pchildren.reset(new ChildList);
74
+ return *pchildren;
61
75
  }
62
76
 
63
- iterator begin ()
77
+ StyleList& styles ()
64
78
  {
65
- if (!pchildren_) return empty_list.begin();
66
- return pchildren_->begin();
79
+ if (!pstyles) pstyles.reset(new StyleList);
80
+ return *pstyles;
67
81
  }
68
82
 
69
- const_iterator begin () const
83
+ };// View::Data
84
+
85
+
86
+ void
87
+ set_window (View* this_, Window* window_)
88
+ {
89
+ if (!this_)
90
+ argument_error(__FILE__, __LINE__);
91
+
92
+ Window* current = this_->self->window;
93
+ if (current == window_) return;
94
+
95
+ if (current)
70
96
  {
71
- if (!pchildren_) return empty_list.begin();
72
- return pchildren_->begin();
97
+ this_->set_capture(View::CAPTURE_NONE);
98
+
99
+ Event e;
100
+ this_->on_detach(&e);
73
101
  }
74
102
 
75
- iterator end ()
103
+ this_->self->window = window_;
104
+
105
+ View::child_iterator end = this_->child_end();
106
+ for (View::child_iterator it = this_->child_begin(); it != end; ++it)
107
+ set_window(it->get(), window_);
108
+
109
+ if (this_->self->window)
76
110
  {
77
- if (!pchildren_) return empty_list.end();
78
- return pchildren_->end();
111
+ Event e;
112
+ this_->on_attach(&e);
79
113
  }
114
+ }
115
+
116
+ static void
117
+ set_parent (View* this_, View* parent_)
118
+ {
119
+ if (!this_)
120
+ argument_error(__FILE__, __LINE__);
121
+
122
+ View* current = this_->self->parent;
123
+ if (current == parent_) return;
80
124
 
81
- const_iterator end () const
125
+ if (current && parent_)
82
126
  {
83
- if (!pchildren_) return empty_list.end();
84
- return pchildren_->end();
127
+ reflex_error(__FILE__, __LINE__,
128
+ "view '%s' already belongs to another parent '%s'.",
129
+ this_->name(), this_->self->parent->name());
130
+ }
131
+
132
+ this_->self->parent = parent_;
133
+ set_window(this_, parent_ ? parent_->window() : NULL);
134
+ }
135
+
136
+ void
137
+ update_view_tree (View* view, const UpdateEvent& event)
138
+ {
139
+ if (!view)
140
+ argument_error(__FILE__, __LINE__);
85
141
 
142
+ UpdateEvent e = event;
143
+ view->on_update(&e);
144
+
145
+ View::child_iterator end = view->child_end();
146
+ for (View::child_iterator it = view->child_begin(); it != end; ++it)
147
+ update_view_tree(it->get(), e);
148
+ }
149
+
150
+ void
151
+ draw_view_tree (
152
+ View* view, const DrawEvent& event, const Point& offset, const Bounds& clip)
153
+ {
154
+ if (!view)
155
+ argument_error(__FILE__, __LINE__);
156
+
157
+ DrawEvent e = event;
158
+ e.painter->push_matrix();
159
+ e.painter->push_attr();
160
+
161
+ Bounds b = view->frame();
162
+ Point p = b.position() - view->scroll();
163
+ e.painter->translate(p);
164
+
165
+ p += offset;
166
+ Bounds c = clip & b.move_to(p);
167
+ e.painter->set_clip(c);
168
+
169
+ e.view = view;
170
+ e.bounds = b.move_to(0, 0, b.z);
171
+ view->on_draw(&e);
172
+
173
+ View::child_iterator end = view->child_end();
174
+ for (View::child_iterator it = view->child_begin(); it != end; ++it)
175
+ draw_view_tree(it->get(), e, p, c);
176
+
177
+ e.painter->pop_attr();
178
+ e.painter->pop_matrix();
179
+ }
180
+ #if 0
181
+ void
182
+ get_all_margins (MarginList* margins, View* view)
183
+ {
184
+ if (!margins || !view)
185
+ argument_error(__FILE__, __LINE__);
186
+ }
187
+
188
+ void
189
+ get_content_size (
190
+ Point* size, View* view, const Point& parent_size, bool min_width, bool min_height)
191
+ {
192
+ if (!size || !view)
193
+ argument_error(__FILE__, __LINE__);
194
+
195
+ const Style& style = view->style();
196
+ const StyleLength4& pos = style.position();
197
+ const StyleLength2& size = style.size();
198
+ const StyleLength4& margin = style.margin();
199
+ bool need_width = true, need_height = true;
200
+ coord n;
201
+
202
+ size->reset(0);
203
+
204
+ if (pos.left && pos.right)
205
+ {
206
+ if (!pos.left.is_fixed())
207
+ layout_error(__FILE__, __LINE__, "");
208
+
209
+ size->x += parent_size.x;
210
+ need_width = false;
211
+ }
212
+ else if (size.width.get_pixel(&n, parent_size.x))
213
+ {
214
+ size->x += n;
215
+ need_width = false;
86
216
  }
87
217
 
88
- };// View::Data
218
+ if (pos.top && pos.bottom)
219
+ size->y += parent_size.y;
220
+ else if (size.height.get_pixel(&n, parent_size.y))
221
+ size->y += n;
222
+ else
223
+ need_height = true;
224
+
225
+ if (need_width || need_height)
226
+ {
227
+ Point content_size = view->content_size();
228
+ bool view_width = false, view_height = false;
229
+
230
+ if (need_width && content_size.x >= 0)
231
+ {
232
+ size->x += content_size.x;
233
+ need_width = false;
234
+ }
235
+
236
+ if (need_height && content_size.y >= 0)
237
+ {
238
+ size->y += content_size.y;
239
+ need_height = false;
240
+ }
241
+
242
+ if (need_width || need_height)
243
+ {
244
+ View::child_iterator end = view->child_end();
245
+ for (View::child_iterator it = view->child_begin(); it != end; ++it)
246
+ {
247
+ const View* child = it->get();
248
+ Point child_size;
249
+ get_content_size(&child_size, child, );
250
+ const Bounds& b = it->frame();
251
+ }
252
+
253
+ for ()
254
+ Point view_size;
255
+ get_view_size(&view_size, );
256
+ }
257
+
258
+ coord m;
259
+ if (margin.left .get_pixel(&m, parent_size.x)) size->x += m;
260
+ if (margin.top .get_pixel(&m, parent_size.y)) size->y += m;
261
+ if (margin.right .get_pixel(&m, parent_size.x)) size->x += m;
262
+ if (margin.bottom.get_pixel(&m, parent_size.y)) size->y += m;
263
+ }
264
+
265
+
266
+
267
+
268
+
269
+
270
+
271
+ const StyleLength4& margin = style.margin();
272
+
273
+ coord left, top, right, bottom;
274
+ bool have_left = pos.left .get_pixel(&left, parent_width);
275
+ bool have_top = pos.top .get_pixel(&top, parent_height);
276
+ bool have_right = pos.right .get_pixel(&right, parent_width);
277
+ bool have_bottom = pos.bottom.get_pixel(&bottom, parent_height);
278
+
279
+ if (have_left && have_right)
280
+ {
281
+ s
282
+ }
283
+
284
+ coord width, height;
285
+ bool have_width = size.width .get_pixel(&width, parent_width);
286
+ bool have_height = size.height.get_pixel(&height, parent_height);
287
+ const StyleLength& w = style.width();
288
+ switch (w.unit())
289
+ {
290
+ case StyleLength::PIXEL:
291
+ case StyleLength::PERCENT:
292
+ case StyleLength::NONE:
293
+ default:
294
+ }
295
+ }
296
+
297
+ static void
298
+ get_flow_factor (int* h, int* v, Style::Flow flow)
299
+ {
300
+ if (!h || !v)
301
+ argument_error(__FILE__, __LINE__);
302
+
303
+ switch (flow)
304
+ {
305
+ case Style::FLOW_DOWN: *h = 0; *v = +1; break;
306
+ case Style::FLOW_RIGHT: *h = +1; *v = 0; break;
307
+ case Style::FLOW_UP: *h = 0; *v = -1; break;
308
+ case Style::FLOW_LEFT: *h = -1; *v = 0; break;
309
+ default: argument_error(__FILE__, __LINE__);
310
+ }
311
+ }
312
+
313
+ struct Length4
314
+ {
315
+
316
+ coord l, t, r, b;
317
+
318
+ Length4 ()
319
+ {
320
+ }
321
+
322
+ Length4 (const StyleLength4& soruce)
323
+ {
324
+ reset(source);
325
+ }
326
+
327
+ void reset (const StyleLength4& source)
328
+ {
329
+ source.left .get_pixel(&l, 0);
330
+ source.top .get_pixel(&t, 0);
331
+ source.right .get_pixel(&r, 0);
332
+ source.bottom.get_pixel(&b, 0);
333
+ }
334
+
335
+ };// Length4
336
+
337
+ struct ChildView
338
+ {
339
+
340
+ View* view;
341
+
342
+ Point size;
343
+
344
+ Length4 margin;
345
+
346
+ ChildView (View* view) : view(view) {}
347
+
348
+ };// ChildView
349
+
350
+ typedef std::vector<ChildView> ChildViewList;
351
+
352
+ static void reflow_view_tree (Point* size, Length4* margin, View* view);
353
+
354
+ static void
355
+ reflow_children (View* view, Point* size, const Style& style)
356
+ {
357
+ assert(view && size);
358
+
359
+ size_t nchildren = view->self->count_children();
360
+ if (nchildren == 0) return;
361
+
362
+ ChildViewList children;
363
+ children.reserve(nchildren);
364
+
365
+ View::child_iterator end = view->child_end();
366
+ for (View::child_iterator it = view->child_begin(); it != end; ++it)
367
+ {
368
+ ChildView c(it->get());
369
+ reflow_view_tree(&c.size, &c.margin, c.view);
370
+ children.push_back(c);
371
+ }
372
+
373
+ assert(children.size() == nchildren)
374
+ #if 0
375
+ Flow flow_main, flow_sub;
376
+ style.get_flow(&flow_main, &flow_sub);
377
+
378
+ int main_h, main_v, sub_h, sub_v;
379
+ get_flow_factor(&main_h, &main_v, flow_main);
380
+ get_flow_factor(&sub_h, &sub_v, flow_sub);
381
+ #endif
382
+ coord x = 0, y = 0;
383
+ coord parent_w = size->x, parent_h = size->y;
384
+ coord height_max = 0;
385
+ int child_count = 0;
386
+ bool multiline = sub != Style::FLOW_NONE;
387
+
388
+ for (size_t i = 0; i < nchildren; ++i)
389
+ {
390
+ const ChildView& child = children[i];
391
+ Bounds& child_frame = child.view->self->frame;
392
+
393
+ child_frame.x = x;
394
+ child_frame.y = y;
395
+ x += child.size.x;
396
+
397
+ if (child.size.y > size_max)
398
+ size_max = child.size.y;
399
+
400
+ if (parent_w >= 0 && x > parent_w && view_count > 0)
401
+ {
402
+ x = 0;
403
+ y += size_max;
404
+ size_max = 0;
405
+ if (parent_h < 0 && y > size->y) size->y = y;
406
+ }
407
+
408
+ ++view_count;
409
+ }
410
+ }
411
+
412
+ static void
413
+ reflow_view_tree (Point* size, Length4* margin, View* view)
414
+ {
415
+ if (!size || !margin || !view)
416
+ argument_error(__FILE__, __LINE__);
417
+
418
+ const Style& style = view->style();
419
+
420
+ *size = view->content_size();
421
+ reflow_children(view, size, style);
89
422
 
423
+ Length4 padding(style.padding());
424
+ size->x += padding.l + padding.r;
425
+ size->y += padding.t + padding.b;
426
+
427
+ Bounds& frame = view->self->frame;
428
+ margin->reset(style.margin());
429
+
430
+ frame.width = margin.l + size->x + margin.r;
431
+ frame.height = margin.t + size->y + margin.b;
432
+ }
90
433
 
91
434
  void
92
- set_owner_window (View* view, Window* owner)
435
+ get_fixed_content_size (Point* size, View* view)
93
436
  {
94
- if (!view) return;
95
- view->self->window = owner;
437
+ if (!size || !view)
438
+ argument_error(__FILE__, __LINE__);
439
+
440
+ const Style& style = view->style();
441
+ const StyleLength2& size = style.size();
442
+ bool need_width = true, need_height = true;
443
+ coord n;
444
+
445
+ size->reset(-1);
446
+
447
+ if (size.width.is_fixed() && size.width.get_pixel(&n, parent_size.x))
448
+ {
449
+ size->x += n;
450
+ need_width = false;
451
+ }
452
+
453
+ if (size.height.get_pixel(&n, parent_size.y))
454
+ {
455
+ size->y += n;
456
+ need_height = false;
457
+ }
458
+
459
+ if (need_width || need_height)
460
+ {
461
+ Point content_size = view->content_size();
462
+ bool view_width = false, view_height = false;
463
+
464
+ if (need_width && content_size.x >= 0)
465
+ {
466
+ size->x += content_size.x;
467
+ need_width = false;
468
+ }
469
+
470
+ if (need_height && content_size.y >= 0)
471
+ {
472
+ size->y += content_size.y;
473
+ need_height = false;
474
+ }
475
+
476
+ if (need_width || need_height)
477
+ {
478
+ View::child_iterator end = view->child_end();
479
+ for (View::child_iterator it = view->child_begin(); it != end; ++it)
480
+ {
481
+ const View* child = it->get();
482
+ Point child_size;
483
+ get_content_size(&child_size, child, );
484
+ const Bounds& b = it->frame();
485
+ }
486
+
487
+ for ()
488
+ Point view_size;
489
+ get_view_size(&view_size, );
490
+ }
491
+
492
+ coord m;
493
+ if (margin.left .get_pixel(&m, parent_size.x)) size->x += m;
494
+ if (margin.top .get_pixel(&m, parent_size.y)) size->y += m;
495
+ if (margin.right .get_pixel(&m, parent_size.x)) size->x += m;
496
+ if (margin.bottom.get_pixel(&m, parent_size.y)) size->y += m;
497
+ }
498
+ }
499
+ #endif
500
+ static void
501
+ reflow_children (View* parent, const FrameEvent* event = NULL)
502
+ {
503
+ if (!parent)
504
+ argument_error(__FILE__, __LINE__);
505
+
506
+ if (!parent->self->pchildren) return;
507
+
508
+ View::ChildList& children = *parent->self->pchildren;
509
+ if (children.empty()) return;
510
+
511
+ #if 0
512
+ int main_h, main_v, sub_h, sub_v;
513
+ get_flow_factor(&main_h, &main_v, flow_main);
514
+ get_flow_factor(&sub_h, &sub_v, flow_sub);
515
+ #endif
516
+
517
+ const Style& style = parent->style();
518
+
519
+ Style::Flow flow_main, flow_sub;
520
+ style.get_flow(&flow_main, &flow_sub);
521
+
522
+ const Bounds& parent_frame = parent->self->frame;
523
+ coord x = 0, y = 0, size_max = 0;
524
+ int child_count = 0;
525
+ bool multiline = flow_sub != Style::FLOW_NONE;
526
+
527
+ size_t nchildren = children.size();
528
+ for (size_t i = 0; i < nchildren; ++i)
529
+ {
530
+ View* child = children[i].get();
531
+ Bounds child_frame = child->self->frame;
532
+
533
+ if (
534
+ (x + child_frame.width) > parent_frame.width &&
535
+ child_count > 0)// && multiline)
536
+ {
537
+ x = 0;
538
+ y += size_max;
539
+ size_max = 0;
540
+ child_count = 0;
541
+ }
542
+
543
+ child_frame.x = x;
544
+ child_frame.y = y;
545
+
546
+ x += child_frame.width;
547
+
548
+ if (size_max < child_frame.height)
549
+ size_max = child_frame.height;
550
+
551
+ //if (y + size_max > parent_frame.height)
552
+ // parent_frame.height = y + size_max;
553
+
554
+ ++child_count;
555
+ child->set_frame(child_frame);
556
+ }
557
+ }
558
+
559
+ template <typename FUN, typename EVENT>
560
+ static void
561
+ call_children (View* parent, FUN fun, const EVENT& e)
562
+ {
563
+ assert(parent);
564
+
565
+ View::child_iterator end = parent->child_end();
566
+ for (View::child_iterator it = parent->child_begin(); it != end; ++it)
567
+ fun(it->get(), e);
96
568
  }
97
569
 
98
570
  void
99
- update_view_tree (View* view, float dt)
571
+ call_key_event (View* child, const KeyEvent& event)
100
572
  {
101
- if (!view) return;
573
+ if (!child)
574
+ argument_error(__FILE__, __LINE__);
102
575
 
103
- view->update(dt);
576
+ bool capturing = child->capture() & View::CAPTURE_KEY;
577
+ if (capturing != event.capture) return;
104
578
 
105
- View::Data::iterator end = view->self->end();
106
- for (View::Data::iterator it = view->self->begin(); it != end; ++it)
107
- update_view_tree(it->get(), dt);
579
+ KeyEvent e = event;
580
+ child->on_key(&e);
108
581
  }
109
582
 
110
583
  void
111
- draw_view_tree (View* view, Painter* p, coord left, coord top)
584
+ call_pointer_event (View* child, const PointerEvent& event)
112
585
  {
113
- if (!view || !p) return;
586
+ if (!child)
587
+ argument_error(__FILE__, __LINE__);
114
588
 
115
- const Bounds& b = view->bounds();
116
- left += b.x;
117
- top += b.y;
589
+ bool capturing = child->capture() & View::CAPTURE_POINTER;
590
+ if (capturing != event.capture) return;
118
591
 
119
- p->push_matrix();
120
- p->translate(b.x, b.y);
121
- p->set_clip(left, top, b.width, b.height);
592
+ const Bounds& frame = child->frame();
122
593
 
123
- view->draw(p, Bounds(0, 0, b.width, b.height));
594
+ if (!capturing)
595
+ {
596
+ bool include = false;
597
+ for (size_t i = 0; i < event.size; ++i)
598
+ {
599
+ if (frame.is_include(event[i]))
600
+ {
601
+ include = true;
602
+ break;
603
+ }
604
+ }
605
+ if (!include) return;
606
+ }
124
607
 
125
- View::Data::iterator end = view->self->end();
126
- for (View::Data::iterator it = view->self->begin(); it != end; ++it)
127
- draw_view_tree(it->get(), p, left, top);
608
+ PointerEvent e = event;
609
+ Point offset = frame.position();
610
+ for (size_t i = 0; i < e.size; ++i)
611
+ e[i] -= offset;
128
612
 
129
- p->pop_matrix();
613
+ child->on_pointer(&e);
614
+
615
+ if (!event.capture)
616
+ call_children(child, call_pointer_event, e);
130
617
  }
131
618
 
619
+ void
620
+ call_wheel_event (View* child, const WheelEvent& event)
621
+ {
622
+ if (!child)
623
+ argument_error(__FILE__, __LINE__);
132
624
 
133
- View::View ()
625
+ const Bounds& frame = child->frame();
626
+
627
+ if (!frame.is_include(event.x, event.y, event.z))
628
+ return;
629
+
630
+ WheelEvent e = event;
631
+ e.position() -= frame.position();
632
+
633
+ child->on_wheel(&e);
634
+
635
+ call_children(child, call_wheel_event, e);
636
+ }
637
+
638
+
639
+ View::View (const char* name)
134
640
  {
641
+ if (name) self->selector().set_name(name);
135
642
  }
136
643
 
137
644
  View::~View ()
138
645
  {
139
646
  }
140
647
 
141
- bool
648
+ void
142
649
  View::show ()
143
650
  {
144
- --self->hidecount;
145
- return true;
651
+ if (!*this)
652
+ invalid_state_error(__FILE__, __LINE__);
653
+
654
+ --self->hide_count;
655
+ redraw();
146
656
  }
147
657
 
148
- bool
658
+ void
149
659
  View::hide ()
150
660
  {
151
- ++self->hidecount;
152
- return true;
661
+ if (!*this)
662
+ invalid_state_error(__FILE__, __LINE__);
663
+
664
+ ++self->hide_count;
665
+ redraw();
153
666
  }
154
667
 
155
668
  bool
669
+ View::hidden () const
670
+ {
671
+ if (!*this)
672
+ invalid_state_error(__FILE__, __LINE__);
673
+
674
+ return self->hide_count > 0;
675
+ }
676
+
677
+ void
156
678
  View::redraw ()
157
679
  {
680
+ if (!*this)
681
+ invalid_state_error(__FILE__, __LINE__);
682
+
158
683
  Window* w = window();
159
- return w && w->redraw();
684
+ if (!w) return;
685
+
686
+ w->redraw();
160
687
  }
161
688
 
162
- bool
689
+ void
163
690
  View::add_child (View* child)
164
691
  {
165
- if (!child) return false;
166
-
167
- View* parent = child->parent();
168
- if (parent) return parent == this;
692
+ if (!child || child == this)
693
+ argument_error(__FILE__, __LINE__);
169
694
 
170
- Data::iterator it = std::find(self->begin(), self->end(), child);
171
- if (it != self->end()) return false;
695
+ if (!*this)
696
+ invalid_state_error(__FILE__, __LINE__);
172
697
 
173
- if (!child->self->set_parent(this))
174
- return false;
698
+ bool found = std::find(child_begin(), child_end(), child) != child_end();
699
+ bool belong = child->parent() == this;
700
+ if (found && belong)
701
+ return;
702
+ else if (found != belong)
703
+ invalid_state_error(__FILE__, __LINE__);
175
704
 
176
- self->children()->push_back(child);
177
- return true;
705
+ self->children().push_back(child);
706
+ set_parent(child, this);
178
707
  }
179
708
 
180
- bool
709
+ void
181
710
  View::remove_child (View* child)
182
711
  {
183
- if (!self->pchildren_ || !child || child->parent() != this)
184
- return false;
712
+ if (!child || child == this)
713
+ argument_error(__FILE__, __LINE__);
185
714
 
186
- Data::iterator it = std::find(self->begin(), self->end(), child);
187
- if (it == self->end()) return false;
715
+ if (!*this)
716
+ invalid_state_error(__FILE__, __LINE__);
188
717
 
189
- if (!child->self->set_parent(NULL))
190
- return false;
718
+ if (!self->pchildren) return;
191
719
 
192
- self->pchildren_->erase(it);
193
- return true;
720
+ child_iterator it = std::find(child_begin(), child_end(), child);
721
+ if (it == child_end()) return;
722
+
723
+ if (child->parent() != this)
724
+ invalid_state_error(__FILE__, __LINE__);
725
+
726
+ set_parent(child, NULL);
727
+ self->pchildren->erase(it);
194
728
  }
195
729
 
196
- View*
197
- View::find_child (const char* name, size_t index, bool recursive)
730
+ static void
731
+ find_all_children (
732
+ View::ChildList* result, const View* view, const Selector& selector, bool recursive)
198
733
  {
199
- if (recursive && index > 0) return NULL;
200
-
201
- for (Data::iterator it = self->begin(); it != self->end(); ++it)
734
+ View::const_child_iterator end = view->child_end();
735
+ for (View::const_child_iterator it = view->child_begin(); it != end; ++it)
202
736
  {
203
- if (
204
- strcmp((*it)->name(), name) == 0 &&
205
- index-- == 0)
206
- {
207
- return (View*) it->get();
208
- }
737
+ const View* child = it->get();
738
+ if (!child)
739
+ invalid_state_error(__FILE__, __LINE__);
209
740
 
210
- This* p = NULL;
211
- if (recursive && (p = dynamic_cast<This*>(it->get())))
212
- {
213
- View* child = p->find_child(name, 0, true);
214
- if (child) return child;
215
- }
741
+ if (selector.match(child->selector()))
742
+ result->push_back(*it);
743
+
744
+ if (recursive) find_all_children(result, child, selector, true);
745
+ }
746
+ }
747
+
748
+ void
749
+ View::find_children (
750
+ ChildList* result, const Selector& selector, bool recursive) const
751
+ {
752
+ if (!*this)
753
+ invalid_state_error(__FILE__, __LINE__);
754
+
755
+ result->clear();
756
+ find_all_children(result, this, selector, recursive);
757
+ }
758
+
759
+ static View::ChildList empty_children;
760
+
761
+ View::child_iterator
762
+ View::child_begin ()
763
+ {
764
+ if (!*this)
765
+ invalid_state_error(__FILE__, __LINE__);
766
+
767
+ if (!self->pchildren) return empty_children.begin();
768
+ return self->pchildren->begin();
769
+ }
770
+
771
+ View::const_child_iterator
772
+ View::child_begin () const
773
+ {
774
+ if (!*this)
775
+ invalid_state_error(__FILE__, __LINE__);
776
+
777
+ if (!self->pchildren) return empty_children.begin();
778
+ return self->pchildren->begin();
779
+ }
780
+
781
+ View::child_iterator
782
+ View::child_end ()
783
+ {
784
+ if (!*this)
785
+ invalid_state_error(__FILE__, __LINE__);
786
+
787
+ if (!self->pchildren) return empty_children.end();
788
+ return self->pchildren->end();
789
+ }
790
+
791
+ View::const_child_iterator
792
+ View::child_end () const
793
+ {
794
+ if (!*this)
795
+ invalid_state_error(__FILE__, __LINE__);
796
+
797
+ if (!self->pchildren) return empty_children.end();
798
+ return self->pchildren->end();
799
+ }
800
+
801
+ Style&
802
+ View::style ()
803
+ {
804
+ if (!*this)
805
+ invalid_state_error(__FILE__, __LINE__);
806
+
807
+ return self->style;
808
+ }
809
+
810
+ const Style&
811
+ View::style () const
812
+ {
813
+ return const_cast<View*>(this)->style();
814
+ }
815
+
816
+ void
817
+ View::add_style (const Style& style)
818
+ {
819
+ if (!*this)
820
+ invalid_state_error(__FILE__, __LINE__);
821
+
822
+ self->styles().push_back(style);
823
+ }
824
+
825
+ void
826
+ View::remove_style (const Style& style)
827
+ {
828
+ if (!*this)
829
+ invalid_state_error(__FILE__, __LINE__);
830
+
831
+ if (!self->pstyles) return;
832
+
833
+ style_iterator it = std::find(style_begin(), style_end(), style);
834
+ if (it == style_end()) return;
835
+
836
+ self->styles().erase(it);
837
+ }
838
+
839
+ Style*
840
+ View::get_style (const Selector& selector)
841
+ {
842
+ if (!*this)
843
+ invalid_state_error(__FILE__, __LINE__);
844
+
845
+ style_iterator end = style_end();
846
+ for (style_iterator it = style_begin(); it != end; ++it)
847
+ {
848
+ if (selector == it->selector())
849
+ return &*it;
216
850
  }
217
851
 
218
852
  return NULL;
219
853
  }
220
854
 
221
- const View*
222
- View::find_child (const char* name, size_t index, bool recursive) const
855
+ const Style*
856
+ View::get_style (const Selector& selector) const
223
857
  {
224
- return const_cast<This*>(this)->find_child(name, index, recursive);
858
+ return const_cast<View*>(this)->get_style(selector);
859
+ }
860
+
861
+ static void
862
+ find_all_styles (
863
+ View::StyleList* result, const View* view, const Selector& selector, bool recursive)
864
+ {
865
+ View::const_style_iterator end = view->style_end();
866
+ for (View::const_style_iterator it = view->style_begin(); it != end; ++it)
867
+ {
868
+ if (selector.match(it->selector()))
869
+ result->push_back(*it);
870
+ }
871
+
872
+ if (recursive)
873
+ {
874
+ View::const_child_iterator end = view->child_end();
875
+ for (View::const_child_iterator it = view->child_begin(); it != end; ++it)
876
+ find_all_styles(result, it->get(), selector, true);
877
+ }
878
+ }
879
+
880
+ void
881
+ View::find_styles (StyleList* result, const Selector& selector, bool recursive) const
882
+ {
883
+ if (!*this)
884
+ invalid_state_error(__FILE__, __LINE__);
885
+
886
+ result->clear();
887
+ find_all_styles(result, this, selector, recursive);
888
+ }
889
+
890
+ static View::StyleList empty_styles;
891
+
892
+ View::style_iterator
893
+ View::style_begin ()
894
+ {
895
+ if (!*this)
896
+ invalid_state_error(__FILE__, __LINE__);
897
+
898
+ if (!self->pstyles) return empty_styles.begin();
899
+ return self->pstyles->begin();
900
+ }
901
+
902
+ View::const_style_iterator
903
+ View::style_begin () const
904
+ {
905
+ if (!*this)
906
+ invalid_state_error(__FILE__, __LINE__);
907
+
908
+ if (!self->pstyles) return empty_styles.begin();
909
+ return self->pstyles->begin();
910
+ }
911
+
912
+ View::style_iterator
913
+ View::style_end ()
914
+ {
915
+ if (!*this)
916
+ invalid_state_error(__FILE__, __LINE__);
917
+
918
+ if (!self->pstyles) return empty_styles.end();
919
+ return self->pstyles->end();
920
+ }
921
+
922
+ View::const_style_iterator
923
+ View::style_end () const
924
+ {
925
+ if (!*this)
926
+ invalid_state_error(__FILE__, __LINE__);
927
+
928
+ if (!self->pstyles) return empty_styles.end();
929
+ return self->pstyles->end();
930
+ }
931
+
932
+ void
933
+ View::focus (bool state)
934
+ {
935
+ Window* w = window();
936
+ if (!w) return;
937
+
938
+ if (state)
939
+ set_focus(w, this);
940
+ else if (w->focus() == this)
941
+ set_focus(w, NULL);
942
+ }
943
+
944
+ void
945
+ View::blur ()
946
+ {
947
+ focus(false);
225
948
  }
226
949
 
227
950
  bool
951
+ View::has_focus () const
952
+ {
953
+ const Window* w = window();
954
+ return w && w->focus() == this;
955
+ }
956
+
957
+ void
958
+ View::resize_to_fit ()
959
+ {
960
+ if (!*this)
961
+ invalid_state_error(__FILE__, __LINE__);
962
+
963
+ Point size = content_size();
964
+ if (size.x < 0 && size.y < 0 && size.z <= 0) return;
965
+
966
+ Bounds b = frame();
967
+ if (size.x >= 0) b.width = size.x;
968
+ if (size.y >= 0) b.height = size.y;
969
+ if (size.z >= 0) b.depth = size.z;
970
+ set_frame(b);
971
+ }
972
+
973
+ Point
974
+ View::content_size () const
975
+ {
976
+ if (!*this)
977
+ invalid_state_error(__FILE__, __LINE__);
978
+
979
+ return -1;
980
+ }
981
+
982
+ void
228
983
  View::set_name (const char* name)
229
984
  {
230
- self->name = name ? name : "";
231
- return true;
985
+ if (!*this)
986
+ invalid_state_error(__FILE__, __LINE__);
987
+
988
+ self->selector().set_name(name);
232
989
  }
233
990
 
234
991
  const char*
235
992
  View::name () const
236
993
  {
237
- return self->name.c_str();
994
+ if (!*this)
995
+ invalid_state_error(__FILE__, __LINE__);
996
+
997
+ const Selector* sel = self->pselector.get();
998
+ return sel ? sel->name() : NULL;
238
999
  }
239
1000
 
240
- bool
241
- View::set_bounds (coord x, coord y, coord width, coord height)
1001
+ void
1002
+ View::add_tag (const char* tag)
242
1003
  {
243
- Bounds& b = self->bounds;
244
- b.x = x;
245
- b.y = y;
246
- b.width = width;
247
- b.height = height;
248
- return true;
1004
+ if (!*this)
1005
+ invalid_state_error(__FILE__, __LINE__);
1006
+
1007
+ self->selector().add_tag(tag);
249
1008
  }
250
1009
 
251
- bool
252
- View::set_bounds (const Bounds& bounds)
1010
+ void
1011
+ View::remove_tag (const char* tag)
253
1012
  {
254
- self->bounds = bounds;
255
- return true;
1013
+ if (!*this)
1014
+ invalid_state_error(__FILE__, __LINE__);
1015
+
1016
+ Selector* sel = self->pselector.get();
1017
+ if (!sel) return;
1018
+
1019
+ sel->remove_tag(tag);
1020
+ }
1021
+
1022
+ static Selector::TagSet empty_tags;
1023
+
1024
+ View::tag_iterator
1025
+ View::tag_begin ()
1026
+ {
1027
+ if (!*this)
1028
+ invalid_state_error(__FILE__, __LINE__);
1029
+
1030
+ Selector* sel = self->pselector.get();
1031
+ return sel ? sel->begin() : empty_tags.begin();
1032
+ }
1033
+
1034
+ View::const_tag_iterator
1035
+ View::tag_begin () const
1036
+ {
1037
+ if (!*this)
1038
+ invalid_state_error(__FILE__, __LINE__);
1039
+
1040
+ const Selector* sel = self->pselector.get();
1041
+ return sel ? sel->begin() : empty_tags.begin();
1042
+ }
1043
+
1044
+ View::tag_iterator
1045
+ View::tag_end ()
1046
+ {
1047
+ if (!*this)
1048
+ invalid_state_error(__FILE__, __LINE__);
1049
+
1050
+ Selector* sel = self->pselector.get();
1051
+ return sel ? sel->end() : empty_tags.end();
1052
+ }
1053
+
1054
+ View::const_tag_iterator
1055
+ View::tag_end () const
1056
+ {
1057
+ if (!*this)
1058
+ invalid_state_error(__FILE__, __LINE__);
1059
+
1060
+ const Selector* sel = self->pselector.get();
1061
+ return sel ? sel->end() : empty_tags.end();
1062
+ }
1063
+
1064
+ void
1065
+ View::set_selector (const Selector& selector)
1066
+ {
1067
+ if (!*this)
1068
+ invalid_state_error(__FILE__, __LINE__);
1069
+
1070
+ self->selector() = selector;
1071
+ }
1072
+
1073
+ Selector&
1074
+ View::selector ()
1075
+ {
1076
+ if (!*this)
1077
+ invalid_state_error(__FILE__, __LINE__);
1078
+
1079
+ return self->selector();
1080
+ }
1081
+
1082
+ const Selector&
1083
+ View::selector () const
1084
+ {
1085
+ static const Selector EMPTY;
1086
+
1087
+ if (!*this)
1088
+ invalid_state_error(__FILE__, __LINE__);
1089
+
1090
+ const Selector* sel = self->pselector.get();
1091
+ return sel ? *sel : EMPTY;
1092
+ }
1093
+
1094
+ void
1095
+ View::set_frame (coord x, coord y, coord width, coord height)
1096
+ {
1097
+ set_frame(Bounds(x, y, width, height));
1098
+ }
1099
+
1100
+ void
1101
+ View::set_frame (const Bounds& frame)
1102
+ {
1103
+ if (!*this)
1104
+ invalid_state_error(__FILE__, __LINE__);
1105
+
1106
+ const Bounds& current = self->frame;
1107
+ if (frame == current) return;
1108
+
1109
+ self->frame = frame;
1110
+
1111
+ FrameEvent event(
1112
+ self->frame,
1113
+ frame.x - current.x, frame.y - current.y,
1114
+ frame.w - current.w, frame.h - current.h);
1115
+ if (event.is_move()) on_move(&event);
1116
+ if (event.is_resize()) on_resize(&event);
1117
+
1118
+ reflow_children(this, &event);
1119
+ redraw();
256
1120
  }
257
1121
 
258
1122
  const Bounds&
259
- View::bounds () const
1123
+ View::frame () const
260
1124
  {
261
- return self->bounds;
1125
+ if (!*this)
1126
+ invalid_state_error(__FILE__, __LINE__);
1127
+
1128
+ return self->frame;
262
1129
  }
263
1130
 
264
- bool
265
- View::hidden () const
1131
+ static const Point ZERO_SCROLL;
1132
+
1133
+ void
1134
+ View::scroll_to (coord x, coord y, coord z)
1135
+ {
1136
+ Point old = self->scroll();
1137
+ self->scroll().reset(x, y, z);
1138
+ ScrollEvent e(x, y, z, x - old.x, y - old.y, z - old.z);
1139
+ on_scroll(&e);
1140
+ redraw();
1141
+ }
1142
+
1143
+ void
1144
+ View::scroll_to (const Point& scroll)
1145
+ {
1146
+ scroll_to(scroll.x, scroll.y, scroll.z);
1147
+ }
1148
+
1149
+ void
1150
+ View::scroll_by (coord x, coord y, coord z)
1151
+ {
1152
+ const Point& p = scroll();
1153
+ scroll_to(p.x + x, p.y + y, p.z + z);
1154
+ }
1155
+
1156
+ void
1157
+ View::scroll_by (const Point& dscroll)
1158
+ {
1159
+ scroll_by(dscroll.x, dscroll.y, dscroll.z);
1160
+ }
1161
+
1162
+ const Point&
1163
+ View::scroll () const
1164
+ {
1165
+ if (self->pscroll)
1166
+ return self->scroll();
1167
+ else
1168
+ return ZERO_SCROLL;
1169
+ }
1170
+
1171
+ void
1172
+ View::set_capture (uint types)
1173
+ {
1174
+ if (types == self->capture) return;
1175
+
1176
+ uint old = self->capture;
1177
+ self->capture = types;
1178
+
1179
+ bool registered = old != CAPTURE_NONE;
1180
+ bool capture = types != CAPTURE_NONE;
1181
+
1182
+ if (capture && !registered)
1183
+ register_capture(this);
1184
+ else if (!capture && registered)
1185
+ unregister_capture(this);
1186
+
1187
+ CaptureEvent e(~old & types, old & ~types);
1188
+ on_capture(&e);
1189
+ }
1190
+
1191
+ uint
1192
+ View::capture () const
266
1193
  {
267
- return self->hidecount > 0;
1194
+ return self->capture;
268
1195
  }
269
1196
 
270
1197
  View*
271
1198
  View::parent ()
272
1199
  {
1200
+ if (!*this)
1201
+ invalid_state_error(__FILE__, __LINE__);
1202
+
273
1203
  return self->parent;
274
1204
  }
275
1205
 
@@ -282,6 +1212,9 @@ namespace Reflex
282
1212
  Window*
283
1213
  View::window ()
284
1214
  {
1215
+ if (!*this)
1216
+ invalid_state_error(__FILE__, __LINE__);
1217
+
285
1218
  return self->window;
286
1219
  }
287
1220
 
@@ -291,24 +1224,190 @@ namespace Reflex
291
1224
  return const_cast<View*>(this)->window();
292
1225
  }
293
1226
 
1227
+ Rays::Point
1228
+ View::from_parent (const Rays::Point& point) const
1229
+ {
1230
+ not_implemented_error(__FILE__, __LINE__);
1231
+ return 0;
1232
+ }
1233
+
1234
+ Rays::Point
1235
+ View::to_parent (const Rays::Point& point) const
1236
+ {
1237
+ not_implemented_error(__FILE__, __LINE__);
1238
+ return 0;
1239
+ }
1240
+
1241
+ Point
1242
+ View::from_window (const Point& point) const
1243
+ {
1244
+ Point p = point;
1245
+ for (const View* v = parent(); v; v = v->parent())
1246
+ p -= v->frame().position();
1247
+ return p;
1248
+ }
1249
+
1250
+ Rays::Point
1251
+ View::to_window (const Rays::Point& point) const
1252
+ {
1253
+ not_implemented_error(__FILE__, __LINE__);
1254
+ return 0;
1255
+ }
1256
+
1257
+ Rays::Point
1258
+ View::from_screen (const Rays::Point& point) const
1259
+ {
1260
+ not_implemented_error(__FILE__, __LINE__);
1261
+ return 0;
1262
+ }
1263
+
1264
+ Rays::Point
1265
+ View::to_screen (const Rays::Point& point) const
1266
+ {
1267
+ not_implemented_error(__FILE__, __LINE__);
1268
+ return 0;
1269
+ }
1270
+
1271
+ void
1272
+ View::on_attach (Event* e)
1273
+ {
1274
+ resize_to_fit();
1275
+ }
1276
+
1277
+ void
1278
+ View::on_detach (Event* e)
1279
+ {
1280
+ if (!e)
1281
+ argument_error(__FILE__, __LINE__);
1282
+ }
1283
+
1284
+ void
1285
+ View::on_update (UpdateEvent* e)
1286
+ {
1287
+ if (!e)
1288
+ argument_error(__FILE__, __LINE__);
1289
+ }
1290
+
1291
+ void
1292
+ View::on_draw (DrawEvent* e)
1293
+ {
1294
+ if (!e)
1295
+ argument_error(__FILE__, __LINE__);
1296
+ }
1297
+
1298
+ void
1299
+ View::on_move (FrameEvent* e)
1300
+ {
1301
+ if (!e)
1302
+ argument_error(__FILE__, __LINE__);
1303
+ }
1304
+
1305
+ void
1306
+ View::on_resize (FrameEvent* e)
1307
+ {
1308
+ if (!e)
1309
+ argument_error(__FILE__, __LINE__);
1310
+ }
1311
+
1312
+ void
1313
+ View::on_scroll (ScrollEvent* e)
1314
+ {
1315
+ if (!e)
1316
+ argument_error(__FILE__, __LINE__);
1317
+ }
1318
+
1319
+ void
1320
+ View::on_focus (FocusEvent* e)
1321
+ {
1322
+ if (!e)
1323
+ argument_error(__FILE__, __LINE__);
1324
+ }
1325
+
294
1326
  void
295
- View::update (float dt)
1327
+ View::on_blur (FocusEvent* e)
296
1328
  {
1329
+ if (!e)
1330
+ argument_error(__FILE__, __LINE__);
297
1331
  }
298
1332
 
299
1333
  void
300
- View::draw (Painter* p, const Bounds& b)
1334
+ View::on_key (KeyEvent* e)
301
1335
  {
1336
+ if (!e)
1337
+ argument_error(__FILE__, __LINE__);
1338
+
1339
+ switch (e->type)
1340
+ {
1341
+ case KeyEvent::DOWN: on_key_down(e); break;
1342
+ case KeyEvent::UP: on_key_up(e); break;
1343
+ case KeyEvent::NONE: break;
1344
+ }
1345
+ }
1346
+
1347
+ void
1348
+ View::on_key_down (KeyEvent* e)
1349
+ {
1350
+ if (!e)
1351
+ argument_error(__FILE__, __LINE__);
1352
+ }
1353
+
1354
+ void
1355
+ View::on_key_up (KeyEvent* e)
1356
+ {
1357
+ if (!e)
1358
+ argument_error(__FILE__, __LINE__);
302
1359
  }
303
1360
 
304
1361
  void
305
- View::moved (coord dx, coord dy)
1362
+ View::on_pointer (PointerEvent* e)
306
1363
  {
1364
+ if (!e)
1365
+ argument_error(__FILE__, __LINE__);
1366
+
1367
+ switch (e->type)
1368
+ {
1369
+ case PointerEvent::DOWN: on_pointer_down(e); break;
1370
+ case PointerEvent::UP: on_pointer_up(e); break;
1371
+ case PointerEvent::MOVE: on_pointer_move(e); break;
1372
+ case PointerEvent::NONE: break;
1373
+ }
1374
+ }
1375
+
1376
+ void
1377
+ View::on_pointer_down (PointerEvent* e)
1378
+ {
1379
+ if (!e)
1380
+ argument_error(__FILE__, __LINE__);
1381
+ }
1382
+
1383
+ void
1384
+ View::on_pointer_up (PointerEvent* e)
1385
+ {
1386
+ if (!e)
1387
+ argument_error(__FILE__, __LINE__);
1388
+ }
1389
+
1390
+ void
1391
+ View::on_pointer_move (PointerEvent* e)
1392
+ {
1393
+ if (!e)
1394
+ argument_error(__FILE__, __LINE__);
1395
+ }
1396
+
1397
+ void
1398
+ View::on_wheel (WheelEvent* e)
1399
+ {
1400
+ if (!e)
1401
+ argument_error(__FILE__, __LINE__);
1402
+
1403
+ //scroll_by(e->dx, e->dy, e->dz);
307
1404
  }
308
1405
 
309
1406
  void
310
- View::resized (coord dwidth, coord dheight)
1407
+ View::on_capture (CaptureEvent* e)
311
1408
  {
1409
+ if (!e)
1410
+ argument_error(__FILE__, __LINE__);
312
1411
  }
313
1412
 
314
1413
  View::operator bool () const