From 91de631a7bc85f81891719ae6e49bf37d661436e Mon Sep 17 00:00:00 2001 From: Stephen Houston Date: Thu, 12 Feb 2015 13:19:27 -0600 Subject: [PATCH] Ephoto: Allow the cropper to freely move and allow full handle control. --- data/themes/crop.edc | 351 ++++++++++++++++++++------------ src/bin/Makefile.am | 3 +- src/bin/ephoto.h | 1 + src/bin/ephoto_single_browser.c | 85 +------- 4 files changed, 235 insertions(+), 205 deletions(-) diff --git a/data/themes/crop.edc b/data/themes/crop.edc index dc68409..39595fd 100644 --- a/data/themes/crop.edc +++ b/data/themes/crop.edc @@ -1,143 +1,238 @@ collections { -group { name: "image_cropper"; - parts { - part { name: "background"; - type: RECT; - description { state: "default" 0.0; - color: 255 255 255 0; + group { name: "ephoto,image,cropper,base"; + script { + public message(Msg_Type:type, id, ...) { + if ((type == MSG_INT_SET) && (id == 1)) { + new cox, coy, cw, ch, pox, poy; + + cox = getarg(2); + coy = getarg(3); + cw = getarg(4); + ch = getarg(5); + + get_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, pox, poy); + + cox += pox; + coy += poy; + + custom_state(PART:"ephoto.swallow.cropper", "default", 0.0); + set_state_val(PART:"ephoto.swallow.cropper", STATE_MIN, cw, ch); + set_state_val(PART:"ephoto.swallow.cropper", STATE_MAX, cw, ch); + set_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, cox, coy); + set_state(PART:"ephoto.swallow.cropper", "custom", 0.0); + } } } - part { name: "clipper"; - type: RECT; - description { state: "default" 0.0; - color: 0 0 0 0; + parts { + part { name: "clipper"; + type: RECT; + description { state: "default" 0.0; + } } - description { state: "show" 0.0; - color: 255 255 255 255; + part { name: "ephoto.swallow.image"; + type: SWALLOW; + scale: 1; + mouse_events: 0; + clip_to: "clipper"; + description { state: "default" 0.0; + } } - } - part { name: "ephoto.swallow.image"; - type: SWALLOW; - scale: 1; - mouse_events: 0; - clip_to: "clipper"; - description { state: "default" 0.0; + part { name: "ephoto.swallow.cropper"; + type: SWALLOW; + scale: 1; + mouse_events: 1; + clip_to: "clipper"; + description { state: "default" 0.0; + } + } + part { name: "shader_top"; + type: RECT; + scale: 1; + mouse_events: 0; + clip_to: "clipper"; + description { state: "default" 0.0; + color: 0 0 0 200; + rel1.to: "clipper"; + rel1.relative: 0.0 0.0; + rel2.to: "ephoto.swallow.cropper"; + rel2.relative: 1.0 0.0; + } } - } - part { name: "shader_top"; - type: RECT; - scale: 1; - mouse_events: 0; - clip_to: "clipper"; - description { state: "default" 0.0; - color: 0 0 0 200; - rel1.to: "clipper"; - rel1.relative: 0.0 0.0; - rel2.to: "cropper"; - rel2.relative: 1.0 0.0; + part { name: "shader_left"; + type: RECT; + scale: 1; + mouse_events: 0; + clip_to: "clipper"; + description { state: "default" 0.0; + color: 0 0 0 200; + rel1.to: "shader_top"; + rel1.relative: 0.0 1.0; + rel2.to: "ephoto.swallow.cropper"; + rel2.relative: 0.0 1.0; + } } - } - part { name: "shader_left"; - type: RECT; - scale: 1; - mouse_events: 0; - clip_to: "clipper"; - description { state: "default" 0.0; - color: 0 0 0 200; - rel1.to: "shader_top"; - rel1.relative: 0.0 1.0; - rel2.to: "cropper"; - rel2.relative: 0.0 1.0; + part { name: "shader_bottom"; + type: RECT; + scale: 1; + mouse_events: 0; + clip_to: "clipper"; + description { state: "default" 0.0; + color: 0 0 0 200; + rel1.to: "shader_left"; + rel1.relative: 0.0 1.0; + rel2.to: "clipper"; + rel2.relative: 1.0 1.0; + } } - } - part { name: "shader_bottom"; - type: RECT; - scale: 1; - mouse_events: 0; - clip_to: "clipper"; - description { state: "default" 0.0; - color: 0 0 0 200; - rel1.to: "shader_left"; - rel1.relative: 0.0 1.0; - rel2.to: "clipper"; - rel2.relative: 1.0 1.0; - } - } - part { name: "shader_right"; - type: RECT; - scale: 1; - mouse_events: 0; - clip_to: "clipper"; - description { state: "default" 0.0; - color: 0 0 0 200; - rel1.to: "shader_top"; - rel1.relative: 1.0 0.0; - rel2.to: "shader_bottom"; - rel2.relative: 1.0 0.0; - } - } - part { name: "cropper"; - type: RECT; - scale: 1; - mouse_events: 0; - clip_to: "clipper"; - description { state: "default" 0.0; - color: 255 255 255 0; - rel1.to: "rel1_dragable"; - rel2.to: "rel2_dragable"; - } - } - part { name: "rel1_dragable"; - type: RECT; - scale: 1; - mouse_events: 1; - clip_to: "clipper"; - description { state: "default" 0.0; - color: 0 0 0 255; - min: 16 16; - max: 16 16; - } - dragable { - confine: "ephoto.swallow.image"; - x: 1 1 0; - y: 1 1 0; - } - } - part { name: "rel2_dragable"; - type: RECT; - scale: 1; - mouse_events: 1; - clip_to: "clipper"; - description { state: "default" 0.0; - color: 0 0 0 255; - min: 16 16; - max: 16 16; - } - dragable { - confine: "ephoto.swallow.image"; - x: 1 1 0; - y: 1 1 0; + part { name: "shader_right"; + type: RECT; + scale: 1; + mouse_events: 0; + clip_to: "clipper"; + description { state: "default" 0.0; + color: 0 0 0 200; + rel1.to: "shader_top"; + rel1.relative: 1.0 0.0; + rel2.to: "shader_bottom"; + rel2.relative: 1.0 0.0; + } } } } - programs { - program { name: "on_load_init"; - signal: "load"; - source: ""; - after: "on_load_show"; - script { - set_drag(PART:"rel1_dragable", 0.2, 0.2); - set_drag(PART:"rel2_dragable", 0.8, 0.8); + group { name: "ephoto,image,cropper"; + parts { + part { name: "cropper"; + type: RECT; + scale: 1; + mouse_events: 1; + description { state: "default" 0.0; + color: 255 255 255 0; + } + } + part { name: "dragger"; + type: RECT; + scale: 1; + mouse_events: 1; + description { state: "default" 0.0; + color: 255 255 255 0; + rel1.to: "cropper"; + rel1.relative: 0.0 0.0; + rel2.to: "cropper"; + rel2.relative: 1.0 1.0; + } + } + part { name: "handle2"; + type: RECT; + scale: 1; + mouse_events: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + min: 10 10; + max: 99999 10; + rel1.to: "cropper"; + rel1.relative: 0.0 0.0; + rel2.to: "cropper"; + rel2.relative: 1.0 0.0; + } + } + part { name: "handle4"; + type: RECT; + scale: 1; + mouse_events: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + min: 10 10; + max: 10 99999; + rel1.to: "cropper"; + rel1.relative: 1.0 0.0; + rel2.to: "cropper"; + rel2.relative: 1.0 1.0; + } + } + part { name: "handle6"; + type: RECT; + scale: 1; + mouse_events: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + min: 10 10; + max: 99999 10; + rel1.to: "cropper"; + rel1.relative: 0.0 1.0; + rel2.to: "cropper"; + rel2.relative: 1.0 1.0; + } + } + part { name: "handle8"; + type: RECT; + scale: 1; + mouse_events: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + min: 10 10; + max: 10 99999; + rel1.to: "cropper"; + rel1.relative: 0.0 0.0; + rel2.to: "cropper"; + rel2.relative: 0.0 1.0; + } + } + part { name: "handle1"; + type: RECT; + scale: 1; + mouse_events: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + min: 10 10; + max: 99999 10; + rel1.to: "cropper"; + rel1.relative: 0.0 0.0; + rel2.to: "cropper"; + rel2.relative: 0.0 0.0; + } + } + part { name: "handle3"; + type: RECT; + scale: 1; + mouse_events: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + min: 10 10; + max: 99999 10; + rel1.to: "cropper"; + rel1.relative: 1.0 0.0; + rel2.to: "cropper"; + rel2.relative: 1.0 0.0; + } + } + part { name: "handle5"; + type: RECT; + scale: 1; + mouse_events: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + min: 10 10; + max: 99999 10; + rel1.to: "cropper"; + rel1.relative: 1.0 1.0; + rel2.to: "cropper"; + rel2.relative: 1.0 1.0; + } + } + part { name: "handle7"; + type: RECT; + scale: 1; + mouse_events: 1; + description { state: "default" 0.0; + color: 0 0 0 255; + min: 10 10; + max: 99999 10; + rel1.to: "cropper"; + rel1.relative: 0.0 1.0; + rel2.to: "cropper"; + rel2.relative: 0.0 1.0; + } } - } - program { name: "on_load_show"; - action: STATE_SET "show" 0.0; - target: "clipper"; - transition: DECELERATE 0.25; - after: "emit_drag_signal"; - } - program { name: "emit_drag_signal"; - action: SIGNAL_EMIT "drag" "rel2_dragable"; } } } diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 905f450..bde2f99 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -19,7 +19,8 @@ ephoto_SOURCES = \ ephoto_config.c \ ephoto_thumb_browser.c \ ephoto_single_browser.c \ - ephoto_slideshow.c + ephoto_slideshow.c \ + ephoto_cropper.c noinst_HEADERS = ephoto.h EXTRA_DIST = ephoto.h diff --git a/src/bin/ephoto.h b/src/bin/ephoto.h index 5c7caa2..5ff11b0 100644 --- a/src/bin/ephoto.h +++ b/src/bin/ephoto.h @@ -46,6 +46,7 @@ void ephoto_about_window(Ephoto *em); Evas_Object *ephoto_single_browser_add(Ephoto *ephoto, Evas_Object *parent); void ephoto_single_browser_entry_set(Evas_Object *obj, Ephoto_Entry *entry); void ephoto_single_browser_path_pending_set(Evas_Object *obj, const char *path); +Evas_Object *ephoto_cropper_add(Evas_Object *parent, const char *file, const char *key); /* smart callbacks called: * "back" - the user wants to go back to the previous screen. */ diff --git a/src/bin/ephoto_single_browser.c b/src/bin/ephoto_single_browser.c index 929279a..ecd3703 100644 --- a/src/bin/ephoto_single_browser.c +++ b/src/bin/ephoto_single_browser.c @@ -685,8 +685,9 @@ _last_entry(Ephoto_Single_Browser *sb) static void _apply_crop(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Evas_Object *win = data; - Evas_Object *layout = evas_object_data_get(win, "layout"); - Evas_Object *image = evas_object_data_get(layout, "image"); + Evas_Object *cropper = evas_object_data_get(win, "cropper"); + Evas_Object *layout = evas_object_data_get(cropper, "layout"); + Evas_Object *image = evas_object_data_get(cropper, "image"); Evas_Object *edje = elm_layout_edje_get(layout); Evas_Object *image_object = elm_image_object_get(image); Evas_Object *crop; @@ -704,7 +705,7 @@ static void _apply_crop(void *data, Evas_Object *obj EINA_UNUSED, void *event_in evas_object_image_file_set(crop, path, key); evas_object_geometry_get(layout, &x, &y, &w, &h); - edje_object_part_geometry_get(edje, "cropper", &cx, &cy, &cw, &ch); + edje_object_part_geometry_get(edje, "ephoto.swallow.cropper", &cx, &cy, &cw, &ch); evas_object_image_size_get(crop, &iw, &ih); idata = evas_object_image_data_get(crop, EINA_FALSE); @@ -766,67 +767,13 @@ static void _cancel_crop(void *data, Evas_Object *obj EINA_UNUSED, void *event_i evas_object_del(win); } -static void _image_resize(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - Evas_Object *image = data; - int sx, sy, sw, sh, iw, ih, diffw, diffh; - - evas_object_geometry_get(obj, &sx, &sy, &sw, &sh); - evas_object_image_size_get(elm_image_object_get(image), &iw, &ih); - if (iw < sw && ih < sh) - { - diffw = sw - iw; - diffh = sh - ih; - diffw /= 2; - diffh /= 2; - evas_object_resize(obj, iw, ih); - evas_object_move(obj, sx+diffw, sy+diffh); - } - else - { - int nw, nh; - if (sw > sh) - { - nw = sw; - nh = ih*((double)sw/(double)iw); - if (nh > sh) - { - int onw, onh; - onw = nw; - onh = nh; - nh = sh; - nw = onw*((double)nh/(double)onh); - } - } - else - { - nh = sh; - nw = iw*((double)sh/(double)ih); - if (nw > sw) - { - int onw, onh; - onw = nw; - onh = nh; - nw = sw; - nh = onh*((double)nw/(double)onw); - } - } - diffw = sw - nw; - diffh = sh - nh; - diffw /= 2; - diffh /= 2; - evas_object_resize(obj, nw, nh); - evas_object_move(obj, sx+diffw, sy+diffh); - } -} - static void _crop_image(void *data, Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED) { const char *path, *key; Ephoto_Single_Browser *sb = data; Ephoto_Viewer *v = evas_object_data_get(sb->viewer, "viewer"); - Evas_Object *win, *box, *frame, *layout, *image, *hbox, *ic, *button; + Evas_Object *win, *box, *frame, *cropper, *hbox, *ic, *button; win = elm_win_inwin_add(sb->ephoto->win); evas_object_data_set(win, "single_browser", sb); @@ -847,23 +794,11 @@ _crop_image(void *data, Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED elm_box_pack_end(box, frame); evas_object_show(frame); - layout = elm_layout_add(frame); - elm_layout_file_set(layout, PACKAGE_DATA_DIR "/themes/crop.edj", "image_cropper"); - evas_object_data_set(win, "layout", layout); - evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_content_set(frame, layout); - evas_object_show(layout); - elm_image_file_get(v->image, &path, &key); - image = elm_image_add(frame); - elm_image_file_set(image, path, key); - evas_object_data_set(layout, "image", image); - evas_object_size_hint_weight_set(image, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(image, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_layout_content_set(layout, "ephoto.swallow.image", image); - evas_object_show(image); - + cropper = ephoto_cropper_add(frame, path, key); + elm_object_content_set(frame, cropper); + evas_object_data_set(win, "cropper", cropper); + hbox = elm_box_add(box); elm_box_homogeneous_set(hbox, EINA_TRUE); elm_box_horizontal_set(hbox, EINA_TRUE); @@ -891,8 +826,6 @@ _crop_image(void *data, Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED evas_object_smart_callback_add(button, "clicked", _cancel_crop, win); elm_box_pack_end(hbox, button); evas_object_show(button); - - evas_object_event_callback_add(layout, EVAS_CALLBACK_RESIZE, _image_resize, image); } static void