#define FIXED_SIZE(_W, _H) \ min: _W _H; max: _W _H; images { image: "sel_border.png" COMP; image: "sel_corner1.png" COMP; image: "sel_corner3.png" COMP; image: "sel_corner5.png" COMP; image: "sel_corner7.png" COMP; } collections { group { name: "ephoto,image,cropper,base"; script { public message(Msg_Type:type, id, ...) { if ((type == MSG_INT_SET) && (id == 1)) { new movetype, cox, coy, pox, poy, ix, iy, iw, ih, cx, cy, cw, ch; movetype = getarg(2); cox = getarg(3); coy = getarg(4); get_geometry(PART:"ephoto.swallow.image", ix, iy, iw, ih); get_geometry(PART:"ephoto.swallow.cropper", cx, cy, cw, ch); custom_state(PART:"ephoto.swallow.cropper", "default", 0.0); if (movetype == 0) { new ppox, ppoy; get_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, pox, poy); get_state_val(PART:"ephoto.swallow.cropper", STATE_REL2_OFFSET, ppox, ppoy); if (cx+cox < ix) cox = ix-cx; if (cx+cw+cox > ix+iw) cox = (ix+iw)-(cx+cw); if (cy+coy < iy) coy = iy-cy; if (cy+ch+coy > iy+ih) coy = (iy+ih)-(cy+ch); pox += cox; poy += coy; ppox += cox; ppoy += coy; set_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, pox, poy); set_state_val(PART:"ephoto.swallow.cropper", STATE_REL2_OFFSET, ppox, ppoy); } if (movetype == 1 || movetype == 2 || movetype == 8) { get_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, pox, poy); if (cx+cox < ix) cox = ix-cx; if (cy+coy < iy) coy = iy-cy; if (cw-cox < 20) return; if (ch-coy < 20) return; cox += pox; coy += poy; set_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, cox, coy); } if (movetype == 3) { new ppox, ppoy; get_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, pox, poy); get_state_val(PART:"ephoto.swallow.cropper", STATE_REL2_OFFSET, ppox, ppoy); if (cx+cw+cox > ix+iw) cox = (ix+iw)-(cx+cw); if (cy+coy < iy) coy = iy-cy; if (cw+cox < 20) return; if (ch-coy < 20) return; poy += coy; ppox += cox; set_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, pox, poy); set_state_val(PART:"ephoto.swallow.cropper", STATE_REL2_OFFSET, ppox, ppoy); } if (movetype == 4 || movetype == 5 || movetype == 6) { get_state_val(PART:"ephoto.swallow.cropper", STATE_REL2_OFFSET, pox, poy); if (cx+cw+cox > ix+iw) cox = (ix+iw)-(cx+cw); if (cy+ch+coy > iy+ih) coy = (iy+ih)-(cy+ch); if (cw+cox < 20) return; if (ch+coy < 20) return; cox += pox; coy += poy; set_state_val(PART:"ephoto.swallow.cropper", STATE_REL2_OFFSET, cox, coy); } if (movetype == 7) { new ppox, ppoy; get_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, pox, poy); get_state_val(PART:"ephoto.swallow.cropper", STATE_REL2_OFFSET, ppox, ppoy); if (cx+cox < ix) cox = ix-cx; if (cy+ch+coy > iy+ih) coy = (iy+ih)-(cy+ch); if (cw-cox < 20) return; if (ch+coy < 20) return; pox += cox; ppoy += coy; set_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, pox, poy); set_state_val(PART:"ephoto.swallow.cropper", STATE_REL2_OFFSET, ppox, ppoy); } if (movetype == 9) { new ppox, ppoy; get_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, pox, poy); get_state_val(PART:"ephoto.swallow.cropper", STATE_REL2_OFFSET, ppox, ppoy); if (cx < ix) cox = ix-cx; if (cx+cw > ix+iw) cox = (ix+iw)-(cx+cw); if (cy < iy) coy = iy-cy; if (cy+ch > iy+ih) coy = (iy+ih)-(cy+ch); pox += cox; ppox += cox; poy += coy; ppoy += coy; set_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, pox, poy); set_state_val(PART:"ephoto.swallow.cropper", STATE_REL2_OFFSET, ppox, ppoy); } if (movetype == 10) { set_state_val(PART:"ephoto.swallow.cropper", STATE_REL1_OFFSET, 0, 0); set_state_val(PART:"ephoto.swallow.cropper", STATE_REL2_OFFSET, 0, 0); } if (movetype == 11) { new buf[32]; snprintf(buf, sizeof(buf), "%dx%d", cox, coy); set_text(PART:"ephoto.cropper.size", buf); } set_state(PART:"ephoto.swallow.cropper", "custom", 0.0); if (movetype != 0) { emit("cropper,changed", "ephoto.swallow.cropper"); } } } } parts { part { name: "clipper"; type: RECT; 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; min: 20 20; rel1.to: "ephoto.swallow.image"; rel1.relative: 0.2 0.2; rel2.to: "ephoto.swallow.image"; rel2.relative: 0.8 0.8; } } part { name: "ephoto.cropper.size"; type: TEXT; effect: GLOW; scale: 1; mouse_events: 0; clip_to: "clipper"; description { state: "default" 0.0; color: 255 255 255 255; rel1.to: "ephoto.swallow.cropper"; rel2.to: "ephoto.swallow.cropper"; text { text: ""; font: FN; size: 12; align: 0.5 1.0; } } } part { name: "shader_top"; type: RECT; scale: 1; mouse_events: 0; clip_to: "clipper"; description { state: "default" 0.0; color: 0 0 0 150; rel1.to: "clipper"; rel1.relative: 0.0 0.0; rel2.to: "ephoto.swallow.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 150; rel1.to: "shader_top"; rel1.relative: 0.0 1.0; rel2.to: "ephoto.swallow.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 150; 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 150; rel1.to: "shader_top"; rel1.relative: 1.0 0.0; rel2.to: "shader_bottom"; rel2.relative: 1.0 0.0; } } } } group { name: "ephoto,image,cropper"; parts { part { name: "cropper"; type: IMAGE; repeat_events: 1; description { state: "default" 0.0; color: 255 255 255 200; image { normal: "sel_border.png"; border: 3 3 3 3; middle: NONE; } } part { name: "dragger"; type: RECT; repeat_events: 1; description { state: "default" 0.0; color: 255 255 255 0; rel1 { to: "handle1"; relative: 1.0 1.0; } rel2 { to: "handle5"; relative: 0.0 0.0; } } } part { name: "handle1"; type: IMAGE; repeat_events: 1; description { state: "default" 0.0; FIXED_SIZE(22, 22) rel1.offset: 1 1; align: 0.0 0.0; color: 255 255 255 0; image.normal: "sel_corner1.png"; } description { state: "visible" 0.0; inherit: "default" 0.0; color: 255 255 255 200; } } part { name: "handle2"; type: RECT; repeat_events: 1; description { state: "default" 0.0; color: 255 255 255 0; rel1 { to: "handle1"; relative: 1.0 0.0; offset: 3 2; } rel2 { to: "handle3"; relative: 0.0 1.0; offset: -4 -2; } } description { state: "visible" 0.0; inherit: "default" 0.0; color: 255 255 255 80; } } part { name: "handle3"; type: IMAGE; repeat_events: 1; description { state: "default" 0.0; FIXED_SIZE(22, 22) rel1.offset: 0 1; rel2.offset: -2 -1; align: 1.0 0.0; color: 255 255 255 0; image.normal: "sel_corner3.png"; } description { state: "visible" 0.0; inherit: "default" 0.0; color: 255 255 255 200; } } part { name: "handle4"; type: RECT; repeat_events: 1; description { state: "default" 0.0; color: 255 255 255 0; rel1 { to: "handle3"; relative: 0.0 1.0; offset: 1 3; } rel2 { to: "handle5"; relative: 1.0 0.0; offset: -3 -4; } } description { state: "visible" 0.0; inherit: "default" 0.0; color: 255 255 255 80; } } part { name: "handle5"; type: IMAGE; repeat_events: 1; description { state: "default" 0.0; FIXED_SIZE(22, 22) rel2.offset: -2 -2; align: 1.0 1.0; color: 255 255 255 0; image.normal: "sel_corner5.png"; } description { state: "visible" 0.0; inherit: "default" 0.0; color: 255 255 255 200; } } part { name: "handle6"; type: RECT; repeat_events: 1; description { state: "default" 0.0; rel1 { to: "handle7"; relative: 1.0 0.0; offset: 3 1; } rel2 { to: "handle5"; relative: 0.0 1.0; offset: -4 -3; } color: 255 255 255 0; } description { state: "visible" 0.0; inherit: "default" 0.0; color: 255 255 255 80; } } part { name: "handle7"; type: IMAGE; repeat_events: 1; description { state: "default" 0.0; FIXED_SIZE(22, 22) rel1.offset: 1 0; rel2.offset: -1 -2; align: 0.0 1.0; color: 255 255 255 0; image.normal: "sel_corner7.png"; } description { state: "visible" 0.0; inherit: "default" 0.0; color: 255 255 255 200; } } part { name: "handle8"; type: RECT; repeat_events: 1; description { state: "default" 0.0; rel1 { to: "handle1"; relative: 0.0 1.0; offset: 2 3; } rel2 { to: "handle7"; relative: 1.0 0.0; offset: -2 -4; } color: 255 255 255 0; } description { state: "visible" 0.0; inherit: "default" 0.0; color: 255 255 255 80; } } program { signal: "mouse,in"; source: "cropper"; action: STATE_SET "visible" 0.0; transition: LINEAR 0.3 ; targets: "handle1" "handle3" "handle5" "handle7"; } program { signal: "mouse,out"; source: "cropper"; action: STATE_SET "default" 0.0; transition: LINEAR 0.3 ; targets: "handle1" "handle3" "handle5" "handle7"; } #define SHOW_HIDE_LATERALS(_NAME_) \ program { signal: "mouse,in"; source: _NAME_; \ action: STATE_SET "visible" 0.0; \ transition: LINEAR 0.3 ; \ target: _NAME_; } \ program { signal: "mouse,out"; source: _NAME_; \ action: STATE_SET "default" 0.0; \ transition: LINEAR 0.3 ; \ target: _NAME_; } SHOW_HIDE_LATERALS("handle2") SHOW_HIDE_LATERALS("handle4") SHOW_HIDE_LATERALS("handle6") SHOW_HIDE_LATERALS("handle8") #undef SHOW_HIDE_LATERALS } } } }