hermet pushed a commit to branch master. http://git.enlightenment.org/tools/enventor.git/commit/?id=66e04b8ec1d85213e147f84fa1658f7cf243d95b
commit 66e04b8ec1d85213e147f84fa1658f7cf243d95b Author: ChunEon Park <[email protected]> Date: Sat Feb 21 18:21:44 2015 +0900 bin/live_edit: improve usage. add better rich control pointers. this patch totally re-implemenet live edit function since the draggable part has a lots of limitation to control it by user. --- data/themes/default/content.edc | 37 ++ data/themes/default/enventor.edc | 2 + data/themes/default/layout_common.edc | 151 ++------ src/bin/live_edit.c | 631 +++++++++++++++++++++++++++------- src/include/live_edit.h | 3 + 5 files changed, 579 insertions(+), 245 deletions(-) diff --git a/data/themes/default/content.edc b/data/themes/default/content.edc index bbc68c3..57176fe 100644 --- a/data/themes/default/content.edc +++ b/data/themes/default/content.edc @@ -105,3 +105,40 @@ group { name: "part_highlight"; } } } + +group { name: "ctrl_pt"; + parts { + part { name: "base"; + type: RECT; + scale: 1; + description { state: "default" 0.0; + min: 8 8; + fixed: 1 1; + rel1.relative: 0.5 0.5; + rel2.relative: 0.5 0.5; + } + description { state: "anim" 0.0; + inherit: "default" 0.0; + color: COL_HI_S; + } + } + } + programs { + program { name: "load"; + signal: "load"; + after: "anim"; + } + program { name: "anim"; + action: STATE_SET "anim" 0.0; + target: "base"; + transition: LINEAR 0.5; + after: "anim2"; + } + program { name: "anim2"; + action: STATE_SET "default" 0.0; + target: "base"; + transition: LINEAR 0.5; + after: "anim"; + } + } +} diff --git a/data/themes/default/enventor.edc b/data/themes/default/enventor.edc index 5504fbf..e1cd21e 100644 --- a/data/themes/default/enventor.edc +++ b/data/themes/default/enventor.edc @@ -1,8 +1,10 @@ #define FN "Sans" #define COL_HI 51 153 255 255; color2: 51 153 255 24; color3: 51 153 255 18 #define COL_HI_TRANS 51 153 255 0; color2: 51 153 255 0; color3: 51 153 255 0 +#define COL_HI_S 51 153 255 255 #define COL_NM 255 255 255 255; color3: 0 0 0 128 #define COL_NM_TRANS 255 255 255 0; color3: 0 0 0 0 +#define COL_NM_S 255 255 255 255 data.item: "version" "110"; diff --git a/data/themes/default/layout_common.edc b/data/themes/default/layout_common.edc index e9420af..db09649 100644 --- a/data/themes/default/layout_common.edc +++ b/data/themes/default/layout_common.edc @@ -11,12 +11,6 @@ images { image: "pm_fill.png" COMP; } -styles { - style { name: "entry_live_edit_style"; - base: "font="FN" font_size=10 text_class=entry color=#3399ff style=glow glow_color=#3399ff18 valign=1 ellipsis=1.0 wrap=none"; - } -} - group { name: "about_layout"; parts { part { name: "clipper"; @@ -1290,12 +1284,8 @@ group { name: "search_layout"; } group { name: "live_edit_layout"; + data.item: "ctrl_size" "8"; parts { - part { name: "base"; - type: SPACER; - description { state: "default" 0.0; - } - } part { name: "clipper"; type: RECT; description { state: "default" 0.0; @@ -1310,19 +1300,24 @@ group { name: "live_edit_layout"; scale: 1; clip_to: "clipper"; description { state: "default" 0.0; - rel1.to: "rel1_dragable"; - rel2.to: "rel2_dragable"; } } - part { name: "frame_l"; + part { name: "cursor_body"; type: RECT; repeat_events: 1; description { state: "default" 0.0; + color: 0 0 0 0; + } + } + part { name: "frame_l"; + type: RECT; + mouse_events: 0; + clip_to: "clipper"; + scale: 1; + description { state: "default" 0.0; align: 0 0.5; rel1.relative: 0 0; rel2.relative: 0 1; - rel1.to: "elm.swallow.symbol"; - rel2.to: "elm.swallow.symbol"; min: 1 0; fixed: 1 0; } @@ -1333,13 +1328,13 @@ group { name: "live_edit_layout"; } part { name: "frame_r"; type: RECT; - repeat_events: 1; + mouse_events: 0; + clip_to: "clipper"; + scale: 1; description { state: "default" 0.0; align: 1 0.5; rel1.relative: 1 0; rel2.relative: 1 1; - rel1.to: "elm.swallow.symbol"; - rel2.to: "elm.swallow.symbol"; min: 1 0; fixed: 1 0; } @@ -1350,13 +1345,13 @@ group { name: "live_edit_layout"; } part { name: "frame_t"; type: RECT; - repeat_events: 1; + mouse_events: 0; + clip_to: "clipper"; + scale: 1; description { state: "default" 0.0; align: 0.5 0; rel1.relative: 0 0; rel2.relative: 1 0; - rel1.to: "elm.swallow.symbol"; - rel2.to: "elm.swallow.symbol"; min: 0 1; fixed: 0 1; } @@ -1367,13 +1362,13 @@ group { name: "live_edit_layout"; } part { name: "frame_b"; type: RECT; - repeat_events: 1; + mouse_events: 0; + clip_to: "clipper"; + scale: 1; description { state: "default" 0.0; align: 0.5 1; rel1.relative: 0 1; rel2.relative: 1 1; - rel1.to: "elm.swallow.symbol"; - rel2.to: "elm.swallow.symbol"; min: 0 1; fixed: 0 1; } @@ -1382,148 +1377,58 @@ group { name: "live_edit_layout"; color: 51 153 255 127; } } - part { name: "rel1_dragable"; - scale: 1; - clip_to: "clipper"; - type: RECT; - description { state: "default" 0.0; - min: 8 8; - fixed: 1 1; - rel1.relative: 0 0; - rel2.relative: 0 0; - align: 0 0; - } - description { state: "anim" 0.0; - inherit: "default" 0.0; - color: 51 153 255 255; - //min: 10 10; - } - dragable { - confine: "base"; - x: 1 1 0; - y: 1 1 0; - } - } part { name: "elm.text.rel1"; type: TEXT; effect: OUTLINE; scale: 1; mouse_events: 0; + clip_to: "clipper"; description { state: "default" 0.0; - rel1.to: "rel1_dragable"; - rel2.to_y: "rel1_dragable"; - rel1.relative: 1 0; rel1.offset: 10 10; color: 255 255 255 255; - align: 0 0.5; + align: 0 0; fixed: 1 1; text { font: FN; size: 10; - align: 0 0.5; + align: 0 0; min: 1 0; ellipsis: -1; } } } - part { name: "rel2_dragable"; - scale: 1; - clip_to: "clipper"; - type: RECT; - description { state: "default" 0.0; - min: 8 8; - fixed: 1 1; - rel1.relative: 1 1; - rel2.relative: 1 1; - align: 1 1; - } - description { state: "anim" 0.0; - inherit: "default" 0.0; - color: 51 153 255 255; - //min: 10 10; - } - dragable { - confine: "base"; - x: 1 1 0; - y: 1 1 0; - } - } part { name: "elm.text.rel2"; type: TEXT; effect: OUTLINE; scale: 1; mouse_events: 0; + clip_to: "clipper"; description { state: "default" 0.0; - rel1.to_y: "rel2_dragable"; rel1.offset: 0 -11; - rel2.to: "rel2_dragable"; - rel2.relative: 0 1; rel2.offset: -11 -11; color: 255 255 255 255; - align: 1 0.5; + align: 1 1; fixed: 1 1; text { font: FN; size: 10; - align: 1 0.5; + align: 1 1; min: 1 0; ellipsis: -1; } } } -/* part { name: "info_bg"; - type: RECT; - scale: 1; - mouse_events: 0; - description { state: "default" 0.0; - rel1.to: "elm.swallow.symbol"; - rel2.to: "elm.swallow.symbol"; - min: 130 50; - max: 130 50; - fixed: 1 1; - color: 0 0 0 0; - } - description { state: "show" 0.0; - inherit:"default" 0.0; - color: 0 0 0 175; - } - } - part { name: "elm.text.info"; - type: TEXTBLOCK; - scale: 1; - mouse_events: 0; - description { - text.style: "entry_live_edit_style"; - rel1.to: "info_bg"; - rel2.to: "info_bg"; - } - } */ } programs { program { name: "on_load_init"; signal: "load"; - source: ""; - script { - set_drag(PART:"rel1_dragable", 0.2, 0.2); - set_drag(PART:"rel2_dragable", 0.8, 0.8); - } - after: "on_load_show"; - after: "anim"; - } - program { name: "on_load_show"; action: STATE_SET "show" 0.0; target: "clipper"; - //target: "info_bg"; transition: DECELERATE 0.25; - after: "emit_drag_signal"; - } - program { name: "emit_drag_signal"; - action: SIGNAL_EMIT "drag" "rel2_dragable"; + after: "anim"; } program { name: "anim"; action: STATE_SET "anim" 0.0; - target: "rel1_dragable"; - target: "rel2_dragable"; target: "frame_l"; target: "frame_r"; target: "frame_t"; @@ -1533,8 +1438,6 @@ group { name: "live_edit_layout"; } program { name: "anim2"; action: STATE_SET "default" 0.0; - target: "rel1_dragable"; - target: "rel2_dragable"; target: "frame_l"; target: "frame_r"; target: "frame_t"; diff --git a/src/bin/live_edit.c b/src/bin/live_edit.c index d936b26..5cc3f9a 100644 --- a/src/bin/live_edit.c +++ b/src/bin/live_edit.c @@ -5,6 +5,19 @@ #include <Elementary_Cursor.h> #include "common.h" +typedef enum +{ + Ctrl_Pt_Rel1 = 0, + Ctrl_Pt_Rel2, + Ctrl_Pt_Rel3, + Ctrl_Pt_Rel4, + Ctrl_Pt_Top, + Ctrl_Pt_Bottom, + Ctrl_Pt_Left, + Ctrl_Pt_Right, + Ctrl_Pt_Cnt +} Ctrl_Pt; + typedef struct ctxpopup_it_data_s { const char *name; @@ -15,8 +28,11 @@ typedef struct live_editor_s { Evas_Object *ctxpopup; Evas_Object *layout; + Evas_Object *live_view; Evas_Object *enventor; Evas_Object *trigger; + Evas_Object *ctrl_pt[Ctrl_Pt_Cnt]; + double half_ctrl_size; struct { unsigned int type; @@ -30,6 +46,8 @@ typedef struct live_editor_s Eina_Bool on : 1; } live_data; +static void live_edit_update(live_data *ld); + static const ctxpopup_it_data CTXPOPUP_ITEMS[] = { {"RECT", EDJE_PART_TYPE_RECTANGLE}, @@ -52,40 +70,21 @@ static const char *LIVE_EDIT_NEW_PART_DATA_STR = static const char *LIVE_EDIT_NEW_PART_REL_STR = "%.2f %.2f"; static void -cur_part_value_update(live_data *ld, Evas_Object *edje) -{ - Evas_Coord x, y, w, h; - Evas_Coord view_w, view_h; - - config_view_size_get(&view_w, &view_h); - edje_object_part_geometry_get(edje, "elm.swallow.symbol", &x, &y, &w, &h); - - ld->part_info.rel1_x = ((float) x) / ((float) view_w); - ld->part_info.rel1_y = ((float) y) / ((float) view_h); - ld->part_info.rel2_x = ((float) (x + w)) / ((float) view_w); - ld->part_info.rel2_y = ((float) (y + h)) / ((float) view_h); - ld->part_info.x = x; - ld->part_info.y = y; - ld->part_info.w = w; - ld->part_info.h = h; -} - -static void -part_info_update(live_data *ld) +text_update(live_data *ld) { Evas_Object *layout = elm_layout_edje_get(ld->layout); - cur_part_value_update(ld, layout); - char part_info[LIVE_EDIT_NEW_PART_DATA_MAX_LEN]; +#if 0 snprintf(part_info, LIVE_EDIT_NEW_PART_DATA_MAX_LEN, LIVE_EDIT_NEW_PART_DATA_STR, CTXPOPUP_ITEMS[ld->part_info.type].name, ld->part_info.x, ld->part_info.y, ld->part_info.w, ld->part_info.h); -// edje_object_part_text_set(layout, -// "elm.text.info", part_info); + edje_object_part_text_set(layout, + "elm.text.info", part_info); +#endif snprintf(part_info, LIVE_EDIT_NEW_PART_REL_STR_MAX_LEN, LIVE_EDIT_NEW_PART_REL_STR, ld->part_info.rel1_x, ld->part_info.rel1_y); @@ -97,107 +96,468 @@ part_info_update(live_data *ld) } static void -layout_drag_cb(void *data, Evas_Object *obj EINA_UNUSED, - const char *emission EINA_UNUSED, const char *source EINA_UNUSED) +live_edit_symbol_set(live_data *ld) +{ + char buf[PATH_MAX]; + snprintf(buf, sizeof(buf), "%s_bg", CTXPOPUP_ITEMS[ld->part_info.type].name); + Evas_Object *layout_symbol = elm_layout_add(ld->layout); + elm_layout_file_set(layout_symbol, EDJE_PATH, buf); + elm_object_part_content_set(ld->layout, "elm.swallow.symbol", layout_symbol); +} + +static Eina_Bool +key_down_cb(void *data, int type EINA_UNUSED, void *ev) { - //TODO: recalc on viewport size changed + Ecore_Event_Key *event = ev; live_data *ld = data; - part_info_update(ld); + + if (!strcmp(event->key, "Return")) + { + enventor_object_template_part_insert(ld->enventor, + CTXPOPUP_ITEMS[ld->part_info.type].type, + ENVENTOR_TEMPLATE_INSERT_LIVE_EDIT, + ld->part_info.rel1_x, + ld->part_info.rel1_y, + ld->part_info.rel2_x, + ld->part_info.rel2_y, + NULL, 0); + enventor_object_save(ld->enventor, config_edc_path_get()); + } + else if (strcmp(event->key, "Delete")) return EINA_TRUE; + + live_edit_cancel(); + return EINA_TRUE; +} + +static void +ctrl_pt_update(live_data *ld) +{ + //Init Control Point Positions + Evas_Coord x, y, w, h; + evas_object_geometry_get(ld->layout, &x, &y, &w, &h); + + int half_ctrl_size = ld->half_ctrl_size; + + //Rel1 + evas_object_move(ld->ctrl_pt[Ctrl_Pt_Rel1], + (x - half_ctrl_size), (y - half_ctrl_size)); + + //Rel2 + evas_object_move(ld->ctrl_pt[Ctrl_Pt_Rel2], + ((x + w) - half_ctrl_size), ((y + h) - half_ctrl_size)); + + //Rel3 + evas_object_move(ld->ctrl_pt[Ctrl_Pt_Rel3], + ((x + w) - half_ctrl_size), (y - half_ctrl_size)); + + //Rel4 + evas_object_move(ld->ctrl_pt[Ctrl_Pt_Rel4], + (x - half_ctrl_size), ((y + h) - half_ctrl_size)); + + //Top + evas_object_move(ld->ctrl_pt[Ctrl_Pt_Top], + ((x + (w/2)) - half_ctrl_size), (y - half_ctrl_size)); + + //Bottom + evas_object_move(ld->ctrl_pt[Ctrl_Pt_Bottom], + ((x + (w/2)) - half_ctrl_size), ((y + h) - half_ctrl_size)); + + //Left + evas_object_move(ld->ctrl_pt[Ctrl_Pt_Left], + (x - half_ctrl_size), ((y + (h/2)) - half_ctrl_size)); + + //Right + evas_object_move(ld->ctrl_pt[Ctrl_Pt_Right], + ((x + w) - half_ctrl_size), ((y + (h/2)) - half_ctrl_size)); } static void -new_part_mouse_move_cb(void *data, Evas *e EINA_UNUSED, - Evas_Object *obj EINA_UNUSED, void *event_info) +cp_top_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info) { + live_data *ld = data; Evas_Event_Mouse_Move *ev = event_info; + + Evas_Coord y = ev->cur.canvas.y; + + //Limit to boundary + Evas_Coord ly, lh; + evas_object_geometry_get(ld->live_view, NULL, &ly, NULL, &lh); + + Evas_Coord rel2_y; + evas_object_geometry_get(ld->ctrl_pt[Ctrl_Pt_Rel2], NULL, &rel2_y, + NULL, NULL); + if (ly > y) y = ly; + if ((y - ld->half_ctrl_size) > rel2_y) y = (rel2_y + ld->half_ctrl_size); + + ld->part_info.rel1_y = ((double) (y - ly) / (double) lh); +} + +static void +cp_bottom_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info) +{ live_data *ld = data; + Evas_Event_Mouse_Move *ev = event_info; - Evas_Coord view_w, view_h; - config_view_size_get(&view_w, &view_h); - int cur_x = ld->part_info.x + ev->cur.canvas.x - ev->prev.canvas.x; - int cur_y = ld->part_info.y + ev->cur.canvas.y - ev->prev.canvas.y; + Evas_Coord y = ev->cur.canvas.y; - if ((cur_x >= 0) && (cur_y >= 0) && - (cur_x <= view_w - ld->part_info.w) && - (cur_y <= view_h - ld->part_info.h)) - { - double dx = ((float) cur_x / (float) view_w) - - ld->part_info.rel1_x; - double dy = ((float) cur_y / (float) view_h) - - ld->part_info.rel1_y; - edje_object_part_drag_step(elm_layout_edje_get(ld->layout), - "rel1_dragable", dx, dy); - edje_object_part_drag_step(elm_layout_edje_get(ld->layout), - "rel2_dragable", dx, dy); - part_info_update(ld); - } + //Limit to boundary + Evas_Coord ly, lh; + evas_object_geometry_get(ld->live_view, NULL, &ly, NULL, &lh); + + Evas_Coord rel1_y; + evas_object_geometry_get(ld->ctrl_pt[Ctrl_Pt_Rel1], NULL, &rel1_y, + NULL, NULL); + if (y > (ly + lh)) y = (ly + lh); + if (rel1_y > (y + ld->half_ctrl_size)) y = (rel1_y - ld->half_ctrl_size); + + ld->part_info.rel2_y = ((double) (y - ly) / (double) lh); } static void -new_part_mouse_down_cb(void *data, - Evas_Object *obj, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) +cp_rel1_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info) { - evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE, - new_part_mouse_move_cb, data); + live_data *ld = data; + Evas_Event_Mouse_Move *ev = event_info; + + Evas_Coord x = ev->cur.canvas.x; + Evas_Coord y = ev->cur.canvas.y; + + //Limit to boundary + Evas_Coord lx, ly, lw, lh; + evas_object_geometry_get(ld->live_view, &lx, &ly, &lw, &lh); + + Evas_Coord rel2_x, rel2_y; + evas_object_geometry_get(ld->ctrl_pt[Ctrl_Pt_Rel2], &rel2_x, &rel2_y, + NULL, NULL); + if (lx > x) x = lx; + if (ly > y) y = ly; + if ((x - ld->half_ctrl_size) > rel2_x) x = (rel2_x + ld->half_ctrl_size); + if ((y - ld->half_ctrl_size) > rel2_y) y = (rel2_y + ld->half_ctrl_size); + + ld->part_info.rel1_x = ((double) (x - lx) / (double) lw); + ld->part_info.rel1_y = ((double) (y - ly) / (double) lh); } static void -new_part_mouse_up_cb(void *data EINA_UNUSED, - Evas_Object *obj, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) +cp_rel2_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info) { - evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_MOVE, - new_part_mouse_move_cb); + live_data *ld = data; + Evas_Event_Mouse_Move *ev = event_info; + + Evas_Coord x = ev->cur.canvas.x; + Evas_Coord y = ev->cur.canvas.y; + + //Limit to boundary + Evas_Coord lx, ly, lw, lh; + evas_object_geometry_get(ld->live_view, &lx, &ly, &lw, &lh); + + Evas_Coord rel1_x, rel1_y; + evas_object_geometry_get(ld->ctrl_pt[Ctrl_Pt_Rel1], &rel1_x, &rel1_y, + NULL, NULL); + if (x > (lx + lw)) x = (lx + lw); + if (y > (ly + lh)) y = (ly + lh); + if (rel1_x > (x + ld->half_ctrl_size)) x = (rel1_x - ld->half_ctrl_size); + if (rel1_y > (y + ld->half_ctrl_size)) y = (rel1_y - ld->half_ctrl_size); + + ld->part_info.rel2_x = ((double) (x - lx) / (double) lw); + ld->part_info.rel2_y = ((double) (y - ly) / (double) lh); } static void -symbol_set(live_data *ld) +cp_rel3_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info) { - char buf[PATH_MAX]; - snprintf(buf, sizeof(buf), "%s_bg", - CTXPOPUP_ITEMS[ld->part_info.type].name); - Evas_Object *bg_layout = elm_layout_add(ld->layout); - elm_layout_file_set(bg_layout, EDJE_PATH, buf); - elm_object_part_content_set(ld->layout, "elm.swallow.symbol", bg_layout); + live_data *ld = data; + Evas_Event_Mouse_Move *ev = event_info; + + Evas_Coord x = ev->cur.canvas.x; + Evas_Coord y = ev->cur.canvas.y; + + //Limit to boundary + Evas_Coord lx, ly, lw, lh; + evas_object_geometry_get(ld->live_view, &lx, &ly, &lw, &lh); + + Evas_Coord rel1_x; + evas_object_geometry_get(ld->ctrl_pt[Ctrl_Pt_Rel1], &rel1_x, NULL, + NULL, NULL); + if (x > (lx + lw)) x = (lx + lw); + if (rel1_x > (x + ld->half_ctrl_size)) x = (rel1_x - ld->half_ctrl_size); + + Evas_Coord rel2_y; + evas_object_geometry_get(ld->ctrl_pt[Ctrl_Pt_Rel2], NULL, &rel2_y, + NULL, NULL); + if (ly > y) y = ly; + if ((y - ld->half_ctrl_size) > rel2_y) y = (rel2_y + ld->half_ctrl_size); + + ld->part_info.rel2_x = ((double) (x - lx) / (double) lw); + ld->part_info.rel1_y = ((double) (y - ly) / (double) lh); } static void -live_edit_reset(live_data *ld) +cp_rel4_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info) { - if (ld->ctxpopup) elm_ctxpopup_dismiss(ld->ctxpopup); + live_data *ld = data; + Evas_Event_Mouse_Move *ev = event_info; - ecore_event_handler_del(ld->key_down_handler); - ld->key_down_handler = NULL; + Evas_Coord x = ev->cur.canvas.x; + Evas_Coord y = ev->cur.canvas.y; - evas_object_del(ld->layout); - ld->layout = NULL; + //Limit to boundary + Evas_Coord lx, ly, lw, lh; + evas_object_geometry_get(ld->live_view, &lx, &ly, &lw, &lh); + + Evas_Coord rel2_x; + evas_object_geometry_get(ld->ctrl_pt[Ctrl_Pt_Rel2], &rel2_x, NULL, + NULL, NULL); + if (lx > x) x = lx; + if ((x - ld->half_ctrl_size) > rel2_x) x = (rel2_x + ld->half_ctrl_size); + + Evas_Coord rel1_y; + evas_object_geometry_get(ld->ctrl_pt[Ctrl_Pt_Rel1], NULL, &rel1_y, + NULL, NULL); + if (y > (ly + lh)) y = (ly + lh); + if (rel1_y > (y + ld->half_ctrl_size)) y = (rel1_y - ld->half_ctrl_size); + + ld->part_info.rel1_x = ((double) (x - lx) / (double) lw); + ld->part_info.rel2_y = ((double) (y - ly) / (double) lh); } -static Eina_Bool -key_down_cb(void *data, int type EINA_UNUSED, void *ev) +static void +cp_left_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info) { - Ecore_Event_Key *event = ev; live_data *ld = data; + Evas_Event_Mouse_Move *ev = event_info; - if (!strcmp(event->key, "Return")) + Evas_Coord x = ev->cur.canvas.x; + + //Limit to boundary + Evas_Coord lx, lw; + evas_object_geometry_get(ld->live_view, &lx, NULL, &lw, NULL); + + Evas_Coord rel2_x; + evas_object_geometry_get(ld->ctrl_pt[Ctrl_Pt_Rel2], &rel2_x, NULL, + NULL, NULL); + if (lx > x) x = lx; + if ((x - ld->half_ctrl_size) > rel2_x) x = (rel2_x + ld->half_ctrl_size); + + ld->part_info.rel1_x = ((double) (x - lx) / (double) lw); +} + +static void +cp_right_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info) +{ + live_data *ld = data; + Evas_Event_Mouse_Move *ev = event_info; + + Evas_Coord x = ev->cur.canvas.x; + + //Limit to boundary + Evas_Coord lx, lw; + evas_object_geometry_get(ld->live_view, &lx, NULL, &lw, NULL); + + Evas_Coord rel1_x; + evas_object_geometry_get(ld->ctrl_pt[Ctrl_Pt_Rel1], &rel1_x, NULL, + NULL, NULL); + if (x > (lx + lw)) x = (lx + lw); + if (rel1_x > (x + ld->half_ctrl_size)) x = (rel1_x - ld->half_ctrl_size); + + ld->part_info.rel2_x = ((double) (x - lx) / (double) lw); +} + +static void +cp_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + //Dispatch to actual mouse move call + Ctrl_Pt cp = (Ctrl_Pt) evas_object_data_get(obj, "index"); + + switch (cp) { - enventor_object_template_part_insert(ld->enventor, - CTXPOPUP_ITEMS[ld->part_info.type].type, - ENVENTOR_TEMPLATE_INSERT_LIVE_EDIT, - ld->part_info.rel1_x, - ld->part_info.rel1_y, - ld->part_info.rel2_x, - ld->part_info.rel2_y, - NULL, 0); - enventor_object_save(ld->enventor, config_edc_path_get()); + case Ctrl_Pt_Rel1: + cp_rel1_mouse_move_cb(data, e, obj, event_info); + break; + case Ctrl_Pt_Rel2: + cp_rel2_mouse_move_cb(data, e, obj, event_info); + break; + case Ctrl_Pt_Rel3: + cp_rel3_mouse_move_cb(data, e, obj, event_info); + break; + case Ctrl_Pt_Rel4: + cp_rel4_mouse_move_cb(data, e, obj, event_info); + break; + case Ctrl_Pt_Top: + cp_top_mouse_move_cb(data, e, obj, event_info); + break; + case Ctrl_Pt_Bottom: + cp_bottom_mouse_move_cb(data, e, obj, event_info); + break; + case Ctrl_Pt_Left: + cp_left_mouse_move_cb(data, e, obj, event_info); + break; + case Ctrl_Pt_Right: + cp_right_mouse_move_cb(data, e, obj, event_info); + break; } - else if (strcmp(event->key, "Delete")) return EINA_TRUE; + live_data *ld = data; + live_edit_update(ld); +} - live_edit_reset(ld); - return EINA_TRUE; +static void +cp_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_MOVE, + cp_mouse_move_cb); +} + +static void +cp_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE, + cp_mouse_move_cb, data); + evas_object_layer_set(obj, EVAS_LAYER_MAX); +} + + + +static void +ctrl_pt_init(live_data *ld) +{ + //Ctrl Point Size + Evas_Object *edje = elm_layout_edje_get(ld->layout); + double ctrl_size = atof(edje_object_data_get(edje, "ctrl_size")); + ctrl_size *= elm_config_scale_get(); + ld->half_ctrl_size = ctrl_size * 0.5; + + //Create Control Points + int i; + for (i = 0; i < Ctrl_Pt_Cnt; i++) + { + Evas_Object *layout = elm_layout_add(ld->layout); + elm_layout_file_set(layout, EDJE_PATH, "ctrl_pt"); + evas_object_resize(layout, ctrl_size, ctrl_size); + evas_object_show(layout); + evas_object_event_callback_add(layout, + EVAS_CALLBACK_MOUSE_DOWN, + cp_mouse_down_cb, ld); + evas_object_event_callback_add(layout, + EVAS_CALLBACK_MOUSE_UP, + cp_mouse_up_cb, ld); + evas_object_data_set(layout, "index", (void *) i); + + ld->ctrl_pt[i] = layout; + } + + //Set Mouse Cursors + elm_object_cursor_set(ld->ctrl_pt[Ctrl_Pt_Rel1], + ELM_CURSOR_TOP_LEFT_CORNER); + elm_object_cursor_set(ld->ctrl_pt[Ctrl_Pt_Rel2], + ELM_CURSOR_BOTTOM_RIGHT_CORNER); + elm_object_cursor_set(ld->ctrl_pt[Ctrl_Pt_Rel3], + ELM_CURSOR_TOP_RIGHT_CORNER); + elm_object_cursor_set(ld->ctrl_pt[Ctrl_Pt_Rel4], + ELM_CURSOR_BOTTOM_LEFT_CORNER); + elm_object_cursor_set(ld->ctrl_pt[Ctrl_Pt_Top], ELM_CURSOR_TOP_SIDE); + elm_object_cursor_set(ld->ctrl_pt[Ctrl_Pt_Bottom], ELM_CURSOR_BOTTOM_SIDE); + elm_object_cursor_set(ld->ctrl_pt[Ctrl_Pt_Left], ELM_CURSOR_LEFT_SIDE); + elm_object_cursor_set(ld->ctrl_pt[Ctrl_Pt_Right], ELM_CURSOR_RIGHT_SIDE); + + + ctrl_pt_update(ld); +} + +static void +layout_update(live_data *ld) +{ + Evas_Coord x, y, w, h; + + evas_object_geometry_get(ld->live_view, &x, &y, &w, &h); + Evas_Coord x2 = (w * ld->part_info.rel1_x); + Evas_Coord y2 = (h * ld->part_info.rel1_y); + evas_object_move(ld->layout, (x + x2), (y + y2)); + Evas_Coord w2 = (w * (ld->part_info.rel2_x)) - x2; + Evas_Coord h2 = (h * (ld->part_info.rel2_y)) - y2; + evas_object_resize(ld->layout, w2, h2); +} + +static void +live_edit_update(live_data *ld) +{ + layout_update(ld); + ctrl_pt_update(ld); + text_update(ld); +} + +static void +live_view_geom_cb(void *data, Evas *e EINA_UNUSED, + Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + live_data *ld = data; + live_edit_update(ld); +} + +static void +layout_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info) +{ + Evas_Event_Mouse_Move *ev = event_info; + live_data *ld = data; + + Evas_Coord lx, ly, lw, lh; + evas_object_geometry_get(ld->live_view, &lx, &ly, &lw, &lh); + + Evas_Coord x, y, w, h; + evas_object_geometry_get(obj, &x, &y, &w, &h); + + //only affect when cursor is inside of the part + if (ev->cur.canvas.x > (x + w)) return; + if (x > ev->cur.canvas.x) return; + if (ev->cur.canvas.y > (y + h)) return; + if (y > ev->cur.canvas.y) return; + + x = ((double) x) + ((double) (ev->cur.canvas.x - ev->prev.canvas.x) * 0.5); + y = ((double) y) + ((double) (ev->cur.canvas.y - ev->prev.canvas.y) * 0.5); + + //limit to live view boundary + if (lx > x) x = lx; + if ((x + w) > (lx + lw)) x -= ((x + w) - (lx + lw)); + if (ly > y) y = ly; + if ((y + h) > (ly + lh)) y -= ((y + h) - (ly + lh)); + + double orig_rel1_x = ld->part_info.rel1_x; + double orig_rel1_y = ld->part_info.rel1_y; + ld->part_info.rel1_x = ((double) (x - lx) / lw); + ld->part_info.rel1_y = ((double) (y - ly) / lh); + ld->part_info.rel2_x += (ld->part_info.rel1_x - orig_rel1_x); + ld->part_info.rel2_y += (ld->part_info.rel1_y - orig_rel1_y); + + evas_object_move(obj, x, y); + + text_update(ld); + ctrl_pt_update(ld); +} + +static void +layout_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_MOVE, + layout_mouse_move_cb); +} + +static void +layout_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE, + layout_mouse_move_cb, data); } static void @@ -206,28 +566,32 @@ live_edit_layer_set(live_data *ld) ld->key_down_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, key_down_cb, ld); + evas_object_event_callback_add(ld->live_view, EVAS_CALLBACK_RESIZE, + live_view_geom_cb, ld); + evas_object_event_callback_add(ld->live_view, EVAS_CALLBACK_MOVE, + live_view_geom_cb, ld); + //Create Live View Layout - Evas_Object *live_view = enventor_object_live_view_get(ld->enventor); - Evas_Object *layout = elm_layout_add(live_view); + Evas_Object *layout = elm_layout_add(ld->live_view); elm_layout_file_set(layout, EDJE_PATH, "live_edit_layout"); - elm_object_part_content_set(live_view, "elm.swallow.live_edit", layout); - elm_object_signal_callback_add(layout, "drag", "rel1_dragable", - layout_drag_cb, ld); - elm_object_signal_callback_add(layout, "drag", "rel2_dragable", - layout_drag_cb, ld); - elm_object_signal_callback_add(layout, "mouse,down,1", "elm.swallow.symbol", - new_part_mouse_down_cb, ld); - elm_object_signal_callback_add(layout, "mouse,up,1", "elm.swallow.symbol", - new_part_mouse_up_cb, ld); - // elm_layout_part_cursor_set(layout, "elm.swallow.symbol", - // ELM_CURSOR_FLEUR); - elm_layout_part_cursor_set(layout, "rel1_dragable", - ELM_CURSOR_TOP_LEFT_CORNER); - elm_layout_part_cursor_set(layout, "rel2_dragable", - ELM_CURSOR_BOTTOM_RIGHT_CORNER); + evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_DOWN, + layout_mouse_down_cb, ld); + evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_UP, + layout_mouse_up_cb, ld); + elm_layout_part_cursor_set(layout, "cursor_body", ELM_CURSOR_FLEUR); + evas_object_show(layout); + ld->layout = layout; - symbol_set(ld); - part_info_update(ld); + + //Initial Layout Geometry + ld->part_info.rel1_x = LIVE_EDIT_REL1; + ld->part_info.rel1_y = LIVE_EDIT_REL1; + ld->part_info.rel2_x = LIVE_EDIT_REL2; + ld->part_info.rel2_y = LIVE_EDIT_REL2; + + live_edit_update(ld); + live_edit_symbol_set(ld); + ctrl_pt_init(ld); } static void @@ -253,11 +617,11 @@ ctxpopup_dismissed_cb(void *data, Evas_Object *obj, } static Evas_Object * -ctxpopup_create(Evas_Object *parent, live_data *ld) +ctxpopup_create(live_data *ld) { const int CTXPOPUP_ITEMS_NUM = 6; int i; - Evas_Object *ctxpopup = elm_ctxpopup_add(parent); + Evas_Object *ctxpopup = elm_ctxpopup_add(ld->live_view); elm_ctxpopup_direction_priority_set(ctxpopup, ELM_CTXPOPUP_DIRECTION_DOWN, ELM_CTXPOPUP_DIRECTION_RIGHT, ELM_CTXPOPUP_DIRECTION_LEFT, @@ -285,23 +649,22 @@ void live_edit_toggle(void) { live_data *ld = g_ld; - ld->on = !ld->on; - - Evas_Object *live_view = enventor_object_live_view_get(ld->enventor); - if (!live_view) return; + Eina_Bool on = !ld->on; - enventor_object_disabled_set(ld->enventor, ld->on); - - if (ld->on) + if (on) { - ld->ctxpopup = ctxpopup_create(live_view, ld); + enventor_object_disabled_set(ld->enventor, EINA_TRUE); + ld->live_view = enventor_object_live_view_get(ld->enventor); + ld->ctxpopup = ctxpopup_create(ld); stats_info_msg_update("Select a part to add in Live View."); } else { - live_edit_reset(ld); + live_edit_cancel(); stats_info_msg_update("Live View Edit Mode Disabled."); } + + ld->on = on; } Eina_Bool @@ -316,7 +679,32 @@ live_edit_cancel(void) { live_data *ld = g_ld; if (!ld->on) return; - live_edit_toggle(); + + if (ld->ctxpopup) elm_ctxpopup_dismiss(ld->ctxpopup); + + enventor_object_disabled_set(ld->enventor, EINA_FALSE); + + ecore_event_handler_del(ld->key_down_handler); + ld->key_down_handler = NULL; + + evas_object_event_callback_del(ld->live_view, EVAS_CALLBACK_RESIZE, + live_view_geom_cb); + evas_object_event_callback_del(ld->live_view, EVAS_CALLBACK_MOVE, + live_view_geom_cb); + ld->live_view = NULL; + + evas_object_del(ld->layout); + ld->layout = NULL; + + //Delete Control Points + int i; + for (i = 0; i < Ctrl_Pt_Cnt; i++) + { + evas_object_del(ld->ctrl_pt[i]); + ld->ctrl_pt[i] = NULL; + } + + ld->on = EINA_FALSE; } void @@ -338,7 +726,8 @@ live_edit_term(void) { live_data *ld = g_ld; evas_object_del(ld->ctxpopup); - live_edit_reset(ld); + ld->ctxpopup = NULL; + live_edit_cancel(); free(ld); g_ld = NULL; } diff --git a/src/include/live_edit.h b/src/include/live_edit.h index a7d759a..28ba7d9 100644 --- a/src/include/live_edit.h +++ b/src/include/live_edit.h @@ -1,3 +1,6 @@ +#define LIVE_EDIT_REL1 0.25 +#define LIVE_EDIT_REL2 0.75 + void live_edit_init(Evas_Object *enventor, Evas_Object *trigger); void live_edit_term(void); void live_edit_toggle(void); --
