one more day of work on ephoto, still not complete.

flow browser (why that name?!) is back, with the my traditional
combination of 255,0 in rgb colored buttons in edje.

tomorrow will work on slideshow and make it work.

NOTE: ProFUSION team will work on a solution to have elm_toolbar +
elm_menu to be good and provide what we have in eve/enjoy in a more
generic way without thousand lines of macros in EDC. The goal is to
have configurable implementation that would provide some UI on desktop
and another on embedded, also showing buttons as we have space, and
hidding them with an automatic "more" entry if there is no space for
all items. That should improve eve, enjoy, ephoto and possibly others.



SVN revision: 53250
This commit is contained in:
Gustavo Sverzut Barbieri 2010-10-11 01:10:27 +00:00
parent 47da8cd526
commit b44a686b53
5 changed files with 919 additions and 158 deletions

View File

@ -725,6 +725,78 @@ collections
type: SWALLOW;
description { state: "default" 0.0;
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
}
parts {
part { name: "ephoto.swallow.flow_browser";
type: SWALLOW;
description { state: "default" 0.0;
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
}
parts {
part { name: "ephoto.swallow.slideshow";
type: SWALLOW;
description { state: "default" 0.0;
}
description { state: "hidden" 0.0;
inherit: "default" 0.0;
visible: 0;
}
}
}
programs {
program {
signal: "thumb_browser,show";
source: "ephoto";
action: STATE_SET "hidden" 0.0;
target: "ephoto.swallow.flow_browser";
target: "ephoto.swallow.slideshow";
after: "thumb_browser.show2";
}
program {
name: "thumb_browser.show2";
action: STATE_SET "default" 0.0;
target: "ephoto.swallow.thumb_browser";
}
program {
signal: "flow_browser,show";
source: "ephoto";
action: STATE_SET "hidden" 0.0;
target: "ephoto.swallow.thumb_browser";
target: "ephoto.swallow.slideshow";
after: "flow_browser.show2";
}
program {
name: "flow_browser.show2";
action: STATE_SET "default" 0.0;
target: "ephoto.swallow.flow_browser";
}
program {
signal: "slideshow,show";
source: "ephoto";
action: STATE_SET "hidden" 0.0;
target: "ephoto.swallow.thumb_browser";
target: "ephoto.swallow.flow_browser";
after: "slideshow.show2";
}
program {
name: "slideshow.show2";
action: STATE_SET "default" 0.0;
target: "ephoto.swallow.slideshow";
}
}
}
@ -794,7 +866,7 @@ collections
}
}
part { name: "ephoto.thumb.swallow";
part { name: "ephoto.swallow.thumb";
type: SWALLOW;
description { state: "default" 0.0;
rel1 { to: "ephoto.location";
@ -915,139 +987,322 @@ collections
}
}
group
{
name: "ephoto/flow/layout";
group { name: "ephoto/flow/layout";
parts {
part {
name: "ephoto.flow.swallow";
type: SWALLOW;
part { name: "back";
type: RECT;
description {
state: "default" 0.0;
rel2.to: "ephoto.toolbar.swallow";
rel2.relative: 1 0;
map {
on: 0;
color: 255 255 0 255;
rel1.offset: 10 5;
rel2 { relative: 0.0 0.0;
offset: 30 24;
}
}
description {
state: "rotate_0" 0.0;
inherit: "default" 0.0;
map {
on: 1;
rotation {
z: 0;
}
}
}
description {
state: "rotate_90" 0.0;
inherit: "default" 0.0;
map {
on: 1;
rotation {
z: 90;
}
}
}
description {
state: "rotate_180" 0.0;
inherit: "default" 0.0;
map {
on: 1;
rotation {
z: 180;
}
}
}
description {
state: "rotate_270" 0.0;
inherit: "default" 0.0;
map {
on: 1;
rotation {
z: 270;
}
}
}
programs {
program {
signal: "mouse,clicked,*";
source: "back";
action: SIGNAL_EMIT "back" "ephoto";
}
}
part {
name: "ephoto.toolbar.swallow";
type: SWALLOW;
description {
color: 0 255 0 255;
state: "default" 0.0;
rel1.relative: 0 1;
rel1.offset: 0 -63;
}
}
}
programs {
program {
name: "go_rotate_0";
signal: "ef,state,rotate,0";
source: "ef";
action: STATE_SET "rotate_0" 0.0;
transition: SINUSOIDAL 0.2;
target: "ephoto.flow.swallow";
}
program {
name: "go_rotate_90";
signal: "ef,state,rotate,90";
source: "ef";
action: STATE_SET "rotate_90" 0.0;
transition: SINUSOIDAL 0.2;
target: "ephoto.flow.swallow";
}
program {
name: "go_rotate_180";
signal: "ef,state,rotate,180";
source: "ef";
action: STATE_SET "rotate_180" 0.0;
transition: SINUSOIDAL 0.2;
target: "ephoto.flow.swallow";
}
program {
name: "go_rotate_270";
signal: "ef,state,rotate,270";
source: "ef";
action: STATE_SET "rotate_270" 0.0;
transition: SINUSOIDAL 0.2;
target: "ephoto.flow.swallow";
}
}
}
group { name: "/ephoto/directory/no-preview";
images {
set { name: "directory";
image {
image: "directory-128.png" COMP;
size: 1 1 128 128;
}
image {
image: "directory-256.png" COMP;
size: 129 129 256 256;
}
image {
image: "directory-512.png" COMP;
size: 257 257 512 512;
}
}
}
parts {
part { name: "img";
type: IMAGE;
part { name: "ephoto.text.title";
type: TEXT;
effect: SOFT_SHADOW;
mouse_events: 0;
description {
state: "default" 0.0;
aspect_preference: BOTH;
aspect: 1.0 1.0;
image.normal: "directory";
description { state: "default" 0.0;
rel1 { to_x: "back";
relative: 1.0 0.0;
offset: 5 5;
}
rel2 { relative: 1.0 0.0;
offset: -11 24;
}
text {
font: "Sans:style=Bold";
size: 12;
}
}
}
part { name: "ephoto.swallow.flow";
type: SWALLOW;
description { state: "default" 0.0;
rel1 { to_y: "ephoto.text.title";
relative: 0.0 1.0;
offset: 0 10;
}
rel2 { to_y: "iconbar.bg";
relative: 1.0 0.0;
}
}
description { state: "rotate_0" 0.0;
inherit: "default" 0.0;
map {
on: 1;
rotation.z: 0;
}
}
description { state: "rotate_90" 0.0;
inherit: "default" 0.0;
map {
on: 1;
rotation.z: 90;
}
}
description { state: "rotate_180" 0.0;
inherit: "default" 0.0;
map {
on: 1;
rotation.z: 180;
}
}
description { state: "rotate_270" 0.0;
inherit: "default" 0.0;
map {
on: 1;
rotation.z: 270;
}
}
}
programs {
program {
signal: "state,rotate,0";
source: "ephoto";
action: STATE_SET "rotate_0" 0.0;
transition: SINUSOIDAL 0.2;
target: "ephoto.swallow.flow";
}
program {
signal: "state,rotate,90";
source: "ephoto";
action: STATE_SET "rotate_90" 0.0;
transition: SINUSOIDAL 0.2;
target: "ephoto.swallow.flow";
}
program {
signal: "state,rotate,180";
source: "ephoto";
action: STATE_SET "rotate_180" 0.0;
transition: SINUSOIDAL 0.2;
target: "ephoto.swallow.flow";
}
program {
signal: "state,rotate,270";
source: "ephoto";
action: STATE_SET "rotate_270" 0.0;
transition: SINUSOIDAL 0.2;
target: "ephoto.swallow.flow";
}
}
part { name: "iconbar.bg";
type: RECT;
description { state: "default" 0.0;
rel1 { relative: 0.0 1.0;
offset: 0 -64;
}
}
}
part { name: "zoom_in_area";
type: RECT;
description { state: "default" 0.0;
color: 0 0 0 0;
rel1.to: "zoom_in";
rel2.to: "zoom_in";
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
visible: 0; /* no events */
}
}
part { name: "zoom_in";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 255 0 0 255;
rel1 { to_y: "iconbar.bg";
relative: 0.0 0.0;
}
rel2.relative: 0.2 1.0;
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
color: 0 0 0 255;
}
}
programs {
program {
signal: "mouse,clicked,*";
source: "zoom_in_area";
action: SIGNAL_EMIT "zoom_in,clicked" "ephoto";
}
program {
signal: "zoom_in,disable";
source: "ephoto";
action: STATE_SET "disabled" 0.0;
target: "zoom_in";
target: "zoom_in_area";
}
program {
signal: "zoom_in,enable";
source: "ephoto";
action: STATE_SET "default" 0.0;
target: "zoom_in";
target: "zoom_in_area";
}
}
part { name: "zoom_out_area";
type: RECT;
description { state: "default" 0.0;
color: 0 0 0 0;
rel1.to: "zoom_out";
rel2.to: "zoom_out";
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
visible: 0; /* no events */
}
}
part { name: "zoom_out";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 0 255 0 255;
rel1 { to_y: "iconbar.bg";
relative: 0.2 0.0;
}
rel2.relative: 0.4 1.0;
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
color: 0 0 0 255;
}
}
programs {
program {
signal: "mouse,clicked,*";
source: "zoom_out_area";
action: SIGNAL_EMIT "zoom_out,clicked" "ephoto";
}
program {
signal: "zoom_out,disable";
source: "ephoto";
action: STATE_SET "disabled" 0.0;
target: "zoom_out";
target: "zoom_out_area";
}
program {
signal: "zoom_out,enable";
source: "ephoto";
action: STATE_SET "default" 0.0;
target: "zoom_out";
target: "zoom_out_area";
}
}
part { name: "prev_area";
type: RECT;
description { state: "default" 0.0;
color: 0 0 0 0;
rel1.to: "prev";
rel2.to: "prev";
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
visible: 0; /* no events */
}
}
part { name: "prev";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 0 0 255 255;
rel1 { to_y: "iconbar.bg";
relative: 0.4 0.0;
}
rel2.relative: 0.6 1.0;
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
color: 0 0 0 255;
}
}
programs {
program {
signal: "mouse,clicked,*";
source: "prev_area";
action: SIGNAL_EMIT "prev,clicked" "ephoto";
}
program {
signal: "prev,disable";
source: "ephoto";
action: STATE_SET "disabled" 0.0;
target: "prev";
target: "prev_area";
}
program {
signal: "prev,enable";
source: "ephoto";
action: STATE_SET "default" 0.0;
target: "prev";
target: "prev_area";
}
}
part { name: "next_area";
type: RECT;
description { state: "default" 0.0;
color: 0 0 0 0;
rel1.to: "next";
rel2.to: "next";
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
visible: 0; /* no events */
}
}
part { name: "next";
type: RECT;
mouse_events: 0;
description { state: "default" 0.0;
color: 255 0 255 255;
rel1 { to_y: "iconbar.bg";
relative: 0.6 0.0;
}
rel2.relative: 0.8 1.0;
}
description { state: "disabled" 0.0;
inherit: "default" 0.0;
color: 0 0 0 255;
}
}
programs {
program {
signal: "mouse,clicked,*";
source: "next_area";
action: SIGNAL_EMIT "next,clicked" "ephoto";
}
program {
signal: "next,disable";
source: "ephoto";
action: STATE_SET "disabled" 0.0;
target: "next";
target: "next_area";
}
program {
signal: "next,enable";
source: "ephoto";
action: STATE_SET "default" 0.0;
target: "next";
target: "next_area";
}
}
}
}
}
}

View File

@ -33,6 +33,7 @@ typedef enum _Ephoto_Orient Ephoto_Orient;
/*Main Functions*/
Evas_Object *ephoto_window_add(const char *path);
void ephoto_title_set(Ephoto *ephoto, const char *title);
void ephoto_thumb_size_set(Ephoto *ephoto, int size);
Evas_Object *ephoto_thumb_add(Ephoto *ephoto, Evas_Object *parent, const char *path);
void ephoto_thumb_path_set(Evas_Object *o, const char *path);
@ -48,7 +49,9 @@ void ephoto_show_preferences(Ephoto *em);
/*Ephoto Flow Browser*/
Evas_Object *ephoto_flow_browser_add(Ephoto *ephoto, Evas_Object *parent);
void ephoto_flow_browser_image_set(Evas_Object *obj, const char *current_image);
void ephoto_flow_browser_path_set(Evas_Object *obj, const char *image);
void ephoto_flow_browser_entry_set(Evas_Object *obj, Ephoto_Entry *entry);
/* smart callbacks called:
* "back" - the user requested to delete the flow browser, typically called when go_back button is pressed or Escape key is typed.
*/
@ -66,6 +69,7 @@ Evas_Object *ephoto_directory_thumb_add(Evas_Object *parent, Ephoto_Entry *e);
/*Ephoto Thumb Browser*/
Evas_Object *ephoto_thumb_browser_add(Ephoto *ephoto, Evas_Object *parent);
void ephoto_thumb_browser_directory_set(Evas_Object *obj, const char *path);
void ephoto_thumb_browser_path_pending_set(Evas_Object *obj, const char *path, void (*cb)(void *data, Ephoto_Entry *entry), const void *data);
/* smart callbacks called:
* "selected" - an item in the thumb browser is selected. The selected file is passed as event_info argument.
@ -116,6 +120,7 @@ struct _Ephoto
Evas_Object *win;
Evas_Object *bg;
Evas_Object *layout;
Evas_Object *edje;
Evas_Object *thumb_browser;
Evas_Object *flow_browser;

View File

@ -1,30 +1,432 @@
#include "ephoto.h"
#ifdef HAVE_LIBEXIF
#include <libexif/exif-data.h>
#include <libexif/exif-data.h>
#endif
#define ZOOM_MIN 0.1
#define ZOOM_MAX 10.0
#define ZOOM_STEP 0.2
typedef struct _Ephoto_Flow_Browser Ephoto_Flow_Browser;
typedef struct _Ephoto_Viewer Ephoto_Viewer;
struct _Ephoto_Flow_Browser
{
Ephoto *ephoto;
Evas_Object *layout;
Evas_Object *edje;
Evas_Object *viewer;
const char *path;
Ephoto_Entry *entry;
double zoom;
};
struct _Ephoto_Viewer
{
Evas_Object *photocam;
Evas_Object *scroller;
Evas_Object *image;
};
static void _zoom_set(Ephoto_Flow_Browser *fb, double zoom);
static Eina_Bool
_path_is_jpeg(const char *path_stringshared)
{
size_t len = eina_stringshare_strlen(path_stringshared);
const char *ext;
if (len < sizeof(".jpg")) return EINA_FALSE;
ext = path_stringshared + len - (sizeof(".jpg") - 1);
if (strcasecmp(ext, ".jpg") == 0) return EINA_TRUE;
if (len < sizeof(".jpeg")) return EINA_FALSE;
ext = path_stringshared + len - (sizeof(".jpeg") - 1);
if (strcasecmp(ext, ".jpeg") == 0) return EINA_TRUE;
return EINA_FALSE;
}
static void
_viewer_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Ephoto_Viewer *v = data;
free(v);
}
static Evas_Object *
_viewer_add(Evas_Object *parent, const char *path)
{
Ephoto_Viewer *v = calloc(1, sizeof(Ephoto_Viewer));
Evas_Object *obj;
int err;
EINA_SAFETY_ON_NULL_RETURN_VAL(v, NULL);
if (_path_is_jpeg(path))
{
obj = v->photocam = elm_photocam_add(parent);
EINA_SAFETY_ON_NULL_GOTO(obj, error);
err = elm_photocam_file_set(obj, path);
if (err != EVAS_LOAD_ERROR_NONE) goto load_error;
}
else
{
Evas_Coord w, h;
obj = v->scroller = elm_scroller_add(parent);
EINA_SAFETY_ON_NULL_GOTO(obj, error);
v->image = evas_object_image_filled_add(evas_object_evas_get(parent));
evas_object_image_file_set(v->image, path, NULL);
err = evas_object_image_load_error_get(v->image);
if (err != EVAS_LOAD_ERROR_NONE) goto load_error;
evas_object_image_size_get(v->image, &w, &h);
evas_object_size_hint_align_set(v->image, 0.5, 0.5);
evas_object_size_hint_min_set(v->image, w, h);
evas_object_size_hint_max_set(v->image, w, h);
evas_object_resize(v->image, w, h);
evas_object_show(v->image);
elm_scroller_content_set(obj, v->image);
}
evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_data_set(obj, "viewer", v);
evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _viewer_del, v);
return obj;
load_error:
ERR("could not load image '%s': %s", path, evas_load_error_str(err));
evas_object_del(obj);
error:
free(v);
return NULL;
}
static void
_viewer_zoom_set(Evas_Object *obj, float zoom)
{
Ephoto_Viewer *v = evas_object_data_get(obj, "viewer");
EINA_SAFETY_ON_NULL_RETURN(v);
if (v->photocam) elm_photocam_zoom_set(v->photocam, 1.0 / zoom);
else
{
Evas_Coord w, h;
evas_object_image_size_get(v->image, &w, &h);
w *= zoom;
h *= zoom;
evas_object_size_hint_min_set(v->image, w, h);
evas_object_size_hint_max_set(v->image, w, h);
}
}
static void
_mouse_wheel(void *data, Evas *e, Evas_Object *o, void *event_info)
{
Ephoto_Flow_Browser *fb = data;
Evas_Event_Mouse_Wheel *ev = event_info;
if (!evas_key_modifier_is_set(ev->modifiers, "Control")) return;
if (ev->z > 0) _zoom_set(fb, fb->zoom + ZOOM_STEP);
else _zoom_set(fb, fb->zoom - ZOOM_STEP);
}
static Ephoto_Entry *
_find_first_entry(Ephoto_Flow_Browser *fb)
{
const Eina_List *l;
Ephoto_Entry *entry;
EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ephoto, NULL);
EINA_LIST_FOREACH(fb->ephoto->entries, l, entry)
if (!entry->is_dir) return entry;
return NULL;
}
static Ephoto_Entry *
_find_last_entry(Ephoto_Flow_Browser *fb)
{
const Eina_List *l;
Ephoto_Entry *entry;
EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ephoto, NULL);
EINA_LIST_REVERSE_FOREACH(fb->ephoto->entries, l, entry)
if (!entry->is_dir) return entry;
return NULL;
}
static void
_ephoto_flow_browser_toolbar_eval(Ephoto_Flow_Browser *fb)
{
if (!fb->entry)
{
edje_object_signal_emit(fb->edje, "slideshow,disable", "ephoto");
edje_object_signal_emit(fb->edje, "prev,disable", "ephoto");
edje_object_signal_emit(fb->edje, "next,disable", "ephoto");
}
else
{
edje_object_signal_emit(fb->edje, "slideshow,enable", "ephoto");
if (fb->entry == _find_first_entry(fb))
edje_object_signal_emit(fb->edje, "prev,disable", "ephoto");
else
edje_object_signal_emit(fb->edje, "prev,enable", "ephoto");
if (fb->entry == _find_last_entry(fb))
edje_object_signal_emit(fb->edje, "next,disable", "ephoto");
else
edje_object_signal_emit(fb->edje, "next,enable", "ephoto");
}
}
static void
_ephoto_flow_browser_recalc(Ephoto_Flow_Browser *fb)
{
if (fb->viewer)
{
evas_object_del(fb->viewer);
fb->viewer = NULL;
}
if (fb->path)
{
const char *bname = ecore_file_file_get(fb->path);
fb->viewer = _viewer_add(fb->layout, fb->path);
elm_layout_content_set(fb->layout, "ephoto.swallow.flow", fb->viewer);
evas_object_event_callback_add
(fb->viewer, EVAS_CALLBACK_MOUSE_WHEEL, _mouse_wheel, fb);
edje_object_part_text_set(fb->edje, "ephoto.text.title", bname);
ephoto_title_set(fb->ephoto, bname);
}
_ephoto_flow_browser_toolbar_eval(fb);
}
static void
_zoom_set(Ephoto_Flow_Browser *fb, double zoom)
{
if (zoom > ZOOM_MAX) zoom = ZOOM_MAX;
else if (zoom < ZOOM_MIN) zoom = ZOOM_MIN;
DBG("zoom %f", zoom);
_viewer_zoom_set(fb->viewer, zoom);
fb->zoom = zoom;
if (zoom <= ZOOM_MIN)
edje_object_signal_emit(fb->edje, "zoom_out,disable", "ephoto");
else
edje_object_signal_emit(fb->edje, "zoom_out,enable", "ephoto");
if (zoom >= ZOOM_MAX)
edje_object_signal_emit(fb->edje, "zoom_in,disable", "ephoto");
else
edje_object_signal_emit(fb->edje, "zoom_in,enable", "ephoto");
}
static void
_zoom_in(void *data, Evas_Object *o, const char *emission, const char *source)
{
Ephoto_Flow_Browser *fb = data;
_zoom_set(fb, fb->zoom + ZOOM_STEP);
}
static void
_zoom_out(void *data, Evas_Object *o, const char *emission, const char *source)
{
Ephoto_Flow_Browser *fb = data;
_zoom_set(fb, fb->zoom - ZOOM_STEP);
}
static void
_next_entry(Ephoto_Flow_Browser *fb)
{
Elm_Gengrid_Item *it;
Ephoto_Entry *entry;
EINA_SAFETY_ON_NULL_RETURN(fb->entry);
EINA_SAFETY_ON_NULL_RETURN(fb->entry->item);
it = fb->entry->item;
while ((it = elm_gengrid_item_next_get(it)))
{
entry = elm_gengrid_item_data_get(it);
if (!entry->is_dir) break;
}
if (!it) return;
DBG("next is '%s'", entry->path);
ephoto_flow_browser_entry_set(fb->layout, entry);
}
static void
_prev_entry(Ephoto_Flow_Browser *fb)
{
Elm_Gengrid_Item *it;
Ephoto_Entry *entry;
EINA_SAFETY_ON_NULL_RETURN(fb->entry);
EINA_SAFETY_ON_NULL_RETURN(fb->entry->item);
it = fb->entry->item;
while ((it = elm_gengrid_item_prev_get(it)))
{
entry = elm_gengrid_item_data_get(it);
if (!entry->is_dir) break;
}
if (!it) return;
DBG("prev is '%s'", entry->path);
ephoto_flow_browser_entry_set(fb->layout, entry);
}
static void
_first_entry(Ephoto_Flow_Browser *fb)
{
Ephoto_Entry *entry = _find_first_entry(fb);
if (!entry) return;
DBG("first is '%s'", entry->path);
ephoto_flow_browser_entry_set(fb->layout, entry);
}
static void
_last_entry(Ephoto_Flow_Browser *fb)
{
Ephoto_Entry *entry = _find_last_entry(fb);
if (!entry) return;
DBG("last is '%s'", entry->path);
ephoto_flow_browser_entry_set(fb->layout, entry);
}
static void
_next_button(void *data, Evas_Object *o, const char *emission, const char *source)
{
Ephoto_Flow_Browser *fb = data;
_next_entry(fb);
}
static void
_prev_button(void *data, Evas_Object *o, const char *emission, const char *source)
{
Ephoto_Flow_Browser *fb = data;
_prev_entry(fb);
}
static void
_back(void *data, Evas_Object *o, const char *emission, const char *source)
{
Ephoto_Flow_Browser *fb = data;
evas_object_smart_callback_call(fb->layout, "back", fb->entry);
}
static void
_key_down(void *data, Evas *e, Evas_Object *o, void *event_info)
{
Ephoto_Flow_Browser *fb = data;
Evas_Event_Key_Down *ev = event_info;
Eina_Bool ctrl = evas_key_modifier_is_set(ev->modifiers, "Control");
const char *k = ev->keyname;
if (ctrl)
{
if ((!strcmp(k, "plus")) || (!strcmp(k, "equal")))
_zoom_set(fb, fb->zoom + ZOOM_STEP);
else if (!strcmp(k, "minus"))
_zoom_set(fb, fb->zoom - ZOOM_STEP);
else if (!strcmp(k, "0"))
_zoom_set(fb, 1.0);
}
if (!strcmp(k, "Escape"))
evas_object_smart_callback_call(fb->layout, "back", fb->entry);
else if (!strcmp(k, "Left"))
_prev_entry(fb);
else if (!strcmp(k, "Right"))
_next_entry(fb);
else if (!strcmp(k, "Home"))
_first_entry(fb);
else if (!strcmp(k, "End"))
_last_entry(fb);
}
static void
_layout_del(void *data, Evas *e, Evas_Object *o, void *event_info)
{
Ephoto_Flow_Browser *fb = data;
eina_stringshare_del(fb->path);
free(fb);
}
Evas_Object *
ephoto_flow_browser_add(Ephoto *ephoto, Evas_Object *parent)
{
Evas_Object *layout = elm_layout_add(parent);
Ephoto_Flow_Browser *fb;
EINA_SAFETY_ON_NULL_RETURN_VAL(layout, NULL);
fb = calloc(1, sizeof(Ephoto_Flow_Browser));
EINA_SAFETY_ON_NULL_GOTO(fb, error);
fb->ephoto = ephoto;
fb->layout = layout;
fb->edje = elm_layout_edje_get(layout);
fb->zoom = 1.0;
evas_object_event_callback_add(layout, EVAS_CALLBACK_DEL, _layout_del, fb);
evas_object_event_callback_add
(layout, EVAS_CALLBACK_KEY_DOWN, _key_down, fb);
elm_object_focus_allow_set(layout, EINA_TRUE);
evas_object_data_set(layout, "flow_browser", fb);
edje_object_signal_callback_add
(fb->edje, "zoom_out,clicked", "ephoto", _zoom_out, fb);
edje_object_signal_callback_add
(fb->edje, "zoom_in,clicked", "ephoto", _zoom_in, fb);
edje_object_signal_callback_add
(fb->edje, "prev,clicked", "ephoto", _prev_button, fb);
edje_object_signal_callback_add
(fb->edje, "next,clicked", "ephoto", _next_button, fb);
edje_object_signal_callback_add
(fb->edje, "back", "ephoto", _back, fb);
if (!elm_layout_file_set(layout, THEME_FILE, "ephoto/flow/layout"))
{
evas_object_del(layout);
return NULL;
}
/* TODO */
_ephoto_flow_browser_toolbar_eval(fb);
return layout;
error:
evas_object_del(layout);
return NULL;
}
void
ephoto_flow_browser_image_set(Evas_Object *obj, const char *path)
ephoto_flow_browser_path_set(Evas_Object *obj, const char *path)
{
/* TODO */
Ephoto_Flow_Browser *fb = evas_object_data_get(obj, "flow_browser");
EINA_SAFETY_ON_NULL_RETURN(fb);
DBG("path '%s', was '%s'", path ? path : "", fb->path ? fb->path : "");
if (!eina_stringshare_replace(&fb->path, path)) return;
fb->entry = NULL;
fb->zoom = 1.0;
_ephoto_flow_browser_recalc(fb);
}
void
ephoto_flow_browser_entry_set(Evas_Object *obj, Ephoto_Entry *entry)
{
Ephoto_Flow_Browser *fb = evas_object_data_get(obj, "flow_browser");
EINA_SAFETY_ON_NULL_RETURN(fb);
DBG("entry %p, was %p", entry, fb->entry);
fb->entry = entry;
if (!eina_stringshare_replace(&fb->path, entry->path))
_ephoto_flow_browser_toolbar_eval(fb);
else
{
fb->zoom = 1.0;
_ephoto_flow_browser_recalc(fb);
}
}

View File

@ -1,31 +1,38 @@
#include "ephoto.h"
static void
_ephoto_flow_browser_delete(void *data, Evas_Object *obj, void *event_info)
_ephoto_thumb_browser_show(Ephoto *ephoto, Ephoto_Entry *entry)
{
Ephoto *ephoto = data;
ephoto->flow_browser = NULL;
elm_layout_content_set
(ephoto->layout, "ephoto.swallow.content", ephoto->thumb_browser);
DBG("entry '%s'", entry ? entry->path : "");
ephoto_flow_browser_path_set(ephoto->flow_browser, NULL);
elm_object_focus(ephoto->thumb_browser);
evas_object_focus_set(ephoto->thumb_browser, EINA_TRUE); // TODO while elm_layout is broken WRT focus
edje_object_signal_emit(ephoto->edje, "thumb_browser,show", "ephoto");
ephoto->state = EPHOTO_STATE_THUMB;
if ((entry) && (entry->item)) elm_gengrid_item_bring_in(entry->item);
}
static void
_ephoto_flow_browser_show(Ephoto *ephoto, Ephoto_Entry *entry)
{
/* remove thumb browser without deleting it */
elm_layout_content_unset(ephoto->layout, "ephoto.swallow.content");
ephoto->flow_browser = ephoto_flow_browser_add(ephoto, ephoto->layout);
ephoto_flow_browser_image_set(ephoto->flow_browser, entry->path);
elm_layout_content_set
(ephoto->layout, "ephoto.swallow.content", ephoto->flow_browser);
evas_object_smart_callback_add
(ephoto->flow_browser, "back", _ephoto_flow_browser_delete, ephoto);
DBG("entry '%s'", entry->path);
ephoto_flow_browser_entry_set(ephoto->flow_browser, entry);
elm_object_focus(ephoto->flow_browser);
evas_object_focus_set(ephoto->flow_browser, EINA_TRUE); // TODO while elm_layout is broken WRT focus
edje_object_signal_emit(ephoto->edje, "flow_browser,show", "ephoto");
ephoto->state = EPHOTO_STATE_FLOW;
}
static void
_ephoto_flow_browser_back(void *data, Evas_Object *obj, void *event_info)
{
Ephoto *ephoto = data;
Ephoto_Entry *entry = event_info;
_ephoto_thumb_browser_show(ephoto, entry);
}
static void
_ephoto_thumb_browser_view(void *data, Evas_Object *obj, void *event_info)
{
@ -35,7 +42,19 @@ _ephoto_thumb_browser_view(void *data, Evas_Object *obj, void *event_info)
}
static void
_win_del(void *data, Evas *e, Evas_Object *o, void *event_info)
_pending_path_found(void *data, Ephoto_Entry *entry)
{
Ephoto *ephoto = data;
if (!entry)
{
ERR("not found entry, but it should be in directory? weird!");
return;
}
ephoto_flow_browser_entry_set(ephoto->flow_browser, entry);
}
static void
_win_free(void *data, Evas *e, Evas_Object *o, void *event_info)
{
Ephoto *ephoto = data;
if (ephoto->timer.thumb_regen) ecore_timer_del(ephoto->timer.thumb_regen);
@ -47,7 +66,6 @@ ephoto_window_add(const char *path)
{
Ephoto *ephoto = calloc(1, sizeof(Ephoto));
Ethumb_Client *client = elm_thumb_ethumb_client_get();
Evas_Object *ed;
Evas_Coord mw, mh, iw, ih;
const char *s;
EINA_SAFETY_ON_NULL_RETURN_VAL(ephoto, NULL);
@ -60,7 +78,7 @@ ephoto_window_add(const char *path)
}
evas_object_event_callback_add
(ephoto->win, EVAS_CALLBACK_DEL, _win_del, ephoto);
(ephoto->win, EVAS_CALLBACK_FREE, _win_free, ephoto);
elm_win_autodel_set(ephoto->win, EINA_TRUE);
evas_object_show(ephoto->win);
@ -94,6 +112,7 @@ ephoto_window_add(const char *path)
evas_object_del(ephoto->win);
return NULL;
}
ephoto->edje = elm_layout_edje_get(ephoto->layout);
evas_object_size_hint_weight_set
(ephoto->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_fill_set
@ -110,30 +129,70 @@ ephoto_window_add(const char *path)
}
elm_layout_content_set
(ephoto->layout, "ephoto.swallow.thumb_browser", ephoto->thumb_browser);
evas_object_smart_callback_add
(ephoto->thumb_browser, "view", _ephoto_thumb_browser_view, ephoto);
ed = elm_layout_edje_get(ephoto->layout);
edje_object_size_min_get(ed, &mw, &mh);
edje_object_size_min_restricted_calc(ed, &mw, &mh, mw, mh);
ephoto->flow_browser = ephoto_flow_browser_add(ephoto, ephoto->layout);
if (!ephoto->flow_browser)
{
ERR("could not add flow browser");
evas_object_del(ephoto->win);
return NULL;
}
elm_layout_content_set
(ephoto->layout, "ephoto.swallow.flow_browser", ephoto->flow_browser);
evas_object_smart_callback_add
(ephoto->flow_browser, "back", _ephoto_flow_browser_back, ephoto);
edje_object_size_min_get(ephoto->edje, &mw, &mh);
edje_object_size_min_restricted_calc(ephoto->edje, &mw, &mh, mw, mh);
if (mw < 1) mw = 320;
if (mh < 1) mh = 240;
s = edje_object_data_get(ed, "initial_size");
s = edje_object_data_get(ephoto->edje, "initial_size");
if ((!s) || (sscanf(s, "%d %d", &iw, &ih) != 2)) iw = ih = 0;
if (iw < mw) iw = mw;
if (ih < mh) ih = mh;
evas_object_resize(ephoto->win, iw, ih);
if (!path)
ephoto_thumb_browser_directory_set
(ephoto->thumb_browser, ephoto->config->directory);
if ((!path) || (!ecore_file_exists(path)))
{
ephoto_thumb_browser_directory_set
(ephoto->thumb_browser, ephoto->config->directory);
_ephoto_thumb_browser_show(ephoto, NULL);
}
else if (ecore_file_is_dir(path))
ephoto_thumb_browser_directory_set(ephoto->thumb_browser, path);
{
ephoto_thumb_browser_directory_set(ephoto->thumb_browser, path);
_ephoto_thumb_browser_show(ephoto, NULL);
}
else
ERR("loading file to be done");
{
char *dir = ecore_file_dir_get(path);
ephoto_thumb_browser_directory_set(ephoto->thumb_browser, dir);
free(dir);
ephoto_thumb_browser_path_pending_set
(ephoto->thumb_browser, path, _pending_path_found, ephoto);
ephoto_flow_browser_path_set(ephoto->flow_browser, path);
elm_object_focus(ephoto->flow_browser);
evas_object_focus_set(ephoto->flow_browser, EINA_TRUE); // TODO while elm_layout is broken WRT focus
edje_object_signal_emit(ephoto->edje, "flow_browser,show", "ephoto");
ephoto->state = EPHOTO_STATE_FLOW;
}
return ephoto->win;
}
void
ephoto_title_set(Ephoto *ephoto, const char *title)
{
char buf[1024] = "Ephoto";
if (title) snprintf(buf, sizeof(buf), "%s - Ephoto", title);
elm_win_title_set(ephoto->win, buf);
}
#if 0
char current_directory[PATH_MAX];
Ethumb_Client *client = elm_thumb_ethumb_client_get();

View File

@ -15,6 +15,11 @@ struct _Ephoto_Thumb_Browser
Evas_Object *edje;
Evas_Object *grid;
Eio_File *ls;
struct {
const char *path;
void (*cb)(void *data, Ephoto_Entry *entry);
const void *data;
} pending;
struct {
Ecore_Job *change_dir;
} job;
@ -147,6 +152,14 @@ _ephoto_populate_main(void *data, const Eina_File_Direct_Info *info)
msg.val = eina_list_count(tb->ephoto->entries);
edje_object_message_send(tb->edje, EDJE_MESSAGE_INT, 1, &msg);
DBG("populate add '%s'", e->path);
if (tb->pending.path == e->path)
{
tb->pending.cb((void*)tb->pending.data, e);
tb->pending.cb = NULL;
tb->pending.data = NULL;
eina_stringshare_replace(&tb->pending.path, NULL);
}
}
static Eina_Bool
@ -171,6 +184,14 @@ _ephoto_populate_end(void *data)
{
Ephoto_Thumb_Browser *tb = data;
tb->ls = NULL;
if (tb->pending.cb)
{
tb->pending.cb((void*)tb->pending.data, NULL);
tb->pending.cb = NULL;
}
tb->pending.data = NULL;
eina_stringshare_replace(&tb->pending.path, NULL);
edje_object_signal_emit(tb->edje, "populate,stop", "ephoto");
}
static void
@ -178,9 +199,8 @@ _ephoto_populate_error(int error, void *data)
{
Ephoto_Thumb_Browser *tb = data;
if (error) ERR("could not populate: %s", strerror(error));
tb->ls = NULL;
edje_object_signal_emit(tb->edje, "populate,stop", "ephoto");
edje_object_signal_emit(tb->edje, "populate,error", "ephoto");
_ephoto_populate_end(tb);
}
static void
@ -236,6 +256,8 @@ _ephoto_thumb_selected(void *data, Evas_Object *o, void *event_info)
Elm_Gengrid_Item *it = event_info;
Ephoto_Entry *e = elm_gengrid_item_data_get(it);
elm_gengrid_item_selected_set(it, EINA_FALSE);
if (e->is_dir)
ephoto_thumb_browser_directory_set(tb->layout, e->path);
else
@ -295,6 +317,8 @@ static void
_layout_del(void *data, Evas *e, Evas_Object *o, void *event_info)
{
Ephoto_Thumb_Browser *tb = data;
if (tb->pending.cb) tb->pending.cb((void*)tb->pending.data, NULL);
eina_stringshare_del(tb->pending.path);
if (tb->ls) eio_file_cancel(tb->ls);
if (tb->job.change_dir) ecore_job_del(tb->job.change_dir);
free(tb);
@ -345,7 +369,7 @@ ephoto_thumb_browser_add(Ephoto *ephoto, Evas_Object *parent)
_zoom_set(tb, tb->ephoto->config->thumb_size);
elm_layout_content_set(tb->layout, "ephoto.thumb.swallow", tb->grid);
elm_layout_content_set(tb->layout, "ephoto.swallow.thumb", tb->grid);
return layout;
@ -360,7 +384,23 @@ ephoto_thumb_browser_directory_set(Evas_Object *obj, const char *path)
Ephoto_Thumb_Browser *tb = evas_object_data_get(obj, "thumb_browser");
EINA_SAFETY_ON_NULL_RETURN(tb);
eina_stringshare_replace(&tb->pending.path, NULL);
tb->pending.cb = NULL;
tb->pending.data = NULL;
ephoto_title_set(tb->ephoto, path);
eina_stringshare_replace(&tb->ephoto->config->directory, path);
if (tb->job.change_dir) ecore_job_del(tb->job.change_dir);
tb->job.change_dir = ecore_job_add(_ephoto_thumb_change_dir, tb);
}
void
ephoto_thumb_browser_path_pending_set(Evas_Object *obj, const char *path, void (*cb)(void *data, Ephoto_Entry *entry), const void *data)
{
Ephoto_Thumb_Browser *tb = evas_object_data_get(obj, "thumb_browser");
EINA_SAFETY_ON_NULL_RETURN(tb);
eina_stringshare_replace(&tb->pending.path, path);
tb->pending.cb = cb;
tb->pending.data = data;
}