yakov pushed a commit to branch master.

http://git.enlightenment.org/tools/erigo.git/commit/?id=89410b863e2499c979a8663cb8b410af1a920360

commit 89410b863e2499c979a8663cb8b410af1a920360
Author: Yakov Goldberg <yako...@samsung.com>
Date:   Sun May 31 17:59:40 2015 +0300

    Add zooming feature
    
    Usage: Ctrl + '+' for Zoom In,
           Ctrl + '-' for Zoom Out,
           Ctrl + '0' for Default
           Ctrl + mouse wheel
---
 src/bin/gui/dnd.c            |  10 +-
 src/bin/gui/editor.c         | 375 ++++++++++++++++++++++++++++++++-----------
 src/bin/gui/egui_layout.json |  18 ++-
 src/lib/gui_widget.c         |  15 ++
 src/lib/gui_widget.h         |   6 +
 5 files changed, 328 insertions(+), 96 deletions(-)

diff --git a/src/bin/gui/dnd.c b/src/bin/gui/dnd.c
index 5944339..a60717d 100644
--- a/src/bin/gui/dnd.c
+++ b/src/bin/gui/dnd.c
@@ -187,8 +187,8 @@ _drop_target_iterate(Gui_Widget **drop_candidate, const 
Gui_Session *session, Ev
         if (w == dragged_wdg)
           continue;
         o = session_eo_get(session, w);
-        eo_do(o, efl_gfx_position_get(&ox, &oy));
-        eo_do(o, efl_gfx_size_get(&ow, &oh));
+        eo_do(o, efl_gfx_position_get(&ox, &oy),
+                 efl_gfx_size_get(&ow, &oh));
         if (((x >= ox) && (x <= ox + ow)) &&
             ((y >= oy) && (y <= oy + oh)))
           {
@@ -228,8 +228,10 @@ _droppos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, 
Elm_Xdnd_Action action
    Evas_Coord p_x = 0, p_y = 0;
    Evas_Coord iwin_x = 0, iwin_y = 0;
    Gui_Widget *drop_candidate = (Gui_Widget *) wdg;
+   const Gui_Context *ctx = wdg_context_get(wdg);
+   double scale = gui_context_scale_get(ctx);
 
-   Gui_Session *session = (Gui_Session *) 
gui_context_editor_session_get(wdg_context_get(wdg));
+   Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(ctx);
    wdg_eo = session_eo_get(session, wdg);
    /* Usually main_wdg is win.
     * But when it is not, need to get image of Editor win */
@@ -247,7 +249,7 @@ _droppos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, 
Elm_Xdnd_Action action
    /* if p_x or p_y is < 0, but we inside this callback, drop to window*/
    p_x = x - iwin_x;
    p_y = y - iwin_y;
-   _drop_target_iterate(&drop_candidate, session, p_x, p_y);
+   _drop_target_iterate(&drop_candidate, session, p_x / scale, p_y / scale);
 
    if (main_wdg_ti->drop_target != drop_candidate)
      {
diff --git a/src/bin/gui/editor.c b/src/bin/gui/editor.c
index 4205650..9119c49 100644
--- a/src/bin/gui/editor.c
+++ b/src/bin/gui/editor.c
@@ -30,6 +30,9 @@
 #define CURSOR_DROP_X "cursor_drop_x"
 #define CURSOR_DROP_Y "cursor_drop_y"
 
+#define FRAME_DELTA_W "__frame_delta_w"
+#define FRAME_DELTA_H "__frame_delta_h"
+
 #define EDITOR_DND_DATA "__EDITOR_DND_DATA__"
 #define EDITOR_DRAG_DATA "__EDITOR_DRAG_DATA__"
 
@@ -64,6 +67,9 @@ _editor_undo_redo_post(const Gui_Memento *memento);
 static void
 _wdg_parent_win_reload(const Gui_Widget *wdg);
 
+static void
+_zoom_label_update(double zoom);
+
 static Gui_Context *_active_ctx = NULL;
 static const Egui_Layout_Widgets *g;
 
@@ -110,7 +116,8 @@ typedef struct _Main_Wdg_Info
 static Main_Wdg_Info*
 main_wdg_info_new()
 {
-   return calloc(1, sizeof(Main_Wdg_Info));
+   Main_Wdg_Info *ret = calloc(1, sizeof(Main_Wdg_Info));
+   return ret;
 }
 
 static void
@@ -362,7 +369,7 @@ _wdg_border_draw(const Gui_Widget *wdg, Eina_Bool 
visibility, int border_type_co
      {
       case BORDER_SELECTION:
            {
-              LINE(base_obj, BORDER_TOP, BORDER_SELECTION, ox, oy - 1, lw, 1, 
visibility);
+              LINE(base_obj, BORDER_TOP, BORDER_SELECTION, ox, oy - 1, lw , 1, 
visibility);
               LINE(base_obj, BORDER_BOTTOM, BORDER_SELECTION, ox, oy + oh - 1, 
lw, 1, visibility);
               LINE(base_obj, BORDER_RIGHT, BORDER_SELECTION, ox + ow - 1, oy - 
1, 1, lh, visibility);
               LINE(base_obj, BORDER_LEFT, BORDER_SELECTION, ox, oy, 1, lh, 
visibility);
@@ -371,7 +378,7 @@ _wdg_border_draw(const Gui_Widget *wdg, Eina_Bool 
visibility, int border_type_co
               MARKER(base_obj, BORDER_MARKER_TOP, ox + ow / 2 - hs / 2, oy - 1 
- hs - 1, visibility);
               MARKER(base_obj, BORDER_MARKER_TOP_RIGHT, ox + ow, oy - 1 - hs - 
1, visibility);
               MARKER(base_obj, BORDER_MARKER_RIGHT, ox + ow, oy + oh / 2 - hs 
/ 2, visibility);
-              MARKER(base_obj, BORDER_MARKER_BOTTOM_RIGHT, ox + ow - 1, oy + 
oh - 1, visibility);
+              MARKER(base_obj, BORDER_MARKER_BOTTOM_RIGHT, ox + ow - 1, oy + 
oh, visibility);
               MARKER(base_obj, BORDER_MARKER_BOTTOM, ox + ow / 2 - hs / 2, oy 
+ oh, visibility);
               MARKER(base_obj, BORDER_MARKER_BOTTOM_LEFT, ox - 1 - hs, oy + 
oh, visibility);
               MARKER(base_obj, BORDER_MARKER_LEFT, ox - 1 - hs, oy + oh / 2 - 
hs / 2, visibility);
@@ -392,36 +399,6 @@ _wdg_border_draw(const Gui_Widget *wdg, Eina_Bool 
visibility, int border_type_co
 #undef MARKER
 #undef STR
 
-static Eina_Bool
-_frame_mouse_move(void *data EINA_UNUSED, Eo *fr, const Eo_Event_Description 
*desc EINA_UNUSED, void *event_info EINA_UNUSED)
-{
-   Evas_Coord ox, oy, ow, oh;
-   Evas_Event_Mouse_Move *ev = event_info;
-   Gui_Widget *wdg;
-   Gui_Widget_Property *prop;
-
-   elm_grid_pack_get(fr, &ox, &oy, &ow, &oh);
-
-   ox = ox + (ev->cur.canvas.x - ev->prev.canvas.x);
-   oy = oy + (ev->cur.canvas.y - ev->prev.canvas.y);
-
-   eo_do(fr, wdg = eo_key_data_get("winwdg"));
-
-   /* FIXME: Move frame here, because we don't know if win must have position 
property*/
-   elm_grid_pack_set(fr, ox, oy, ow, oh);
-   prop = wdg_prop_get(wdg, DB_DEF_EFL_GFX_BASE_CLASS, POSITION_SET);
-   if (prop)
-     {
-        Gui_Value *val;
-        val = prop_value_nth_get(prop, 0);
-        gui_value_int_set(val, ox);
-        val = prop_value_nth_get(prop, 1);
-        gui_value_int_set(val, oy);
-        propview_item_update(prop);
-     }
-   return EO_CALLBACK_CONTINUE;
-}
-
 const Gui_Widget*
 _editor_wdg_selected_get()
 {
@@ -579,9 +556,17 @@ typedef struct
    void *data;
    Gui_Widget_Property *prop_size;
    Gui_Widget_Property *prop_pos;
+   Evas_Coord down_x;
+   Evas_Coord down_y;
+   Evas_Coord object_w;
+   Evas_Coord object_h;
+   Evas_Coord object_x;
+   Evas_Coord object_y;
+   Evas_Coord delta_x;
+   Evas_Coord delta_y;
 } _Marker_Move_Data;
 
-_Marker_Move_Data _mmd;
+static _Marker_Move_Data _mmd = {NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0};
 
 static Eina_Bool
 _drag_widget_start(void *data)
@@ -615,7 +600,8 @@ _mouse_down_main(void *data EINA_UNUSED, Eo *obj, const 
Eo_Event_Description *de
    drag_candidate = wdg_main;
    Evas_Coord x, y;
    eo_do(obj, efl_gfx_position_get(&x, &y));
-   _drag_widget_iterate(&drag_candidate, session, ev->canvas.x - x, 
ev->canvas.y - y);
+   double scale = gui_context_scale_get(_active_context_get());
+   _drag_widget_iterate(&drag_candidate, session, (ev->canvas.x - x) / scale, 
(ev->canvas.y - y) / scale);
    /* Case, when clicking on empty window. */
    if (drag_candidate == wdg_main)
      {
@@ -673,12 +659,14 @@ _mouse_up_main(void *data EINA_UNUSED, Eo *obj 
EINA_UNUSED, const Eo_Event_Descr
 static Eina_Bool
 _marker_mouse_move(void *data, Eo *marker EINA_UNUSED, const 
Eo_Event_Description *desc EINA_UNUSED, void *event_info)
 {
-   Gui_Session *session = (Gui_Session *) 
gui_context_editor_session_get(_active_context_get());
+   Gui_Context *ctx = _active_context_get();
+   double scale = gui_context_scale_get(ctx);
+   Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(ctx);
    Eo *weo;
-   Evas_Coord ox, oy, ow, oh, minw, minh, dx, dy;
+   Evas_Coord ox, oy, ow, oh, minw, minh;
    /* Pointer coords inside canvas: global canvas for windows,
     * local canvas(inlined img) for other objects. */
-   Evas_Coord canvas_ptr_x, canvas_ptr_y;
+   //Evas_Coord canvas_ptr_x, canvas_ptr_y;
    Evas_Event_Mouse_Move *ev = event_info;
    /*FIXME: type */
    Border_Type border = (int) (intptr_t) data;
@@ -686,9 +674,6 @@ _marker_mouse_move(void *data, Eo *marker EINA_UNUSED, 
const Eo_Event_Descriptio
    Eo *cur_logo = NULL;
    const Gui_Widget *wdg = _editor_wdg_selected_get();
 
-   dx = ev->cur.canvas.x - ev->prev.canvas.x;
-   dy = ev->cur.canvas.y - ev->prev.canvas.y;
-
    /* Cursor description is saved in base object.
     * base object is win's Eo for widget EINA_UNUSED,
     * and canvas(main window) for frame. */
@@ -705,17 +690,14 @@ _marker_mouse_move(void *data, Eo *marker EINA_UNUSED, 
const Eo_Event_Descriptio
         Eo *ww = session_eo_get(session, wdg);
         eo_do(ww, evas_obj_size_hint_min_get(&minw, &minh));
         intptr_t dw, dh;
-        eo_do(weo, dw = (intptr_t) eo_key_data_get("dw"));
-        eo_do(weo, dh = (intptr_t) eo_key_data_get("dh"));
+        eo_do(weo, dw = (intptr_t) eo_key_data_get(FRAME_DELTA_W));
+        eo_do(weo, dh = (intptr_t) eo_key_data_get(FRAME_DELTA_H));
         minw += dw;
         minh += dh;
 
         elm_grid_pack_get(weo, &ox, &oy, &ow, &oh);
         Evas_Coord cx, cy;
         eo_do(canvas_get(), efl_gfx_position_get(&cx, &cy));
-        /* Calculate cursor coordinates inside grid */
-        canvas_ptr_x = ev->prev.canvas.x - cx;
-        canvas_ptr_y = ev->prev.canvas.y - cy;
      }
    else
      {
@@ -726,55 +708,72 @@ _marker_mouse_move(void *data, Eo *marker EINA_UNUSED, 
const Eo_Event_Descriptio
         eo_do(weo, evas_obj_size_hint_min_get(&minw, &minh));
         eo_do(weo, efl_gfx_position_get(&ox, &oy));
         eo_do(weo, efl_gfx_size_get(&ow, &oh));
-        canvas_ptr_x = ev->prev.canvas.x;
-        canvas_ptr_y = ev->prev.canvas.y;
+        /* All objects inside windows are located on a canvas(not grid as main 
windows),
+         * so no need to apply scale to delta. */
+        scale = 1.0;
      }
 
    eo_do(base_obj, cur_logo = eo_key_data_get("cursor"));
    if (cur_logo)
      eo_do(cur_logo, efl_gfx_position_set(ev->cur.canvas.x + 7, 
ev->cur.canvas.y + 5));
 
+   Eina_Bool vert_up = EINA_FALSE, hor_up = EINA_FALSE;
+   Evas_Coord new_w = _mmd.object_w, new_h = _mmd.object_h, new_x = 
_mmd.object_x, new_y = _mmd.object_y;
    if (border & BORDER_MARKER_LEFT)
      {
-        if ((canvas_ptr_x < ox) && ((ow - dx) > 0) && ((ow - dx) >= minw))
+        _mmd.delta_x = - _mmd.down_x + ev->cur.canvas.x;
+        new_w = _mmd.object_w - _mmd.delta_x / scale;
+        new_x = _mmd.object_x + _mmd.delta_x / scale;
+        if (new_w > minw && (new_x < _mmd.object_x + _mmd.object_w))
           {
-             ow = ow - dx;
-             ox = ox + dx;
+             hor_up = EINA_TRUE;
           }
      }
    else if (border & BORDER_MARKER_RIGHT)
      {
-        if ((canvas_ptr_x > (ox + ow)) && ((ow + dx) >= minw))
+        _mmd.delta_x = - _mmd.down_x + ev->cur.canvas.x;
+        new_w = _mmd.object_w + _mmd.delta_x / scale;
+        if (new_w > minw)
           {
-             ow = ow + dx;
+             hor_up = EINA_TRUE;
           }
      }
 
    if (border & BORDER_MARKER_TOP)
      {
-        if ((canvas_ptr_y < oy) && ((oh - dy) > 0) && ((oh - dy) >= minh))
+        _mmd.delta_y = - _mmd.down_y + ev->cur.canvas.y;
+        new_h = _mmd.object_h - _mmd.delta_y / scale;
+        new_y = _mmd.object_y + _mmd.delta_y / scale;
+        if (new_h >= minh)
           {
-             oh = oh - dy;
-             oy = oy + dy;
+             vert_up = EINA_TRUE;
           }
      }
    else if (border & BORDER_MARKER_BOTTOM)
      {
-        if ((canvas_ptr_y >= (oy + oh)) && ((oh + dy) >= minh))
+        _mmd.delta_y = - _mmd.down_y + ev->cur.canvas.y;
+        new_h = _mmd.object_h + _mmd.delta_y / scale;
+        if (new_h > minh)
           {
-             oh = oh + dy;
+             vert_up = EINA_TRUE;
           }
      }
 
+   if (!hor_up && !vert_up)
+     return EO_CALLBACK_CONTINUE;
+
    /* Set position */
    if (IS_MAIN(wdg))
      {
-        elm_grid_pack_set(weo, ox, oy, ow, oh);
+        elm_grid_pack_set(weo, (hor_up) ? new_x : ox,
+                               (vert_up) ? new_y : oy,
+                               (hor_up) ? new_w : ow,
+                               (vert_up) ? new_h : oh);
      }
    else
      {
-        eo_do(weo, efl_gfx_position_set(ox, oy));
-        eo_do(weo, efl_gfx_size_set(ow, oh));
+        eo_do(weo, efl_gfx_position_set(hor_up ? new_x : ox, (vert_up) ? new_y 
: oy));
+        eo_do(weo, efl_gfx_size_set(hor_up ? new_w : ow, (vert_up) ? new_h : 
oh));
      }
 
    if (IS_MAIN(wdg))
@@ -787,20 +786,29 @@ _marker_mouse_move(void *data, Eo *marker EINA_UNUSED, 
const Eo_Event_Descriptio
              Op_Desc *op = db_mro_op_desc_get(wdg_class_name_get(wdg), 
DB_DEF_EFL_GFX_BASE_CLASS, SIZE_SET);
              prop = prop_create_for_op(op);
              wdg_prop_add((Gui_Widget *) wdg, prop);
+
+             val = prop_value_nth_get(prop, 0);
+             gui_value_int_set(val, new_w);
+             val = prop_value_nth_get(prop, 1);
+             gui_value_int_set(val, new_h);
           }
 
-        Evas_Coord dw, dh;
-        eo_do(weo, dw = (Evas_Coord) (intptr_t) eo_key_data_get("dw"));
-        eo_do(weo, dh = (Evas_Coord) (intptr_t) eo_key_data_get("dh"));
-        /* ow and oh are frame's sizes, we need to subtract delta,
+        //Evas_Coord dw, dh;
+        //eo_do(weo, dw = (Evas_Coord) (intptr_t) 
eo_key_data_get(FRAME_DELTA_W));
+        //eo_do(weo, dh = (Evas_Coord) (intptr_t) 
eo_key_data_get(FRAME_DELTA_H));
+        /* new_w and new_h are frame's sizes, we need to subtract delta,
          * to get window's size.*/
-        ow = ow - dw;
-        oh = oh - dh;
 
-        val = prop_value_nth_get(prop, 0);
-        gui_value_int_set(val, ow);
-        val = prop_value_nth_get(prop, 1);
-        gui_value_int_set(val, oh);
+        if (hor_up)
+          {
+             val = prop_value_nth_get(prop, 0);
+             gui_value_int_set(val, new_w);
+          }
+        if (vert_up)
+          {
+             val = prop_value_nth_get(prop, 1);
+             gui_value_int_set(val, new_h);
+          }
         propview_item_update(prop);
         /* win has size prop, so move it through manager*/
         manager_widget_property_add(session, wdg, prop, MODE_EDITOR, NULL);
@@ -809,7 +817,7 @@ _marker_mouse_move(void *data, Eo *marker EINA_UNUSED, 
const Eo_Event_Descriptio
           {
              Eo *main_obj_eo = session_eo_get(session, wdg);
              Eo *main_obj_win = eo_do_ret(main_obj_eo, main_obj_win, 
eo_key_data_get("__editor_win"));
-             eo_do(main_obj_win, efl_gfx_size_set(ow, oh));
+             eo_do(main_obj_win, efl_gfx_size_set(new_w, new_h));
           }
      }
    else
@@ -824,11 +832,22 @@ _marker_mouse_move(void *data, Eo *marker EINA_UNUSED, 
const Eo_Event_Descriptio
              Op_Desc *op = db_mro_op_desc_get(wdg_class_name_get(wdg), 
DB_DEF_EFL_GFX_BASE_CLASS, SIZE_SET);
              prop = prop_create_for_op(op);
              wdg_prop_add((Gui_Widget *) wdg, prop);
+
+             val = prop_value_nth_get(prop, 0);
+             gui_value_int_set(val, new_w);
+             val = prop_value_nth_get(prop, 1);
+             gui_value_int_set(val, new_h);
+          }
+        if (hor_up)
+          {
+             val = prop_value_nth_get(prop, 0);
+             gui_value_int_set(val, new_w);
+          }
+        if (vert_up)
+          {
+             val = prop_value_nth_get(prop, 1);
+             gui_value_int_set(val, new_h);
           }
-        val = prop_value_nth_get(prop, 0);
-        gui_value_int_set(val, ow);
-        val = prop_value_nth_get(prop, 1);
-        gui_value_int_set(val, oh);
         propview_item_update(prop);
 
         prop = wdg_prop_get(wdg, DB_DEF_EFL_GFX_BASE_CLASS, POSITION_SET);
@@ -837,11 +856,22 @@ _marker_mouse_move(void *data, Eo *marker EINA_UNUSED, 
const Eo_Event_Descriptio
              Op_Desc *op = db_mro_op_desc_get(wdg_class_name_get(wdg), 
DB_DEF_EFL_GFX_BASE_CLASS, POSITION_SET);
              prop = prop_create_for_op(op);
              wdg_prop_add((Gui_Widget *) wdg, prop);
+
+             val = prop_value_nth_get(prop, 0);
+             gui_value_int_set(val, new_x);
+             val = prop_value_nth_get(prop, 1);
+             gui_value_int_set(val, new_y);
+          }
+        if (hor_up)
+          {
+             val = prop_value_nth_get(prop, 0);
+             gui_value_int_set(val, new_x);
+          }
+        if (vert_up)
+          {
+             val = prop_value_nth_get(prop, 1);
+             gui_value_int_set(val, new_y);
           }
-        val = prop_value_nth_get(prop, 0);
-        gui_value_int_set(val, ox);
-        val = prop_value_nth_get(prop, 1);
-        gui_value_int_set(val, oy);
         propview_item_update(prop);
      }
 
@@ -852,6 +882,11 @@ static Eina_Bool
 _marker_mouse_down(void *data, Eo *obj, const Eo_Event_Description *desc 
EINA_UNUSED, void *event_info EINA_UNUSED)
 {
    const Gui_Widget *wdg = _editor_wdg_selected_get();
+   Evas_Event_Mouse_Down *ev = event_info;
+   _mmd.down_x = ev->output.x;
+   _mmd.down_y = ev->output.y;
+   _mmd.delta_x = 0;
+   _mmd.delta_y = 0;
 
    Gui_Widget_Property *prop;
    prop = wdg_prop_get(wdg, DB_DEF_EFL_GFX_BASE_CLASS, SIZE_SET);
@@ -860,6 +895,9 @@ _marker_mouse_down(void *data, Eo *obj, const 
Eo_Event_Description *desc EINA_UN
         _mmd.prop_size = prop;
         prop_ref(prop);
         wdg_prop_remove((Gui_Widget *) wdg, prop);
+
+        _mmd.object_w = INT_GET(prop_value_nth_get(prop, 0));
+        _mmd.object_h = INT_GET(prop_value_nth_get(prop, 1));
      }
    if (!IS_MAIN(wdg))
      {
@@ -869,8 +907,19 @@ _marker_mouse_down(void *data, Eo *obj, const 
Eo_Event_Description *desc EINA_UN
              _mmd.prop_pos = prop;
              prop_ref(prop);
              wdg_prop_remove((Gui_Widget *) wdg, prop);
+             _mmd.object_x = INT_GET(prop_value_nth_get(prop, 0));
+             _mmd.object_y = INT_GET(prop_value_nth_get(prop, 1));
           }
      }
+   else
+     {
+        Evas_Coord ox, oy, ow, oh;
+        Main_Wdg_Info *wi = wdg_data_get(wdg, MAIN_WDG_INFO);
+        Eo *fr = main_wdg_info_frame_get(wi);
+        elm_grid_pack_get(fr, &ox, &oy, &ow, &oh);
+        _mmd.object_x = ox;
+        _mmd.object_y = oy;
+     }
 
    eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_MOVE, 
_marker_mouse_move, data));
    eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_UP, 
_marker_mouse_up, data));
@@ -952,6 +1001,14 @@ end:
         prop_unref(_mmd.prop_pos);
         _mmd.prop_pos = NULL;
      }
+   _mmd.down_x = 0;
+   _mmd.down_y = 0;
+   _mmd.object_w = 0;
+   _mmd.object_h = 0;
+   _mmd.object_x = 0;
+   _mmd.object_y = 0;
+   _mmd.delta_x = 0;
+   _mmd.delta_y = 0;
    return EO_CALLBACK_CONTINUE;
 }
 
@@ -1037,7 +1094,42 @@ _marker_mouse_out(void *data EINA_UNUSED, Eo *obj 
EINA_UNUSED, const Eo_Event_De
 }
 
 static Eina_Bool
-_frame_mouse_down(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Description 
*desc EINA_UNUSED, void *event_info EINA_UNUSED)
+_frame_mouse_move(void *data EINA_UNUSED, Eo *fr, const Eo_Event_Description 
*desc EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Coord ox, oy, ow, oh;
+   Evas_Event_Mouse_Move *ev = event_info;
+   Gui_Widget *wdg;
+   Gui_Widget_Property *prop;
+   double scale = gui_context_scale_get(_active_context_get());
+
+   elm_grid_pack_get(fr, &ox, &oy, &ow, &oh);
+
+
+   _mmd.delta_x = ev->cur.canvas.x - _mmd.down_x;
+   _mmd.delta_y = ev->cur.canvas.y - _mmd.down_y;
+
+   ox = _mmd.object_x + _mmd.delta_x / scale;
+   oy = _mmd.object_y + _mmd.delta_y / scale;
+
+   eo_do(fr, wdg = eo_key_data_get("winwdg"));
+
+   /* FIXME: Move frame here, because we don't know if win must have position 
property*/
+   elm_grid_pack_set(fr, ox, oy, ow, oh);
+   prop = wdg_prop_get(wdg, DB_DEF_EFL_GFX_BASE_CLASS, POSITION_SET);
+   if (prop)
+     {
+        Gui_Value *val;
+        val = prop_value_nth_get(prop, 0);
+        gui_value_int_set(val, ox);
+        val = prop_value_nth_get(prop, 1);
+        gui_value_int_set(val, oy);
+        //propview_item_update(prop);
+     }
+   return EO_CALLBACK_CONTINUE;
+}
+
+static Eina_Bool
+_frame_mouse_down(void *data EINA_UNUSED, Eo *obj, const Eo_Event_Description 
*desc EINA_UNUSED, void *event_info)
 {
    Gui_Widget *wdg;
    drag_started = EINA_FALSE;
@@ -1046,6 +1138,22 @@ _frame_mouse_down(void *data EINA_UNUSED, Eo *obj, const 
Eo_Event_Description *d
    _editor_wdg_selected_set(wdg);
    objtree_item_selected_set(wdg);
 
+   if (IS_MAIN(wdg))
+     {
+        Evas_Event_Mouse_Down *ev = event_info;
+        Evas_Coord ox, oy, ow, oh;
+        elm_grid_pack_get(obj, &ox, &oy, &ow, &oh);
+
+        _mmd.down_x = ev->output.x;
+        _mmd.down_y = ev->output.y;
+        _mmd.delta_x = 0;
+        _mmd.delta_y = 0;
+        _mmd.object_x = ox;
+        _mmd.object_y = oy;
+        _mmd.object_w = ow;
+        _mmd.object_h = oh;
+     }
+
    /* Don't use dnd for dragging window around canvas. */
    if (IS_WIN(wdg))
      {
@@ -1101,6 +1209,14 @@ _frame_mouse_up(void *data EINA_UNUSED, Eo *obj, const 
Eo_Event_Description *des
           }
      }
    _canvas_resize_cb(NULL, g->main_win->canvas_scroller, NULL, NULL);
+   _mmd.down_x = 0;
+   _mmd.down_y = 0;
+   _mmd.object_w = 0;
+   _mmd.object_h = 0;
+   _mmd.object_x = 0;
+   _mmd.object_y = 0;
+   _mmd.delta_x = 0;
+   _mmd.delta_y = 0;
    return EO_CALLBACK_CONTINUE;
 }
 
@@ -1243,9 +1359,8 @@ _win_resize(void *data EINA_UNUSED, Eo *o, const 
Eo_Event_Description *desc EINA
    eo_do(o, fr = eo_key_data_get("__editor_frame"));
 
    intptr_t dw, dh;
-   eo_do(fr, dw = (intptr_t) eo_key_data_get("dw"));
-   eo_do(fr, dh = (intptr_t) eo_key_data_get("dh"));
-   eo_do(fr, efl_gfx_size_set(ow + dw, oh + dh));
+   eo_do(fr, dw = (intptr_t) eo_key_data_get(FRAME_DELTA_W));
+   eo_do(fr, dh = (intptr_t) eo_key_data_get(FRAME_DELTA_H));
 
    Evas_Coord x, y, w, h;
    elm_grid_pack_get(fr, &x, &y, &w, &h);
@@ -2186,6 +2301,7 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
    Gui_Widget *wdg = data;
    DnD_Info *di = NULL;
    Eo *wdg_eo = NULL;
+   double scale = gui_context_scale_get(_active_context_get());
    /* If wdg == NULL, then canvas is a drop target or we have a error.*/
    if (wdg)
      {
@@ -2193,6 +2309,8 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
         di = wdg_data_get(wdg_main_wdg_get(wdg), EDITOR_DND_DATA);
         wdg_eo = session_eo_get(session, wdg);
         _wdg_border_draw(wdg, EINA_TRUE, BORDER_DROP_TARGET);
+        x = x / scale;
+        y = y / scale;
      }
    else if (canvas_drop_target != NULL)
      {
@@ -2201,8 +2319,24 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
          * but we are inside scroller. */
         Evas_Coord obj_x = 0, obj_y = 0;
         eo_do(canvas_drop_target, efl_gfx_position_get(&obj_x, &obj_y));
-        x = x - obj_x;
-        y = y - obj_y;
+
+        Evas_Coord delta_x, delta_y;
+        delta_x = x - _mmd.down_x;
+        delta_y = y - _mmd.down_y;
+        /* _mmd.down_x and _mmd.down_y are ) when dragging object inside 
window.
+         * But if we are in current point, object is dragged from window on 
canvas,
+         * so take pointer coords on canvas. )*/
+        if (_mmd.down_x == 0 && _mmd.down_y == 0)
+          {
+             x = (x - obj_x) / scale;
+             y = (y - obj_y) / scale;
+          }
+        /* When dragging frame around canvas, calculate respectivly to object 
coords. */
+        else
+          {
+             x = _mmd.object_x + delta_x / scale;
+             y = _mmd.object_y + delta_y / scale;
+          }
      }
    else
      {
@@ -2232,7 +2366,7 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
         Eo *child, *candidate = NULL;
         int idx = 0;
         //if (di->packed)
-          eo_do(wdg_eo, elm_obj_box_unpack(di->eo_cur));
+        eo_do(wdg_eo, elm_obj_box_unpack(di->eo_cur));
         Eina_List *box_chld = eo_do_ret(wdg_eo, box_chld, 
elm_obj_box_children_get()), *l;
         di->box_pack_idx = 0;
         EINA_LIST_FOREACH(box_chld, l, child)
@@ -2463,7 +2597,7 @@ _drag_start_cb(const Gui_Widget *wdg, const Eo *_wdg_eo)
         if (wi)
           {
              Eo *fr = main_wdg_info_frame_get(wi);
-             eo_do(fr, efl_gfx_position_get(&x, &y));
+             elm_grid_pack_get(fr, &x, &y, NULL, NULL);
              eo_do(fr, efl_gfx_visible_set(EINA_FALSE));
           }
         _drop_target_pos(NULL, 
egui_layout_gui_get()->main_win->canvas_scroller, x, y, 
ELM_XDND_ACTION_UNKNOWN);
@@ -2644,8 +2778,8 @@ _widget_add(Gui_Session *session, const Gui_Widget *wdg, 
void *data)
              dw = ow - im_w;
              dh = oh - im_h;
              /* Save deltas in frame data*/
-             eo_do(fr, eo_key_data_set("dw", (void *) (intptr_t) dw));
-             eo_do(fr, eo_key_data_set("dh", (void *) (intptr_t) dh));
+             eo_do(fr, eo_key_data_set(FRAME_DELTA_W, (void *) (intptr_t) dw));
+             eo_do(fr, eo_key_data_set(FRAME_DELTA_H, (void *) (intptr_t) dh));
              /* Resize properly. */
              eo_do(iwin, efl_gfx_size_set(ow, oh));
              elm_grid_pack_set(fr, ox, oy, ow + dw, oh + dh);
@@ -4383,6 +4517,7 @@ _switch_to_context(Gui_Context *ctx)
    Gui_Widget *wdg = gui_context_data_get(ctx, SELECTED_WDG);
    _editor_wdg_selected_set(wdg);
    objtree_item_selected_set(wdg);
+   _canvas_resize_cb(NULL, g->main_win->canvas_scroller, NULL, NULL);
 }
 
 static void
@@ -4583,6 +4718,44 @@ _key_binding_wdg_del_cb(void *data EINA_UNUSED)
      }
 }
 
+static double _scale_step = 0.1;
+
+/* Update text in zoom label. */
+static void
+_zoom_label_update(double zoom)
+{
+   char zoom_str[10] = {'\0'};
+   sprintf(zoom_str, "%.f %%", zoom);
+   eo_do(g->main_win->zoom_label, elm_obj_widget_part_text_set(NULL, 
zoom_str));
+}
+
+static void
+_key_binding_zoom_cb(void *data)
+{
+   double scale;
+   Gui_Context *ctx = _active_context_get();
+   int z = (intptr_t) data;
+   if (!ctx) return;
+
+   scale = gui_context_scale_get(ctx);
+
+   if (z == -1)
+     {
+        scale = scale + _scale_step;
+     }
+   else if (z == 1)
+     {
+        if (scale <= 0.11) return;
+        scale = scale - _scale_step;
+     }
+   else
+     {
+        scale = 1.0;
+     }
+   gui_context_scale_set(ctx, scale);
+   _canvas_resize_cb(NULL, g->main_win->canvas_scroller, NULL, NULL);
+}
+
 Eina_Bool
 _theme_selector_hover_selected_cb(void *data EINA_UNUSED, Eo *obj, const 
Eo_Event_Description *desc EINA_UNUSED, void *event_info)
 {
@@ -4676,6 +4849,7 @@ _canvas_resize_cb(void *data EINA_UNUSED, Eo *obj, const 
Eo_Event_Description *d
 {
    Evas_Coord right_x, bottom_y, left_x, top_y;
    _max_coords_get(&left_x, &top_y, &right_x, &bottom_y);
+   Gui_Context *ctx = _active_context_get();
    if (g)
      {
         Evas_Coord dx = 17, dy = 2, w, h;
@@ -4698,7 +4872,6 @@ _canvas_resize_cb(void *data EINA_UNUSED, Eo *obj, const 
Eo_Event_Description *d
              Evas_Coord region_x, region_y, region_w, region_h;
              elm_scroller_region_get(obj, &region_x, &region_y, &region_w, 
&region_h);
              Eid *wdg_id;
-             Gui_Context *ctx = _active_context_get();
              if (!ctx) return EO_CALLBACK_CONTINUE;
              Eina_List *main_widgets = gui_context_main_widgets_get(ctx), *itr;
              EINA_LIST_FOREACH(main_widgets, itr, wdg_id)
@@ -4715,10 +4888,25 @@ _canvas_resize_cb(void *data EINA_UNUSED, Eo *obj, 
const Eo_Event_Description *d
                                                (top_y < 0) ? -top_y : 0,
                                                region_w, region_h);
           }
+        double scale =  gui_context_scale_get(ctx);
+        eo_do(g->main_win->canvas_grid, evas_obj_size_hint_min_set((w - dx) * 
scale, (h - dy) * scale));
+        _zoom_label_update(scale * 100);
      }
+
    return EO_CALLBACK_CONTINUE;
 }
 
+static Eina_Bool
+_mouse_wheel_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *ev 
EINA_UNUSED)
+{
+   /* event->z == -1 for push, and 1 for pull */
+   Ecore_Event_Mouse_Wheel *event = ev;
+   Eina_Bool ctrl = !!(event->modifiers & ECORE_EVENT_MODIFIER_CTRL);
+   if (!ctrl) return ECORE_CALLBACK_PASS_ON;
+   _key_binding_zoom_cb((void *) (intptr_t) event->z);
+   return ECORE_CALLBACK_PASS_ON;
+}
+
 void
 editor_init(GuiLogicCbs *_guilogic_cbs)
 {
@@ -4780,5 +4968,10 @@ editor_init(GuiLogicCbs *_guilogic_cbs)
    key_binding_new(_key_binding_undo_cb, NULL, "ctrl", "z", NULL);
    key_binding_new(_key_binding_redo_cb, NULL, "ctrl", "shift", "z", NULL);
    key_binding_new(_key_binding_wdg_del_cb, NULL, "delete", NULL);
+   key_binding_new(_key_binding_zoom_cb, (void *) (intptr_t) -1, "ctrl", 
"equal", NULL);
+   key_binding_new(_key_binding_zoom_cb, (void *) (intptr_t) 1, "ctrl", 
"minus", NULL);
+   key_binding_new(_key_binding_zoom_cb, (void *) (intptr_t) 0, "ctrl", "0", 
NULL);
+
+   ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _mouse_wheel_cb, NULL);
 }
 
diff --git a/src/bin/gui/egui_layout.json b/src/bin/gui/egui_layout.json
index a3122af..ad12d4b 100644
--- a/src/bin/gui/egui_layout.json
+++ b/src/bin/gui/egui_layout.json
@@ -4072,7 +4072,7 @@
         "Evas.Object.size_hint_align":[-1, 0],
         "Evas.Object.size_hint_weight":[1, 0]
       },
-      "Contains":["theme_selector_label", "theme_selector_hoversel"]
+      "Contains":["theme_selector_label", "theme_selector_hoversel", 
"zoom_label"]
     },
     "theme_selector_label":
     {
@@ -4109,6 +4109,22 @@
       {
         "selected":["Invoke", "_theme_selector_hover_selected_cb", null]
       }
+    },
+    "zoom_label":
+    {
+      "Desc":
+      {
+        "parent":"theme_selector_box",
+        "class":"Elm.Label",
+        "public":true
+      },
+      "Properties":
+      {
+        "Evas.Object.size_hint_weight":[0, 0],
+        "Evas.Object.size_hint_align":[1, 0],
+        "Efl.Gfx.Base.visible":[true],
+        "Elm.Widget.part_text":[null, "100%"]
+      }
     }
   }
  }
diff --git a/src/lib/gui_widget.c b/src/lib/gui_widget.c
index b91027c..be9b95a 100644
--- a/src/lib/gui_widget.c
+++ b/src/lib/gui_widget.c
@@ -167,6 +167,8 @@ struct _Gui_Context
    Eina_List *current_memento;
    Eina_List *memento_list;
 
+   double scale;
+
    char *edit_theme_name;
 };
 
@@ -336,6 +338,7 @@ gui_context_new()
    ctx->id = i;
    context_array[i] = ctx;
 
+   ctx->scale = 1.0;
    ctx->wdg_list = NULL;
    ctx->main_widgets = NULL;
    ctx->names_hash = eina_hash_string_superfast_new(NULL);
@@ -695,6 +698,18 @@ gui_context_edit_theme_name_get(const Gui_Context *ctx)
    return ctx->edit_theme_name;
 }
 
+double
+gui_context_scale_get(const Gui_Context *ctx)
+{
+   return ctx->scale;
+}
+
+void
+gui_context_scale_set(Gui_Context *ctx, double scale)
+{
+   ctx->scale = scale;
+}
+
 Eid_Data *
 _eid_data_get(Eid *eid)
 {
diff --git a/src/lib/gui_widget.h b/src/lib/gui_widget.h
index e5d4839..656f332 100644
--- a/src/lib/gui_widget.h
+++ b/src/lib/gui_widget.h
@@ -982,4 +982,10 @@ gui_context_edit_theme_name_set(Gui_Context *ctx, const 
char *theme_name);
 const char *
 gui_context_edit_theme_name_get(const Gui_Context *ctx);
 
+double
+gui_context_scale_get(const Gui_Context *ctx);
+
+void
+gui_context_scale_set(Gui_Context *ctx, double scale);
+
 #endif

-- 


Reply via email to