[elm] And here comes image, icon and photo on the

new schema.
els_icon smart object was brought to be the base of the image widget,
in the form of an image class.

An elm icon is now a elm image, with a little more on top of it.

An elm photo is a now base widget aggregating an icon.

Toolbar's internal usage of the former els_icon is now changed to
icons, instead.

Some naviframe instantiations were set to enable events during
transitions, because this code is buggy and my chages exposed the
problem. It will be fixed as soon as I get to port Naviframe.



SVN revision: 71429
This commit is contained in:
Gustavo Lima Chaves 2012-05-25 19:53:59 +00:00
parent 87b422c93a
commit 4f8b51b1aa
17 changed files with 2624 additions and 2224 deletions

View File

@ -3002,6 +3002,7 @@ _status_config_full(Evas_Object *win,
evas_object_show(tb);
naviframe = elm_naviframe_add(win);
elm_naviframe_event_enabled_set(naviframe, EINA_TRUE);
evas_object_size_hint_align_set(naviframe, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(naviframe, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_data_set(win, "naviframe", naviframe);

View File

@ -235,6 +235,7 @@ test_naviframe(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_i
elm_win_autodel_set(win, EINA_TRUE);
nf = elm_naviframe_add(win);
elm_naviframe_event_enabled_set(nf, EINA_TRUE);
evas_object_size_hint_weight_set(nf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, nf);
evas_object_show(nf);

View File

@ -42,7 +42,9 @@ includesdir = $(includedir)/elementary-@VMAJ@
includesunstable_HEADERS = \
elm_widget.h \
elm_widget_button.h \
elm_widget_container.h \
elm_widget_image.h \
elm_widget_layout.h
includesunstabledir = $(includedir)/elementary-@VMAJ@
@ -217,15 +219,12 @@ elm_win.c \
els_box.c \
els_box.h \
els_cursor.c \
els_icon.c \
els_icon.h \
els_pan.c \
els_pan.h \
els_scroller.c \
els_scroller.h \
els_tooltip.c \
elu_ews_wm.c \
elm_widget_button.h
elu_ews_wm.c
libelementary_la_CFLAGS =
libelementary_la_LIBADD = \

File diff suppressed because it is too large Load Diff

View File

@ -5,64 +5,73 @@
* @image html img/widget/icon/preview-00.png
* @image latex img/widget/icon/preview-00.eps
*
* An object that provides standard icon images (delete, edit, arrows, etc.)
* or a custom file (PNG, JPG, EDJE, etc.) used for an icon.
* An icon object is used to display standard icon images ("delete",
* "edit", "arrows", etc.) or images coming from a custom file (PNG,
* JPG, EDJE, etc.), on icon contexts.
*
* The icon image requested can be in the elementary theme, or in the
* freedesktop.org paths. It's possible to set the order of preference from
* where the image will be used.
* The icon image requested can be in the Elementary theme in use, or
* in the @c freedesktop.org theme paths. It's possible to set the
* order of preference from where an image will be fetched.
*
* This API is very similar to @ref Image, but with ready to use images.
* This widget inherits from the @ref Image one, so that all the
* functions acting on it also work for icon objects.
*
* Default images provided by the theme are described below.
* Besides, its API is very similar to the one of its parent object,
* so that similar calls exist here just wrapping their counterparts
* on @ref Image.
*
* The first list contains icons that were first intended to be used in
* Default images provided by Elementary's default theme are described
* below.
*
* These are names for icons that were first intended to be used in
* toolbars, but can be used in many other places too:
* @li home
* @li close
* @li apps
* @li arrow_up
* @li arrow_down
* @li arrow_left
* @li arrow_right
* @li chat
* @li clock
* @li delete
* @li edit
* @li refresh
* @li folder
* @li file
* @li @c "home"
* @li @c "close"
* @li @c "apps"
* @li @c "arrow_up"
* @li @c "arrow_down"
* @li @c "arrow_left"
* @li @c "arrow_right"
* @li @c "chat"
* @li @c "clock"
* @li @c "delete"
* @li @c "edit"
* @li @c "refresh"
* @li @c "folder"
* @li @c "file"
*
* Now some icons that were designed to be used in menus (but again, you can
* use them anywhere else):
* @li menu/home
* @li menu/close
* @li menu/apps
* @li menu/arrow_up
* @li menu/arrow_down
* @li menu/arrow_left
* @li menu/arrow_right
* @li menu/chat
* @li menu/clock
* @li menu/delete
* @li menu/edit
* @li menu/refresh
* @li menu/folder
* @li menu/file
* These are names for icons that were designed to be used in menus
* (but again, you can use them anywhere else):
* @li @c "menu/home"
* @li @c "menu/close"
* @li @c "menu/apps"
* @li @c "menu/arrow_up"
* @li @c "menu/arrow_down"
* @li @c "menu/arrow_left"
* @li @c "menu/arrow_right"
* @li @c "menu/chat"
* @li @c "menu/clock"
* @li @c "menu/delete"
* @li @c "menu/edit"
* @li @c "menu/refresh"
* @li @c "menu/folder"
* @li @c "menu/file"
*
* And here we have some media player specific icons:
* @li media_player/forward
* @li media_player/info
* @li media_player/next
* @li media_player/pause
* @li media_player/play
* @li media_player/prev
* @li media_player/rewind
* @li media_player/stop
* And these are names for some media player specific icons:
* @li @c "media_player/forward"
* @li @c "media_player/info"
* @li @c "media_player/next"
* @li @c "media_player/pause"
* @li @c "media_player/play"
* @li @c "media_player/prev"
* @li @c "media_player/rewind"
* @li @c "media_player/stop"
*
* Signals that you can add callbacks for are:
*
* "clicked" - This is called when a user has clicked the icon
* This widget emits the following signals, besides the ones sent from
* @ref Image:
* - @c "thumb,done" - elm_icon_thumb_set() has completed with success
* (@since 1.1)
* - @c "thumb,error" - elm_icon_thumb_set() has failed (@since 1.1)
*
* Supported elm_object common APIs.
* @li @ref elm_object_signal_emit

File diff suppressed because it is too large Load Diff

View File

@ -4,22 +4,28 @@
*
* @image html img/widget/image/preview-00.png
* @image latex img/widget/image/preview-00.eps
*
* An object that allows one to load an image file to it. It can be used
* anywhere like any other elementary widget.
* An Elementary image object is a direct realization of
* @ref elm-image-class, and it allows one to load and display an @b image
* file on it, be it from a disk file or from a memory
* region. Exceptionally, one may also load an Edje group as the
* contents of the image. In this case, though, most of the functions
* of the image API will act as a no-op.
*
* This widget provides most of the functionality provided from @ref Bg or @ref
* Icon, but with a slightly different API (use the one that fits better your
* needs).
* One can tune various properties of the image, like:
* - pre-scaling,
* - smooth scaling,
* - orientation,
* - aspect ratio during resizes, etc.
*
* The features not provided by those two other image widgets are:
* @li allowing to get the basic @c Evas_Object with elm_image_object_get();
* @li change the object orientation with elm_image_orient_set();
* @li and turning the image editable with elm_image_editable_set().
* An image object may also be made valid source and destination for
* drag and drop actions, through the elm_image_editable_set() call.
*
* Signals that you can add callbacks for are:
*
* @li @c "drop" - This is called when a user has dropped an image
* typed object onto the object in question -- the
* event info argument is the path to that image file
* @li @c "clicked" - This is called when a user has clicked the image
*
* An example of usage for this API follows:
@ -65,17 +71,50 @@ typedef enum
EAPI Evas_Object *elm_image_add(Evas_Object *parent);
/**
* Set the file that will be used as image.
* Set a location in memory to be used as an image object's source
* bitmap.
*
* @param obj The image object
* @param file The path to file that will be used as image
* @param group The group that the image belongs in edje file (if it's an
* edje image)
* @param img The binary data that will be used as image source
* @param size The size of binary data blob @p img
* @param format (Optional) expected format of @p img bytes
* @param key Optional indexing key of @p img to be passed to the
* image loader (eg. if @p img is a memory-mapped EET file)
*
* This function is handy when the contents of an image file are
* mapped in memory, for example.
*
* The @p format string should be something like @c "png", @c "jpg",
* @c "tga", @c "tiff", @c "bmp" etc, when provided (@c NULL, on the
* contrary). This improves the loader performance as it tries the
* "correct" loader first, before trying a range of other possible
* loaders until one succeeds.
*
* @return (@c EINA_TRUE = success, @c EINA_FALSE = error)
*
* @since 1.1
*
* @ingroup Image
*/
EAPI Eina_Bool elm_image_memfile_set(Evas_Object *obj, const void *img, size_t size, const char *format, const char *key);
/**
* Set the file that will be used as the image's source.
*
* @param obj The image object
* @param file The path to file that will be used as image source
* @param group The group that the image belongs to, in case it's an
* EET (including Edje case) file
*
* @return (@c EINA_TRUE = success, @c EINA_FALSE = error)
*
* @see elm_image_file_get()
*
* @note This function will trigger the Edje file case based on the
* extension of the @a file string (expects @c ".edj", for this
* case). If one wants to force this type of file independently of the
* extension, elm_image_file_edje_set() must be used, instead.
*
* @ingroup Image
*/
EAPI Eina_Bool elm_image_file_set(Evas_Object *obj, const char *file, const char *group);

View File

@ -86,24 +86,6 @@ struct _Elm_Layout_Sub_Object_Cursor
Eina_Bool engine_only : 1;
};
/* FIXME: get rid of Edje_Signal_Data after the last compat widget is
* migrated */
/* this is here in order to hide the layout's inner Edje object
* (unless the user wants to bypass it and call elm_layout_edje_get())
* as much as possible. so, when registering signal callbacks on it,
* we call back passing the actual widget as object, not the Edje
* object, for example */
typedef struct _Layout_Signal_Data Layout_Signal_Data;
struct _Layout_Signal_Data
{
Evas_Object *obj;
Edje_Signal_Cb func;
const char *emission;
const char *source;
void *data;
};
/* layout's sizing evaluation is deferred. evaluation requests are
* queued up and only flag the object as 'changed'. when it comes to
* Evas's rendering phase, it will be addressed, finally (see
@ -515,9 +497,9 @@ _edje_signal_callback(void *data,
const char *emission,
const char *source)
{
Layout_Signal_Data *lsd = data;
Edje_Signal_Data *esd = data;
lsd->func(lsd->data, lsd->obj, emission, source);
esd->func(esd->data, esd->obj, emission, source);
}
static void
@ -527,23 +509,23 @@ _elm_layout_smart_callback_add(Evas_Object *obj,
Edje_Signal_Cb func_cb,
void *data)
{
Layout_Signal_Data *lsd;
Edje_Signal_Data *esd;
ELM_LAYOUT_DATA_GET(obj, sd);
lsd = ELM_NEW(Layout_Signal_Data);
if (!lsd) return;
esd = ELM_NEW(Edje_Signal_Data);
if (!esd) return;
lsd->obj = obj;
lsd->func = func_cb;
lsd->emission = eina_stringshare_add(emission);
lsd->source = eina_stringshare_add(source);
lsd->data = data;
sd->edje_signals = eina_list_append(sd->edje_signals, lsd);
esd->obj = obj;
esd->func = func_cb;
esd->emission = eina_stringshare_add(emission);
esd->source = eina_stringshare_add(source);
esd->data = data;
sd->edje_signals = eina_list_append(sd->edje_signals, esd);
edje_object_signal_callback_add
(ELM_WIDGET_DATA(sd)->resize_obj, emission, source,
_edje_signal_callback, lsd);
_edje_signal_callback, esd);
}
static void *
@ -552,26 +534,26 @@ _elm_layout_smart_callback_del(Evas_Object *obj,
const char *source,
Edje_Signal_Cb func_cb)
{
Layout_Signal_Data *lsd = NULL;
Edje_Signal_Data *esd = NULL;
void *data = NULL;
Eina_List *l;
ELM_LAYOUT_DATA_GET(obj, sd);
EINA_LIST_FOREACH (sd->edje_signals, l, lsd)
EINA_LIST_FOREACH (sd->edje_signals, l, esd)
{
if ((lsd->func == func_cb) && (!strcmp(lsd->emission, emission)) &&
(!strcmp(lsd->source, source)))
if ((esd->func == func_cb) && (!strcmp(esd->emission, emission)) &&
(!strcmp(esd->source, source)))
{
sd->edje_signals = eina_list_remove_list(sd->edje_signals, l);
eina_stringshare_del(lsd->emission);
eina_stringshare_del(lsd->source);
data = lsd->data;
free(lsd);
eina_stringshare_del(esd->emission);
eina_stringshare_del(esd->source);
data = esd->data;
free(esd);
edje_object_signal_callback_del_full
(ELM_WIDGET_DATA(sd)->resize_obj, emission, source,
_edje_signal_callback, lsd);
_edje_signal_callback, esd);
return data; /* stop at 1st match */
}
@ -1216,7 +1198,7 @@ _elm_layout_smart_del(Evas_Object *obj)
{
Elm_Layout_Sub_Object_Data *sub_d;
Elm_Layout_Sub_Object_Cursor *pc;
Layout_Signal_Data *lsd;
Edje_Signal_Data *esd;
Evas_Object *child;
Eina_List *l;
@ -1235,11 +1217,11 @@ _elm_layout_smart_del(Evas_Object *obj)
EINA_LIST_FREE (sd->parts_cursors, pc)
_part_cursor_free(pc);
EINA_LIST_FREE (sd->edje_signals, lsd)
EINA_LIST_FREE (sd->edje_signals, esd)
{
eina_stringshare_del(lsd->emission);
eina_stringshare_del(lsd->source);
free(lsd);
eina_stringshare_del(esd->emission);
eina_stringshare_del(esd->source);
free(esd);
}
eina_stringshare_del(sd->klass);
@ -1456,7 +1438,8 @@ elm_layout_text_set(Evas_Object *obj,
ELM_LAYOUT_CHECK(obj) EINA_FALSE;
ELM_LAYOUT_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->text_set(obj, part, text);
return ELM_LAYOUT_CLASS(ELM_WIDGET_DATA(sd)->api)->text_set
(obj, part, text);
}
EAPI const char *

View File

@ -1,216 +1,171 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "els_icon.h"
#include "els_scroller.h"
typedef struct _Widget_Data Widget_Data;
static const char PHOTO_SMART_NAME[] = "elm_photo";
struct _Widget_Data
typedef struct _Elm_Photo_Smart_Data Elm_Photo_Smart_Data;
struct _Elm_Photo_Smart_Data
{
Evas_Object *frm;
Evas_Object *img;
int size;
Eina_Bool fill;
Ecore_Timer *longtimer;
Elm_Widget_Smart_Data base;
Evas_Object *icon;
int size;
Eina_Bool fill_inside;
Ecore_Timer *long_press_timer;
#ifdef HAVE_ELEMENTARY_ETHUMB
struct
{
int id;
struct
{
const char *path;
const char *key;
} file, thumb;
Ethumb_Exists *exists;
Ecore_Event_Handler *eeh;
Ethumb_Thumb_Format format;
Eina_Bool retry : 1;
{
struct
{
const char *path;
const char *key;
} file, thumb;
} thumb;
#endif
};
#ifdef HAVE_ELEMENTARY_ETHUMB
static Eina_List *_elm_icon_retry = NULL;
static int _icon_pending_request = 0;
#define ELM_PHOTO_DATA_GET(o, sd) \
Elm_Photo_Smart_Data * sd = evas_object_smart_data_get(o)
static void _icon_thumb_exists(void *data, Ethumb_Client *client __UNUSED__, Ethumb_Exists *thread, Eina_Bool exists);
static void _icon_thumb_stop(Widget_Data *wd, void *ethumbd);
#endif
#define ELM_PHOTO_DATA_GET_OR_RETURN(o, ptr) \
ELM_PHOTO_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return; \
}
static const char *widtype = NULL;
static void _del_hook(Evas_Object *obj);
static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
static void _theme_hook(Evas_Object *obj);
static void _sizing_eval(Evas_Object *obj);
static void _mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
#define ELM_PHOTO_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
ELM_PHOTO_DATA_GET(o, ptr); \
if (!ptr) \
{ \
CRITICAL("No widget data for object %p (%s)", \
o, evas_object_type_get(o)); \
return val; \
}
#define ELM_PHOTO_CHECK(obj) \
if (!obj || !elm_widget_type_check((obj), PHOTO_SMART_NAME, __func__)) \
return
static const char SIG_CLICKED[] = "clicked";
static const char SIG_DRAG_START[] = "drag,start";
static const char SIG_DRAG_END[] = "drag,end";
static const Evas_Smart_Cb_Description _signals[] = {
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{SIG_CLICKED, ""},
{SIG_DRAG_START, ""},
{SIG_DRAG_END, ""},
{NULL, NULL}
};
static void
_del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
#ifdef HAVE_ELEMENTARY_ETHUMB
Ethumb_Client *ethumbd;
#endif
if (!wd) return;
#ifdef HAVE_ELEMENTARY_ETHUMB
ethumbd = elm_thumb_ethumb_client_get();
_icon_thumb_stop(wd, ethumbd);
eina_stringshare_del(wd->thumb.file.path);
eina_stringshare_del(wd->thumb.file.key);
eina_stringshare_del(wd->thumb.thumb.path);
eina_stringshare_del(wd->thumb.thumb.key);
if (wd->thumb.eeh)
ecore_event_handler_del(wd->thumb.eeh);
#endif
free(wd);
}
static void
_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_mirrored_set(wd->frm, rtl);
}
static void
_theme_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_widget_mirrored_reload(obj);
_mirrored_set(wd->frm, elm_widget_mirrored_get(obj));
_elm_theme_object_set(obj, wd->frm, "photo", "base",
elm_widget_style_get(obj));
edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->img);
edje_object_scale_set(wd->frm, elm_widget_scale_get(obj) *
_elm_config->scale);
_sizing_eval(obj);
}
EVAS_SMART_SUBCLASS_NEW
(PHOTO_SMART_NAME, _elm_photo, Elm_Widget_Smart_Class,
Elm_Widget_Smart_Class, elm_widget_smart_class_get, _smart_callbacks);
static void
_sizing_eval(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
double scale;
if (!wd) return;
if (wd->size > 0)
{
double scale = 0.0;
ELM_PHOTO_DATA_GET(obj, sd);
scale = (wd->size * elm_widget_scale_get(obj) * _elm_config->scale);
evas_object_size_hint_min_set(wd->img, scale, scale);
edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->img);
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
edje_object_size_min_restricted_calc(wd->frm, &minw, &minh, minw, minh);
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
maxw = minw;
maxh = minh;
evas_object_size_hint_min_set(obj, minw, minh);
evas_object_size_hint_max_set(obj, maxw, maxh);
}
if (sd->size <= 0) return;
scale = (sd->size * elm_widget_scale_get(obj) * elm_config_scale_get());
evas_object_size_hint_min_set(sd->icon, scale, scale);
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
edje_object_size_min_restricted_calc
(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, minw, minh);
elm_coords_finger_size_adjust(1, &minw, 1, &minh);
maxw = minw;
maxh = minh;
evas_object_size_hint_min_set(obj, minw, minh);
evas_object_size_hint_max_set(obj, maxw, maxh);
}
static Eina_Bool
_elm_photo_smart_theme(Evas_Object *obj)
{
ELM_PHOTO_DATA_GET(obj, sd);
if (!ELM_WIDGET_CLASS(_elm_photo_parent_sc)->theme(obj))
return EINA_FALSE;
edje_object_mirrored_set
(ELM_WIDGET_DATA(sd)->resize_obj, elm_widget_mirrored_get(obj));
elm_widget_theme_object_set
(obj, ELM_WIDGET_DATA(sd)->resize_obj, "photo", "base",
elm_widget_style_get(obj));
elm_object_scale_set(sd->icon, elm_widget_scale_get(obj));
edje_object_scale_set(ELM_WIDGET_DATA(sd)->resize_obj,
elm_widget_scale_get(obj) * elm_config_scale_get());
_sizing_eval(obj);
return EINA_TRUE;
}
static void
_icon_move_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
_icon_move_resize_cb(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
Evas_Coord w, h;
Widget_Data *wd = elm_widget_data_get(data);
if (!wd) return;
if (wd->fill)
ELM_PHOTO_DATA_GET(data, sd);
if (sd->fill_inside)
{
Edje_Message_Int_Set *msg;
Evas_Object *icon = _els_smart_icon_object_get(wd->img);
Evas_Object *img = elm_icon_object_get(sd->icon);
evas_object_geometry_get(icon, NULL, NULL, &w, &h);
evas_object_geometry_get(img, NULL, NULL, &w, &h);
msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
msg->count=2;
msg->count = 2;
msg->val[0] = (int)w;
msg->val[1] = (int)h;
edje_object_message_send(wd->frm, EDJE_MESSAGE_INT_SET, 0, msg);
edje_object_message_send
(ELM_WIDGET_DATA(sd)->resize_obj, EDJE_MESSAGE_INT_SET, 0, msg);
}
#ifdef HAVE_ELEMENTARY_ETHUMB
if (wd->thumb.file.path)
elm_photo_thumb_set(data, wd->thumb.file.path, wd->thumb.file.key);
if (sd->thumb.file.path)
elm_icon_thumb_set(sd->icon, sd->thumb.file.path, sd->thumb.file.key);
#endif
}
static void
_drag_done_cb(void *unused __UNUSED__, Evas_Object *obj)
_drag_done_cb(void *unused __UNUSED__,
Evas_Object *obj)
{
elm_object_scroll_freeze_pop(obj);
evas_object_smart_callback_call(obj, SIG_DRAG_END, NULL);
}
static Eina_Bool
_longpress(void *objv)
{
Widget_Data *wd = elm_widget_data_get(objv);
Evas_Object *tmp;
const char *file;
DBG("Long press: start drag!");
wd->longtimer = NULL; /* clear: must return NULL now */
evas_object_event_callback_del(objv, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move);
tmp = _els_smart_icon_object_get(wd->img);
file = NULL;
evas_object_image_file_get(tmp,&file,NULL);
if (file)
{
char buf[4096 + 7];
/* FIXME: Deal with relative paths; use PATH_MAX */
snprintf(buf, sizeof(buf), "file://%s", file);
if (elm_drag_start(objv, ELM_SEL_FORMAT_IMAGE,
buf, _drag_done_cb, NULL))
{
elm_object_scroll_freeze_push(objv);
evas_object_smart_callback_call(objv, SIG_DRAG_START, NULL);
}
}
return 0; /* Don't call again */
}
static void
_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event)
_mouse_move(void *data,
Evas *e __UNUSED__,
Evas_Object *icon,
void *event)
{
Widget_Data *wd = elm_widget_data_get(data);
Evas_Event_Mouse_Move *move = event;
ELM_PHOTO_DATA_GET(data, sd);
/* Sanity */
if (!wd->longtimer)
if (!sd->long_press_timer)
{
evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move);
evas_object_event_callback_del
(icon, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move);
return;
}
@ -218,35 +173,74 @@ _mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event)
if (move->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
{
/* Moved too far: No longpress for you! */
ecore_timer_del(wd->longtimer);
wd->longtimer = NULL;
evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_MOVE,
_mouse_move);
ecore_timer_del(sd->long_press_timer);
sd->long_press_timer = NULL;
evas_object_event_callback_del
(icon, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move);
}
}
static void
_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
static Eina_Bool
_long_press_cb(void *obj)
{
Widget_Data *wd = elm_widget_data_get(data);
Evas_Object *img;
const char *file;
if (wd->longtimer) ecore_timer_del(wd->longtimer);
ELM_PHOTO_DATA_GET(obj, sd);
/* FIXME: Hard coded timeout */
wd->longtimer = ecore_timer_add(0.7, _longpress, data);
evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE,
_mouse_move, data);
DBG("Long press: start drag!");
sd->long_press_timer = NULL; /* clear: must return NULL now */
evas_object_event_callback_del
(sd->icon, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move);
img = elm_icon_object_get(sd->icon);
file = NULL;
evas_object_image_file_get(img, &file, NULL);
if (file)
{
char buf[4096 + 7];
/* FIXME: Deal with relative paths; use PATH_MAX */
snprintf(buf, sizeof(buf), "file://%s", file);
if (elm_drag_start
(obj, ELM_SEL_FORMAT_IMAGE, buf, _drag_done_cb, NULL))
{
elm_object_scroll_freeze_push(obj);
evas_object_smart_callback_call(obj, SIG_DRAG_START, NULL);
}
}
return EINA_FALSE; /* Don't call again */
}
static void
_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
_mouse_down(void *data,
Evas *e __UNUSED__,
Evas_Object *icon,
void *event_info __UNUSED__)
{
Widget_Data *wd = elm_widget_data_get(data);
ELM_PHOTO_DATA_GET(data, sd);
if ((wd) && (wd->longtimer))
if (sd->long_press_timer) ecore_timer_del(sd->long_press_timer);
/* FIXME: Hard coded timeout */
sd->long_press_timer = ecore_timer_add(0.7, _long_press_cb, data);
evas_object_event_callback_add
(icon, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, data);
}
static void
_mouse_up(void *data,
Evas *e __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
ELM_PHOTO_DATA_GET(data, sd);
if (sd->long_press_timer)
{
ecore_timer_del(wd->longtimer);
wd->longtimer = NULL;
ecore_timer_del(sd->long_press_timer);
sd->long_press_timer = NULL;
}
evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
@ -256,378 +250,207 @@ static inline int
_icon_size_min_get(Evas_Object *icon)
{
int size;
_els_smart_icon_size_get(icon, &size, NULL);
elm_icon_size_get(icon, &size, NULL);
return (size < 32) ? 32 : size;
}
#ifdef HAVE_ELEMENTARY_ETHUMB
static void
_icon_thumb_stop(Widget_Data *wd, void *ethumbd)
_elm_photo_internal_image_follow(Evas_Object *obj)
{
if (wd->thumb.id >= 0)
{
ethumb_client_generate_cancel(ethumbd, wd->thumb.id, NULL, NULL, NULL);
wd->thumb.id = -1;
_icon_pending_request--;
}
Evas_Object *img;
if (wd->thumb.exists)
{
ethumb_client_thumb_exists_cancel(wd->thumb.exists);
wd->thumb.exists = NULL;
_icon_pending_request--;
}
ELM_PHOTO_DATA_GET(obj, sd);
if (wd->thumb.retry)
{
_elm_icon_retry = eina_list_remove(_elm_icon_retry, wd);
wd->thumb.retry = EINA_FALSE;
}
}
img = elm_icon_object_get(sd->icon);
static Eina_Bool
_icon_thumb_display(Widget_Data *wd)
{
Eina_Bool ret = EINA_FALSE;
if (wd->thumb.format == ETHUMB_THUMB_EET)
{
static const char *extensions[] = {
".avi", ".mp4", ".ogv", ".mov", ".mpg", ".wmv", NULL
};
const char **ext, *ptr;
int prefix_size;
Eina_Bool video = EINA_FALSE;
prefix_size = eina_stringshare_strlen(wd->thumb.file.path) - 4;
if (prefix_size >= 0)
{
ptr = wd->thumb.file.path + prefix_size;
for (ext = extensions; *ext; ++ext)
if (!strcasecmp(ptr, *ext))
{
video = EINA_TRUE;
break;
}
}
if (video)
ret = _els_smart_icon_file_edje_set(wd->img, wd->thumb.thumb.path, wd->thumb.thumb.key);
}
if (!ret)
ret = _els_smart_icon_file_key_set(wd->img, wd->thumb.thumb.path, wd->thumb.thumb.key);
return ret;
}
static Eina_Bool
_icon_thumb_retry(Widget_Data *wd)
{
return _icon_thumb_display(wd);
evas_object_event_callback_add
(img, EVAS_CALLBACK_MOVE, _icon_move_resize_cb, obj);
evas_object_event_callback_add
(img, EVAS_CALLBACK_RESIZE, _icon_move_resize_cb, obj);
}
static void
_icon_thumb_cleanup(Ethumb_Client *ethumbd)
_on_thumb_done(void *data,
Evas_Object *obj __UNUSED__,
void *event __UNUSED__)
{
Eina_List *l, *ll;
Widget_Data *wd;
EINA_LIST_FOREACH_SAFE(_elm_icon_retry, l, ll, wd)
if (_icon_thumb_retry(wd))
{
_elm_icon_retry = eina_list_remove_list(_elm_icon_retry, l);
wd->thumb.retry = EINA_FALSE;
}
if (_icon_pending_request == 0)
EINA_LIST_FREE(_elm_icon_retry, wd)
_icon_thumb_stop(wd, ethumbd);
_elm_photo_internal_image_follow(data);
}
static void
_icon_thumb_finish(Widget_Data *wd, Ethumb_Client *ethumbd)
_elm_photo_smart_add(Evas_Object *obj)
{
const char *file = NULL, *group = NULL;
Eina_Bool ret;
EVAS_SMART_DATA_ALLOC(obj, Elm_Photo_Smart_Data);
_els_smart_icon_file_get(wd->img, &file, &group);
file = eina_stringshare_ref(file);
group = eina_stringshare_ref(group);
ELM_WIDGET_CLASS(_elm_photo_parent_sc)->base.add(obj);
ret = _icon_thumb_display(wd);
elm_widget_can_focus_set(obj, EINA_FALSE);
if (!ret && file)
{
const char *p;
priv->icon = elm_icon_add(obj);
evas_object_repeat_events_set(priv->icon, EINA_TRUE);
if (!wd->thumb.retry)
{
_elm_icon_retry = eina_list_append(_elm_icon_retry, wd);
wd->thumb.retry = EINA_TRUE;
}
elm_icon_resizable_set(priv->icon, EINA_TRUE, EINA_TRUE);
elm_icon_smooth_set(priv->icon, EINA_TRUE);
elm_icon_fill_outside_set(priv->icon, !priv->fill_inside);
elm_icon_prescale_set(priv->icon, 0);
/* Back to previous image */
if (((p = strrchr(file, '.'))) && (!strcasecmp(p, ".edj")))
_els_smart_icon_file_edje_set(wd->img, file, group);
else
_els_smart_icon_file_key_set(wd->img, file, group);
}
elm_object_scale_set(priv->icon, elm_widget_scale_get(obj));
_icon_thumb_cleanup(ethumbd);
evas_object_event_callback_add
(priv->icon, EVAS_CALLBACK_MOUSE_UP, _mouse_up, obj);
evas_object_event_callback_add
(priv->icon, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, obj);
eina_stringshare_del(file);
eina_stringshare_del(group);
evas_object_smart_callback_add
(priv->icon, "thumb,done", _on_thumb_done, obj);
elm_widget_sub_object_add(obj, priv->icon);
priv->long_press_timer = NULL;
_elm_photo_internal_image_follow(obj);
_sizing_eval(obj);
}
static void
_icon_thumb_cb(void *data,
Ethumb_Client *ethumbd,
int id,
const char *file __UNUSED__,
const char *key __UNUSED__,
const char *thumb_path,
const char *thumb_key,
Eina_Bool success)
_elm_photo_smart_del(Evas_Object *obj)
{
Widget_Data *wd = data;
ELM_PHOTO_DATA_GET(obj, sd);
EINA_SAFETY_ON_FALSE_RETURN(wd->thumb.id == id);
wd->thumb.id = -1;
if (sd->long_press_timer) ecore_timer_del(sd->long_press_timer);
sd->long_press_timer = NULL;
_icon_pending_request--;
if (success)
{
eina_stringshare_replace(&wd->thumb.thumb.path, thumb_path);
eina_stringshare_replace(&wd->thumb.thumb.key, thumb_key);
wd->thumb.format = ethumb_client_format_get(ethumbd);
_icon_thumb_finish(wd, ethumbd);
}
else
{
ERR("could not generate thumbnail for %s (key: %s)", file, key);
_icon_thumb_cleanup(ethumbd);
}
ELM_WIDGET_CLASS(_elm_photo_parent_sc)->base.del(obj);
}
static void
_icon_thumb_exists(void *data, Ethumb_Client *client __UNUSED__, Ethumb_Exists *thread, Eina_Bool exists)
_elm_photo_smart_set_user(Elm_Widget_Smart_Class *sc)
{
Widget_Data *wd = data;
Ethumb_Client *ethumbd;
ELM_WIDGET_CLASS(sc)->base.add = _elm_photo_smart_add;
ELM_WIDGET_CLASS(sc)->base.del = _elm_photo_smart_del;
if (ethumb_client_thumb_exists_check(thread))
return ;
wd->thumb.exists = NULL;
ethumbd = elm_thumb_ethumb_client_get();
if (exists)
{
const char *thumb_path, *thumb_key;
_icon_pending_request--;
ethumb_client_thumb_path_get(ethumbd, &thumb_path, &thumb_key);
eina_stringshare_replace(&wd->thumb.thumb.path, thumb_path);
eina_stringshare_replace(&wd->thumb.thumb.key, thumb_key);
wd->thumb.format = ethumb_client_format_get(ethumbd);
_icon_thumb_finish(wd, ethumbd);
}
else if ((wd->thumb.id = ethumb_client_generate(ethumbd, _icon_thumb_cb, wd, NULL)) == -1)
{
ERR("Generate was unable to start !");
/* Failed to generate thumbnail */
_icon_pending_request--;
}
ELM_WIDGET_CLASS(sc)->theme = _elm_photo_smart_theme;
}
static void
_icon_thumb_apply(Widget_Data *wd)
{
Ethumb_Client *ethumbd;
ethumbd = elm_thumb_ethumb_client_get();
_icon_thumb_stop(wd, ethumbd);
if (!wd->thumb.file.path) return ;
_icon_pending_request++;
if (!ethumb_client_file_set(ethumbd, wd->thumb.file.path, wd->thumb.file.key)) return ;
ethumb_client_size_set(ethumbd, _icon_size_min_get(wd->img), _icon_size_min_get(wd->img));
wd->thumb.exists = ethumb_client_thumb_exists(ethumbd, _icon_thumb_exists, wd);
}
static Eina_Bool
_icon_thumb_apply_cb(void *data, int type __UNUSED__, void *ev __UNUSED__)
{
Widget_Data *wd = data;
_icon_thumb_apply(wd);
return ECORE_CALLBACK_RENEW;
}
#endif
EAPI Evas_Object *
elm_photo_add(Evas_Object *parent)
{
Evas_Object *obj;
Evas *e;
Widget_Data *wd;
Evas_Object *icon;
Evas_Object *obj;
ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
ELM_SET_WIDTYPE(widtype, "photo");
elm_widget_type_set(obj, "photo");
elm_widget_sub_object_add(parent, obj);
elm_widget_data_set(obj, wd);
elm_widget_del_hook_set(obj, _del_hook);
elm_widget_theme_hook_set(obj, _theme_hook);
elm_widget_can_focus_set(obj, EINA_FALSE);
e = evas_object_evas_get(parent);
if (!e) return NULL;
wd->frm = edje_object_add(e);
_elm_theme_object_set(obj, wd->frm, "photo", "base", "default");
elm_widget_resize_object_set(obj, wd->frm);
obj = evas_object_smart_add(e, _elm_photo_smart_class_new());
wd->img = _els_smart_icon_add(e);
_els_smart_icon_scale_up_set(wd->img, 1);
_els_smart_icon_scale_down_set(wd->img, 1);
_els_smart_icon_smooth_scale_set(wd->img, 1);
_els_smart_icon_fill_inside_set(wd->img, 0);
_els_smart_icon_scale_size_set(wd->img, 0);
wd->fill = EINA_FALSE;
_els_smart_icon_scale_set(wd->img,
elm_widget_scale_get(obj) * _elm_config->scale);
evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_UP,
_mouse_up, obj);
evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_DOWN,
_mouse_down, obj);
evas_object_repeat_events_set(wd->img, 1);
edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->img);
evas_object_show(wd->img);
elm_widget_sub_object_add(obj, wd->img);
if (!elm_widget_sub_object_add(parent, obj))
ERR("could not add %p as sub object of %p", obj, parent);
wd->longtimer = NULL;
ELM_PHOTO_DATA_GET(obj, sd);
icon = _els_smart_icon_object_get(wd->img);
evas_object_event_callback_add(icon, EVAS_CALLBACK_MOVE,
_icon_move_resize, obj);
evas_object_event_callback_add(icon, EVAS_CALLBACK_RESIZE,
_icon_move_resize, obj);
elm_widget_resize_object_set(obj, edje_object_add(e));
evas_object_smart_callbacks_descriptions_set(obj, _signals);
elm_widget_theme_object_set
(obj, ELM_WIDGET_DATA(sd)->resize_obj, "photo", "base", "default");
#ifdef HAVE_ELEMENTARY_ETHUMB
wd->thumb.id = -1;
#endif
edje_object_part_swallow
(ELM_WIDGET_DATA(sd)->resize_obj, "elm.swallow.content", sd->icon);
_mirrored_set(obj, elm_widget_mirrored_get(obj));
_sizing_eval(obj);
return obj;
}
EAPI Eina_Bool
elm_photo_file_set(Evas_Object *obj, const char *file)
elm_photo_file_set(Evas_Object *obj,
const char *file)
{
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
ELM_PHOTO_CHECK(obj) EINA_FALSE;
ELM_PHOTO_DATA_GET(obj, sd);
if (!wd) return EINA_FALSE;
if (!_els_smart_icon_file_key_set(wd->img, file, NULL))
if (!elm_icon_file_set(sd->icon, file, NULL))
return EINA_FALSE;
_sizing_eval(obj);
return EINA_TRUE;
}
EAPI void
elm_photo_size_set(Evas_Object *obj, int size)
elm_photo_size_set(Evas_Object *obj,
int size)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
ELM_PHOTO_CHECK(obj);
ELM_PHOTO_DATA_GET(obj, sd);
if (!wd) return;
wd->size = (size > 0) ? size : 0;
sd->size = (size > 0) ? size : 0;
_els_smart_icon_scale_size_set(wd->img, wd->size);
elm_image_prescale_set(sd->icon, sd->size);
_sizing_eval(obj);
}
EAPI void
elm_photo_fill_inside_set(Evas_Object *obj, Eina_Bool fill)
elm_photo_fill_inside_set(Evas_Object *obj,
Eina_Bool fill)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
ELM_PHOTO_CHECK(obj);
ELM_PHOTO_DATA_GET(obj, sd);
elm_icon_fill_outside_set(sd->icon, !fill);
sd->fill_inside = !!fill;
if (!wd) return;
_els_smart_icon_fill_inside_set(wd->img, fill);
wd->fill = fill;
_sizing_eval(obj);
}
EAPI void
elm_photo_editable_set(Evas_Object *obj, Eina_Bool set)
elm_photo_editable_set(Evas_Object *obj,
Eina_Bool set)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
ELM_PHOTO_CHECK(obj);
ELM_PHOTO_DATA_GET(obj, sd);
if (!wd) return;;
_els_smart_icon_edit_set(wd->img, set, obj);
elm_image_editable_set(sd->icon, set);
}
EAPI void
elm_photo_thumb_set(const Evas_Object *obj, const char *file, const char *group)
elm_photo_thumb_set(const Evas_Object *obj,
const char *file,
const char *group)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
ELM_PHOTO_CHECK(obj);
ELM_PHOTO_DATA_GET(obj, sd);
#ifdef HAVE_ELEMENTARY_ETHUMB
eina_stringshare_replace(&wd->thumb.file.path, file);
eina_stringshare_replace(&wd->thumb.file.key, group);
eina_stringshare_replace(&sd->thumb.file.path, file);
eina_stringshare_replace(&sd->thumb.file.key, group);
if (elm_thumb_ethumb_client_connected_get())
{
_icon_thumb_apply(wd);
return ;
}
if (!wd->thumb.eeh)
{
wd->thumb.eeh = ecore_event_handler_add(ELM_ECORE_EVENT_ETHUMB_CONNECT, _icon_thumb_apply_cb, wd);
}
elm_icon_thumb_set(sd->icon, file, group);
#else
(void) obj;
(void) file;
(void) group;
(void)obj;
(void)file;
(void)group;
#endif
}
EAPI void
elm_photo_aspect_fixed_set(Evas_Object *obj, Eina_Bool fixed)
elm_photo_aspect_fixed_set(Evas_Object *obj,
Eina_Bool fixed)
{
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
return _els_smart_icon_aspect_fixed_set(wd->img, fixed);
ELM_PHOTO_CHECK(obj);
ELM_PHOTO_DATA_GET(obj, sd);
return elm_icon_aspect_fixed_set(sd->icon, fixed);
}
EAPI Eina_Bool
elm_photo_aspect_fixed_get(const Evas_Object *obj)
{
ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return EINA_FALSE;
return _els_smart_icon_aspect_fixed_get(wd->img);
ELM_PHOTO_CHECK(obj) EINA_FALSE;
ELM_PHOTO_DATA_GET(obj, sd);
return elm_icon_aspect_fixed_get(sd->icon);
}
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/

View File

@ -2,14 +2,20 @@
* @defgroup Photo Photo
* @ingroup Elementary
*
* For displaying a photo, for ex., a person (contact). Simple, yet
* with a very specific purpose.
* An Elementary photo widget is intended for displaying a photo, for
* ex., a person's image (contact). Simple, yet with a very specific
* purpose. It has a decorative frame around the inner image itself,
* on the default theme.
*
* This widget relies on an internal @ref Icon, so that the APIs of
* these two widgets are similar (drag and drop is also possible here,
* for example).
*
* Signals that you can add callbacks for are:
*
* "clicked" - This is called when a user has clicked the photo
* "drag,start" - dragging the image out of the photo object
* "drag,end" - Drop the dragged item
* - @c "clicked" - This is called when a user has clicked the photo
* - @c "drag,start" - One has started dragging the inner image out of the
* photo's frame
* - @c "drag,end" - One has dropped the dragged image somewhere
*
* @{
*/

View File

@ -45,10 +45,20 @@
#endif
#define N_(string) (string)
typedef struct _Edje_Signal_Data Edje_Signal_Data;
typedef struct _Elm_Config Elm_Config;
typedef struct _Elm_Module Elm_Module;
typedef struct _Elm_Datetime_Module_Data Elm_Datetime_Module_Data;
struct _Edje_Signal_Data
{
Evas_Object *obj;
Edje_Signal_Cb func;
const char *emission;
const char *source;
void *data;
};
struct _Elm_Theme
{
Eina_List *overlay;
@ -214,7 +224,7 @@ void _elm_win_rescale(Elm_Theme *th, Eina_Bool use_theme);
void _elm_win_translate(void);
Eina_Bool _elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style);
Eina_Bool _elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *group, const char *style);
Eina_Bool _elm_theme_object_icon_set(Evas_Object *o, const char *group, const char *style);
Eina_Bool _elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *group, const char *style);
Eina_Bool _elm_theme_icon_set(Elm_Theme *th, Evas_Object *o, const char *group, const char *style);
Eina_Bool _elm_theme_parse(Elm_Theme *th, const char *theme);

View File

@ -1,6 +1,5 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "els_icon.h"
static Elm_Theme theme_default =
{
@ -242,11 +241,14 @@ _elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, con
return _elm_theme_set(th, o, clas, group, style);
}
/* only issued by elm_icon.c */
Eina_Bool
_elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *group, const char *style)
_elm_theme_object_icon_set(Evas_Object *o,
const char *group,
const char *style)
{
Elm_Theme *th = NULL;
if (parent) th = elm_widget_theme_get(parent);
Elm_Theme *th = elm_widget_theme_get(o);
return _elm_theme_icon_set(th, o, group, style);
}
@ -280,7 +282,10 @@ _elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *grou
}
Eina_Bool
_elm_theme_icon_set(Elm_Theme *th, Evas_Object *o, const char *group, const char *style)
_elm_theme_icon_set(Elm_Theme *th,
Evas_Object *o,
const char *group,
const char *style)
{
const char *file;
char buf2[1024];
@ -291,16 +296,19 @@ _elm_theme_icon_set(Elm_Theme *th, Evas_Object *o, const char *group, const char
file = _elm_theme_group_file_find(th, buf2);
if (file)
{
_els_smart_icon_file_edje_set(o, file, buf2);
_els_smart_icon_size_get(o, &w, &h);
elm_icon_file_set(o, file, buf2);
elm_icon_size_get(o, &w, &h);
if (w > 0) return EINA_TRUE;
}
snprintf(buf2, sizeof(buf2), "elm/icon/%s/default", group);
file = _elm_theme_group_file_find(th, buf2);
if (!file) return EINA_FALSE;
_els_smart_icon_file_edje_set(o, file, buf2);
_els_smart_icon_size_get(o, &w, &h);
return (w > 0);
elm_icon_file_set(o, file, buf2);
elm_icon_size_get(o, &w, &h);
return w > 0;
}
Eina_Bool

View File

@ -2,7 +2,6 @@
#include "elm_priv.h"
#include "els_scroller.h"
#include "els_box.h"
#include "els_icon.h"
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Toolbar_Item Elm_Toolbar_Item;
@ -576,7 +575,7 @@ _sizing_eval(Evas_Object *obj)
static void
_item_menu_create(Widget_Data *wd, Elm_Toolbar_Item *item)
{
item->o_menu = elm_menu_add(WIDGET(item));
item->o_menu = elm_menu_add(elm_widget_parent_get(WIDGET(item)));
item->menu = EINA_TRUE;
if (wd->menu_parent)
elm_menu_parent_set(item->o_menu, wd->menu_parent);
@ -1089,6 +1088,7 @@ _item_new(Evas_Object *obj, const char *icon, const char *label, Evas_Smart_Cb f
icon_obj = elm_icon_add(obj);
elm_icon_order_lookup_set(icon_obj, wd->lookup_order);
if (!icon_obj) return NULL;
it = elm_widget_item_new(obj, Elm_Toolbar_Item);
if (!it)
{
@ -1747,9 +1747,9 @@ elm_toolbar_item_icon_memfile_set(Elm_Object_Item *it, const void *img, size_t s
if (img && size)
{
icon_obj = _els_smart_icon_add(evas_object_evas_get(obj));
icon_obj = elm_icon_add(obj);
evas_object_repeat_events_set(icon_obj, EINA_TRUE);
ret = _els_smart_icon_memfile_set(icon_obj, img, size, format, key);
ret = elm_icon_memfile_set(icon_obj, img, size, format, key);
if (!ret)
{
evas_object_del(icon_obj);
@ -1780,9 +1780,9 @@ elm_toolbar_item_icon_file_set(Elm_Object_Item *it, const char *file, const char
if (file)
{
icon_obj = _els_smart_icon_add(evas_object_evas_get(obj));
icon_obj = elm_icon_add(obj);
evas_object_repeat_events_set(icon_obj, EINA_TRUE);
ret = _els_smart_icon_file_key_set(icon_obj, file, key);
ret = elm_icon_file_set(icon_obj, file, key);
if (!ret)
{
evas_object_del(icon_obj);

View File

@ -1,6 +1,7 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_widget_container.h"
#include "elm_widget_image.h"
static const char SMART_NAME[] = "elm_widget";
static const char SMART_NAME_COMPAT[] = "elm_widget_compat";
@ -145,19 +146,9 @@ typedef struct _Elm_Widget_Compat_Smart_Class
* @}
*/
typedef struct _Edje_Signal_Data Edje_Signal_Data;
typedef struct _Elm_Event_Cb_Data Elm_Event_Cb_Data;
typedef struct _Elm_Translate_String_Data Elm_Translate_String_Data;
struct _Edje_Signal_Data
{
Evas_Object *obj;
Edje_Signal_Cb func;
const char *emission;
const char *source;
void *data;
};
struct _Elm_Event_Cb_Data
{
Elm_Event_Cb func;
@ -1300,16 +1291,19 @@ elm_widget_mirrored_get(const Evas_Object *obj)
*/
EAPI void
elm_widget_mirrored_set(Evas_Object *obj,
Eina_Bool mirrored)
Eina_Bool mirrored)
{
API_ENTRY return;
if (sd->is_mirrored != mirrored)
{
sd->is_mirrored = mirrored;
elm_widget_theme(obj);
}
mirrored = !!mirrored;
if (sd->is_mirrored == mirrored) return;
sd->is_mirrored = mirrored;
elm_widget_theme(obj);
}
/**
* @internal
* Resets the mirrored mode from the system mirror mode for widgets that are in
@ -2515,6 +2509,8 @@ elm_widget_signal_emit(Evas_Object *obj,
COMPAT_SMART_DATA(sd)->signal(obj, emission, source);
else if (evas_object_smart_type_check(obj, "elm_layout"))
elm_layout_signal_emit(obj, emission, source);
else if (evas_object_smart_type_check(obj, "elm_image"))
ELM_IMAGE_CLASS(sd->api)->signal(obj, emission, source);
}
static void
@ -2539,12 +2535,10 @@ elm_widget_signal_callback_add(Evas_Object *obj,
EINA_SAFETY_ON_NULL_RETURN(func);
if (_elm_legacy_is(obj) && !COMPAT_SMART_DATA(sd)->callback_add) return;
else if (!evas_object_smart_type_check(obj, "elm_layout"))
return;
if (_elm_legacy_is(obj))
{
if (!COMPAT_SMART_DATA(sd)->callback_add) return;
esd = ELM_NEW(Edje_Signal_Data);
if (!esd) return;
@ -2559,8 +2553,11 @@ elm_widget_signal_callback_add(Evas_Object *obj,
COMPAT_SMART_DATA(sd)->callback_add
(obj, emission, source, _edje_signal_callback, esd);
}
else
else if (!evas_object_smart_type_check(obj, "elm_layout"))
elm_layout_signal_callback_add(obj, emission, source, func, data);
else if (evas_object_smart_type_check(obj, "elm_image"))
ELM_IMAGE_CLASS(sd->api)->callback_add(obj, emission, source, func, data);
}
EAPI void *
@ -2574,13 +2571,10 @@ elm_widget_signal_callback_del(Evas_Object *obj,
void *data = NULL;
API_ENTRY return NULL;
if (_elm_legacy_is(obj) && !COMPAT_SMART_DATA(sd)->callback_del)
return NULL;
else if (!evas_object_smart_type_check(obj, "elm_layout"))
return NULL;
if (_elm_legacy_is(obj))
{
if (!COMPAT_SMART_DATA(sd)->callback_del) return NULL;
EINA_LIST_FOREACH (COMPAT_SMART_DATA(sd)->edje_signals, l, esd)
{
if ((esd->func == func) && (!strcmp(esd->emission, emission)) &&
@ -2599,8 +2593,11 @@ elm_widget_signal_callback_del(Evas_Object *obj,
COMPAT_SMART_DATA(sd)->callback_del
(obj, emission, source, _edje_signal_callback, esd);
}
else
else if (!evas_object_smart_type_check(obj, "elm_layout"))
elm_layout_signal_callback_del(obj, emission, source, func);
else if (evas_object_smart_type_check(obj, "elm_image"))
ELM_IMAGE_CLASS(sd->api)->callback_del(obj, emission, source, func);
return data;
}

View File

@ -0,0 +1,227 @@
#ifndef ELM_WIDGET_IMAGE_H
#define ELM_WIDGET_IMAGE_H
/**
* @addtogroup Widget
* @{
*
* @section elm-image-class The Elementary Image Class
*
* This class defines a common interface for @b image objects having
* an image as their basic graphics. This interface is so that one can
* tune various properties of the image, like:
* - smooth scaling,
* - orientation,
* - aspect ratio during resizes, etc.
*
* Image files may be set via memory buffers, image files, EET files
* with image data or Edje files. On the last case (which is
* exceptional), most of the properties cited above will @b not be
* changeable anymore.
*/
/**
* @def ELM_IMAGE_CLASS
*
* Use this macro to cast whichever subclass of
* #Elm_Image_Smart_Class into it, so to acess its fields.
*
* @ingroup Widget
*/
#define ELM_IMAGE_CLASS(x) ((Elm_Image_Smart_Class *) x)
/**
* @def ELM_IMAGE_DATA
*
* Use this macro to cast whichever subdata of
* #Elm_Image_Smart_Data into it, so to acess its fields.
*
* @ingroup Widget
*/
#define ELM_IMAGE_DATA(x) ((Elm_Image_Smart_Data *) x)
/**
* @def ELM_IMAGE_SMART_CLASS_VERSION
*
* Current version for Elementary image @b base smart class, a value
* which goes to _Elm_Image_Smart_Class::version.
*
* @ingroup Widget
*/
#define ELM_IMAGE_SMART_CLASS_VERSION 1
/**
* @def ELM_IMAGE_SMART_CLASS_INIT
*
* Initializer for a whole #Elm_Image_Smart_Class structure, with
* @c NULL values on its specific fields.
*
* @param smart_class_init initializer to use for the "base" field
* (#Evas_Smart_Class).
*
* @see EVAS_SMART_CLASS_INIT_NULL
* @see EVAS_SMART_CLASS_INIT_NAME_VERSION
* @see ELM_IMAGE_SMART_CLASS_INIT_NULL
* @see ELM_IMAGE_SMART_CLASS_INIT_NAME_VERSION
*
* @ingroup Widget
*/
#define ELM_IMAGE_SMART_CLASS_INIT(smart_class_init) \
{smart_class_init, ELM_IMAGE_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
/**
* @def ELM_IMAGE_SMART_CLASS_INIT_NULL
*
* Initializer to zero out a whole #Elm_Image_Smart_Class structure.
*
* @see ELM_IMAGE_SMART_CLASS_INIT_NAME_VERSION
* @see ELM_IMAGE_SMART_CLASS_INIT
*
* @ingroup Widget
*/
#define ELM_IMAGE_SMART_CLASS_INIT_NULL \
ELM_IMAGE_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NULL)
/**
* @def ELM_IMAGE_SMART_CLASS_INIT_NAME_VERSION
*
* Initializer to zero out a whole #Elm_Image_Smart_Class structure and
* set its name and version.
*
* This is similar to #ELM_IMAGE_SMART_CLASS_INIT_NULL, but it will
* also set the version field of #Elm_Image_Smart_Class (base field)
* to the latest #ELM_IMAGE_SMART_CLASS_VERSION and name it to the
* specific value.
*
* It will keep a reference to the name field as a <c>"const char *"</c>,
* i.e., the name must be available while the structure is
* used (hint: static or global variable!) and must not be modified.
*
* @see ELM_IMAGE_SMART_CLASS_INIT_NULL
* @see ELM_IMAGE_SMART_CLASS_INIT
*
* @ingroup Widget
*/
#define ELM_IMAGE_SMART_CLASS_INIT_NAME_VERSION(name) \
ELM_IMAGE_SMART_CLASS_INIT(ELM_WIDGET_SMART_CLASS_INIT_NAME_VERSION(name))
/**
* Elementary image base smart class. This inherits directly from
* #Elm_Widget_Smart_Class and is meant to build widgets relying on an
* image as the building block of its visuals.
*/
typedef struct _Elm_Image_Smart_Class
{
Elm_Widget_Smart_Class base; /**< Base Elementary widget class struct, since we're inheriting from it */
int version; /**< Version of this smart class definition */
void (*sizing_eval)(Evas_Object *obj); /* 'Virtual' function on evalutating the object's final geometry */
void (*signal)(Evas_Object *obj,
const char *emission,
const char *source); /* 'Virtual' function on emitting an (Edje) signal to the object, acting on its internal layout */
void (*callback_add)(Evas_Object *obj,
const char *emission,
const char *source,
Edje_Signal_Cb func,
void *data); /* 'Virtual' function on adding an (Edje) signal callback to the object, proxyed from its internal layout */
void *(*callback_del)(Evas_Object * obj,
const char *emission,
const char *source,
Edje_Signal_Cb func); /* 'Virtual' function on deleting an (Edje) signal callback on the object, proxyed from its internal layout */
Eina_Bool (*memfile_set)(Evas_Object *obj,
const void *img,
size_t size,
const char *format,
const char *key); /* 'Virtual' function on setting the image content on the object via a memory buffer */
Eina_Bool (*file_set)(Evas_Object *obj,
const char *file,
const char *key); /* 'Virtual' function on setting the image content on the object via a file. It may be a direct image, an EET-encoded image or an Edje file. They @a key argument will be used for the last two cases mentioned (@c NULL must be used on the first). Beware that the Edje case will only be detected by an @c "edj" extension on the file name. */
void (*file_get)(const Evas_Object *obj,
const char **file,
const char **key); /* 'Virtual' function on retrieving back the image object's file path and key */
Evas_Object *(*image_object_get)(const Evas_Object *obj); /* 'Virtual' function on retrieving the object's internal image file, which may me an Evas image or an Edje file */
void (*size_get)(const Evas_Object *obj,
int *w,
int *h); /* 'Virtual' function on retrieving the size of the object's internal image. */
void (*preload_set)(Evas_Object *obj,
Eina_Bool disable); /* 'Virtual' function on enabling/disabling pre-loading for the object's image data. */
void (*fill_inside_set)(Evas_Object *obj,
Eina_Bool fill_inside); /* 'Virtual' function on how to resize the object's internal image, when maintaining a given aspect ratio -- leave blank spaces or scale to fill all space, with pixels out of bounds. */
Eina_Bool (*fill_inside_get)(const Evas_Object *obj); /* 'Virtual' function on retrieving how the object's internal image is to be resized, when maintaining a given aspect ratio. */
void (*scale_set)(Evas_Object *obj,
double scale); /* 'Virtual' function on setting the scale for the object's image size (@c 1.0 meaning original size). */
double (*scale_get)(const Evas_Object *obj); /* 'Virtual' function on retrieving the scale for the object's image size. */
void (*smooth_scale_set)(Evas_Object *obj,
Eina_Bool smooth); /* 'Virtual' function on setting whether the object's image should be scaled smoothly or not. */
Eina_Bool (*smooth_scale_get)(const Evas_Object *obj); /* 'Virtual' function on retrieving whether the object's image is to scaled smoothly or not. */
void (*scale_up_set)(Evas_Object *obj,
Eina_Bool scale_up); /* 'Virtual' function on setting whether the object's image can be resized to a size greater than the original one. */
Eina_Bool (*scale_up_get)(const Evas_Object *obj); /* 'Virtual' function on retrieving whether the object's image can be resized to a size greater than the original one. */
void (*scale_down_set)(Evas_Object *obj,
Eina_Bool scale_down); /* 'Virtual' function on setting whether the object's image can be resized to a size smaller than the original one. */
Eina_Bool (*scale_down_get)(const Evas_Object *obj); /* 'Virtual' function on retrieving whether the object's image can be resized to a size smaller than the original one. */
void (*load_size_set)(Evas_Object *obj,
int size); /* 'Virtual' function on setting the object's image loading size (in pixels, applied to both axis). */
int (*load_size_get)(const Evas_Object *obj); /* 'Virtual' function on retrieving the object's image loading size. */
void (*orient_set)(Evas_Object *obj,
Elm_Image_Orient orient); /* 'Virtual' function on setting the object's image orientation. */
Elm_Image_Orient (*orient_get)(const Evas_Object *obj); /* 'Virtual' function on retrieving the object's image orientation. */
void (*aspect_fixed_set)(Evas_Object *obj,
Eina_Bool fixed); /* 'Virtual' function on setting whether the original aspect ratio of the object's image should be kept if it's resized. */
Eina_Bool (*aspect_fixed_get)(const Evas_Object *obj); /* 'Virtual' function on retrieving whether the original aspect ratio of the object's image is to be kept if it's resized. */
void (*edit_set)(Evas_Object *obj,
Eina_Bool edit,
Evas_Object *parent); /* 'Virtual' function on setting whether the object is a valid target/source for drag and drop actions. */
Eina_Bool (*edit_get)(const Evas_Object *obj); /* 'Virtual' function on retrieving whether the object is a valid target/source for drag and drop actions. */
} Elm_Image_Smart_Class;
/**
* Base widget smart data extended with image instance data.
*/
typedef struct _Elm_Image_Smart_Data Elm_Image_Smart_Data;
struct _Elm_Image_Smart_Data
{
Elm_Widget_Smart_Data base;
Evas_Object *img;
Evas_Object *prev_img;
Evas_Coord img_x, img_y, img_w, img_h;
int load_size;
double scale;
Elm_Image_Orient orient;
Eina_List *edje_signals;
Eina_Bool aspect_fixed : 1;
Eina_Bool fill_inside : 1;
Eina_Bool scale_down : 1;
Eina_Bool preloading : 1;
Eina_Bool scale_up : 1;
Eina_Bool no_scale : 1;
Eina_Bool smooth : 1;
Eina_Bool show : 1;
Eina_Bool edit : 1;
Eina_Bool edje : 1;
};
/**
* @}
*/
EAPI const Elm_Image_Smart_Class *elm_image_smart_class_get(void);
#endif

View File

@ -1,843 +0,0 @@
#include <Elementary.h>
#include "elm_priv.h"
#include "els_icon.h"
#ifdef _WIN32
# define FMT_SIZE_T "%Iu"
#else
# define FMT_SIZE_T "%zu"
#endif
typedef struct _Smart_Data Smart_Data;
struct _Smart_Data
{
Evas_Coord x, y, w, h;
Evas_Object *obj;
Evas_Object *prev;
int size;
double scale;
Eina_Bool fill_inside : 1;
Eina_Bool scale_up : 1;
Eina_Bool scale_down : 1;
Eina_Bool preloading : 1;
Eina_Bool show : 1;
Eina_Bool edit : 1;
Eina_Bool edje : 1;
Eina_Bool aspect_fixed: 1;
Elm_Image_Orient orient;
};
/* local subsystem functions */
static void _smart_reconfigure(Smart_Data *sd);
static void _smart_init(void);
static void _smart_add(Evas_Object *obj);
static void _smart_del(Evas_Object *obj);
static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
static void _smart_show(Evas_Object *obj);
static void _smart_hide(Evas_Object *obj);
static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
static void _smart_clip_unset(Evas_Object *obj);
static void _els_smart_icon_flip_horizontal(Smart_Data *sd);
static void _els_smart_icon_flip_vertical(Smart_Data *sd);
static void _els_smart_icon_rotate_180(Smart_Data *sd);
static Eina_Bool _els_smart_icon_dropcb(void *,Evas_Object *, Elm_Selection_Data *);
/* local subsystem globals */
static Evas_Smart *_e_smart = NULL;
/* externally accessible functions */
Evas_Object *
_els_smart_icon_add(Evas *evas)
{
_smart_init();
return evas_object_smart_add(evas, _e_smart);
}
static void
_preloaded(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event __UNUSED__)
{
Smart_Data *sd = data;
sd->preloading = EINA_FALSE;
if (obj == sd->obj)
{
if (sd->show)
evas_object_show(sd->obj);
}
if (sd->prev) evas_object_del(sd->prev);
sd->prev = NULL;
}
static void
_els_smart_icon_file_helper(Evas_Object *obj)
{
Smart_Data *sd;
Evas_Object *pclip;
sd = evas_object_smart_data_get(obj);
/* smart code here */
if (sd->prev) evas_object_del(sd->prev);
pclip = evas_object_clip_get(sd->obj);
if (sd->obj) sd->prev = sd->obj;
sd->obj = evas_object_image_add(evas_object_evas_get(obj));
evas_object_image_load_orientation_set(sd->obj, EINA_TRUE);
evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED,
_preloaded, sd);
evas_object_smart_member_add(sd->obj, obj);
if (sd->prev) evas_object_smart_member_add(sd->prev, obj);
evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
evas_object_clip_set(sd->obj, pclip);
sd->edje = EINA_FALSE;
if (!sd->size)
evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
}
Eina_Bool
_els_smart_icon_memfile_set(Evas_Object *obj, const void *img, size_t size, const char *format, const char *key)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return EINA_FALSE;
_els_smart_icon_file_helper(obj);
evas_object_image_memfile_set(sd->obj, (void*)img, size, (char*)format, (char*)key);
sd->preloading = EINA_TRUE;
sd->show = EINA_TRUE;
evas_object_hide(sd->obj);
evas_object_image_preload(sd->obj, EINA_FALSE);
if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
{
ERR("Things are going bad for some random " FMT_SIZE_T " byte chunk of memory (%p)", size, sd->obj);
return EINA_FALSE;
}
_smart_reconfigure(sd);
return EINA_TRUE;
}
Eina_Bool
_els_smart_icon_file_key_set(Evas_Object *obj, const char *file, const char *key)
{
Smart_Data *sd;
Evas_Coord w, h;
sd = evas_object_smart_data_get(obj);
if (!sd) return EINA_FALSE;
_els_smart_icon_file_helper(obj);
evas_object_image_file_set(sd->obj, file, key);
sd->preloading = EINA_TRUE;
sd->show = EINA_TRUE;
evas_object_hide(sd->obj);
_els_smart_icon_size_get(obj, &w, &h);
evas_object_image_load_size_set(sd->obj, w, h);
evas_object_image_preload(sd->obj, EINA_FALSE);
if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
{
ERR("Things are going bad for '%s' (%p)", file, sd->obj);
return EINA_FALSE;
}
_smart_reconfigure(sd);
return EINA_TRUE;
}
void
_els_smart_icon_preload_set(Evas_Object *obj, Eina_Bool disable)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if ((!sd) || sd->edje) return;
evas_object_image_preload(sd->obj, disable);
sd->preloading = !disable;
}
Eina_Bool
_els_smart_icon_file_edje_set(Evas_Object *obj, const char *file, const char *part)
{
Smart_Data *sd;
Evas_Object *pclip;
sd = evas_object_smart_data_get(obj);
if (!sd) return EINA_FALSE;
/* smart code here */
if (sd->prev) evas_object_del(sd->prev);
sd->prev = NULL;
if (!sd->edje)
{
pclip = evas_object_clip_get(sd->obj);
if (sd->obj) evas_object_del(sd->obj);
sd->obj = edje_object_add(evas_object_evas_get(obj));
evas_object_smart_member_add(sd->obj, obj);
if (sd->show) evas_object_show(sd->obj);
evas_object_clip_set(sd->obj, pclip);
}
sd->edje = EINA_TRUE;
if (!edje_object_file_set(sd->obj, file, part))
return EINA_FALSE;
/* FIXME: do i want to update icon on file change ? */
_smart_reconfigure(sd);
return EINA_TRUE;
}
void
_els_smart_icon_file_get(const Evas_Object *obj, const char **file, const char **key)
{
Smart_Data *sd = evas_object_smart_data_get(obj);
if (!sd) return;
if (sd->edje)
edje_object_file_get(sd->obj, file, key);
else
evas_object_image_file_get(sd->obj, file, key);
}
void
_els_smart_icon_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth)
{
Smart_Data *sd = evas_object_smart_data_get(obj);
if (!sd) return;
if (sd->edje)
return;
evas_object_image_smooth_scale_set(sd->obj, smooth);
}
Eina_Bool
_els_smart_icon_smooth_scale_get(const Evas_Object *obj)
{
Smart_Data *sd = evas_object_smart_data_get(obj);
if (!sd) return EINA_FALSE;
if (sd->edje)
return EINA_FALSE;
return evas_object_image_smooth_scale_get(sd->obj);
}
Evas_Object *
_els_smart_icon_object_get(const Evas_Object *obj)
{
Smart_Data *sd = evas_object_smart_data_get(obj);
if (!sd) return NULL;
return sd->obj;
}
void
_els_smart_icon_size_get(const Evas_Object *obj, int *w, int *h)
{
Smart_Data *sd;
int tw, th;
int cw, ch;
const char *type;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
type = evas_object_type_get(sd->obj);
if (!type) return;
if (!strcmp(type, "edje"))
edje_object_size_min_get(sd->obj, &tw, &th);
else
evas_object_image_size_get(sd->obj, &tw, &th);
evas_object_geometry_get(sd->obj, NULL, NULL, &cw, &ch);
tw = tw > cw ? tw : cw;
th = th > ch ? th : ch;
tw = ((double)tw) * sd->scale;
th = ((double)th) * sd->scale;
if (w) *w = tw;
if (h) *h = th;
}
void
_els_smart_icon_fill_inside_set(Evas_Object *obj, Eina_Bool fill_inside)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
if (((sd->fill_inside) && (fill_inside)) ||
((!sd->fill_inside) && (!fill_inside))) return;
sd->fill_inside = fill_inside;
_smart_reconfigure(sd);
}
Eina_Bool
_els_smart_icon_fill_inside_get(const Evas_Object *obj)
{
Smart_Data *sd = evas_object_smart_data_get(obj);
if (!sd) return EINA_FALSE;
return sd->fill_inside;
}
void
_els_smart_icon_scale_up_set(Evas_Object *obj, Eina_Bool scale_up)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
if (((sd->scale_up) && (scale_up)) ||
((!sd->scale_up) && (!scale_up))) return;
sd->scale_up = scale_up;
_smart_reconfigure(sd);
}
Eina_Bool
_els_smart_icon_scale_up_get(const Evas_Object *obj)
{
Smart_Data *sd; sd = evas_object_smart_data_get(obj);
if (!sd) return EINA_FALSE;
return sd->scale_up;
}
void
_els_smart_icon_scale_down_set(Evas_Object *obj, Eina_Bool scale_down)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
if (((sd->scale_down) && (scale_down)) ||
((!sd->scale_down) && (!scale_down))) return;
sd->scale_down = scale_down;
_smart_reconfigure(sd);
}
Eina_Bool
_els_smart_icon_scale_down_get(const Evas_Object *obj)
{
Smart_Data *sd; sd = evas_object_smart_data_get(obj);
if (!sd) return EINA_FALSE;
return sd->scale_up;
}
void
_els_smart_icon_scale_size_set(Evas_Object *obj, int size)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
sd->size = size;
if (!sd->obj) return;
if (sd->edje)
return;
evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
}
int
_els_smart_icon_scale_size_get(const Evas_Object *obj)
{
Smart_Data *sd; sd = evas_object_smart_data_get(obj);
if (!sd) return 0;
return sd->size;
}
void
_els_smart_icon_scale_set(Evas_Object *obj, double scale)
{
Smart_Data *sd = evas_object_smart_data_get(obj);
if (!sd) return;
sd->scale = scale;
_smart_reconfigure(sd);
}
double
_els_smart_icon_scale_get(const Evas_Object *obj)
{
Smart_Data *sd; sd = evas_object_smart_data_get(obj);
if (!sd) return 0.0;
return sd->scale;
}
void
_els_smart_icon_orient_set(Evas_Object *obj, Elm_Image_Orient orient)
{
Smart_Data *sd;
unsigned int *data, *data2 = NULL, *to, *from;
int x, y, w, hw, iw, ih;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
if (sd->edje)
return;
switch (orient)
{
case ELM_IMAGE_FLIP_HORIZONTAL:
_els_smart_icon_flip_horizontal(sd);
return;
case ELM_IMAGE_FLIP_VERTICAL:
_els_smart_icon_flip_vertical(sd);
return;
case ELM_IMAGE_ROTATE_180:
_els_smart_icon_rotate_180(sd);
return;
default:
break;
}
evas_object_image_size_get(sd->obj, &iw, &ih);
/* we need separate destination memory if we want to rotate 90 or 270 degree */
evas_object_image_data_copy_set(sd->obj, data2);
if (!data2) return;
w = ih;
ih = iw;
iw = w;
hw = w * ih;
evas_object_image_size_set(sd->obj, iw, ih);
data = evas_object_image_data_get(sd->obj, EINA_TRUE);
switch (orient)
{
case ELM_IMAGE_FLIP_TRANSPOSE:
to = data;
hw = -hw + 1;
break;
case ELM_IMAGE_FLIP_TRANSVERSE:
to = data + hw - 1;
w = -w;
hw = hw - 1;
break;
case ELM_IMAGE_ROTATE_90:
to = data + w - 1;
hw = -hw - 1;
break;
case ELM_IMAGE_ROTATE_270:
to = data + hw - w;
w = -w;
hw = hw + 1;
break;
default:
ERR("unknown orient %d", orient);
evas_object_image_data_set(sd->obj, data); // give it back
if (data2) free(data2);
return;
}
from = data2;
for (x = iw; --x >= 0;)
{
for (y = ih; --y >= 0;)
{
*to = *from;
from++;
to += w;
}
to += hw;
}
sd->orient = orient;
if (data2) free(data2);
evas_object_image_data_set(sd->obj, data);
evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
_smart_reconfigure(sd);
}
Elm_Image_Orient
_els_smart_icon_orient_get(const Evas_Object *obj)
{
Smart_Data *sd; sd = evas_object_smart_data_get(obj);
if (!sd) return 0;
return sd->orient;
}
/**
* Turns on editing through drag and drop and copy and paste.
*/
void
_els_smart_icon_edit_set(Evas_Object *obj, Eina_Bool edit, Evas_Object *parent)
{
Smart_Data *sd = evas_object_smart_data_get(obj);
if (!sd) return;
if (sd->edje)
{
printf("No editing edje objects yet (ever)\n");
return;
}
/* Unfortunately eina bool is not a bool, but a char */
if (edit == sd->edit) return;
sd->edit = edit;
if (sd->edit)
elm_drop_target_add(obj, ELM_SEL_FORMAT_IMAGE, _els_smart_icon_dropcb,
parent);
else
elm_drop_target_del(obj);
}
Eina_Bool
_els_smart_icon_edit_get(const Evas_Object *obj)
{
Smart_Data *sd; sd = evas_object_smart_data_get(obj);
if (!sd) return EINA_FALSE;
return sd->edit;
}
Evas_Object *
_els_smart_icon_edje_get(Evas_Object *obj)
{
Smart_Data *sd = evas_object_smart_data_get(obj);
if (!sd) return NULL;
if (!sd->edje) return NULL;
return sd->obj;
}
void
_els_smart_icon_aspect_fixed_set(Evas_Object *obj, Eina_Bool fixed)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
fixed = !!fixed;
if (sd->aspect_fixed == fixed) return;
sd->aspect_fixed = fixed;
_smart_reconfigure(sd);
}
Eina_Bool
_els_smart_icon_aspect_fixed_get(const Evas_Object *obj)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return EINA_FALSE;
return sd->aspect_fixed;
}
/* local subsystem globals */
static void
_smart_reconfigure(Smart_Data *sd)
{
Evas_Coord x, y, w, h;
const char *type;
if (!sd->obj) return;
w = sd->w;
h = sd->h;
type = evas_object_type_get(sd->obj);
if (!type) return;
if (!strcmp(type, "edje"))
{
x = sd->x;
y = sd->y;
evas_object_move(sd->obj, x, y);
evas_object_resize(sd->obj, w, h);
}
else
{
int iw = 0, ih = 0;
double alignh = 0.5, alignv = 0.5;
Evas_Object *parent;
evas_object_image_size_get(sd->obj, &iw, &ih);
iw = ((double)iw) * sd->scale;
ih = ((double)ih) * sd->scale;
if (iw < 1) iw = 1;
if (ih < 1) ih = 1;
if (sd->aspect_fixed)
{
h = ((double)ih * w) / (double)iw;
if (sd->fill_inside)
{
if (h > sd->h)
{
h = sd->h;
w = ((double)iw * h) / (double)ih;
}
}
else
{
if (h < sd->h)
{
h = sd->h;
w = ((double)iw * h) / (double)ih;
}
}
}
if (!sd->scale_up)
{
if (w > iw) w = iw;
if (h > ih) h = ih;
}
if (!sd->scale_down)
{
if (w < iw) w = iw;
if (h < ih) h = ih;
}
parent = elm_widget_parent_widget_get(sd->obj);
if (parent)
evas_object_size_hint_align_get(parent, &alignh, &alignv);
if (alignh == EVAS_HINT_FILL) alignh = 0.5;
if (alignv == EVAS_HINT_FILL) alignv = 0.5;
x = sd->x + ((sd->w - w) * alignh);
y = sd->y + ((sd->h - h) * alignv);
evas_object_move(sd->obj, x, y);
evas_object_image_fill_set(sd->obj, 0, 0, w, h);
evas_object_resize(sd->obj, w, h);
}
}
static void
_smart_init(void)
{
if (_e_smart) return;
{
static const Evas_Smart_Class sc =
{
"e_icon",
EVAS_SMART_CLASS_VERSION,
_smart_add,
_smart_del,
_smart_move,
_smart_resize,
_smart_show,
_smart_hide,
_smart_color_set,
_smart_clip_set,
_smart_clip_unset,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
_e_smart = evas_smart_class_new(&sc);
}
}
static void
_smart_add(Evas_Object *obj)
{
Smart_Data *sd;
sd = calloc(1, sizeof(Smart_Data));
if (!sd) return;
sd->obj = evas_object_image_add(evas_object_evas_get(obj));
sd->prev = NULL;
evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
sd->x = 0;
sd->y = 0;
sd->w = 0;
sd->h = 0;
sd->fill_inside = EINA_TRUE;
sd->scale_up = EINA_TRUE;
sd->scale_down = EINA_TRUE;
sd->aspect_fixed = EINA_TRUE;
sd->size = 64;
sd->scale = 1.0;
evas_object_smart_member_add(sd->obj, obj);
evas_object_smart_data_set(obj, sd);
evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED,
_preloaded, sd);
}
static void
_smart_del(Evas_Object *obj)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
evas_object_del(sd->obj);
if (sd->prev) evas_object_del(sd->prev);
free(sd);
}
static void
_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
if ((sd->x == x) && (sd->y == y)) return;
sd->x = x;
sd->y = y;
_smart_reconfigure(sd);
}
static void
_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
if ((sd->w == w) && (sd->h == h)) return;
sd->w = w;
sd->h = h;
_smart_reconfigure(sd);
}
static void
_smart_show(Evas_Object *obj)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
sd->show = EINA_TRUE;
if (!sd->preloading)
{
evas_object_show(sd->obj);
if (sd->prev) evas_object_del(sd->prev);
sd->prev = NULL;
}
}
static void
_smart_hide(Evas_Object *obj)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
sd->show = EINA_FALSE;
evas_object_hide(sd->obj);
if (sd->prev) evas_object_del(sd->prev);
sd->prev = NULL;
}
static void
_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
evas_object_color_set(sd->obj, r, g, b, a);
if (sd->prev) evas_object_color_set(sd->prev, r, g, b, a);
}
static void
_smart_clip_set(Evas_Object *obj, Evas_Object * clip)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
evas_object_clip_set(sd->obj, clip);
if (sd->prev) evas_object_clip_set(sd->prev, clip);
}
static void
_smart_clip_unset(Evas_Object *obj)
{
Smart_Data *sd;
sd = evas_object_smart_data_get(obj);
if (!sd) return;
evas_object_clip_unset(sd->obj);
if (sd->prev) evas_object_clip_unset(sd->prev);
}
static void
_els_smart_icon_flip_horizontal(Smart_Data *sd)
{
unsigned int *data;
unsigned int *p1, *p2, tmp;
int x, y, iw, ih;
evas_object_image_size_get(sd->obj, &iw, &ih);
data = evas_object_image_data_get(sd->obj, EINA_TRUE);
for (y = 0; y < ih; y++)
{
p1 = data + (y * iw);
p2 = data + ((y + 1) * iw) - 1;
for (x = 0; x < (iw >> 1); x++)
{
tmp = *p1;
*p1 = *p2;
*p2 = tmp;
p1++;
p2--;
}
}
evas_object_image_data_set(sd->obj, data);
evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
_smart_reconfigure(sd);
}
static void
_els_smart_icon_flip_vertical(Smart_Data *sd)
{
unsigned int *data;
unsigned int *p1, *p2, tmp;
int x, y, iw, ih;
evas_object_image_size_get(sd->obj, &iw, &ih);
data = evas_object_image_data_get(sd->obj, EINA_TRUE);
for (y = 0; y < (ih >> 1); y++)
{
p1 = data + (y * iw);
p2 = data + ((ih - 1 - y) * iw);
for (x = 0; x < iw; x++)
{
tmp = *p1;
*p1 = *p2;
*p2 = tmp;
p1++;
p2++;
}
}
evas_object_image_data_set(sd->obj, data);
evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
_smart_reconfigure(sd);
}
static void
_els_smart_icon_rotate_180(Smart_Data *sd)
{
unsigned int *data;
unsigned int *p1, *p2, tmp;
int x, hw, iw, ih;
evas_object_image_size_get(sd->obj, &iw, &ih);
data = evas_object_image_data_get(sd->obj, 1);
hw = iw * ih;
x = (hw / 2);
p1 = data;
p2 = data + hw - 1;
for (; --x > 0;)
{
tmp = *p1;
*p1 = *p2;
*p2 = tmp;
p1++;
p2--;
}
evas_object_image_data_set(sd->obj, data);
evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
_smart_reconfigure(sd);
}
static Eina_Bool
_els_smart_icon_dropcb(void *elmobj,Evas_Object *obj, Elm_Selection_Data *drop)
{
_els_smart_icon_file_key_set(obj, drop->data, NULL);
evas_object_smart_callback_call(elmobj, "drop", drop->data);
return EINA_TRUE;
}
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/

View File

@ -1,27 +0,0 @@
Evas_Object *_els_smart_icon_add(Evas *evas);
Eina_Bool _els_smart_icon_memfile_set(Evas_Object *obj, const void *file, size_t size, const char *format, const char *key);
Eina_Bool _els_smart_icon_file_key_set(Evas_Object *obj, const char *file, const char *key);
Eina_Bool _els_smart_icon_file_edje_set(Evas_Object *obj, const char *file, const char *part);
void _els_smart_icon_file_get(const Evas_Object *obj, const char **file, const char **key);
void _els_smart_icon_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth);
Eina_Bool _els_smart_icon_smooth_scale_get(const Evas_Object *obj);
Evas_Object *_els_smart_icon_object_get(const Evas_Object *obj);
void _els_smart_icon_size_get(const Evas_Object *obj, int *w, int *h);
void _els_smart_icon_fill_inside_set(Evas_Object *obj, Eina_Bool fill_inside);
Eina_Bool _els_smart_icon_fill_inside_get(const Evas_Object *obj);
void _els_smart_icon_scale_up_set(Evas_Object *obj, Eina_Bool scale_up);
Eina_Bool _els_smart_icon_scale_up_get(const Evas_Object *obj);
void _els_smart_icon_scale_down_set(Evas_Object *obj, Eina_Bool scale_down);
Eina_Bool _els_smart_icon_scale_down_get(const Evas_Object *obj);
void _els_smart_icon_scale_size_set(Evas_Object *obj, int size);
int _els_smart_icon_scale_size_get(const Evas_Object *obj);
void _els_smart_icon_scale_set(Evas_Object *obj, double scale);
double _els_smart_icon_scale_get(const Evas_Object *obj);
void _els_smart_icon_orient_set(Evas_Object *obj, Elm_Image_Orient orient);
Elm_Image_Orient _els_smart_icon_orient_get(const Evas_Object *obj);
void _els_smart_icon_edit_set(Evas_Object *obj, Eina_Bool, Evas_Object *parent);
Eina_Bool _els_smart_icon_edit_get(const Evas_Object *obj);
Evas_Object *_els_smart_icon_edje_get(Evas_Object *obj);
void _els_smart_icon_aspect_fixed_set(Evas_Object *obj, Eina_Bool fixed);
Eina_Bool _els_smart_icon_aspect_fixed_get(const Evas_Object *obj);
void _els_smart_icon_preload_set(Evas_Object *obj, Eina_Bool disable);