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, ®ion_x, ®ion_y, ®ion_w, ®ion_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 --