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);

-- 


Reply via email to