diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/evas/src/lib/canvas/evas_object_line.c | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2 SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz |
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/evas/src/lib/canvas/evas_object_line.c')
-rw-r--r-- | libraries/evas/src/lib/canvas/evas_object_line.c | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/canvas/evas_object_line.c b/libraries/evas/src/lib/canvas/evas_object_line.c new file mode 100644 index 0000000..b09a6e2 --- /dev/null +++ b/libraries/evas/src/lib/canvas/evas_object_line.c | |||
@@ -0,0 +1,461 @@ | |||
1 | #include "evas_common.h" | ||
2 | #include "evas_private.h" | ||
3 | |||
4 | /* private magic number for line objects */ | ||
5 | static const char o_type[] = "line"; | ||
6 | |||
7 | /* private struct for line object internal data */ | ||
8 | typedef struct _Evas_Object_Line Evas_Object_Line; | ||
9 | |||
10 | struct _Evas_Object_Line | ||
11 | { | ||
12 | DATA32 magic; | ||
13 | struct { | ||
14 | struct { | ||
15 | int x1, y1, x2, y2; | ||
16 | struct { | ||
17 | Evas_Coord w, h; | ||
18 | } object; | ||
19 | } cache; | ||
20 | Evas_Coord x1, y1, x2, y2; | ||
21 | } cur, prev; | ||
22 | |||
23 | void *engine_data; | ||
24 | |||
25 | char changed : 1; | ||
26 | }; | ||
27 | |||
28 | /* private methods for line objects */ | ||
29 | static void evas_object_line_init(Evas_Object *obj); | ||
30 | static void *evas_object_line_new(void); | ||
31 | static void evas_object_line_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y); | ||
32 | static void evas_object_line_free(Evas_Object *obj); | ||
33 | static void evas_object_line_render_pre(Evas_Object *obj); | ||
34 | static void evas_object_line_render_post(Evas_Object *obj); | ||
35 | |||
36 | static unsigned int evas_object_line_id_get(Evas_Object *obj); | ||
37 | static unsigned int evas_object_line_visual_id_get(Evas_Object *obj); | ||
38 | static void *evas_object_line_engine_data_get(Evas_Object *obj); | ||
39 | |||
40 | static int evas_object_line_is_opaque(Evas_Object *obj); | ||
41 | static int evas_object_line_was_opaque(Evas_Object *obj); | ||
42 | static int evas_object_line_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y); | ||
43 | static int evas_object_line_was_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y); | ||
44 | static void evas_object_line_coords_recalc(Evas_Object *obj); | ||
45 | |||
46 | static const Evas_Object_Func object_func = | ||
47 | { | ||
48 | /* methods (compulsory) */ | ||
49 | evas_object_line_free, | ||
50 | evas_object_line_render, | ||
51 | evas_object_line_render_pre, | ||
52 | evas_object_line_render_post, | ||
53 | evas_object_line_id_get, | ||
54 | evas_object_line_visual_id_get, | ||
55 | evas_object_line_engine_data_get, | ||
56 | /* these are optional. NULL = nothing */ | ||
57 | NULL, | ||
58 | NULL, | ||
59 | NULL, | ||
60 | NULL, | ||
61 | evas_object_line_is_opaque, | ||
62 | evas_object_line_was_opaque, | ||
63 | evas_object_line_is_inside, | ||
64 | evas_object_line_was_inside, | ||
65 | evas_object_line_coords_recalc, | ||
66 | NULL, | ||
67 | NULL, | ||
68 | NULL, | ||
69 | NULL | ||
70 | }; | ||
71 | |||
72 | /* the actual api call to add a rect */ | ||
73 | /* it has no other api calls as all properties are standard */ | ||
74 | |||
75 | EVAS_MEMPOOL(_mp_obj); | ||
76 | |||
77 | EAPI Evas_Object * | ||
78 | evas_object_line_add(Evas *e) | ||
79 | { | ||
80 | Evas_Object *obj; | ||
81 | |||
82 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
83 | return NULL; | ||
84 | MAGIC_CHECK_END(); | ||
85 | obj = evas_object_new(e); | ||
86 | evas_object_line_init(obj); | ||
87 | evas_object_inject(obj, e); | ||
88 | return obj; | ||
89 | } | ||
90 | |||
91 | EAPI void | ||
92 | evas_object_line_xy_set(Evas_Object *obj, Evas_Coord x1, Evas_Coord y1, Evas_Coord x2, Evas_Coord y2) | ||
93 | { | ||
94 | Evas_Object_Line *o; | ||
95 | Evas_Coord min_x, max_x, min_y, max_y; | ||
96 | int is, was = 0; | ||
97 | |||
98 | MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); | ||
99 | return; | ||
100 | MAGIC_CHECK_END(); | ||
101 | o = (Evas_Object_Line *)(obj->object_data); | ||
102 | MAGIC_CHECK(o, Evas_Object_Line, MAGIC_OBJ_LINE); | ||
103 | return; | ||
104 | MAGIC_CHECK_END(); | ||
105 | if ((x1 == o->cur.x1) && (y1 == o->cur.y1) && | ||
106 | (x2 == o->cur.x2) && (y2 == o->cur.y2)) return; | ||
107 | if (obj->layer->evas->events_frozen <= 0) | ||
108 | { | ||
109 | if (!evas_event_passes_through(obj) && | ||
110 | !evas_event_freezes_through(obj)) | ||
111 | was = evas_object_is_in_output_rect(obj, | ||
112 | obj->layer->evas->pointer.x, | ||
113 | obj->layer->evas->pointer.y, | ||
114 | 1, 1); | ||
115 | } | ||
116 | if (x1 < x2) | ||
117 | { | ||
118 | min_x = x1; | ||
119 | max_x = x2; | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | min_x = x2; | ||
124 | max_x = x1; | ||
125 | } | ||
126 | if (y1 < y2) | ||
127 | { | ||
128 | min_y = y1; | ||
129 | max_y = y2; | ||
130 | } | ||
131 | else | ||
132 | { | ||
133 | min_y = y2; | ||
134 | max_y = y1; | ||
135 | } | ||
136 | obj->cur.geometry.x = min_x; | ||
137 | obj->cur.geometry.y = min_y; | ||
138 | obj->cur.geometry.w = max_x - min_x + 2; | ||
139 | obj->cur.geometry.h = max_y - min_y + 2; | ||
140 | //// obj->cur.cache.geometry.validity = 0; | ||
141 | o->cur.x1 = x1 - min_x; | ||
142 | o->cur.y1 = y1 - min_y; | ||
143 | o->cur.x2 = x2 - min_x; | ||
144 | o->cur.y2 = y2 - min_y; | ||
145 | o->changed = 1; | ||
146 | evas_object_change(obj); | ||
147 | evas_object_coords_recalc(obj); | ||
148 | evas_object_clip_dirty(obj); | ||
149 | if (obj->layer->evas->events_frozen <= 0) | ||
150 | { | ||
151 | is = evas_object_is_in_output_rect(obj, | ||
152 | obj->layer->evas->pointer.x, | ||
153 | obj->layer->evas->pointer.y, 1, 1); | ||
154 | if (!evas_event_passes_through(obj) && | ||
155 | !evas_event_freezes_through(obj)) | ||
156 | { | ||
157 | if ((is ^ was) && obj->cur.visible) | ||
158 | evas_event_feed_mouse_move(obj->layer->evas, | ||
159 | obj->layer->evas->pointer.x, | ||
160 | obj->layer->evas->pointer.y, | ||
161 | obj->layer->evas->last_timestamp, | ||
162 | NULL); | ||
163 | } | ||
164 | } | ||
165 | evas_object_inform_call_move(obj); | ||
166 | evas_object_inform_call_resize(obj); | ||
167 | } | ||
168 | |||
169 | EAPI void | ||
170 | evas_object_line_xy_get(const Evas_Object *obj, Evas_Coord *x1, Evas_Coord *y1, Evas_Coord *x2, Evas_Coord *y2) | ||
171 | { | ||
172 | Evas_Object_Line *o; | ||
173 | |||
174 | MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); | ||
175 | if (x1) *x1 = 0; | ||
176 | if (y1) *y1 = 0; | ||
177 | if (x2) *x2 = 0; | ||
178 | if (y2) *y2 = 0; | ||
179 | return; | ||
180 | MAGIC_CHECK_END(); | ||
181 | o = (Evas_Object_Line *)(obj->object_data); | ||
182 | MAGIC_CHECK(o, Evas_Object_Line, MAGIC_OBJ_LINE); | ||
183 | if (x1) *x1 = 0; | ||
184 | if (y1) *y1 = 0; | ||
185 | if (x2) *x2 = 0; | ||
186 | if (y2) *y2 = 0; | ||
187 | return; | ||
188 | MAGIC_CHECK_END(); | ||
189 | if (x1) *x1 = obj->cur.geometry.x + o->cur.x1; | ||
190 | if (y1) *y1 = obj->cur.geometry.y + o->cur.y1; | ||
191 | if (x2) *x2 = obj->cur.geometry.x + o->cur.x2; | ||
192 | if (y2) *y2 = obj->cur.geometry.y + o->cur.y2; | ||
193 | } | ||
194 | |||
195 | /* all nice and private */ | ||
196 | static void | ||
197 | evas_object_line_init(Evas_Object *obj) | ||
198 | { | ||
199 | /* alloc image ob, setup methods and default values */ | ||
200 | obj->object_data = evas_object_line_new(); | ||
201 | /* set up default settings for this kind of object */ | ||
202 | obj->cur.color.r = 255; | ||
203 | obj->cur.color.g = 255; | ||
204 | obj->cur.color.b = 255; | ||
205 | obj->cur.color.a = 255; | ||
206 | obj->cur.geometry.x = 0; | ||
207 | obj->cur.geometry.y = 0; | ||
208 | obj->cur.geometry.w = 0; | ||
209 | obj->cur.geometry.h = 0; | ||
210 | obj->cur.layer = 0; | ||
211 | obj->cur.anti_alias = 1; | ||
212 | obj->cur.render_op = EVAS_RENDER_BLEND; | ||
213 | /* set up object-specific settings */ | ||
214 | obj->prev = obj->cur; | ||
215 | /* set up methods (compulsory) */ | ||
216 | obj->func = &object_func; | ||
217 | obj->type = o_type; | ||
218 | } | ||
219 | |||
220 | static void * | ||
221 | evas_object_line_new(void) | ||
222 | { | ||
223 | Evas_Object_Line *o; | ||
224 | |||
225 | /* alloc obj private data */ | ||
226 | EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_line", Evas_Object_Line, 16, NULL); | ||
227 | o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Line); | ||
228 | if (!o) return NULL; | ||
229 | EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Line); | ||
230 | o->magic = MAGIC_OBJ_LINE; | ||
231 | o->cur.x1 = 0; | ||
232 | o->cur.y1 = 0; | ||
233 | o->cur.x2 = 31; | ||
234 | o->cur.y2 = 31; | ||
235 | o->prev = o->cur; | ||
236 | return o; | ||
237 | } | ||
238 | |||
239 | static void | ||
240 | evas_object_line_free(Evas_Object *obj) | ||
241 | { | ||
242 | Evas_Object_Line *o; | ||
243 | |||
244 | /* frees private object data. very simple here */ | ||
245 | o = (Evas_Object_Line *)(obj->object_data); | ||
246 | MAGIC_CHECK(o, Evas_Object_Line, MAGIC_OBJ_LINE); | ||
247 | return; | ||
248 | MAGIC_CHECK_END(); | ||
249 | /* free obj */ | ||
250 | o->magic = 0; | ||
251 | EVAS_MEMPOOL_FREE(_mp_obj, o); | ||
252 | } | ||
253 | |||
254 | static void | ||
255 | evas_object_line_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y) | ||
256 | { | ||
257 | Evas_Object_Line *o; | ||
258 | |||
259 | /* render object to surface with context, and offxet by x,y */ | ||
260 | o = (Evas_Object_Line *)(obj->object_data); | ||
261 | obj->layer->evas->engine.func->context_color_set(output, | ||
262 | context, | ||
263 | obj->cur.cache.clip.r, | ||
264 | obj->cur.cache.clip.g, | ||
265 | obj->cur.cache.clip.b, | ||
266 | obj->cur.cache.clip.a); | ||
267 | obj->layer->evas->engine.func->context_multiplier_unset(output, | ||
268 | context); | ||
269 | obj->layer->evas->engine.func->context_anti_alias_set(output, context, | ||
270 | obj->cur.anti_alias); | ||
271 | obj->layer->evas->engine.func->context_render_op_set(output, context, | ||
272 | obj->cur.render_op); | ||
273 | obj->layer->evas->engine.func->line_draw(output, | ||
274 | context, | ||
275 | surface, | ||
276 | o->cur.cache.x1 + x, | ||
277 | o->cur.cache.y1 + y, | ||
278 | o->cur.cache.x2 + x, | ||
279 | o->cur.cache.y2 + y); | ||
280 | } | ||
281 | |||
282 | static void | ||
283 | evas_object_line_render_pre(Evas_Object *obj) | ||
284 | { | ||
285 | Evas_Object_Line *o; | ||
286 | int is_v, was_v; | ||
287 | |||
288 | /* dont pre-render the obj twice! */ | ||
289 | if (obj->pre_render_done) return; | ||
290 | obj->pre_render_done = 1; | ||
291 | /* pre-render phase. this does anything an object needs to do just before */ | ||
292 | /* rendering. this could mean loading the image data, retrieving it from */ | ||
293 | /* elsewhere, decoding video etc. */ | ||
294 | /* then when this is done the object needs to figure if it changed and */ | ||
295 | /* if so what and where and add the appropriate redraw lines */ | ||
296 | o = (Evas_Object_Line *)(obj->object_data); | ||
297 | /* if someone is clipping this obj - go calculate the clipper */ | ||
298 | if (obj->cur.clipper) | ||
299 | { | ||
300 | if (obj->cur.cache.clip.dirty) | ||
301 | evas_object_clip_recalc(obj->cur.clipper); | ||
302 | obj->cur.clipper->func->render_pre(obj->cur.clipper); | ||
303 | } | ||
304 | /* now figure what changed and add draw rects */ | ||
305 | /* if it just became visible or invisible */ | ||
306 | is_v = evas_object_is_visible(obj); | ||
307 | was_v = evas_object_was_visible(obj); | ||
308 | if (is_v != was_v) | ||
309 | { | ||
310 | evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, obj, is_v, was_v); | ||
311 | goto done; | ||
312 | } | ||
313 | if ((obj->cur.map != obj->prev.map) || | ||
314 | (obj->cur.usemap != obj->prev.usemap)) | ||
315 | { | ||
316 | evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj); | ||
317 | goto done; | ||
318 | } | ||
319 | /* it's not visible - we accounted for it appearing or not so just abort */ | ||
320 | if (!is_v) goto done; | ||
321 | /* clipper changed this is in addition to anything else for obj */ | ||
322 | evas_object_render_pre_clipper_change(&obj->layer->evas->clip_changes, obj); | ||
323 | /* if we restacked (layer or just within a layer) */ | ||
324 | if (obj->restack) | ||
325 | { | ||
326 | evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj); | ||
327 | goto done; | ||
328 | } | ||
329 | /* if it changed anti_alias */ | ||
330 | if (obj->cur.anti_alias != obj->prev.anti_alias) | ||
331 | { | ||
332 | evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj); | ||
333 | goto done; | ||
334 | } | ||
335 | /* if it changed render op */ | ||
336 | if (obj->cur.render_op != obj->prev.render_op) | ||
337 | { | ||
338 | evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj); | ||
339 | goto done; | ||
340 | } | ||
341 | /* if it changed color */ | ||
342 | if ((obj->cur.color.r != obj->prev.color.r) || | ||
343 | (obj->cur.color.g != obj->prev.color.g) || | ||
344 | (obj->cur.color.b != obj->prev.color.b) || | ||
345 | (obj->cur.color.a != obj->prev.color.a)) | ||
346 | { | ||
347 | evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj); | ||
348 | goto done; | ||
349 | } | ||
350 | /* if it changed geometry - and obviously not visibility or color */ | ||
351 | /* calculate differences since we have a constant color fill */ | ||
352 | /* we really only need to update the differences */ | ||
353 | if ((obj->cur.geometry.x != obj->prev.geometry.x) || | ||
354 | (obj->cur.geometry.y != obj->prev.geometry.y) || | ||
355 | (obj->cur.geometry.w != obj->prev.geometry.w) || | ||
356 | (obj->cur.geometry.h != obj->prev.geometry.h) || | ||
357 | ((o->changed) && | ||
358 | ((o->cur.x1 != o->prev.x1) || | ||
359 | (o->cur.y1 != o->prev.y1) || | ||
360 | (o->cur.x2 != o->prev.x2) || | ||
361 | (o->cur.y2 != o->prev.y2))) | ||
362 | ) | ||
363 | { | ||
364 | evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj); | ||
365 | goto done; | ||
366 | } | ||
367 | done: | ||
368 | evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, obj, is_v, was_v); | ||
369 | } | ||
370 | |||
371 | static void | ||
372 | evas_object_line_render_post(Evas_Object *obj) | ||
373 | { | ||
374 | Evas_Object_Line *o; | ||
375 | |||
376 | /* this moves the current data to the previous state parts of the object */ | ||
377 | /* in whatever way is safest for the object. also if we don't need object */ | ||
378 | /* data anymore we can free it if the object deems this is a good idea */ | ||
379 | o = (Evas_Object_Line *)(obj->object_data); | ||
380 | /* remove those pesky changes */ | ||
381 | evas_object_clip_changes_clean(obj); | ||
382 | /* move cur to prev safely for object data */ | ||
383 | obj->prev = obj->cur; | ||
384 | o->prev = o->cur; | ||
385 | o->changed = 0; | ||
386 | } | ||
387 | |||
388 | static unsigned int evas_object_line_id_get(Evas_Object *obj) | ||
389 | { | ||
390 | Evas_Object_Line *o; | ||
391 | |||
392 | o = (Evas_Object_Line *)(obj->object_data); | ||
393 | if (!o) return 0; | ||
394 | return MAGIC_OBJ_LINE; | ||
395 | } | ||
396 | |||
397 | static unsigned int evas_object_line_visual_id_get(Evas_Object *obj) | ||
398 | { | ||
399 | Evas_Object_Line *o; | ||
400 | |||
401 | o = (Evas_Object_Line *)(obj->object_data); | ||
402 | if (!o) return 0; | ||
403 | return MAGIC_OBJ_SHAPE; | ||
404 | } | ||
405 | |||
406 | static void *evas_object_line_engine_data_get(Evas_Object *obj) | ||
407 | { | ||
408 | Evas_Object_Line *o; | ||
409 | |||
410 | o = (Evas_Object_Line *)(obj->object_data); | ||
411 | if (!o) return NULL; | ||
412 | return o->engine_data; | ||
413 | } | ||
414 | |||
415 | static int | ||
416 | evas_object_line_is_opaque(Evas_Object *obj __UNUSED__) | ||
417 | { | ||
418 | /* this returns 1 if the internal object data implies that the object is */ | ||
419 | /* currently fully opaque over the entire line it occupies */ | ||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int | ||
424 | evas_object_line_was_opaque(Evas_Object *obj __UNUSED__) | ||
425 | { | ||
426 | /* this returns 1 if the internal object data implies that the object was */ | ||
427 | /* previously fully opaque over the entire line it occupies */ | ||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | static int | ||
432 | evas_object_line_is_inside(Evas_Object *obj __UNUSED__, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__) | ||
433 | { | ||
434 | /* this returns 1 if the canvas co-ordinates are inside the object based */ | ||
435 | /* on object private data. not much use for rects, but for polys, images */ | ||
436 | /* and other complex objects it might be */ | ||
437 | return 1; | ||
438 | } | ||
439 | |||
440 | static int | ||
441 | evas_object_line_was_inside(Evas_Object *obj __UNUSED__, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__) | ||
442 | { | ||
443 | /* this returns 1 if the canvas co-ordinates were inside the object based */ | ||
444 | /* on object private data. not much use for rects, but for polys, images */ | ||
445 | /* and other complex objects it might be */ | ||
446 | return 1; | ||
447 | } | ||
448 | |||
449 | static void | ||
450 | evas_object_line_coords_recalc(Evas_Object *obj) | ||
451 | { | ||
452 | Evas_Object_Line *o; | ||
453 | |||
454 | o = (Evas_Object_Line *)(obj->object_data); | ||
455 | o->cur.cache.x1 = obj->cur.geometry.x + o->cur.x1; | ||
456 | o->cur.cache.y1 = obj->cur.geometry.y + o->cur.y1; | ||
457 | o->cur.cache.x2 = obj->cur.geometry.x + o->cur.x2; | ||
458 | o->cur.cache.y2 = obj->cur.geometry.y + o->cur.y2; | ||
459 | o->cur.cache.object.w = obj->cur.geometry.w; | ||
460 | o->cur.cache.object.h = obj->cur.geometry.h; | ||
461 | } | ||