diff --git a/data/images/grid.png b/data/images/grid.png new file mode 100644 index 0000000..4fa3d86 Binary files /dev/null and b/data/images/grid.png differ diff --git a/data/images/single.png b/data/images/single.png new file mode 100644 index 0000000..d9f71a0 Binary files /dev/null and b/data/images/single.png differ diff --git a/data/themes/crop.edc b/data/themes/crop.edc deleted file mode 100644 index a6bc21d..0000000 --- a/data/themes/crop.edc +++ /dev/null @@ -1,437 +0,0 @@ - -#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 - } - } - } -} - diff --git a/data/themes/ephoto.edc b/data/themes/ephoto.edc new file mode 100644 index 0000000..a03af5e --- /dev/null +++ b/data/themes/ephoto.edc @@ -0,0 +1,792 @@ +#define FIXED_SIZE(_W, _H) \ + min: _W _H; max: _W _H; + +collections { + images { + image: "images/shadow_circle_horiz.png" COMP; + image: "images/shadow_circle_vert.png" COMP; + image: "images/tile.png" COMP; + image: "images/shadow.png" COMP; + image: "images/sel_border.png" COMP; + image: "images/sel_corner1.png" COMP; + image: "images/sel_corner3.png" COMP; + image: "images/sel_corner5.png" COMP; + image: "images/sel_corner7.png" COMP; + } + group { name: "ephoto,main,layout"; + script { + public offseth = 0; + public offsetv = 0; + public custom = 0 ; + public custom_folders = 0; + public message(Msg_Type:type, id, ...) { + if ((type == MSG_INT_SET) && (id == 1)) { + new hoffset = getarg(2); + new voffset = getarg(3); + new hoff, voff, roneoff; + + set_int(custom, 1); + hoffset *= -1; + voffset *= -1; + + get_state_val(PART:"ephoto.swallow.controls", STATE_REL1_OFFSET, + 0, roneoff); + get_state_val(PART:"ephoto.swallow.controls", STATE_REL2_OFFSET, + hoff, voff); + + roneoff -= get_int(offsetv); + roneoff += voffset; + hoff -= get_int(offseth); + voff -= get_int(offsetv); + hoff += hoffset; + voff += voffset; + set_int(offseth, hoffset); + set_int(offsetv, voffset); + + custom_state(PART:"ephoto.swallow.controls", "default", 0.0); + set_state_val(PART:"ephoto.swallow.controls", STATE_REL1_OFFSET, + 0, roneoff); + set_state_val(PART:"ephoto.swallow.controls", STATE_REL2_OFFSET, + hoff, voff); + set_state(PART:"ephoto.swallow.controls", "custom", 0.0); + } + if ((type == MSG_INT_SET) && (id == 2)) { + new minw = getarg(2); + set_int(custom_folders, 1); + custom_state(PART:"ephoto.swallow.folders", "visible", 0.0); + set_state_val(PART:"ephoto.swallow.folders", + STATE_MIN, minw, 0); + } + } + } + parts { + rect { name: "ephoto,main,clip"; + scale: 1; + description { state: "default" 0.0; + } + } + image { name: "background_tile"; + scale: 1; + clip_to: "ephoto,main,clip"; + description { state: "default" 0.0; + fixed: 1 1; + image.normal: "images/tile.png"; + color: 210 210 210 255; + fill { + size.relative: 0.0 0.0; + size.offset: 32 32; + } + } + } + swallow { name: "ephoto.swallow.main"; + scale: 1; + mouse_events: 1; + clip_to: "ephoto,main,clip"; + description { state: "default" 0.0; + rel2.to: "ephoto,editor"; + rel2.relative: 0.0 1.0; + } + } + rect { name: "ephoto,editor"; + scale: 1; + clip_to: "ephoto,main,clip"; + description { state: "default" 0.0; + fixed: 1 1; + rel1.to: "ephoto.swallow.editor"; + rel2.to: "ephoto.swallow.editor"; + visible: 0; + } + description { state: "visible" 0.0; + inherit: default 0.0; + visible: 1; + } + } + image { name: "editor_shadow"; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + fixed: 1 1; + image.normal: "images/shadow_circle_vert.png"; + min: 32 0; + color: 255 255 255 0; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + fixed: 1 1; + rel1.to: "ephoto,editor"; + rel1.relative: 1.0 0.0; + rel2.to: "ephoto,editor"; + color: 255 255 255 128; + visible: 1; + } + } + rect { name: "editor_base"; + clip_to: "ephoto,editor"; + scale: 1; + description { state: "default" 0.0; + color: 15 15 15 150; + rel1.to: "ephoto,editor"; + rel2.to: "ephoto,editor"; + } + } + swallow { name: "ephoto.swallow.editor"; + scale: 1; + mouse_events: 1; + clip_to: "ephoto,editor"; + description { state: "default" 0.0; + fixed: 1 1; + rel1.to: "ephoto,main,clip"; + rel1.relative: 1.0 0.0; + rel2.to: "ephoto,main,clip"; + rel2.relative: 1.0 1.0; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + rel1.to: "ephoto,main,clip"; + rel1.relative: 1.0 0.0; + rel2.to: "ephoto,main,clip"; + rel2.relative: 1.0 1.0; + align: 1.0 0.0; + visible: 1; + } + } + rect { name: "ephoto,folders"; + clip_to: "ephoto,main,clip"; + scale: 1; + description { state: "default" 0.0; + fixed: 1 1; + min: 220 0; + rel1.to: "ephoto.swallow.folders"; + rel2.to: "ephoto.swallow.folders"; + visible: 0; + } + description { state: "visible" 0.0; + inherit: default 0.0; + rel1.to: "ephoto.swallow.folders"; + rel2.to: "ephoto.swallow.folders"; + visible: 1; + } + } + image { name: "folders_shadow"; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + fixed: 1 1; + image.normal: "images/shadow_circle_vert.png"; + min: 32 0; + color: 255 255 255 0; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + fixed: 1 1; + rel1.to: "ephoto,folders"; + rel1.relative: 1.0 0.0; + rel2.to: "ephoto,folders"; + color: 255 255 255 128; + visible: 1; + } + } + rect { name: "folders_base"; + clip_to: "ephoto,folders"; + scale: 1; + description { state: "default" 0.0; + color: 15 15 15 150; + rel1.to: "ephoto,folders"; + rel2.to: "ephoto,folders"; + } + } + swallow { name: "ephoto.swallow.folders"; + scale: 1; + mouse_events: 1; + clip_to: "ephoto,folders"; + description { state: "default" 0.0; + fixed: 1 1; + rel1.to: "ephoto,controls"; + rel1.relative: 0.0 0.0; + rel2.to: "ephoto,controls"; + rel2.relative: 0.0 0.0; + visible: 0; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + rel1.to: "ephoto.swallow.main"; + rel1.relative: 0.0 0.0; + rel2.to: "ephoto,controls"; + rel2.relative: 0.0 0.0; + align: 0.0 0.0; + visible: 1; + } + } + rect { name: "ephoto,controls"; + scale: 1; + clip_to: "ephoto,main,clip"; + description { state: "default" 0.0; + fixed: 0 1; + rel1.to: "ephoto.swallow.controls"; + rel2.to: "ephoto.swallow.controls"; + color: 255 255 255 255; + visible: 1; + } + description { state: "hidden" 0.0; + inherit: "default" 0.0; + color: 255 255 255 0; + visible: 0; + } + } + rect { name: "controls_base"; + clip_to: "ephoto,controls"; + scale: 1; + description { state: "default" 0.0; + color: 15 15 15 150; + rel1.to: "ephoto,controls"; + rel2.to: "ephoto,controls"; + } + } + image { name: "controls_shadow"; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + fixed: 1 1; + rel1.to: "controls_base"; + rel1.relative: 0.0 0.0; + rel2.to: "controls_base"; + rel2.relative: 1.0 0.0; + image.normal: "images/shadow_circle_horiz.png"; + min: 0 32; + color: 255 255 255 128; + } + description { state: "hidden" 0.0; + inherit: "default" 0.0; + color: 255 255 255 0; + visible: 0; + } + } + swallow { name: "ephoto.swallow.controls"; + scale: 1; + mouse_events: 1; + clip_to: "ephoto,controls"; + description { state: "default" 0.0; + fixed: 1 1; + rel1.to: "ephoto.swallow.main"; + rel2.to: "ephoto.swallow.main"; + rel1.relative: 0.0 1.0; + rel1.offset: 0 -1; + rel2.offset: 0 -1; + align: 0.5 1.0; + color: 255 255 255 255; + visible: 1; + } + description { state: "hidden" 0.0; + inherit: "default" 0.0; + color: 255 255 255 0; + rel1.to: "ephoto.swallow.main"; + rel1.relative: 0.0 1.0; + rel2.to: "ephoto.swallow.main"; + rel2.relative: 1.0 2.0; + visible: 0; + } + } + } + programs { + program { signal: "ephoto,editor,hide"; + source: "ephoto"; + action: STATE_SET "default" 0.0; + target: "ephoto.swallow.editor"; + target: "editor_shadow"; + target: "ephoto,editor"; + } + program { signal: "ephoto,editor,show"; + source: "ephoto"; + action: STATE_SET "visible" 0.0; + target: "ephoto.swallow.editor"; + target: "editor_shadow"; + target: "ephoto,editor"; + } + program { signal: "ephoto,folders,hide"; + source: "ephoto"; + action: STATE_SET "default" 0.0; + target: "ephoto.swallow.folders"; + target: "folders_shadow"; + target: "ephoto,folders"; + } + program { signal: "ephoto,folders,show"; + source: "ephoto"; + script { + if (get_int(custom_folders)) { + set_state(PART:"ephoto.swallow.folders", "custom", 0.0); + } + else { + set_state(PART:"ephoto.swallow.folders", "visible", 0.0); + } + set_state(PART:"folders_shadow", "visible", 0.0); + set_state(PART:"ephoto,folders", "visible", 0.0); + } + } + program { signal: "ephoto,controls,hide"; + source: "ephoto"; + action: STATE_SET "hidden" 0.0; + target: "ephoto.swallow.controls"; + target: "controls_shadow"; + target: "ephoto,controls"; + } + program { signal: "ephoto,controls,show"; + source: "ephoto"; + script { + if (get_int(custom)) { + set_state(PART:"ephoto.swallow.controls", "custom", 0.0); + } + else { + set_state(PART:"ephoto.swallow.controls", "default", 0.0); + } + set_state(PART:"controls_shadow", "default", 0.0); + set_state(PART:"ephoto,controls", "default", 0.0); + } + } + } + } + group { "elm/label/base/info"; + mouse_events: 0; + styles { + style { name: "info_style"; + base: "font=Sans font_size=10 align=center valign=0.5 color=#ffffff style=glow glow_color=#151515 glow_color2=#000000 wrap=mixed text_class=info color_class=text"; + } + } + parts { + textblock { "elm.text"; + scale: 1; + desc { + text { + style: "info_style"; + min: 1 1; + ellipsis: -1; + } + } + } + } + } + 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 { + rect { name: "clipper"; + description { state: "default" 0.0; + } + } + swallow { name: "ephoto.swallow.image"; + scale: 1; + mouse_events: 0; + clip_to: "clipper"; + description { state: "default" 0.0; + } + } + swallow { name: "ephoto.swallow.cropper"; + 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; + } + } + text { name: "ephoto.cropper.size"; + 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; + } + } + } + rect { name: "shader_top"; + 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; + } + } + rect { name: "shader_left"; + + 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; + } + } + rect { name: "shader_bottom"; + 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; + } + } + rect { name: "shader_right"; + 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 { + image { name: "cropper"; + repeat_events: 1; + description { state: "default" 0.0; + color: 255 255 255 200; + image { + normal: "images/sel_border.png"; + border: 3 3 3 3; + middle: NONE; + } + } + } + rect { name: "dragger"; + 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; + } + } + } + image { name: "handle1"; + 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: "images/sel_corner1.png"; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + color: 255 255 255 200; + } + } + rect { name: "handle2"; + 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; + } + } + image { name: "handle3"; + 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: "images/sel_corner3.png"; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + color: 255 255 255 200; + } + } + rect { name: "handle4"; + 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; + } + } + image { name: "handle5"; + 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: "images/sel_corner5.png"; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + color: 255 255 255 200; + } + } + rect { name: "handle6"; + 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; + } + } + image { name: "handle7"; + 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: "images/sel_corner7.png"; + } + description { state: "visible" 0.0; + inherit: "default" 0.0; + color: 255 255 255 200; + } + } + rect { name: "handle8"; + 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; + } + } + } + programs { + 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 + } + } +} + diff --git a/data/themes/sel_border.png b/data/themes/images/sel_border.png similarity index 100% rename from data/themes/sel_border.png rename to data/themes/images/sel_border.png diff --git a/data/themes/sel_corner1.png b/data/themes/images/sel_corner1.png similarity index 100% rename from data/themes/sel_corner1.png rename to data/themes/images/sel_corner1.png diff --git a/data/themes/sel_corner3.png b/data/themes/images/sel_corner3.png similarity index 100% rename from data/themes/sel_corner3.png rename to data/themes/images/sel_corner3.png diff --git a/data/themes/sel_corner5.png b/data/themes/images/sel_corner5.png similarity index 100% rename from data/themes/sel_corner5.png rename to data/themes/images/sel_corner5.png diff --git a/data/themes/sel_corner7.png b/data/themes/images/sel_corner7.png similarity index 100% rename from data/themes/sel_corner7.png rename to data/themes/images/sel_corner7.png diff --git a/data/themes/images/shadow.png b/data/themes/images/shadow.png new file mode 100644 index 0000000..9d1e0a6 Binary files /dev/null and b/data/themes/images/shadow.png differ diff --git a/data/themes/images/shadow_circle_horiz.png b/data/themes/images/shadow_circle_horiz.png new file mode 100644 index 0000000..f5fcc5c Binary files /dev/null and b/data/themes/images/shadow_circle_horiz.png differ diff --git a/data/themes/images/shadow_circle_vert.png b/data/themes/images/shadow_circle_vert.png new file mode 100644 index 0000000..f06b622 Binary files /dev/null and b/data/themes/images/shadow_circle_vert.png differ diff --git a/data/themes/images/tile.png b/data/themes/images/tile.png new file mode 100644 index 0000000..219cc80 Binary files /dev/null and b/data/themes/images/tile.png differ diff --git a/src/bin/ephoto_directory_browser.c b/src/bin/ephoto_directory_browser.c new file mode 100644 index 0000000..7295193 --- /dev/null +++ b/src/bin/ephoto_directory_browser.c @@ -0,0 +1,1200 @@ +#include "ephoto.h" + +#define FILESEP "file://" +#define FILESEP_LEN sizeof(FILESEP) - 1 + +#define TODO_ITEM_MIN_BATCH 5 + +#define ANIM_TIME 0.2 + +typedef struct _Ephoto_Directory_Browser Ephoto_Directory_Browser; + +struct _Ephoto_Directory_Browser +{ + Ephoto *ephoto; + Evas_Object *main; + Evas_Object *fsel; + Evas_Object *fsel_back; + Evas_Object *leftbox; + Elm_Object_Item *dir_current; + Elm_Object_Item *last_sel; + Eio_File *ls; + Eina_Bool dirs_only; + Eina_Bool thumbs_only; + Ecore_File_Monitor *monitor; + Eina_List *handlers; + Eina_List *todo_items; + Ecore_Job *change_dir_job; + Ecore_Timer *click_timer; + Eina_Bool dragging; + Eina_Bool processing; + Eina_Bool initializing; + struct + { + Ecore_Animator *todo_items; + int count; + int processed; + } animator; + Eina_Bool main_deleted:1; + const char *back_directory; +}; + +static Elm_Genlist_Item_Class _ephoto_dir_class; + +static char * _drag_data_extract(char **drag_data); + +static void _fsel_mouse_up_cb(void *data, Evas *e EINA_UNUSED, + Evas_Object *obj EINA_UNUSED, void *event_info); + +/*File Pane Callbacks*/ +static void +_menu_dismissed_cb(void *data, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + + db->ephoto->menu_blocking = EINA_FALSE; + evas_object_del(obj); + elm_object_focus_set(db->main, EINA_TRUE); +} + +static void +_menu_empty_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + Eina_List *paths = NULL; + Elm_Object_Item *item; + Ephoto_Entry *file; + + item = elm_genlist_first_item_get(db->fsel); + while (item) + { + file = elm_object_item_data_get(item); + paths = eina_list_append(paths, strdup(file->path)); + item = elm_genlist_item_next_get(item); + } + if (eina_list_count(paths) <= 0) + return; + ephoto_file_empty_trash(db->ephoto, paths); +} + +static Eina_Bool +_drop_dropcb(void *data EINA_UNUSED, Evas_Object *obj, Elm_Object_Item *it, + Elm_Selection_Data *ev, int xposret EINA_UNUSED, int yposret EINA_UNUSED) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(it, EINA_TRUE); + + Ephoto_Entry *entry = elm_object_item_data_get(it); + const char *path = entry->path; + Eina_List *files = NULL; + Ephoto_Directory_Browser *db = evas_object_data_get(obj, "directory_browser"); + + if (!ev->data) + return EINA_FALSE; + if (ev->len <= 0) + return EINA_FALSE; + if (!path) + return EINA_FALSE; + + char *dd = strdup(ev->data); + + if (!dd) + return EINA_FALSE; + + char *s = _drag_data_extract(&dd); + + while (s) + { + files = eina_list_append(files, s); + s = _drag_data_extract(&dd); + } + free(dd); + + if (db->ephoto->config->move_drop) + ephoto_file_move(db->ephoto, files, path); + else + ephoto_file_copy(db->ephoto, files, path); + if (db->dir_current) + elm_genlist_item_selected_set(db->dir_current, EINA_TRUE); + return EINA_TRUE; +} + +static Elm_Object_Item * +_drop_item_getcb(Evas_Object *obj, Evas_Coord x, Evas_Coord y, + int *xposret EINA_UNUSED, int *yposret) +{ + Elm_Object_Item *gli; + + gli = elm_genlist_at_xy_item_get(obj, x, y, yposret); + + return gli; +} + +static void +_drop_enter(void *data, Evas_Object *obj EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + + if (db->dragging) + elm_object_cursor_set(db->main, ELM_CURSOR_TARGET); +} + +static void +_drop_leave(void *data, Evas_Object *obj EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + + if (db->dragging) + { + elm_object_cursor_set(db->main, ELM_CURSOR_HAND2); + if (db->dir_current) + elm_genlist_item_selected_set(db->dir_current, EINA_TRUE); + } +} + +static void +_drop_pos(void *data EINA_UNUSED, Evas_Object *cont EINA_UNUSED, + Elm_Object_Item *it EINA_UNUSED, Evas_Coord x EINA_UNUSED, + Evas_Coord y EINA_UNUSED, int xposret EINA_UNUSED, + int yposret EINA_UNUSED, Elm_Xdnd_Action action EINA_UNUSED) +{ + elm_genlist_item_selected_set(it, EINA_TRUE); +} + +static char * +_drag_data_extract(char **drag_data) +{ + char *uri = NULL; + + if (!drag_data) + return uri; + + char *p = *drag_data; + + if (!p) + return uri; + char *s = strstr(p, FILESEP); + + if (s) + p += FILESEP_LEN; + s = strchr(p, '\n'); + uri = p; + if (s) + { + if (s - p > 0) + { + char *s1 = s - 1; + + if (s1[0] == '\r') + s1[0] = '\0'; + else + { + char *s2 = s + 1; + + if (s2[0] == '\r') + { + s[0] = '\0'; + s++; + } + else + s[0] = '\0'; + } + } + else + s[0] = '\0'; + s++; + } + else + p = NULL; + *drag_data = s; + + return uri; +} + +static int +_entry_cmp(const void *pa, const void *pb) +{ + const Ephoto_Entry *a, *b; + + a = elm_object_item_data_get(pa); + b = elm_object_item_data_get(pb); + + return strcasecmp(a->basename, b->basename); +} + +static void +_on_list_expand_req(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info) +{ + Ephoto_Directory_Browser *db = data; + Elm_Object_Item *it = event_info; + + if (db->initializing) + return; + + ecore_job_del(db->change_dir_job); + db->change_dir_job = NULL; + ecore_timer_del(db->click_timer); + db->click_timer = NULL; + elm_genlist_item_expanded_set(it, EINA_TRUE); +} + +static void +_on_list_contract_req(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info) +{ + Ephoto_Directory_Browser *db = data; + Elm_Object_Item *it = event_info; + + if (db->initializing) + return; + + ecore_job_del(db->change_dir_job); + db->change_dir_job = NULL; + ecore_timer_del(db->click_timer); + db->click_timer = NULL; + elm_genlist_item_expanded_set(it, EINA_FALSE); +} + +static void +_on_list_expanded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ephoto_Directory_Browser *db = data; + Elm_Object_Item *it = event_info; + Ephoto_Entry *entry; + const char *path; + + if (db->initializing) + return; + + entry = elm_object_item_data_get(it); + path = entry->path; + db->dirs_only = 0; + if (!strcmp(path, db->ephoto->config->directory)) + db->dirs_only = 1; + else + db->dirs_only = 0; + db->thumbs_only = 0; + ephoto_directory_set(db->ephoto, path, it, db->dirs_only, db->thumbs_only); + ephoto_title_set(db->ephoto, db->ephoto->config->directory); +} + +static void +_on_list_contracted(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ephoto_Directory_Browser *db = data; + Elm_Object_Item *it = event_info; + Ephoto_Entry *entry; + const char *path; + + if (db->initializing) + return; + + entry = elm_object_item_data_get(it); + path = entry->path; + elm_genlist_item_subitems_clear(it); + if (!strcmp(path, db->ephoto->config->directory)) + return; + db->thumbs_only = 1; + db->dirs_only = 0; + ephoto_directory_set(db->ephoto, path, NULL, + db->dirs_only, db->thumbs_only); + ephoto_title_set(db->ephoto, + db->ephoto->config->directory); +} + +static void +_dir_job(void *data) +{ + Elm_Object_Item *it = data; + Ephoto_Directory_Browser *db = evas_object_data_get(it, "directory_browser"); + Ephoto_Entry *entry; + const char *path; + + entry = elm_object_item_data_get(it); + path = entry->path; + db->change_dir_job = NULL; + db->thumbs_only = 1; + db->dirs_only = 0; + ephoto_directory_set(db->ephoto, path, NULL, + db->dirs_only, db->thumbs_only); + ephoto_title_set(db->ephoto, db->ephoto->config->directory); +} + +static void +_wait_job(void *data) +{ + Elm_Object_Item *it = data; + Ephoto_Directory_Browser *db = evas_object_data_get(it, "directory_browser"); + + if (db->change_dir_job) + ecore_job_del(db->change_dir_job); + db->change_dir_job = ecore_job_add(_dir_job, it); +} + +static void +_on_list_selected(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info) +{ + Ephoto_Directory_Browser *db = data; + Elm_Object_Item *it = event_info; + + evas_object_data_set(it, "directory_browser", db); + if (!db->dragging) + { + db->dir_current = it; + + ecore_job_add(_wait_job, it); + } +} + +static char * +_dir_item_text_get(void *data, Evas_Object *obj EINA_UNUSED, + const char *part EINA_UNUSED) +{ + Ephoto_Entry *e = data; + + return strdup(e->label); +} + +static Evas_Object * +_dir_item_icon_get(void *data EINA_UNUSED, Evas_Object *obj, + const char *part) +{ + if (!strcmp(part, "elm.swallow.end")) + return NULL; + Evas_Object *ic = elm_icon_add(obj); + + elm_icon_order_lookup_set(ic, ELM_ICON_LOOKUP_FDO_THEME); + elm_icon_standard_set(ic, "folder"); + return ic; +} + +static void +_dir_item_del(void *data, Evas_Object *obj EINA_UNUSED) +{ + Ephoto_Entry *e = data; + + if (!e->no_delete) + ephoto_entry_free(e->ephoto, e); +} + +static Eina_Bool +_check_for_subdirs(Ephoto_Entry *entry) +{ + Eina_Iterator *ls = eina_file_direct_ls(entry->path); + Eina_File_Direct_Info *info; + + if (!ls) + return EINA_FALSE; + EINA_ITERATOR_FOREACH(ls, info) + { + if (info->type == EINA_FILE_DIR) + { + eina_iterator_free(ls); + return EINA_TRUE; + } + } + eina_iterator_free(ls); + return EINA_FALSE; +} + +static void +_trash_back(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + + elm_box_clear(db->leftbox); + db->fsel = db->fsel_back; + elm_box_pack_end(db->leftbox, db->fsel); + evas_object_show(db->fsel); + db->fsel_back = NULL; + + db->thumbs_only = 1; + db->dirs_only = 0; + ephoto_directory_set(db->ephoto, db->back_directory, NULL, + db->dirs_only, db->thumbs_only); + ephoto_title_set(db->ephoto, db->back_directory); +} + +static void +_dir_go_trash(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + char path[PATH_MAX]; + Evas_Object *ic, *but; + + db->fsel_back = db->fsel; + evas_object_hide(db->fsel_back); + elm_box_unpack(db->leftbox, db->fsel_back); + + ic = elm_icon_add(db->leftbox); + evas_object_size_hint_min_set(ic, 20*elm_config_scale_get(), + 20*elm_config_scale_get()); + elm_icon_order_lookup_set(ic, ELM_ICON_LOOKUP_FDO_THEME); + elm_icon_standard_set(ic, "go-previous"); + evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_BOTH, 1, 1); + + but = elm_button_add(db->leftbox); + elm_object_text_set(but, _("Back")); + elm_object_part_content_set(but, "icon", ic); + evas_object_size_hint_weight_set(but, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_fill_set(but, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_smart_callback_add(but, "clicked", _trash_back, db); + elm_box_pack_end(db->leftbox, but); + evas_object_show(but); + + db->fsel = elm_genlist_add(db->leftbox); + elm_genlist_homogeneous_set(db->fsel, EINA_FALSE); + elm_genlist_select_mode_set(db->fsel, ELM_OBJECT_SELECT_MODE_ALWAYS); + evas_object_size_hint_weight_set(db->fsel, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(db->fsel, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_smart_callback_add(db->fsel, "expand,request", + _on_list_expand_req, db); + evas_object_smart_callback_add(db->fsel, "contract,request", + _on_list_contract_req, db); + evas_object_smart_callback_add(db->fsel, "expanded", _on_list_expanded, db); + evas_object_smart_callback_add(db->fsel, "contracted", _on_list_contracted, + db); + evas_object_event_callback_add(db->fsel, EVAS_CALLBACK_MOUSE_UP, + _fsel_mouse_up_cb, db); + evas_object_data_set(db->fsel, "directory_browser", db); + evas_object_size_hint_min_set(db->fsel, (int)round(195 * elm_config_scale_get()), 0); + elm_box_pack_end(db->leftbox, db->fsel); + evas_object_show(db->fsel); + + eina_stringshare_replace(&db->back_directory, + db->ephoto->config->directory); + snprintf(path, PATH_MAX, "%s/.config/ephoto/trash", getenv("HOME")); + if (!ecore_file_exists(path)) + ecore_file_mkpath(path); + db->thumbs_only = 0; + db->dirs_only = 0; + ephoto_directory_set(db->ephoto, path, NULL, + db->dirs_only, db->thumbs_only); + ephoto_title_set(db->ephoto, _("Trash")); + ephoto_directory_browser_top_dir_set(db->ephoto, db->ephoto->config->directory); +} + +static Eina_Bool +_click_timer_cb(void *data) +{ + Elm_Object_Item *item = data; + Ephoto_Directory_Browser *db = evas_object_data_get(item, "directory_browser"); + + _on_list_selected(db, NULL, item); + db->click_timer = NULL; + + return ECORE_CALLBACK_CANCEL; +} + +static void +_fsel_menu_new_dir_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + Elm_Object_Item *item = elm_genlist_selected_item_get(db->fsel); + Ephoto_Entry *entry; + const char *path; + + if (item) + { + entry = elm_object_item_data_get(item); + path = entry->path; + } + else + path = db->ephoto->config->directory; + if (!path) + return; + ephoto_file_new_dir(db->ephoto, path); +} + +static void +_fsel_menu_paste_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + Elm_Object_Item *item = elm_genlist_selected_item_get(db->fsel); + + ephoto_thumb_browser_paste(db->ephoto, item); +} + +static void +_fsel_menu_rename_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + Elm_Object_Item *item = elm_genlist_selected_item_get(db->fsel); + Ephoto_Entry *entry; + const char *path; + + if (!item) + return; + entry = elm_object_item_data_get(item); + path = entry->path; + if (!path) + return; + ephoto_file_rename(db->ephoto, path); +} + +static void +_fsel_menu_delete_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + Elm_Object_Item *item = elm_genlist_selected_item_get(db->fsel); + Ephoto_Entry *entry; + Eina_List *files = NULL; + const char *path; + + if (!item) + return; + entry = elm_object_item_data_get(item); + path = entry->path; + if (!path) + return; + files = eina_list_append(files, path); + ephoto_file_delete(db->ephoto, files, EINA_FILE_DIR); +} + +static void +_fsel_mouse_up_cb(void *data, Evas *e EINA_UNUSED, + Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ephoto_Directory_Browser *db = data; + Evas_Object *menu; + Elm_Object_Item *item, *menu_it; + Evas_Event_Mouse_Up *info = event_info; + char trash[PATH_MAX]; + Evas_Coord x, y; + + evas_pointer_canvas_xy_get(evas_object_evas_get(db->fsel), &x, &y); + item = elm_genlist_at_xy_item_get(db->fsel, x, y, 0); + + if (info->button == 1 && item) + { + if (info->flags == EVAS_BUTTON_DOUBLE_CLICK) + { + if (elm_genlist_item_type_get(item) == ELM_GENLIST_ITEM_TREE) + { + if (db->click_timer) + { + ecore_timer_del(db->click_timer); + db->click_timer = NULL; + elm_genlist_item_expanded_set(item, + !elm_genlist_item_expanded_get(item)); + } + } + } + else + { + evas_object_data_set(item, "directory_browser", db); + if (elm_genlist_item_type_get(item) == ELM_GENLIST_ITEM_TREE) + db->click_timer = ecore_timer_add(.3, _click_timer_cb, item); + else + _on_list_selected(db, NULL, item); + } + } + else if (!item) + { + Elm_Object_Item *it; + + it = elm_genlist_selected_item_get(db->fsel); + if (it) + elm_genlist_item_selected_set(it, EINA_FALSE); + ephoto_directory_set(db->ephoto, db->ephoto->top_directory, NULL, 0, 1); + } + + if (info->button != 3) + return; + + snprintf(trash, PATH_MAX, "%s/.config/ephoto/trash", getenv("HOME")); + + if (item) + elm_genlist_item_selected_set(item, EINA_TRUE); + + db->ephoto->menu_blocking = EINA_TRUE; + + menu = elm_menu_add(db->ephoto->win); + elm_menu_move(menu, x, y); + + menu_it = elm_menu_item_add(menu, NULL, "document-properties", _("Edit"), + NULL, NULL); + if (strcmp(db->ephoto->config->directory, trash)) + { + elm_menu_item_add(menu, menu_it, "folder-new", _("New Folder"), + _fsel_menu_new_dir_cb, db); + } + if (item) + { + evas_object_data_set(item, "directory_browser", db); + elm_menu_item_add(menu, menu_it, "edit", _("Rename"), + _fsel_menu_rename_cb, item); + elm_menu_item_add(menu, menu_it, "edit-paste", _("Paste"), + _fsel_menu_paste_cb, db); + } + else if (!strcmp(db->ephoto->config->directory, trash) && + elm_genlist_first_item_get(db->fsel)) + { + elm_menu_item_add(menu, menu_it, "edit-delete", _("Empty Trash"), + _menu_empty_cb, db); + } + if (strcmp(db->ephoto->config->directory, trash) && item) + { + elm_menu_item_add(menu, menu_it, "edit-delete", _("Delete"), + _fsel_menu_delete_cb, db); + elm_menu_item_separator_add(menu, NULL); + menu_it = elm_menu_item_add(menu, NULL, "user-trash", _("Trash"), + _dir_go_trash, db); + } + evas_object_smart_callback_add(menu, "dismissed", _menu_dismissed_cb, + db); + evas_object_show(menu); +} + +static void +_ephoto_directory_view_add(Ephoto_Directory_Browser *db) +{ + Edje_Message_Int_Set *msg; + + msg = alloca(sizeof(Edje_Message_Int_Set) + (1 * sizeof(int))); + msg->count = 1; + msg->val[0] = (int)round(220 * elm_config_scale_get()); + edje_object_message_send(elm_layout_edje_get(db->ephoto->layout), + EDJE_MESSAGE_INT_SET, 2, msg); + + db->leftbox = elm_box_add(db->main); + elm_box_horizontal_set(db->leftbox, EINA_FALSE); + elm_box_homogeneous_set(db->leftbox, EINA_FALSE); + elm_box_padding_set(db->leftbox, 0, -5); + evas_object_size_hint_weight_set(db->leftbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(db->leftbox, + EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_box_pack_end(db->main, db->leftbox); + evas_object_show(db->leftbox); + + db->fsel = elm_genlist_add(db->leftbox); + elm_genlist_homogeneous_set(db->fsel, EINA_FALSE); + elm_genlist_select_mode_set(db->fsel, ELM_OBJECT_SELECT_MODE_ALWAYS); + evas_object_size_hint_weight_set(db->fsel, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(db->fsel, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_smart_callback_add(db->fsel, "expand,request", + _on_list_expand_req, db); + evas_object_smart_callback_add(db->fsel, "contract,request", + _on_list_contract_req, db); + evas_object_smart_callback_add(db->fsel, "expanded", _on_list_expanded, db); + evas_object_smart_callback_add(db->fsel, "contracted", _on_list_contracted, + db); + evas_object_event_callback_add(db->fsel, EVAS_CALLBACK_MOUSE_UP, + _fsel_mouse_up_cb, db); + evas_object_data_set(db->fsel, "directory_browser", db); + evas_object_size_hint_min_set(db->fsel, (int)round(195 * elm_config_scale_get()), 0); + elm_box_pack_end(db->leftbox, db->fsel); + evas_object_show(db->fsel); + + elm_drop_item_container_add(db->fsel, ELM_SEL_FORMAT_TARGETS, + _drop_item_getcb, _drop_enter, db, _drop_leave, db, _drop_pos, db, + _drop_dropcb, NULL); +} + +/*Ephoto Populating Functions*/ +static void +_todo_items_free(Ephoto_Directory_Browser *db) +{ + eina_list_free(db->todo_items); + db->todo_items = NULL; +} + +static void +_monitor_cb(void *data, Ecore_File_Monitor *em EINA_UNUSED, + Ecore_File_Event event, const char *path) +{ + Elm_Object_Item *item; + Ephoto_Entry *entry = data; + Ephoto_Entry *e; + char file[PATH_MAX], dir[PATH_MAX]; + const Elm_Genlist_Item_Class *ic; + char buf[PATH_MAX]; + + if (!entry) + return; + + snprintf(file, PATH_MAX, "%s", path); + snprintf(dir, PATH_MAX, "%s", ecore_file_dir_get(file)); + + if (strcmp(entry->path, dir)) + return; + if (event == ECORE_FILE_EVENT_CREATED_DIRECTORY) + { + if (!ecore_file_is_dir(path)) + return; + if (ephoto_entry_exists(entry->ephoto, path)) + return; + + if (elm_genlist_item_type_get(entry->item) == ELM_GENLIST_ITEM_TREE && + elm_genlist_item_expanded_get(entry->item) == EINA_TRUE) + { + ic = &_ephoto_dir_class; + snprintf(buf, PATH_MAX, "%s", path); + e = ephoto_entry_new(entry->ephoto, path, basename(buf), + EINA_FILE_DIR); + e->genlist = entry->genlist; + e->parent = entry->item; + e->item = + elm_genlist_item_sorted_insert(entry->genlist, ic, e, + e->parent, ELM_GENLIST_ITEM_NONE, _entry_cmp, NULL, NULL); + if (e->item) + e->monitor = ecore_file_monitor_add(e->path, _monitor_cb, e); + } + if (elm_genlist_item_type_get(entry->item) == ELM_GENLIST_ITEM_NONE) + { + Elm_Object_Item *parent; + + ic = &_ephoto_dir_class; + parent = + elm_genlist_item_insert_before(entry->genlist, ic, entry, + entry->parent, entry->item, ELM_GENLIST_ITEM_TREE, NULL, NULL); + entry->no_delete = EINA_TRUE; + if (entry->monitor) + ecore_file_monitor_del(entry->monitor); + elm_object_item_del(entry->item); + entry->item = parent; + entry->no_delete = EINA_FALSE; + entry->monitor = ecore_file_monitor_add(entry->path, _monitor_cb, entry); + } + return; + } + else if (event == ECORE_FILE_EVENT_DELETED_DIRECTORY) + { + item = elm_genlist_first_item_get(entry->genlist); + while (item) + { + e = elm_object_item_data_get(item); + if (!strcmp(e->path, path)) + { + elm_object_item_del(e->item); + //if (!strcmp(e->path, e->ephoto->config->directory)) + break; + } + item = elm_genlist_item_next_get(item); + } + if (elm_genlist_item_type_get(entry->item) == ELM_GENLIST_ITEM_TREE && + _check_for_subdirs(entry) == EINA_FALSE) + { + Elm_Object_Item *parent; + + ic = &_ephoto_dir_class; + parent = + elm_genlist_item_insert_before(entry->genlist, ic, entry, + entry->parent, entry->item, ELM_GENLIST_ITEM_NONE, NULL, NULL); + entry->no_delete = EINA_TRUE; + elm_object_item_del(entry->item); + entry->item = parent; + entry->no_delete = EINA_FALSE; + } + if (!ecore_file_exists(entry->ephoto->config->directory)) + { + ephoto_directory_set(entry->ephoto, entry->path, entry->parent, 0, 1); + ephoto_title_set(entry->ephoto, entry->path); + } + return; + } + else if (event == ECORE_FILE_EVENT_MODIFIED) + { + if (!ecore_file_is_dir(path)) + return; + if ((elm_genlist_item_expanded_get(entry->item) == EINA_TRUE)) + { + item = elm_genlist_first_item_get(entry->genlist); + while (item) + { + e = elm_object_item_data_get(item); + if (!strcmp(e->path, path)) + { + elm_genlist_item_update(e->item); + break; + } + item = elm_genlist_item_next_get(item); + } + } + return; + } +} + +static void +_top_monitor_cb(void *data, Ecore_File_Monitor *em EINA_UNUSED, + Ecore_File_Event event, const char *path) +{ + Elm_Object_Item *item; + Ephoto_Directory_Browser *db = data; + Ephoto_Entry *e; + const Elm_Genlist_Item_Class *ic; + char buf[PATH_MAX], file[PATH_MAX], dir[PATH_MAX]; + + if (!db) + return; + snprintf(file, PATH_MAX, "%s", path); + snprintf(dir, PATH_MAX, "%s", ecore_file_dir_get(file)); + + if (strcmp(db->ephoto->top_directory, dir)) + return; + if (event == ECORE_FILE_EVENT_CREATED_DIRECTORY) + { + if (!ecore_file_is_dir(path)) + return; + if (ephoto_entry_exists(db->ephoto, path)) + return; + snprintf(buf, PATH_MAX, "%s", path); + e = ephoto_entry_new(db->ephoto, path, basename(buf), + EINA_FILE_DIR); + e->genlist = db->fsel; + ic = &_ephoto_dir_class; + e->item = + elm_genlist_item_append(db->fsel, ic, e, + NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); + if (e->item) + e->monitor = ecore_file_monitor_add(e->path, _monitor_cb, e); + return; + } + else if (event == ECORE_FILE_EVENT_DELETED_DIRECTORY) + { + item = elm_genlist_first_item_get(db->fsel); + while (item) + { + e = elm_object_item_data_get(item); + if (!strcmp(e->path, path)) + { + if (!strcmp(path, db->ephoto->config->directory)) + elm_genlist_item_expanded_set(e->parent, EINA_TRUE); + else + elm_object_item_del(e->item); + break; + } + item = elm_genlist_item_next_get(item); + } + return; + } + else if (event == ECORE_FILE_EVENT_MODIFIED) + { + if (!ecore_file_is_dir(path)) + return; + item = elm_genlist_first_item_get(db->fsel); + while (item) + { + e = elm_object_item_data_get(item); + if (!strcmp(e->path, path)) + { + elm_genlist_item_update(e->item); + break; + } + item = elm_genlist_item_next_get(item); + } + return; + } +} + +static Eina_Bool +_todo_items_process(void *data) +{ + Ephoto_Directory_Browser *db = data; + Ephoto_Entry *entry; + int i = 0; + + if ((!db->ls) && (db->animator.processed == db->animator.count)) + { + if (db->animator.count == 0) + return EINA_TRUE; + db->animator.todo_items = NULL; + db->processing = 0; + return EINA_FALSE; + } + if ((db->ls) && (eina_list_count(db->todo_items) < TODO_ITEM_MIN_BATCH)) + return EINA_TRUE; + + db->animator.todo_items = NULL; + db->processing = 1; + EINA_LIST_FREE(db->todo_items, entry) + { + i++; + if (i > TODO_ITEM_MIN_BATCH) + return EINA_TRUE; + if (entry->is_dir && !entry->item) + { + const Elm_Genlist_Item_Class *ic; + + ic = &_ephoto_dir_class; + if (_check_for_subdirs(entry)) + entry->item = + elm_genlist_item_sorted_insert(db->fsel, ic, entry, + entry->parent, ELM_GENLIST_ITEM_TREE, _entry_cmp, NULL, NULL); + else + entry->item = + elm_genlist_item_sorted_insert(db->fsel, ic, entry, + entry->parent, ELM_GENLIST_ITEM_NONE, _entry_cmp, NULL, NULL); + if (!entry->item) + { + ephoto_entry_free(db->ephoto, entry); + } + else + { + entry->monitor = ecore_file_monitor_add(entry->path, _monitor_cb, entry); + entry->genlist = db->fsel; + } + } + db->animator.processed++; + } + return EINA_TRUE; +} + +static Eina_Bool +_ephoto_dir_populate_start(void *data, int type EINA_UNUSED, + void *event EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + + evas_object_smart_callback_call(db->main, "changed,directory", NULL); + + db->animator.processed = 0; + db->animator.count = 0; + _todo_items_free(db); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ephoto_dir_populate_end(void *data, int type EINA_UNUSED, + void *event EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + + db->ls = NULL; + if (db->main_deleted) + { + free(db); + return ECORE_CALLBACK_PASS_ON; + } + db->dirs_only = 0; + db->thumbs_only = 0; + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ephoto_dir_populate_error(void *data, int type EINA_UNUSED, + void *event EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + + db->dirs_only = 0; + db->thumbs_only = 0; + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ephoto_dir_entry_create(void *data, int type EINA_UNUSED, void *event) +{ + Ephoto_Directory_Browser *db = data; + Ephoto_Event_Entry_Create *ev = event; + Ephoto_Entry *e; + + e = ev->entry; + if (e->is_dir) + { + db->todo_items = eina_list_append(db->todo_items, e); + db->animator.count++; + } + if (!db->animator.todo_items) + db->animator.todo_items = ecore_animator_add(_todo_items_process, db); + + return ECORE_CALLBACK_PASS_ON; +} + +/*Ephoto Directory Browser Main Callbacks*/ +static void +_ephoto_main_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Ephoto_Directory_Browser *db = data; + Ecore_Event_Handler *handler; + + _todo_items_free(db); + EINA_LIST_FREE(db->handlers, handler) ecore_event_handler_del(handler); + if (db->animator.todo_items) + { + ecore_animator_del(db->animator.todo_items); + db->animator.todo_items = NULL; + } + if (db->ls) + { + db->main_deleted = EINA_TRUE; + eio_file_cancel(db->ls); + return; + } + if (db->monitor) + ecore_file_monitor_del(db->monitor); + free(db); +} + +void +ephoto_directory_browser_top_dir_set(Ephoto *ephoto, const char *dir) +{ + Ephoto_Directory_Browser *db = + evas_object_data_get(ephoto->dir_browser, "directory_browser"); + + if (db->monitor) + ecore_file_monitor_del(db->monitor); + if (ephoto->top_directory) + eina_stringshare_replace(&ephoto->top_directory, dir); + else + ephoto->top_directory = eina_stringshare_add(dir); + db->monitor = ecore_file_monitor_add(dir, _top_monitor_cb, db); +} + +void +ephoto_directory_browser_initialize_structure(Ephoto *ephoto) +{ + Ephoto_Directory_Browser *db = + evas_object_data_get(ephoto->dir_browser, "directory_browser"); + Eina_List *dirs = NULL, *l; + Elm_Object_Item *next = NULL, *cur = NULL; + char path[PATH_MAX], *dir; + + db->initializing = EINA_TRUE; + snprintf(path, PATH_MAX, "%s", ephoto->config->directory); + dirs = eina_list_prepend(dirs, strdup(path)); + dir = strdup(path); + while (strcmp(dir, "/")) + { + if (dir) + { + free(dir); + dir = NULL; + } + dir = ecore_file_dir_get(path); + dirs = eina_list_prepend(dirs, strdup(dir)); + memset(path, 0x00, sizeof(path)); + snprintf(path, PATH_MAX, "%s", dir); + } + if (dir) + { + free(dir); + dir = NULL; + } + EINA_LIST_FOREACH(dirs, l, dir) + { + Eina_Iterator *it; + Eina_File_Direct_Info *finfo; + const char *n = eina_list_data_get(eina_list_next(l)); + + it = eina_file_direct_ls(dir); + EINA_ITERATOR_FOREACH(it, finfo) + { + cur = next; + if (finfo->type == EINA_FILE_DIR && + strncmp(finfo->path + finfo->name_start, ".", 1)) + { + Ephoto_Entry *entry = ephoto_entry_new(db->ephoto, finfo->path, + finfo->path+finfo->name_start, finfo->type); + entry->parent = cur; + if (entry->is_dir && !entry->item) + { + const Elm_Genlist_Item_Class *ic; + ic = &_ephoto_dir_class; + if (_check_for_subdirs(entry)) + entry->item = + elm_genlist_item_sorted_insert(db->fsel, ic, entry, + entry->parent, ELM_GENLIST_ITEM_TREE, _entry_cmp, NULL, NULL); + else + entry->item = + elm_genlist_item_sorted_insert(db->fsel, ic, entry, + entry->parent, ELM_GENLIST_ITEM_NONE, _entry_cmp, NULL, NULL); + if (!entry->item) + { + ephoto_entry_free(db->ephoto, entry); + } + else + { + entry->monitor = ecore_file_monitor_add(entry->path, _monitor_cb, entry); + entry->genlist = db->fsel; + } + if (n) + { + if (!strcmp(n, entry->path)) + { + next = entry->item; + elm_genlist_item_expanded_set(next, EINA_TRUE); + } + } + } + } + } + free(dir); + } + ephoto_directory_set(db->ephoto, db->ephoto->config->directory, next, EINA_FALSE, EINA_TRUE); + ephoto_directory_browser_top_dir_set(db->ephoto, "/"); + db->initializing = EINA_FALSE; +} + +Evas_Object * +ephoto_directory_browser_add(Ephoto *ephoto, Evas_Object *parent) +{ + Evas_Object *box = elm_box_add(parent); + Ephoto_Directory_Browser *db; + + EINA_SAFETY_ON_NULL_RETURN_VAL(box, NULL); + + db = calloc(1, sizeof(Ephoto_Directory_Browser)); + EINA_SAFETY_ON_NULL_GOTO(db, error); + + _ephoto_dir_class.item_style = "tree_effect"; + _ephoto_dir_class.func.text_get = _dir_item_text_get; + _ephoto_dir_class.func.content_get = _dir_item_icon_get; + _ephoto_dir_class.func.state_get = NULL; + _ephoto_dir_class.func.del = _dir_item_del; + + db->ephoto = ephoto; + db->dir_current = NULL; + db->main = box; + + elm_box_horizontal_set(db->main, EINA_FALSE); + evas_object_size_hint_weight_set(db->main, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(db->main, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_event_callback_add(db->main, EVAS_CALLBACK_DEL, + _ephoto_main_del, db); + evas_object_size_hint_min_set(db->main, (int)round(195 * elm_config_scale_get()), 0); + evas_object_data_set(db->main, "directory_browser", db); + + _ephoto_directory_view_add(db); + + db->handlers = + eina_list_append(db->handlers, + ecore_event_handler_add(EPHOTO_EVENT_POPULATE_START, + _ephoto_dir_populate_start, db)); + + db->handlers = + eina_list_append(db->handlers, + ecore_event_handler_add(EPHOTO_EVENT_POPULATE_END, + _ephoto_dir_populate_end, db)); + + db->handlers = + eina_list_append(db->handlers, + ecore_event_handler_add(EPHOTO_EVENT_POPULATE_ERROR, + _ephoto_dir_populate_error, db)); + + db->handlers = + eina_list_append(db->handlers, + ecore_event_handler_add(EPHOTO_EVENT_ENTRY_CREATE, + _ephoto_dir_entry_create, db)); + + return db->main; + + error: + evas_object_del(db->main); + return NULL; +}