1 #include "evas_common.h"
2 #include "evas_private.h"
4 /* private magic number for line objects */
5 static const char o_type[] = "line";
7 /* private struct for line object internal data */
8 typedef struct _Evas_Object_Line Evas_Object_Line;
10 struct _Evas_Object_Line
20 Evas_Coord x1, y1, x2, y2;
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);
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);
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);
46 static const Evas_Object_Func object_func =
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 */
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,
72 /* the actual api call to add a rect */
73 /* it has no other api calls as all properties are standard */
77 * @addtogroup Evas_Line_Group
81 EVAS_MEMPOOL(_mp_obj);
84 * Adds a new evas line object to the given evas.
85 * @param e The given evas.
86 * @return The new evas line object.
89 evas_object_line_add(Evas *e)
93 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
96 obj = evas_object_new(e);
97 evas_object_line_init(obj);
98 evas_object_inject(obj, e);
103 * Sets the coordinates of the end points of the given evas line object.
104 * @param obj The given evas line object.
105 * @param x1 The X coordinate of the first point.
106 * @param y1 The Y coordinate of the first point.
107 * @param x2 The X coordinate of the second point.
108 * @param y2 The Y coordinate of the second point.
111 evas_object_line_xy_set(Evas_Object *obj, Evas_Coord x1, Evas_Coord y1, Evas_Coord x2, Evas_Coord y2)
114 Evas_Coord min_x, max_x, min_y, max_y;
117 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
120 o = (Evas_Object_Line *)(obj->object_data);
121 MAGIC_CHECK(o, Evas_Object_Line, MAGIC_OBJ_LINE);
124 if ((x1 == o->cur.x1) && (y1 == o->cur.y1) &&
125 (x2 == o->cur.x2) && (y2 == o->cur.y2)) return;
126 if (obj->layer->evas->events_frozen <= 0)
128 if (!evas_event_passes_through(obj))
129 was = evas_object_is_in_output_rect(obj,
130 obj->layer->evas->pointer.x,
131 obj->layer->evas->pointer.y, 1, 1);
153 obj->cur.geometry.x = min_x;
154 obj->cur.geometry.y = min_y;
155 obj->cur.geometry.w = max_x - min_x + 2;
156 obj->cur.geometry.h = max_y - min_y + 2;
157 //// obj->cur.cache.geometry.validity = 0;
158 o->cur.x1 = x1 - min_x;
159 o->cur.y1 = y1 - min_y;
160 o->cur.x2 = x2 - min_x;
161 o->cur.y2 = y2 - min_y;
163 evas_object_change(obj);
164 evas_object_coords_recalc(obj);
165 evas_object_clip_dirty(obj);
166 if (obj->layer->evas->events_frozen <= 0)
168 is = evas_object_is_in_output_rect(obj,
169 obj->layer->evas->pointer.x,
170 obj->layer->evas->pointer.y, 1, 1);
171 if (!evas_event_passes_through(obj))
173 if ((is ^ was) && obj->cur.visible)
174 evas_event_feed_mouse_move(obj->layer->evas,
175 obj->layer->evas->pointer.x,
176 obj->layer->evas->pointer.y,
177 obj->layer->evas->last_timestamp,
181 evas_object_inform_call_move(obj);
182 evas_object_inform_call_resize(obj);
186 * Retrieves the coordinates of the end points of the given evas line object.
187 * @param obj The given line object.
188 * @param x1 Pointer to an integer in which to store the X coordinate of the
190 * @param y1 Pointer to an integer in which to store the Y coordinate of the
192 * @param x2 Pointer to an integer in which to store the X coordinate of the
194 * @param y2 Pointer to an integer in which to store the Y coordinate of the
198 evas_object_line_xy_get(const Evas_Object *obj, Evas_Coord *x1, Evas_Coord *y1, Evas_Coord *x2, Evas_Coord *y2)
202 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
209 o = (Evas_Object_Line *)(obj->object_data);
210 MAGIC_CHECK(o, Evas_Object_Line, MAGIC_OBJ_LINE);
217 if (x1) *x1 = obj->cur.geometry.x + o->cur.x1;
218 if (y1) *y1 = obj->cur.geometry.y + o->cur.y1;
219 if (x2) *x2 = obj->cur.geometry.x + o->cur.x2;
220 if (y2) *y2 = obj->cur.geometry.y + o->cur.y2;
227 /* all nice and private */
229 evas_object_line_init(Evas_Object *obj)
231 /* alloc image ob, setup methods and default values */
232 obj->object_data = evas_object_line_new();
233 /* set up default settings for this kind of object */
234 obj->cur.color.r = 255;
235 obj->cur.color.g = 255;
236 obj->cur.color.b = 255;
237 obj->cur.color.a = 255;
238 obj->cur.geometry.x = 0;
239 obj->cur.geometry.y = 0;
240 obj->cur.geometry.w = 0;
241 obj->cur.geometry.h = 0;
243 obj->cur.anti_alias = 1;
244 obj->cur.render_op = EVAS_RENDER_BLEND;
245 /* set up object-specific settings */
246 obj->prev = obj->cur;
247 /* set up methods (compulsory) */
248 obj->func = &object_func;
253 evas_object_line_new(void)
257 /* alloc obj private data */
258 EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_line", Evas_Object_Line, 16, NULL);
259 o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Line);
261 EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Line);
262 o->magic = MAGIC_OBJ_LINE;
272 evas_object_line_free(Evas_Object *obj)
276 /* frees private object data. very simple here */
277 o = (Evas_Object_Line *)(obj->object_data);
278 MAGIC_CHECK(o, Evas_Object_Line, MAGIC_OBJ_LINE);
283 EVAS_MEMPOOL_FREE(_mp_obj,o);
287 evas_object_line_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
291 /* render object to surface with context, and offxet by x,y */
292 o = (Evas_Object_Line *)(obj->object_data);
293 obj->layer->evas->engine.func->context_color_set(output,
295 obj->cur.cache.clip.r,
296 obj->cur.cache.clip.g,
297 obj->cur.cache.clip.b,
298 obj->cur.cache.clip.a);
299 obj->layer->evas->engine.func->context_multiplier_unset(output,
301 obj->layer->evas->engine.func->context_anti_alias_set(output, context,
302 obj->cur.anti_alias);
303 obj->layer->evas->engine.func->context_render_op_set(output, context,
305 obj->layer->evas->engine.func->line_draw(output,
311 o->cur.cache.y2 + y);
315 evas_object_line_render_pre(Evas_Object *obj)
320 /* dont pre-render the obj twice! */
321 if (obj->pre_render_done) return;
322 obj->pre_render_done = 1;
323 /* pre-render phase. this does anything an object needs to do just before */
324 /* rendering. this could mean loading the image data, retrieving it from */
325 /* elsewhere, decoding video etc. */
326 /* then when this is done the object needs to figure if it changed and */
327 /* if so what and where and add the appropriate redraw lines */
328 o = (Evas_Object_Line *)(obj->object_data);
329 /* if someone is clipping this obj - go calculate the clipper */
330 if (obj->cur.clipper)
332 if (obj->cur.cache.clip.dirty)
333 evas_object_clip_recalc(obj->cur.clipper);
334 obj->cur.clipper->func->render_pre(obj->cur.clipper);
336 /* now figure what changed and add draw rects */
337 /* if it just became visible or invisible */
338 is_v = evas_object_is_visible(obj);
339 was_v = evas_object_was_visible(obj);
342 evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, obj, is_v, was_v);
345 if ((obj->cur.map != obj->prev.map) ||
346 (obj->cur.usemap != obj->prev.usemap))
348 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
351 /* it's not visible - we accounted for it appearing or not so just abort */
352 if (!is_v) goto done;
353 /* clipper changed this is in addition to anything else for obj */
354 evas_object_render_pre_clipper_change(&obj->layer->evas->clip_changes, obj);
355 /* if we restacked (layer or just within a layer) */
358 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
361 /* if it changed anti_alias */
362 if (obj->cur.anti_alias != obj->prev.anti_alias)
364 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
367 /* if it changed render op */
368 if (obj->cur.render_op != obj->prev.render_op)
370 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
373 /* if it changed color */
374 if ((obj->cur.color.r != obj->prev.color.r) ||
375 (obj->cur.color.g != obj->prev.color.g) ||
376 (obj->cur.color.b != obj->prev.color.b) ||
377 (obj->cur.color.a != obj->prev.color.a))
379 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
382 /* if it changed geometry - and obviously not visibility or color */
383 /* calculate differences since we have a constant color fill */
384 /* we really only need to update the differences */
385 if ((obj->cur.geometry.x != obj->prev.geometry.x) ||
386 (obj->cur.geometry.y != obj->prev.geometry.y) ||
387 (obj->cur.geometry.w != obj->prev.geometry.w) ||
388 (obj->cur.geometry.h != obj->prev.geometry.h) ||
390 ((o->cur.x1 != o->prev.x1) ||
391 (o->cur.y1 != o->prev.y1) ||
392 (o->cur.x2 != o->prev.x2) ||
393 (o->cur.y2 != o->prev.y2)))
396 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
400 evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, obj, is_v, was_v);
404 evas_object_line_render_post(Evas_Object *obj)
408 /* this moves the current data to the previous state parts of the object */
409 /* in whatever way is safest for the object. also if we don't need object */
410 /* data anymore we can free it if the object deems this is a good idea */
411 o = (Evas_Object_Line *)(obj->object_data);
412 /* remove those pesky changes */
413 evas_object_clip_changes_clean(obj);
414 /* move cur to prev safely for object data */
415 obj->prev = obj->cur;
420 static unsigned int evas_object_line_id_get(Evas_Object *obj)
424 o = (Evas_Object_Line *)(obj->object_data);
426 return MAGIC_OBJ_LINE;
429 static unsigned int evas_object_line_visual_id_get(Evas_Object *obj)
433 o = (Evas_Object_Line *)(obj->object_data);
435 return MAGIC_OBJ_SHAPE;
438 static void *evas_object_line_engine_data_get(Evas_Object *obj)
442 o = (Evas_Object_Line *)(obj->object_data);
444 return o->engine_data;
448 evas_object_line_is_opaque(Evas_Object *obj __UNUSED__)
450 /* this returns 1 if the internal object data implies that the object is */
451 /* currently fully opaque over the entire line it occupies */
456 evas_object_line_was_opaque(Evas_Object *obj __UNUSED__)
458 /* this returns 1 if the internal object data implies that the object was */
459 /* previously fully opaque over the entire line it occupies */
464 evas_object_line_is_inside(Evas_Object *obj __UNUSED__, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
466 /* this returns 1 if the canvas co-ordinates are inside the object based */
467 /* on object private data. not much use for rects, but for polys, images */
468 /* and other complex objects it might be */
473 evas_object_line_was_inside(Evas_Object *obj __UNUSED__, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
475 /* this returns 1 if the canvas co-ordinates were inside the object based */
476 /* on object private data. not much use for rects, but for polys, images */
477 /* and other complex objects it might be */
482 evas_object_line_coords_recalc(Evas_Object *obj)
486 o = (Evas_Object_Line *)(obj->object_data);
487 o->cur.cache.x1 = obj->cur.geometry.x + o->cur.x1;
488 o->cur.cache.y1 = obj->cur.geometry.y + o->cur.y1;
489 o->cur.cache.x2 = obj->cur.geometry.x + o->cur.x2;
490 o->cur.cache.y2 = obj->cur.geometry.y + o->cur.y2;
491 o->cur.cache.object.w = obj->cur.geometry.w;
492 o->cur.cache.object.h = obj->cur.geometry.h;