Ephoto: Allow the cropper to freely move and allow full handle control.

This commit is contained in:
Stephen Houston 2015-02-12 13:19:27 -06:00
parent 04f6182eab
commit 91de631a7b
4 changed files with 235 additions and 205 deletions

View File

@ -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";
}
}
}

View File

@ -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

View File

@ -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.
*/

View File

@ -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