#include "e.h" //#include "e_comp_wl.h" #include "e_surface.h" /* local structures */ typedef struct _E_Smart_Data E_Smart_Data; struct _E_Smart_Data { /* canvas */ Evas *evas; /* object geometry */ Evas_Coord x, y, w, h; /* input geometry */ struct { Evas_Coord x, y, w, h; } input; /* main image object where we draw pixels to */ Evas_Object *o_img; /* input rectangle */ Evas_Object *o_input; double mouse_down_time; }; /* smart function prototypes */ static void _e_smart_add(Evas_Object *obj); static void _e_smart_del(Evas_Object *obj); static void _e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y); static void _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h); static void _e_smart_show(Evas_Object *obj); static void _e_smart_hide(Evas_Object *obj); static void _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip); static void _e_smart_clip_unset(Evas_Object *obj); /* local function prototypes */ static void _e_surface_cb_focus_in(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED); static void _e_surface_cb_focus_out(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED); static void _e_surface_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); static void _e_surface_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); static void _e_surface_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); static void _e_surface_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); static void _e_surface_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event); static void _e_surface_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event); static void _e_surface_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); static void _e_surface_cb_key_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); EAPI Evas_Object * e_surface_add(Evas *evas) { /* Evas_Object *obj = NULL; */ /* E_Smart_Data *sd = NULL; */ static Evas_Smart *smart = NULL; static const Evas_Smart_Class sc = { "smart_surface", EVAS_SMART_CLASS_VERSION, _e_smart_add, _e_smart_del, _e_smart_move, _e_smart_resize, _e_smart_show, _e_smart_hide, NULL, _e_smart_clip_set, _e_smart_clip_unset, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /* create the smart class */ if (!smart) if (!(smart = evas_smart_class_new(&sc))) return NULL; /* create new smart object */ /* obj = evas_object_smart_add(evas, smart); */ /* get the smart data and set reference to the surface */ /* if ((sd = evas_object_smart_data_get(obj))) */ /* sd->ews = ews; */ /* return newly created smart object */ return evas_object_smart_add(evas, smart); } EAPI void e_surface_input_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) { E_Smart_Data *sd = NULL; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; sd->input.x = x; sd->input.y = y; sd->input.w = w; sd->input.h = h; if ((w >= 0) && (h >= 0)) { if (sd->o_img) evas_object_pass_events_set(sd->o_img, EINA_TRUE); } else if (sd->o_img) evas_object_pass_events_set(sd->o_img, EINA_FALSE); /* update input rectangle geometry */ if (sd->o_input) { evas_object_move(sd->o_input, x, y); evas_object_resize(sd->o_input, w, h); } } EAPI void e_surface_damage_add(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) { E_Smart_Data *sd = NULL; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; /* update the image damaged area */ if (sd->o_img) evas_object_image_data_update_add(sd->o_img, x, y, w, h); } EAPI void e_surface_image_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h, void *pixels) { E_Smart_Data *sd = NULL; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; /* update the image damaged area */ if (sd->o_img) { evas_object_image_size_set(sd->o_img, w, h); evas_object_image_data_copy_set(sd->o_img, pixels); } } EAPI void e_surface_border_input_set(Evas_Object *obj, E_Border *bd) { E_Smart_Data *sd = NULL; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; e_border_input_object_set(bd, sd->o_input); } /* smart functions */ static void _e_smart_add(Evas_Object *obj) { E_Smart_Data *sd = NULL; /* try to allocate space for the smart data structure */ if (!(sd = E_NEW(E_Smart_Data, 1))) return; /* get a reference to the canvas */ sd->evas = evas_object_evas_get(obj); evas_event_callback_add(sd->evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _e_surface_cb_focus_in, obj); evas_event_callback_add(sd->evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, _e_surface_cb_focus_out, obj); /* create the base input rectangle */ sd->o_input = evas_object_rectangle_add(sd->evas); evas_object_color_set(sd->o_input, 0, 0, 0, 0); evas_object_propagate_events_set(sd->o_input, EINA_FALSE); evas_object_repeat_events_set(sd->o_input, EINA_FALSE); /* we have to set focus to the input object first, or else Evas will * never report any key events (up/down) to us */ evas_object_focus_set(sd->o_input, EINA_TRUE); /* add the event callbacks we need to listen for */ evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_MOUSE_IN, _e_surface_cb_mouse_in, obj); evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_MOUSE_OUT, _e_surface_cb_mouse_out, obj); evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_MOUSE_MOVE, _e_surface_cb_mouse_move, obj); evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_MOUSE_DOWN, _e_surface_cb_mouse_down, obj); evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_MOUSE_UP, _e_surface_cb_mouse_up, obj); evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_MOUSE_WHEEL, _e_surface_cb_mouse_wheel, obj); evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_KEY_DOWN, _e_surface_cb_key_down, obj); evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_KEY_UP, _e_surface_cb_key_up, obj); evas_object_smart_member_add(sd->o_input, obj); /* create the image object */ sd->o_img = evas_object_image_filled_add(sd->evas); evas_object_image_content_hint_set(sd->o_img, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); evas_object_image_scale_hint_set(sd->o_img, EVAS_IMAGE_SCALE_HINT_DYNAMIC); evas_object_image_smooth_scale_set(sd->o_img, EINA_FALSE); evas_object_image_alpha_set(sd->o_img, EINA_TRUE); evas_object_pass_events_set(sd->o_img, EINA_FALSE); evas_object_propagate_events_set(sd->o_img, EINA_FALSE); evas_object_smart_member_add(sd->o_img, obj); /* set the objects smart data */ evas_object_smart_data_set(obj, sd); } static void _e_smart_del(Evas_Object *obj) { E_Smart_Data *sd = NULL; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; /* delete the image object */ if (sd->o_img) evas_object_del(sd->o_img); /* delete the input rectangle */ if (sd->o_input) { /* delete the callbacks */ evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_MOUSE_IN, _e_surface_cb_mouse_in); evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_MOUSE_OUT, _e_surface_cb_mouse_out); evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_MOUSE_MOVE, _e_surface_cb_mouse_move); evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_MOUSE_DOWN, _e_surface_cb_mouse_down); evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_MOUSE_UP, _e_surface_cb_mouse_up); evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_MOUSE_WHEEL, _e_surface_cb_mouse_wheel); evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_KEY_DOWN, _e_surface_cb_key_down); evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_KEY_UP, _e_surface_cb_key_up); evas_object_del(sd->o_input); } /* delete the event callbacks */ evas_event_callback_del(sd->evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _e_surface_cb_focus_in); evas_event_callback_del(sd->evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, _e_surface_cb_focus_out); /* free the allocated smart data structure */ E_FREE(sd); /* set the objects smart data */ evas_object_smart_data_set(obj, NULL); } static void _e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y) { E_Smart_Data *sd = NULL; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; if ((sd->x == x) && (sd->y == y)) return; sd->x = x; sd->y = y; /* move the input rectangle */ if (sd->o_input) evas_object_move(sd->o_input, sd->input.x, sd->input.y); /* move the image object */ if (sd->o_img) evas_object_move(sd->o_img, x, y); } static void _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) { E_Smart_Data *sd = NULL; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; if ((sd->w == w) && (sd->h == h)) return; sd->w = w; sd->h = h; /* resize the input rectangle */ if (sd->o_input) evas_object_resize(sd->o_input, sd->input.w, sd->input.h); /* resize the image object */ if (sd->o_img) evas_object_resize(sd->o_img, w, h); } static void _e_smart_show(Evas_Object *obj) { E_Smart_Data *sd = NULL; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; /* show the input rectangle */ if (sd->o_input) evas_object_show(sd->o_input); /* show the image object */ if (sd->o_img) evas_object_show(sd->o_img); } static void _e_smart_hide(Evas_Object *obj) { E_Smart_Data *sd = NULL; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; /* hide the input rectangle */ if (sd->o_input) evas_object_hide(sd->o_input); /* hide the image object */ if (sd->o_img) evas_object_hide(sd->o_img); } static void _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip) { E_Smart_Data *sd = NULL; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; /* TODO: Hmmm, set clip on the input rectangle ?? */ /* set the clip on the image object */ if (sd->o_img) evas_object_clip_set(sd->o_img, clip); } static void _e_smart_clip_unset(Evas_Object *obj) { E_Smart_Data *sd = NULL; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; /* TODO: Hmmm, unset clip on the input rectangle ?? */ /* unset the image object clip */ if (sd->o_img) evas_object_clip_unset(sd->o_img); } /* local functions */ static void _e_surface_cb_focus_in(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED) { evas_object_smart_callback_call(data, "focus_in", NULL); } static void _e_surface_cb_focus_out(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED) { evas_object_smart_callback_call(data, "focus_out", NULL); } static void _e_surface_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) { evas_object_smart_callback_call(data, "mouse_in", event); } static void _e_surface_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) { evas_object_smart_callback_call(data, "mouse_out", event); } static void _e_surface_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) { evas_object_smart_callback_call(data, "mouse_move", event); } static void _e_surface_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) { E_Smart_Data *sd = NULL; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(data))) return; /* grab the loop time for this mouse down event * * NB: we use this for comparison in the mouse_up callback due to * some e_border grab shenanigans. Basically, this lets us ignore the * spurious mouse_up that we get from e_border grabs */ sd->mouse_down_time = ecore_loop_time_get(); evas_object_smart_callback_call(data, "mouse_down", event); } static void _e_surface_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) { E_Smart_Data *sd = NULL; double timestamp; /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(data))) return; timestamp = ecore_loop_time_get(); if (fabs(timestamp - sd->mouse_down_time) <= 0.010) return; evas_object_smart_callback_call(data, "mouse_up", event); } static void _e_surface_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) { evas_object_smart_callback_call(data, "mouse_wheel", event); } static void _e_surface_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) { evas_object_smart_callback_call(data, "key_down", event); } static void _e_surface_cb_key_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) { evas_object_smart_callback_call(data, "key_up", event); }