Fix a lot of things in ephoto.. reuse some older code but in a good way. Add in a single image browser. Use externals(ugh, but its faster for some reason?)

SVN revision: 57313
v-1.6.0
titan 12 years ago committed by titan
parent 362047fe24
commit 7a11918ac3
  1. 899
      data/themes/default/ephoto.edc
  2. 11
      data/themes/default/images/Makefile.am
  3. BIN
      data/themes/default/images/bt_sm_base1.png
  4. BIN
      data/themes/default/images/bt_sm_hilight.png
  5. BIN
      data/themes/default/images/bt_sm_shine.png
  6. BIN
      data/themes/default/images/directory-128.png
  7. BIN
      data/themes/default/images/directory-256.png
  8. BIN
      data/themes/default/images/directory-512.png
  9. BIN
      data/themes/default/images/raise.png
  10. BIN
      data/themes/default/images/up-128.png
  11. BIN
      data/themes/default/images/up-256.png
  12. BIN
      data/themes/default/images/up-512.png
  13. 9
      src/bin/Makefile.am
  14. 85
      src/bin/ephoto.c
  15. 197
      src/bin/ephoto.h
  16. 158
      src/bin/ephoto_config.c
  17. 15
      src/bin/ephoto_flow_browser.c
  18. 576
      src/bin/ephoto_main.c
  19. 189
      src/bin/ephoto_preferences.c
  20. 1025
      src/bin/ephoto_single_browser.c
  21. 207
      src/bin/ephoto_slideshow.c
  22. 639
      src/bin/ephoto_thumb_browser.c

@ -1,373 +1,530 @@
externals {
external: "elm";
}
collections {
group
{
name: "flow_image";
image: "thumb_shadow.png" COMP;
parts
{
part
{
name: "event";
type: RECT;
repeat_events: 1;
description
{
state: "default" 0.0;
color: 0 0 0 0;
}
}
part
{
name: "border-shadow";
type: IMAGE;
mouse_events: 0;
description
{
state: "default" 0.0;
rel1
{
to: "image";
offset: -18 -18;
}
rel2
{
to: "image";
offset: 17 17;
}
image
{
normal: "thumb_shadow.png";
border: 17 17 17 17;
middle: NONE;
}
}
}
part
{
name: "border";
type: RECT;
mouse_events: 0;
description
{
state: "default" 0.0;
rel1
{
to: "border-shadow";
offset: 16 16;
}
rel2
{
to: "border-shadow";
offset: -15 -15;
}
}
}
part
{
name: "image";
type: SWALLOW;
mouse_events: 0;
description
{
state: "default" 0.0;
aspect_preference: BOTH;
aspect: 1.0 1.0;
rel1.offset: 0 8;
rel2.offset: -1 -2;
}
}
// part
// {
// name: "text";
// type: TEXT;
// effect: SOFT_SHADOW;
// mouse_events: 0;
// scale: 1;
// description
// {
// state: "default" 0.0;
// color: 0 0 0 255;
// color3: 0 0 0 0;
// align: 0.5 1.0;
// rel1
// {
// relative: 0.0 1.0;
// offset: 20 -30;
// }
// rel2
// {
// relative: 1.0 1.0;
// offset: -21 -15;
// }
// text
// {
// font: "Sans";
// size: 10;
// min: 0 1;
// align: 0.5 0.0;
// text_class: "image";
// }
// }
// }
}
}
group
{
name: "flow";
parts
{
part
{
name: "offscreen_left";
type: SWALLOW;
mouse_events: 1;
description
{
state: default 0.0;
fixed: 1 1;
visible: 0;
rel1.relative: 0.0 0.3;
rel1.offset: 0 0;
rel2.relative: 0.0 0.7;
rel2.offset: 0 0;
}
description
{
state: right 0.0;
visible: 1;
rel1.relative: 0.0 0.3;
rel1.offset: 0 0;
rel2.relative: 0.2 0.7;
rel2.offset: 0 0;
}
description
{
state: left 0.0;
visible: 0;
rel1.relative: 1.0 0.3;
rel1.offset: 0 0;
rel2.relative: 1.0 0.7;
rel2.offset: 0 0;
}
}
part
{
name: "left";
type: SWALLOW;
mouse_events: 1;
description
{
state: default 0.0;
visible: 1;
rel1.relative: 0.0 0.3;
rel1.offset: 0 0;
rel2.relative: 0.2 0.7;
rel2.offset: 0 0;
}
description
{
state: right 0.0;
rel1.relative: 0.2 0.2;
rel1.offset: 0 0;
rel2.relative: 0.8 0.8;
rel2.offset: 0 0;
}
description
{
state: left 0.0;
rel1.relative: 0.0 0.3;
rel1.offset: 0 0;
rel2.relative: 0.0 0.7;
rel2.offset: 0 0;
}
description
{
state: full 0.0;
map.on: 1;
inherit: default 0.0;
visible: 0;
}
}
part
{
name: "right";
type: SWALLOW;
mouse_events: 1;
description
{
state: default 0.0;
visible: 1;
rel1.relative: 0.8 0.3;
rel1.offset: 0 0;
rel2.relative: 1.0 0.7;
rel2.offset: 0 0;
}
description
{
state: right 0.0;
rel1.relative: 1.0 0.3;
rel1.offset: 0 0;
rel2.relative: 1.0 0.7;
rel2.offset: 0 0;
}
description
{
state: left 0.0;
rel1.relative: 0.2 0.2;
rel1.offset: 0 0;
rel2.relative: 0.8 0.8;
rel2.offset: 0 0;
}
description
{
state: full 0.0;
map.on: 1;
inherit: default 0.0;
visible: 0;
}
}
part
{
name: "center";
type: SWALLOW;
mouse_events: 1;
description
{
state: default 0.0;
rel1.relative: 0.2 0.2;
rel1.offset: 0 0;
rel2.relative: 0.8 0.8;
rel2.offset: 0 0;
}
description
{
state: right 0.0;
rel1.relative: 0.8 0.3;
rel1.offset: 0 0;
rel2.relative: 1.0 0.7;
rel2.offset: 0 0;
}
description
{
state: left 0.0;
rel1.relative: 0.0 0.3;
rel1.offset: 0 0;
rel2.relative: 0.2 0.7;
rel2.offset: 0 0;
}
description
{
state: full 0.0;
rel1.relative: 0.0 0.0;
rel1.offset: 0 0;
rel2.relative: 1.0 1.0;
rel2.offset: -1 -1;
}
}
part
{
name: "offscreen_right";
type: SWALLOW;
mouse_events: 1;
description
{
state: default 0.0;
fixed: 1 1;
visible: 0;
rel1.relative: 1.0 0.3;
rel1.offset: 0 0;
rel2.relative: 1.0 0.7;
rel2.offset: 0 0;
}
description
{
state: right 0.0;
visible: 0;
rel1.relative: 0.0 0.3;
rel1.offset: 0 0;
rel2.relative: 0.0 0.7;
rel2.offset: 0 0;
}
description
{
state: left 0.0;
visible: 1;
rel1.relative: 0.8 0.3;
rel1.offset: 0 0;
rel2.relative: 1.0 0.7;
rel2.offset: 0 0;
}
}
}
programs
{
program
{
name: "right";
signal: "right";
source: "ephoto";
action: STATE_SET right 0.0;
transition: LINEAR 0.4;
target: "offscreen_right";
target: "right";
target: "center";
target: "left";
target: "offscreen_left";
after: "done";
}
program
{
name: "left";
signal: "left";
source: "ephoto";
action: STATE_SET left 0.0;
transition: LINEAR 0.4;
target: "offscreen_left";
target: "left";
target: "center";
target: "right";
target: "offscreen_right";
after: "done";
}
program
{
name: "full";
signal: "full";
source: "ephoto";
action: STATE_SET full 0.0;
transition: LINEAR 0.2;
target: "left";
target: "right";
target: "center";
}
program
{
name: "full_reset";
signal: "full_reset";
source: "ephoto";
action: STATE_SET default 0.0;
transition: LINEAR 0.2;
target: "left";
target: "right";
target: "center";
}
program
{
name: "done";
action: SIGNAL_EMIT "done" "ephoto";
}
program
{
name: "reset";
signal: "reset";
source: "ephoto";
action: STATE_SET default 0.0;
target: "offscreen_right";
target: "right";
target: "center";
target: "left";
target: "offscreen_left";
}
}
}
images
{
image: "thumb_shadow.png" COMP;
}
group
{
name: "elm/layout/ephoto/orient";
parts
{
part
{
name: "elm.swallow.content";
type: SWALLOW;
description
{
state: "default" 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;
}
}
description
{
state: "flip_horiz" 0.0;
inherit: "default" 0.0;
map
{
on: 1;
rotation.y : 180;
}
}
description
{
state: "flip_vert" 0.0;
inherit: "default" 0.0;
map
{
on: 1;
rotation.x : 180;
}
}
description
{
state: "flip_horiz_90" 0.0;
inherit: "default" 0.0;
map
{
on: 1;
rotation
{
z: 90;
y: 180;
}
}
}
description
{
state: "flip_vert_90" 0.0;
inherit: "default" 0.0;
map
{
on: 1;
rotation
{
z: 90;
x: 180;
}
}
}
}
programs
{
program
{
signal: "state,rotate,0";
source: "ephoto";
action: STATE_SET "rotate_0" 0.0;
target: "elm.swallow.content";
}
program
{
signal: "state,rotate,90";
source: "ephoto";
action: STATE_SET "rotate_90" 0.0;
target: "elm.swallow.content";
}
program
{
signal: "state,rotate,180";
source: "ephoto";
action: STATE_SET "rotate_180" 0.0;
target: "elm.swallow.content";
}
program
{
signal: "state,rotate,270";
source: "ephoto";
action: STATE_SET "rotate_270" 0.0;
target: "elm.swallow.content";
}
program
{
signal: "state,flip,horiz";
source: "ephoto";
action: STATE_SET "flip_horiz" 0.0;
target: "elm.swallow.content";
}
program
{
signal: "state,flip,vert";
source: "ephoto";
action: STATE_SET "flip_vert" 0.0;
target: "elm.swallow.content";
}
program
{
signal: "state,flip,horiz,90";
source: "ephoto";
action: STATE_SET "flip_horiz_90" 0.0;
target: "elm.swallow.content";
}
program
{
signal: "state,flip,vert,90";
source: "ephoto";
action: STATE_SET "flip_vert_90" 0.0;
target: "elm.swallow.content";
}
}
}
}
group
{
name: "ephoto,thumb,grid";
parts
{
part
{
name: "ephoto.swallow.content.thumb";
type: SWALLOW;
mouse_events: 1;
description
{
state: "default" 0.0;
rel1.relative : 0.0 0.0;
rel1.offset : 0 0;
rel2.relative : 1.0 1.0;
rel2.offset : -1 -1;
}
}
}
}
group
{
name: "flow_image";
parts
{
part
{
name: "event";
type: RECT;
repeat_events: 1;
description
{
state: "default" 0.0;
color: 0 0 0 0;
}
}
part
{
name: "border-shadow";
type: IMAGE;
mouse_events: 0;
description
{
state: "default" 0.0;
rel1
{
to: "image";
offset: -18 -18;
}
rel2
{
to: "image";
offset: 17 17;
}
image
{
normal: "thumb_shadow.png";
border: 17 17 17 17;
middle: NONE;
}
}
}
part
{
name: "border";
type: RECT;
mouse_events: 0;
description
{
state: "default" 0.0;
rel1
{
to: "border-shadow";
offset: 16 16;
}
rel2
{
to: "border-shadow";
offset: -15 -15;
}
}
}
part
{
name: "image";
type: SWALLOW;
mouse_events: 0;
description
{
state: "default" 0.0;
aspect_preference: BOTH;
aspect: 1.0 1.0;
rel1.offset : 0 8;
rel2.offset : -1 -2;
}
}
}
}
group
{
name: "flow";
parts
{
part
{
name: "offscreen_left";
type: SWALLOW;
mouse_events: 1;
description
{
state: default 0.0;
fixed: 1 1;
visible: 0;
rel1.relative : 0.0 0.3;
rel1.offset : 0 0;
rel2.relative : 0.0 0.7;
rel2.offset : 0 0;
}
description
{
state: right 0.0;
visible: 1;
rel1.relative : 0.0 0.3;
rel1.offset : 0 0;
rel2.relative : 0.2 0.7;
rel2.offset : 0 0;
}
description
{
state: left 0.0;
visible: 0;
rel1.relative : 1.0 0.3;
rel1.offset : 0 0;
rel2.relative : 1.0 0.7;
rel2.offset : 0 0;
}
}
part
{
name: "left";
type: SWALLOW;
mouse_events: 1;
description
{
state: default 0.0;
visible: 1;
rel1.relative : 0.0 0.3;
rel1.offset : 0 0;
rel2.relative : 0.2 0.7;
rel2.offset : 0 0;
}
description
{
state: right 0.0;
rel1.relative : 0.2 0.2;
rel1.offset : 0 0;
rel2.relative : 0.8 0.8;
rel2.offset : 0 0;
}
description
{
state: left 0.0;
rel1.relative : 0.0 0.3;
rel1.offset : 0 0;
rel2.relative : 0.0 0.7;
rel2.offset : 0 0;
}
description
{
state: full 0.0;
inherit: default 0.0;
visible: 0;
}
}
part
{
name: "offscreen_right";
type: SWALLOW;
mouse_events: 1;
description
{
state: default 0.0;
fixed: 1 1;
visible: 0;
rel1.relative : 1.0 0.3;
rel1.offset : 0 0;
rel2.relative : 1.0 0.7;
rel2.offset : 0 0;
}
description
{
state: right 0.0;
visible: 0;
rel1.relative : 0.0 0.3;
rel1.offset : 0 0;
rel2.relative : 0.0 0.7;
rel2.offset : 0 0;
}
description
{
state: left 0.0;
visible: 1;
rel1.relative : 0.8 0.3;
rel1.offset : 0 0;
rel2.relative : 1.0 0.7;
rel2.offset : 0 0;
}
}
part
{
name: "right";
type: SWALLOW;
mouse_events: 1;
description
{
state: default 0.0;
visible: 1;
rel1.relative : 0.8 0.3;
rel1.offset : 0 0;
rel2.relative : 1.0 0.7;
rel2.offset : 0 0;
}
description
{
state: right 0.0;
rel1.relative : 1.0 0.3;
rel1.offset : 0 0;
rel2.relative : 1.0 0.7;
rel2.offset : 0 0;
}
description
{
state: left 0.0;
rel1.relative : 0.2 0.2;
rel1.offset : 0 0;
rel2.relative : 0.8 0.8;
rel2.offset : 0 0;
}
description
{
state: full 0.0;
inherit: default 0.0;
visible: 0;
}
}
part
{
name: "center";
type: SWALLOW;
mouse_events: 1;
description
{
state: default 0.0;
rel1.relative : 0.2 0.2;
rel1.offset : 0 0;
rel2.relative : 0.8 0.8;
rel2.offset : 0 0;
}
description
{
state: right 0.0;
rel1.relative : 0.8 0.3;
rel1.offset : 0 0;
rel2.relative : 1.0 0.7;
rel2.offset : 0 0;
}
description
{
state: left 0.0;
rel1.relative : 0.0 0.3;
rel1.offset : 0 0;
rel2.relative : 0.2 0.7;
rel2.offset : 0 0;
}
description
{
state: full 0.0;
rel1.relative : 0.0 0.0;
rel1.offset : 0 0;
rel2.relative : 1.0 1.0;
rel2.offset : -1 -1;
}
}
}
programs
{
program
{
name: "right";
signal: "right";
source: "ephoto";
action: STATE_SET right 0.0;
transition: LINEAR 0.4;
target: "offscreen_right";
target: "right";
target: "center";
target: "left";
target: "offscreen_left";
after: "done";
}
program
{
name: "left";
signal: "left";
source: "ephoto";
action: STATE_SET left 0.0;
transition: LINEAR 0.4;
target: "offscreen_left";
target: "left";
target: "center";
target: "right";
target: "offscreen_right";
after: "done";
}
program
{
name: "full";
signal: "full";
source: "ephoto";
action: STATE_SET full 0.0;
transition: LINEAR 0.2;
target: "left";
target: "right";
target: "center";
}
program
{
name: "full_reset";
signal: "full_reset";
source: "ephoto";
action: STATE_SET default 0.0;
transition: LINEAR 0.2;
target: "left";
target: "right";
target: "center";
}
program
{
name: "done";
action: SIGNAL_EMIT "done" "ephoto";
}
program
{
name: "reset";
signal: "reset";
source: "ephoto";
action: STATE_SET default 0.0;
target: "offscreen_right";
target: "right";
target: "center";
target: "left";
target: "offscreen_left";
}
}
}
}

@ -1,14 +1,5 @@
MAINTAINERCLEANFILES = Makefile.in
EXTRA_DIST = \
thumb_shadow.png \
bt_sm_base1.png \
bt_sm_shine.png \
bt_sm_hilight.png \
up-128.png \
up-256.png \
up-512.png \
directory-128.png \
directory-256.png \
directory-512.png
thumb_shadow.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

@ -16,9 +16,12 @@ endif
_sources = \
ephoto.c \
ephoto_main.c \
ephoto_flow_browser.c \
ephoto_slideshow.c \
ephoto_thumb_browser.c
ephoto_config.c \
ephoto_preferences.c \
ephoto_thumb_browser.c \
ephoto_single_browser.c \
ephoto_flow_browser.c \
ephoto_slideshow.c
_libs = @ELEMENTARY_LIBS@ @EFREET_MIME_LIBS@ @EIO_LIBS@ @EXIF_LIBS@

@ -1,9 +1,16 @@
#include "ephoto.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <Elementary.h>
#ifndef ELM_LIB_QUICKLAUNCH
#include "ephoto.h"
static void _ephoto_display_usage(void);
/* Global log domain pointer */
int __log_domain = -1;
EAPI int
elm_main(int argc, char **argv)
{
@ -22,58 +29,67 @@ elm_main(int argc, char **argv)
elm_need_ethumb();
elm_init(argc, argv);
elm_theme_extension_add(NULL, PACKAGE_DATA_DIR "/themes/default/ephoto.edj");
elm_theme_extension_add(NULL, PACKAGE_DATA_DIR"/themes/default/ephoto.edj");
if (!efreet_mime_init())
fprintf(stderr, "Could not init efreet_mime!\n");
client = elm_thumb_ethumb_client_get();
if (!client)
{
printf("Ephoto could not get ethumb_client; Terminating...\n");
ERR("could not get ethumb_client");
r = 1;
goto end;
goto end_log_domain;
}
ethumb_client_crop_align_set(client, 0.5, 0.5);
ethumb_client_aspect_set(client, ETHUMB_THUMB_CROP);
ethumb_client_orientation_set(client, ETHUMB_THUMB_ORIENT_ORIGINAL);
__log_domain = eina_log_domain_register("ephoto", EINA_COLOR_ORANGE);
if (!__log_domain)
{
EINA_LOG_ERR("Could not register log domain: Ephoto");
r = 1;
goto end_log_domain;
}
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
DBG("Logging initialized");
if (argc > 2)
{
printf("Too many arguments; Terminating...\n");
printf("Too Many Arguments!\n");
_ephoto_display_usage();
r = 1;
goto end;
}
else if (argc == 2)
else if (argc < 2)
{
if (!strncmp(argv[1], "--help", 6) || !strncmp(argv[1], "-h", 2))
Evas_Object *win = ephoto_window_add(NULL);
if (!win)
{
_ephoto_display_usage();
r = 0;
r = 1;
goto end;
}
else
{
char *real = ecore_file_realpath(argv[1]);
if (!real)
{
printf("Invalid file or directory: '%s'; Terminating...\n", argv[1]);
r = 1;
goto end;
}
if (!ephoto_window_add(real))
{
printf("Could not create the main window; Terminating...\n");
goto end;
r = 1;
}
}
}
else if (!strncmp(argv[1], "--help", 6))
{
_ephoto_display_usage();
r = 0;
goto end;
}
else
{
if (!ephoto_window_add(NULL))
char *real = ecore_file_realpath(argv[1]);
if (!real)
{
printf("invalid file or directory: '%s'\n", argv[1]);
r = 1;
goto end;
}
Evas_Object *win = ephoto_window_add(real);
free(real);
if (!win)
{
printf("Could not create the main window; Terminating...\n");
r = 1;
goto end;
}
@ -82,20 +98,25 @@ elm_main(int argc, char **argv)
elm_run();
end:
eina_log_domain_unregister(__log_domain);
end_log_domain:
efreet_mime_shutdown();
elm_shutdown();
eio_shutdown();
return r;
}
/*Display useage commands for ephoto*/
static void
_ephoto_display_usage(void)
{
printf("Ephoto Usage: \n"
"ephoto --help | -h : This page\n"
"ephoto filename : Specifies a file to open\n"
"ephoto directory : Specifies a directory to open\n");
"ephoto --help : This page\n"
"ephoto filename : Specifies a file to open\n"
"ephoto dirname : Specifies a directory to open\n");
}
#endif
ELM_MAIN()

@ -7,6 +7,7 @@
#include <Eet.h>
#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Ecore_File.h>
#include <Efreet_Mime.h>
#include <Elementary.h>
@ -15,101 +16,189 @@
#include <Evas.h>
#include <Eio.h>
#include <Ethumb_Client.h>
#include <libgen.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
/*Ephoto Typedefs*/
typedef struct _Ephoto Ephoto;
typedef struct _Ephoto_Entry Ephoto_Entry;
typedef struct _Ephoto_Event_Entry_Create Ephoto_Event_Entry_Create;
typedef enum _Ephoto_State Ephoto_State;
#define THEME_FILE PACKAGE_DATA_DIR"/themes/default/ephoto.edj"
typedef struct _Ephoto_Config Ephoto_Config;
typedef struct _Ephoto Ephoto;
typedef struct _Ephoto_Entry Ephoto_Entry;
typedef struct _Ephoto_Event_Entry_Create Ephoto_Event_Entry_Create;
typedef enum _Ephoto_State Ephoto_State;
typedef enum _Ephoto_Orient Ephoto_Orient;
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);
void ephoto_directory_set(Ephoto *ephoto, const char *path);
Ephoto_Orient ephoto_file_orient_get(const char *path);
Eina_Bool ephoto_config_init(Ephoto *em);
void ephoto_config_save(Ephoto *em, Eina_Bool instant);
void ephoto_config_free(Ephoto *em);
Evas_Object *ephoto_single_browser_add(Ephoto *ephoto, Evas_Object *parent);
void ephoto_single_browser_entry_set(Evas_Object *obj, Ephoto_Entry *entry);
void ephoto_single_browser_path_pending_set(Evas_Object *obj, const char *path);
/* smart callbacks called:
* "back" - the user wants to go back to the previous screen.
* "slideshow" - the user wants to view a slideshow.
*/
Evas_Object *ephoto_flow_browser_add(Ephoto *e, Evas_Object *parent);
void ephoto_flow_browser_entry_set(Evas_Object *obj __UNUSED__, Ephoto_Entry *entry);
/* smart callbacks called:
* "back" - the user wants to go back to the previous screen.
* "slideshow" - the user wants to view a slideshow.
*/
Evas_Object *ephoto_slideshow_add(Ephoto *ephoto, Evas_Object *parent);
void ephoto_slideshow_entry_set(Evas_Object *obj, Ephoto_Entry *entry);
/* smart callbacks called:
* "back" - the user want to go back to the previous screen.
*/
Evas_Object *ephoto_thumb_browser_add(Ephoto *ephoto, Evas_Object *parent);
/* smart callbacks called:
* "selected" - an item in the thumb browser is selected. The selected Ephoto_Entry is passed as event_info argument.
*/
/*Ephoto States*/
enum _Ephoto_State
{
EPHOTO_STATE_THUMB,
EPHOTO_STATE_FLOW,
EPHOTO_STATE_SLIDESHOW
EPHOTO_STATE_THUMB,
EPHOTO_STATE_FLOW,
EPHOTO_STATE_SINGLE,
EPHOTO_STATE_SLIDESHOW
};
enum _Ephoto_Orient /* matches with exif orientation tag */
{
EPHOTO_ORIENT_0 = 1,
EPHOTO_ORIENT_FLIP_HORIZ = 2,
EPHOTO_ORIENT_180 = 3,
EPHOTO_ORIENT_FLIP_VERT = 4,
EPHOTO_ORIENT_FLIP_VERT_90 = 5,
EPHOTO_ORIENT_90 = 6,
EPHOTO_ORIENT_FLIP_HORIZ_90 = 7,
EPHOTO_ORIENT_270 = 8
};
/* TODO: split into window & global config, allow multi window
*
* This also requires single instance, as 2 instances changing the
* same configuration will lead to problems.
*
* Single instance is better done as DBus, using FDO standard methods.
*/
struct _Ephoto_Config
{
int config_version;
const char *editor;
double slideshow_timeout;
const char *slideshow_transition;
/* these should be per-window */
int thumb_size;
int thumb_gen_size;
const char *directory;
};
/*Ephoto Main Structure*/
struct _Ephoto
{
/*Main Objects*/
Evas_Object *win;
Evas_Object *bg;
Evas_Object *pager;
/*Main Children*/
Evas_Object *thumb_browser;
Evas_Object *flow_browser;
Evas_Object *single_browser;
Evas_Object *slideshow;
/*Main Variables*/
const char *directory;
Ecore_Job *change_dir;
Ecore_Timer *regen;
Eio_File *ls;
Eina_List *entries;
Eina_List *thumbs; /* live thumbs that need to be regenerated on changes */
int thumb_gen_size; /* pending value for thumb_regen */
struct {
Ecore_Timer *thumb_regen;
} timer;
struct {
Ecore_Job *change_dir;
} job;
Eio_File *ls;
Evas_Object *prefs_win;
Ephoto_State state, prev_state;
Ethumb_Client *client;
Ephoto_Config *config;
};
/*Ephoto Entry*/
struct _Ephoto_Entry
{
/*These variables identify each thumbnail*/
const char *path;
const char *basename;
const char *basename; /* pointer inside path */
const char *label;
Ephoto *ephoto;
Elm_Gengrid_Item *item;
Eina_List *free_listeners;
};
/*Ephoto Entry Event*/
struct _Ephoto_Event_Entry_Create
{
Ephoto_Entry *entry;
};
/*Main Functions*/
Evas_Object *ephoto_window_add(const char *path);
void ephoto_populate(const char *path);
void ephoto_title_set(const char *title);
void ephoto_state_set(Ephoto_State state);
void ephoto_flow_browser_show(Ephoto_Entry *entry);
void ephoto_slideshow_show(Ephoto_Entry *entry);
void ephoto_thumb_browser_show(Ephoto_Entry *entry);
Ephoto_Entry *ephoto_entry_new(const char *path, const char *label);
void ephoto_entry_free(Ephoto_Entry *entry);
void ephoto_entry_free_listener_add(Ephoto_Entry *entry, void (*cb)(void *data, const Ephoto_Entry *entry), const void *data);
void ephoto_entry_free_listener_del(Ephoto_Entry *entry, void (*cb)(void *data, const Ephoto_Entry *entry), const void *data);
void ephoto_entries_free(void);
/*Main Children*/
Evas_Object *ephoto_flow_browser_add(void);
void ephoto_flow_browser_entry_set(Ephoto_Entry *entry);
void ephoto_flow_browser_del(void);
Evas_Object *ephoto_slideshow_add(void);
void ephoto_slideshow_entry_set(Ephoto_Entry *entry);
void ephoto_slideshow_del(void);
Evas_Object *ephoto_thumb_browser_add(void);
void ephoto_thumb_browser_entry_set(Ephoto_Entry *entry);
void ephoto_thumb_browser_thumb_append(Eina_List *node);
void ephoto_thumb_browser_del(void);
/*Ephoto Events*/
Ephoto_Entry *ephoto_entry_new(Ephoto *ephoto, const char *path, const char *label);
void ephoto_entry_free(Ephoto_Entry *entry);
void ephoto_entry_free_listener_add(Ephoto_Entry *entry, void (*cb)(void *data, const Ephoto_Entry *entry), const void *data);
void ephoto_entry_free_listener_del(Ephoto_Entry *entry, void (*cb)(void *data, const Ephoto_Entry *entry), const void *data);
void ephoto_entries_free(Ephoto *ephoto);
extern int __log_domain;
#define DBG(...) EINA_LOG_DOM_DBG(__log_domain, __VA_ARGS__)
#define INF(...) EINA_LOG_DOM_INFO(__log_domain, __VA_ARGS__)
#define ERR(...) EINA_LOG_DOM_ERR(__log_domain, __VA_ARGS__)
static inline Eina_Bool
_ephoto_eina_file_direct_info_image_useful(const Eina_File_Direct_Info *info)
{
const char /* *type, */ *bname, *ext;
bname = info->path + info->name_start;
if (bname[0] == '.') return EINA_FALSE;
if ((info->type != EINA_FILE_REG) && (info->type != EINA_FILE_UNKNOWN))
return EINA_FALSE;
ext = info->path + info->path_length - 1;
for (; ext > bname; ext--) if (*ext == '.') break;
if (*ext == '.')
{
ext++;
if ((strcasecmp(ext, "jpg") == 0) ||
(strcasecmp(ext, "jpeg") == 0) ||
(strcasecmp(ext, "png") == 0))
return EINA_TRUE;
}
return EINA_FALSE;
/* seems that this does not play nice with threads */
//if (!(type = efreet_mime_type_get(info->path))) return EINA_FALSE;
//return strncmp(type, "image/", sizeof("image/") - 1) == 0;
}
extern int EPHOTO_EVENT_ENTRY_CREATE;
extern int EPHOTO_EVENT_POPULATE_START;
extern int EPHOTO_EVENT_POPULATE_END;
extern int EPHOTO_EVENT_POPULATE_ERROR;
extern Ephoto *ephoto;
#endif

@ -0,0 +1,158 @@
#include "ephoto.h"
#define CONFIG_VERSION 5
static int _ephoto_config_load(Ephoto *ephoto);
static Eina_Bool _ephoto_on_config_save(void *data);
static Eet_Data_Descriptor *edd = NULL;
static Ecore_Timer *save_timer = NULL;
Eina_Bool
ephoto_config_init(Ephoto *ephoto)
{
Eet_Data_Descriptor_Class eddc;
if (!eet_eina_stream_data_descriptor_class_set(&eddc, sizeof (eddc), "Ephoto_Config", sizeof(Ephoto_Config)))
{
ERR("Unable to create the config data descriptor!");
return EINA_FALSE;
}
if (!edd) edd = eet_data_descriptor_stream_new(&eddc);
#undef T
#undef D
#define T Ephoto_Config
#define D edd
#define C_VAL(edd, type, member, dtype) EET_DATA_DESCRIPTOR_ADD_BASIC(edd, type, #member, member, dtype)
C_VAL(D, T, config_version, EET_T_INT);
C_VAL(D, T, thumb_size, EET_T_INT);
C_VAL(D, T, thumb_gen_size, EET_T_INT);
C_VAL(D, T, directory, EET_T_STRING);
C_VAL(D, T, slideshow_timeout, EET_T_DOUBLE);
C_VAL(D, T, slideshow_transition, EET_T_STRING);
C_VAL(D, T, editor, EET_T_STRING);
switch (_ephoto_config_load(ephoto))
{
case 0:
/* Start a new config */
ephoto->config->config_version = CONFIG_VERSION;
ephoto->config->thumb_size = 256;
ephoto->config->thumb_gen_size = 256;
ephoto->config->slideshow_timeout = 4.0;
ephoto->config->slideshow_transition = eina_stringshare_add("fade");
ephoto->config->editor = eina_stringshare_add("gimp %s");
break;
case -1:
/* Incremental additions */
if (ephoto->config->config_version < 2)
{
ephoto->config->slideshow_timeout = 4.0;
ephoto->config->slideshow_transition = eina_stringshare_add("fade");
}
if (ephoto->config->config_version < 3)
ephoto->config->editor = eina_stringshare_add("gimp %s");
if (ephoto->config->config_version < 5)
ephoto->config->thumb_gen_size = 256;
ephoto->config->config_version = CONFIG_VERSION;
break;
default:
return EINA_TRUE;
}
ephoto_config_save(ephoto, EINA_FALSE);
return EINA_TRUE;
}
void
ephoto_config_save(Ephoto *ephoto, Eina_Bool instant)
{
if (save_timer)
{
ecore_timer_del(save_timer);
save_timer = NULL;
}
if (instant)
_ephoto_on_config_save(ephoto);
else
save_timer = ecore_timer_add(5.0, _ephoto_on_config_save, ephoto);
}
void
ephoto_config_free(Ephoto *ephoto)
{
free(ephoto->config);
ephoto->config = NULL;
}
static int
_ephoto_config_load(Ephoto *ephoto)
{
Eet_File *ef;
char buf[4096], buf2[4096];
snprintf(buf2, sizeof(buf2), "%s/.config/ephoto", getenv("HOME"));
ecore_file_mkpath(buf2);
snprintf(buf, sizeof(buf), "%s/ephoto.cfg", buf2);
ef = eet_open(buf, EET_FILE_MODE_READ);
if (!ef)
{
ephoto_config_free(ephoto);
ephoto->config = calloc(1, sizeof(Ephoto_Config));
return 0;
}
ephoto->config = eet_data_read(ef, edd, "config");
eet_close(ef);
if (ephoto->config->config_version > CONFIG_VERSION)
{
ephoto_config_free(ephoto);
ephoto->config = calloc(1, sizeof(Ephoto_Config));
return 0;
}
if (ephoto->config->config_version < CONFIG_VERSION)
return -1;
return 1;
}
static Eina_Bool
_ephoto_on_config_save(void *data)
{
Ephoto *ephoto = data;
Eet_File *ef;
char buf[4096], buf2[4096];
snprintf(buf, sizeof(buf), "%s/.config/ephoto/ephoto.cfg", getenv("HOME"));
snprintf(buf2, sizeof(buf2), "%s.tmp", buf);
ef = eet_open(buf2, EET_FILE_MODE_WRITE);
if (!ef) goto save_end;
eet_data_write(ef, edd, "config", ephoto->config, 1);
if (eet_close(ef)) goto save_end;
if (!ecore_file_mv(buf2, buf)) goto save_end;
INF("Config saved");
save_end:
ecore_file_unlink(buf2);
if (save_timer)
{
ecore_timer_de