2008-09-29 23:58:56 -07:00
|
|
|
#include <Elementary.h>
|
|
|
|
#include "elm_priv.h"
|
|
|
|
|
2010-03-22 14:36:59 -07:00
|
|
|
static const char SMART_NAME[] = "elm_widget";
|
|
|
|
|
2009-02-02 21:09:03 -08:00
|
|
|
#define API_ENTRY \
|
|
|
|
Smart_Data *sd = evas_object_smart_data_get(obj); \
|
2010-03-22 14:36:59 -07:00
|
|
|
if ((!obj) || (!sd) || (!_elm_widget_is(obj)))
|
2009-02-02 21:09:03 -08:00
|
|
|
#define INTERNAL_ENTRY \
|
|
|
|
Smart_Data *sd = evas_object_smart_data_get(obj); \
|
|
|
|
if (!sd) return;
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
typedef struct _Smart_Data Smart_Data;
|
2008-09-29 23:58:56 -07:00
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
struct _Smart_Data
|
2009-07-06 23:46:51 -07:00
|
|
|
{
|
2008-10-22 01:58:56 -07:00
|
|
|
Evas_Object *obj;
|
2009-05-13 05:21:52 -07:00
|
|
|
const char *type;
|
2008-10-06 18:23:49 -07:00
|
|
|
Evas_Object *parent_obj;
|
|
|
|
Evas_Coord x, y, w, h;
|
2008-10-22 07:11:59 -07:00
|
|
|
Eina_List *subobjs;
|
2008-10-06 18:23:49 -07:00
|
|
|
Evas_Object *resize_obj;
|
2008-10-07 23:38:20 -07:00
|
|
|
Evas_Object *hover_obj;
|
Tooltips: split owner/eventarea, allow subitems to have indepentent tooltips.
Now owner widget (elm_widget) is just used to listen for theme changes
and create/destroy the tooltip data. The actual mouse events operates
on all Evas_Object and is the one where tooltip data is actually
stored.
The public API is basically the same, just the event_info is now NULL
to avoid confusion.
The internal API introduces elm_object_sub_tooltip_content_cb_set()
and as the first parameter the eventarea. While this may be confusing,
as the second parameter is the actual elementary object, it is the one
that all other calls receive, like elm_object_tooltip_hide() or
elm_object_tooltip_unset(), thus it does make sense to have such order.
Also internal API, elm_widget_item_tooltip_* functions were
added. They are a variation of the widget API to handle its items, as
such the func() gets one more parameter: item, and the del_cb() gets
the item as event_info (that's why the public widget version got
event_info always NULL, to not confuse with this one!)
Widgets with items that makes sense to have tooltips got extra API:
* toolbar
* list
* gengrid
* genlist
SVN revision: 52173
2010-09-12 14:05:13 -07:00
|
|
|
Eina_List *tooltips;
|
2008-10-06 18:23:49 -07:00
|
|
|
void (*del_func) (Evas_Object *obj);
|
2008-10-24 19:11:06 -07:00
|
|
|
void (*del_pre_func) (Evas_Object *obj);
|
2008-10-06 18:23:49 -07:00
|
|
|
void (*focus_func) (Evas_Object *obj);
|
|
|
|
void (*activate_func) (Evas_Object *obj);
|
|
|
|
void (*disable_func) (Evas_Object *obj);
|
2008-11-14 22:09:04 -08:00
|
|
|
void (*theme_func) (Evas_Object *obj);
|
2010-09-20 19:02:24 -07:00
|
|
|
Eina_Bool (*event_func) (Evas_Object *obj, Evas_Object *source, Evas_Callback_Type type, void *event_info);
|
2010-06-15 07:11:13 -07:00
|
|
|
void (*signal_func) (Evas_Object *obj, const char *emission,
|
|
|
|
const char *source);
|
2010-06-28 08:32:20 -07:00
|
|
|
void (*callback_add_func) (Evas_Object *obj, const char *emission,
|
2010-06-25 15:38:32 -07:00
|
|
|
const char *source, void (*func) (void *data,
|
|
|
|
Evas_Object *o, const char *emission,
|
|
|
|
const char *source), void *data);
|
2010-06-28 08:32:20 -07:00
|
|
|
void *(*callback_del_func) (Evas_Object *obj, const char *emission,
|
2010-06-25 15:38:32 -07:00
|
|
|
const char *source, void (*func) (void *data,
|
|
|
|
Evas_Object *o, const char *emission,
|
|
|
|
const char *source));
|
2009-11-17 08:32:45 -08:00
|
|
|
void (*changed_func) (Evas_Object *obj);
|
2008-10-06 18:23:49 -07:00
|
|
|
void (*on_focus_func) (void *data, Evas_Object *obj);
|
|
|
|
void *on_focus_data;
|
|
|
|
void (*on_change_func) (void *data, Evas_Object *obj);
|
|
|
|
void *on_change_data;
|
2008-10-17 07:40:54 -07:00
|
|
|
void (*on_show_region_func) (void *data, Evas_Object *obj);
|
|
|
|
void *on_show_region_data;
|
2008-10-06 18:23:49 -07:00
|
|
|
void *data;
|
2008-10-17 07:40:54 -07:00
|
|
|
Evas_Coord rx, ry, rw, rh;
|
2008-11-18 02:11:57 -08:00
|
|
|
int scroll_hold;
|
2009-03-20 08:08:33 -07:00
|
|
|
int scroll_freeze;
|
2009-02-02 21:09:03 -08:00
|
|
|
double scale;
|
2010-05-11 18:03:46 -07:00
|
|
|
Elm_Theme *theme;
|
2009-04-22 21:03:27 -07:00
|
|
|
const char *style;
|
2010-06-21 00:39:49 -07:00
|
|
|
unsigned int focus_order;
|
2010-05-07 06:21:45 -07:00
|
|
|
|
|
|
|
int child_drag_x_locked;
|
|
|
|
int child_drag_y_locked;
|
|
|
|
Eina_Bool drag_x_locked : 1;
|
|
|
|
Eina_Bool drag_y_locked : 1;
|
|
|
|
|
|
|
|
Eina_Bool can_focus : 1;
|
|
|
|
Eina_Bool child_can_focus : 1;
|
|
|
|
Eina_Bool focused : 1;
|
Begins highlight on focused object.
There's still work to do here, particularly in the theme, but it has
something nice and fun to see the code working.
The idea behind this:
Window tracks focused object and sends the highlight object(s) to it. These
are simple edje objects, one on top, one below the focused widget for nice
effects. Widgets can choose to ignore the highlight and this will be sent to
the parent object, if it doesn't ignore it as well.
About the bottom object, it doesn't work now. For the most part, focused
widget will always be a member of some smart object, so stacking won't work
and the desired effect is nowhere to be seen. This will be worked out later.
To be done now:
- Let the theme for a widget define its own highlight, disabling if needed
the standard one for those objects.
- Needed base in code to allow animations when switching focus. All in theme.
- Properly test all widgets and fix some things that will most likely work
in weird ways, given the nature of Evas/Edje and how Elementary makes use
of them.
- Forgot the rest, stay tuned, test, report, give ideas, plant a tree.
Work started by glima, continued with some refactors by me when he
decided he needed vacations.
SVN revision: 52524
2010-09-20 15:18:58 -07:00
|
|
|
Eina_Bool highlight_ignore : 1;
|
2010-05-07 06:21:45 -07:00
|
|
|
Eina_Bool disabled : 1;
|
2009-07-06 23:46:51 -07:00
|
|
|
};
|
2008-10-06 18:23:49 -07:00
|
|
|
|
|
|
|
/* local subsystem functions */
|
|
|
|
static void _smart_reconfigure(Smart_Data *sd);
|
|
|
|
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);
|
2009-11-17 08:32:45 -08:00
|
|
|
static void _smart_calculate(Evas_Object *obj);
|
2008-10-06 18:23:49 -07:00
|
|
|
static void _smart_init(void);
|
|
|
|
|
2010-06-23 19:54:03 -07:00
|
|
|
static void _if_focused_revert(Evas_Object *obj);
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
/* local subsystem globals */
|
|
|
|
static Evas_Smart *_e_smart = NULL;
|
2010-09-13 00:56:23 -07:00
|
|
|
static Eina_List *widtypes = NULL;
|
2008-10-06 18:23:49 -07:00
|
|
|
|
2010-06-21 00:39:49 -07:00
|
|
|
static unsigned int focus_order = 0;
|
|
|
|
|
2010-09-13 00:56:23 -07:00
|
|
|
// internal funcs
|
|
|
|
static inline Eina_Bool
|
|
|
|
_elm_widget_is(const Evas_Object *obj)
|
|
|
|
{
|
|
|
|
const char *type = evas_object_type_get(obj);
|
|
|
|
return type == SMART_NAME;
|
|
|
|
}
|
|
|
|
|
2008-10-07 23:38:20 -07:00
|
|
|
static void
|
2010-03-09 09:51:30 -08:00
|
|
|
_sub_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
|
2008-10-07 23:38:20 -07:00
|
|
|
{
|
|
|
|
Smart_Data *sd = data;
|
2009-10-17 23:03:03 -07:00
|
|
|
|
2008-11-26 21:41:13 -08:00
|
|
|
if (obj == sd->resize_obj)
|
2009-10-17 23:03:03 -07:00
|
|
|
sd->resize_obj = NULL;
|
2009-10-22 15:10:23 -07:00
|
|
|
else if (obj == sd->hover_obj)
|
2009-10-17 23:03:03 -07:00
|
|
|
sd->hover_obj = NULL;
|
2008-11-26 21:41:13 -08:00
|
|
|
else
|
2009-10-17 23:03:03 -07:00
|
|
|
sd->subobjs = eina_list_remove(sd->subobjs, obj);
|
2008-12-23 21:04:33 -08:00
|
|
|
evas_object_smart_callback_call(sd->obj, "sub-object-del", obj);
|
2008-10-07 23:38:20 -07:00
|
|
|
}
|
|
|
|
|
2008-10-22 01:58:56 -07:00
|
|
|
static void
|
2010-03-09 09:51:30 -08:00
|
|
|
_sub_obj_mouse_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
|
2008-10-22 01:58:56 -07:00
|
|
|
{
|
2010-03-22 14:36:59 -07:00
|
|
|
Evas_Object *o = obj;
|
2010-05-07 06:21:45 -07:00
|
|
|
do
|
|
|
|
{
|
|
|
|
if (_elm_widget_is(o)) break;
|
|
|
|
o = evas_object_smart_parent_get(o);
|
|
|
|
}
|
|
|
|
while (o);
|
2009-10-22 05:04:55 -07:00
|
|
|
if (!o) return;
|
|
|
|
if (!elm_widget_can_focus_get(o)) return;
|
|
|
|
elm_widget_focus_steal(o);
|
2008-10-22 01:58:56 -07:00
|
|
|
}
|
|
|
|
|
2010-09-13 00:56:23 -07:00
|
|
|
static void
|
|
|
|
_propagate_x_drag_lock(Evas_Object *obj, int dir)
|
|
|
|
{
|
|
|
|
Smart_Data *sd = evas_object_smart_data_get(obj);
|
|
|
|
if (sd->parent_obj)
|
|
|
|
{
|
|
|
|
Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
|
|
|
|
if (sd2)
|
|
|
|
{
|
|
|
|
sd2->child_drag_x_locked += dir;
|
|
|
|
_propagate_x_drag_lock(sd->parent_obj, dir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_propagate_y_drag_lock(Evas_Object *obj, int dir)
|
|
|
|
{
|
|
|
|
Smart_Data *sd = evas_object_smart_data_get(obj);
|
|
|
|
if (sd->parent_obj)
|
|
|
|
{
|
|
|
|
Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
|
|
|
|
if (sd2)
|
|
|
|
{
|
|
|
|
sd2->child_drag_y_locked += dir;
|
|
|
|
_propagate_y_drag_lock(sd->parent_obj, dir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-20 19:02:24 -07:00
|
|
|
static void
|
|
|
|
_propagate_event(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
INTERNAL_ENTRY;
|
|
|
|
Evas_Callback_Type type = (Evas_Callback_Type)(long) data;
|
|
|
|
Evas_Event_Flags *event_flags = NULL;
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case EVAS_CALLBACK_KEY_DOWN:
|
|
|
|
{
|
|
|
|
Evas_Event_Key_Down *ev = event_info;
|
|
|
|
event_flags = &(ev->event_flags);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case EVAS_CALLBACK_KEY_UP:
|
|
|
|
{
|
|
|
|
Evas_Event_Key_Up *ev = event_info;
|
|
|
|
event_flags = &(ev->event_flags);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event_flags && (*event_flags & EVAS_EVENT_FLAG_ON_HOLD))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (sd->event_func && sd->event_func(obj, obj, type, event_info))
|
|
|
|
return;
|
|
|
|
|
|
|
|
elm_widget_parent_event_propagate(obj, type, event_info);
|
|
|
|
}
|
|
|
|
|
2010-09-13 00:56:23 -07:00
|
|
|
static void
|
|
|
|
_parent_focus(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
Evas_Object *o = elm_widget_parent_get(obj);
|
|
|
|
|
|
|
|
if (sd->focused) return;
|
|
|
|
if (o) _parent_focus(o);
|
|
|
|
focus_order++;
|
|
|
|
sd->focus_order = focus_order;
|
|
|
|
sd->focused = 1;
|
|
|
|
if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
|
|
|
|
if (sd->focus_func) sd->focus_func(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
// exposed util funcs to elm
|
|
|
|
void
|
|
|
|
_elm_widget_type_clear(void)
|
|
|
|
{
|
|
|
|
const char **ptr;
|
|
|
|
|
|
|
|
EINA_LIST_FREE(widtypes, ptr)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(*ptr);
|
|
|
|
*ptr = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// exposed api for making widgets
|
|
|
|
EAPI void
|
|
|
|
elm_widget_type_register(const char **ptr)
|
|
|
|
{
|
|
|
|
widtypes = eina_list_append(widtypes, (void *)ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
|
|
|
elm_widget_api_check(int ver)
|
|
|
|
{
|
|
|
|
if (ver != ELM_INTERNAL_API_VERSION)
|
|
|
|
{
|
|
|
|
CRITICAL("Elementary widget api versions do not match");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI Evas_Object *
|
|
|
|
elm_widget_add(Evas *evas)
|
|
|
|
{
|
|
|
|
_smart_init();
|
|
|
|
return evas_object_smart_add(evas, _e_smart);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->del_func = func;
|
|
|
|
}
|
|
|
|
|
2008-10-24 19:11:06 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_del_pre_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->del_pre_func = func;
|
|
|
|
}
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_focus_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->focus_func = func;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_activate_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->activate_func = func;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_disable_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->disable_func = func;
|
|
|
|
}
|
|
|
|
|
2008-11-14 22:09:04 -08:00
|
|
|
EAPI void
|
|
|
|
elm_widget_theme_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->theme_func = func;
|
|
|
|
}
|
|
|
|
|
2010-09-20 19:02:24 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_event_hook_set(Evas_Object *obj, Eina_Bool (*func) (Evas_Object *obj, Evas_Object *source, Evas_Callback_Type type, void *event_info))
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->event_func = func;
|
|
|
|
}
|
|
|
|
|
2009-11-17 08:32:45 -08:00
|
|
|
EAPI void
|
|
|
|
elm_widget_changed_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->changed_func = func;
|
|
|
|
}
|
|
|
|
|
2010-06-15 07:11:13 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_signal_emit_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source))
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->signal_func = func;
|
|
|
|
}
|
|
|
|
|
2010-06-25 15:38:32 -07:00
|
|
|
EAPI void
|
2010-06-28 08:32:20 -07:00
|
|
|
elm_widget_signal_callback_add_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data))
|
2010-06-25 15:38:32 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return;
|
2010-06-28 08:32:20 -07:00
|
|
|
sd->callback_add_func = func;
|
2010-06-25 15:38:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2010-06-28 08:32:20 -07:00
|
|
|
elm_widget_signal_callback_del_hook_set(Evas_Object *obj, void *(*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source)))
|
2010-06-25 15:38:32 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return;
|
2010-06-28 08:32:20 -07:00
|
|
|
sd->callback_del_func = func;
|
2010-06-25 15:38:32 -07:00
|
|
|
}
|
|
|
|
|
2008-11-14 22:09:04 -08:00
|
|
|
EAPI void
|
|
|
|
elm_widget_theme(Evas_Object *obj)
|
|
|
|
{
|
2009-02-25 11:50:45 -08:00
|
|
|
const Eina_List *l;
|
|
|
|
Evas_Object *child;
|
Tooltips: split owner/eventarea, allow subitems to have indepentent tooltips.
Now owner widget (elm_widget) is just used to listen for theme changes
and create/destroy the tooltip data. The actual mouse events operates
on all Evas_Object and is the one where tooltip data is actually
stored.
The public API is basically the same, just the event_info is now NULL
to avoid confusion.
The internal API introduces elm_object_sub_tooltip_content_cb_set()
and as the first parameter the eventarea. While this may be confusing,
as the second parameter is the actual elementary object, it is the one
that all other calls receive, like elm_object_tooltip_hide() or
elm_object_tooltip_unset(), thus it does make sense to have such order.
Also internal API, elm_widget_item_tooltip_* functions were
added. They are a variation of the widget API to handle its items, as
such the func() gets one more parameter: item, and the del_cb() gets
the item as event_info (that's why the public widget version got
event_info always NULL, to not confuse with this one!)
Widgets with items that makes sense to have tooltips got extra API:
* toolbar
* list
* gengrid
* genlist
SVN revision: 52173
2010-09-12 14:05:13 -07:00
|
|
|
Elm_Tooltip *tt;
|
2009-02-25 11:50:45 -08:00
|
|
|
|
2008-11-14 22:09:04 -08:00
|
|
|
API_ENTRY return;
|
2010-09-13 00:56:23 -07:00
|
|
|
EINA_LIST_FOREACH(sd->subobjs, l, child) elm_widget_theme(child);
|
2008-11-14 22:09:04 -08:00
|
|
|
if (sd->resize_obj) elm_widget_theme(sd->resize_obj);
|
|
|
|
if (sd->hover_obj) elm_widget_theme(sd->hover_obj);
|
2010-09-13 00:56:23 -07:00
|
|
|
EINA_LIST_FOREACH(sd->tooltips, l, tt) elm_tooltip_theme(tt);
|
2008-11-15 05:58:50 -08:00
|
|
|
if (sd->theme_func) sd->theme_func(obj);
|
2008-11-14 22:09:04 -08:00
|
|
|
}
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->on_focus_func = func;
|
|
|
|
sd->on_focus_data = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_on_change_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->on_change_func = func;
|
|
|
|
sd->on_change_data = data;
|
|
|
|
}
|
|
|
|
|
2008-10-17 07:40:54 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_on_show_region_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->on_show_region_func = func;
|
|
|
|
sd->on_show_region_data = data;
|
|
|
|
}
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_data_set(Evas_Object *obj, void *data)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->data = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void *
|
2009-02-25 07:54:26 -08:00
|
|
|
elm_widget_data_get(const Evas_Object *obj)
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return NULL;
|
|
|
|
return sd->data;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2008-10-06 18:23:49 -07:00
|
|
|
API_ENTRY return;
|
2009-02-02 21:09:03 -08:00
|
|
|
double scale, pscale = elm_widget_scale_get(sobj);
|
2010-05-11 18:03:46 -07:00
|
|
|
Elm_Theme *th, *pth = elm_widget_theme_get(sobj);
|
2009-10-17 23:03:03 -07:00
|
|
|
|
2008-10-22 07:11:59 -07:00
|
|
|
sd->subobjs = eina_list_append(sd->subobjs, sobj);
|
2008-10-06 18:23:49 -07:00
|
|
|
if (!sd->child_can_focus)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2008-10-06 18:23:49 -07:00
|
|
|
if (elm_widget_can_focus_get(sobj)) sd->child_can_focus = 1;
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
2010-03-22 14:36:59 -07:00
|
|
|
if (_elm_widget_is(sobj))
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2008-11-26 21:41:13 -08:00
|
|
|
Smart_Data *sd2 = evas_object_smart_data_get(sobj);
|
|
|
|
if (sd2)
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
2009-10-22 15:10:23 -07:00
|
|
|
if (sd2->parent_obj)
|
2010-09-13 00:56:23 -07:00
|
|
|
elm_widget_sub_object_del(sd2->parent_obj, sobj);
|
2008-11-26 21:41:13 -08:00
|
|
|
sd2->parent_obj = obj;
|
2008-10-06 18:23:49 -07:00
|
|
|
}
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
2010-03-22 14:36:59 -07:00
|
|
|
evas_object_data_set(sobj, "elm-parent", obj);
|
2008-11-26 21:41:13 -08:00
|
|
|
evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
|
2008-10-06 23:55:11 -07:00
|
|
|
evas_object_smart_callback_call(obj, "sub-object-add", sobj);
|
2009-02-02 21:09:03 -08:00
|
|
|
scale = elm_widget_scale_get(sobj);
|
2010-05-11 18:03:46 -07:00
|
|
|
th = elm_widget_theme_get(sobj);
|
|
|
|
if ((scale != pscale) || (th != pth)) elm_widget_theme(sobj);
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2010-03-22 14:36:59 -07:00
|
|
|
Evas_Object *sobj_parent;
|
2008-10-06 18:23:49 -07:00
|
|
|
API_ENTRY return;
|
2010-03-13 19:48:22 -08:00
|
|
|
if (!sobj) return;
|
2010-03-22 14:36:59 -07:00
|
|
|
|
|
|
|
sobj_parent = evas_object_data_del(sobj, "elm-parent");
|
|
|
|
if (sobj_parent != obj)
|
|
|
|
{
|
|
|
|
static int abort_on_warn = -1;
|
|
|
|
ERR("removing sub object %p from parent %p, "
|
|
|
|
"but elm-parent is different %p!",
|
|
|
|
sobj, obj, sobj_parent);
|
|
|
|
if (EINA_UNLIKELY(abort_on_warn == -1))
|
|
|
|
{
|
|
|
|
if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
|
|
|
|
else abort_on_warn = 0;
|
|
|
|
}
|
|
|
|
if (abort_on_warn == 1) abort();
|
|
|
|
}
|
2008-10-22 07:11:59 -07:00
|
|
|
sd->subobjs = eina_list_remove(sd->subobjs, sobj);
|
2008-10-06 18:23:49 -07:00
|
|
|
if (!sd->child_can_focus)
|
|
|
|
{
|
|
|
|
if (elm_widget_can_focus_get(sobj)) sd->child_can_focus = 0;
|
|
|
|
}
|
2010-03-22 14:36:59 -07:00
|
|
|
if (_elm_widget_is(sobj))
|
2008-10-24 19:11:06 -07:00
|
|
|
{
|
2008-11-26 21:41:13 -08:00
|
|
|
Smart_Data *sd2 = evas_object_smart_data_get(sobj);
|
2009-03-16 17:37:02 -07:00
|
|
|
if (sd2) sd2->parent_obj = NULL;
|
2008-10-24 19:11:06 -07:00
|
|
|
}
|
2010-09-13 00:56:23 -07:00
|
|
|
evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL,
|
|
|
|
_sub_obj_del, sd);
|
2008-10-06 23:55:11 -07:00
|
|
|
evas_object_smart_callback_call(obj, "sub-object-del", sobj);
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2008-10-06 18:23:49 -07:00
|
|
|
API_ENTRY return;
|
2008-10-07 23:38:20 -07:00
|
|
|
if (sd->resize_obj)
|
|
|
|
{
|
2010-03-22 14:36:59 -07:00
|
|
|
evas_object_data_del(sd->resize_obj, "elm-parent");
|
|
|
|
if (_elm_widget_is(sd->resize_obj))
|
2009-07-06 23:46:51 -07:00
|
|
|
{
|
|
|
|
Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
|
|
|
|
if (sd2) sd2->parent_obj = NULL;
|
|
|
|
}
|
2009-10-22 15:10:23 -07:00
|
|
|
evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_DEL,
|
2010-09-13 00:56:23 -07:00
|
|
|
_sub_obj_del, sd);
|
2009-10-22 15:10:23 -07:00
|
|
|
evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_MOUSE_DOWN,
|
2010-09-13 00:56:23 -07:00
|
|
|
_sub_obj_mouse_down, sd);
|
2008-10-07 23:38:20 -07:00
|
|
|
evas_object_smart_member_del(sd->resize_obj);
|
|
|
|
}
|
2008-10-06 18:23:49 -07:00
|
|
|
sd->resize_obj = sobj;
|
2008-10-07 23:38:20 -07:00
|
|
|
if (sd->resize_obj)
|
|
|
|
{
|
2010-03-22 14:36:59 -07:00
|
|
|
if (_elm_widget_is(sd->resize_obj))
|
2009-07-06 23:46:51 -07:00
|
|
|
{
|
|
|
|
Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
|
|
|
|
if (sd2) sd2->parent_obj = obj;
|
|
|
|
}
|
2008-10-24 19:11:06 -07:00
|
|
|
evas_object_clip_set(sobj, evas_object_clip_get(obj));
|
2008-10-07 23:38:20 -07:00
|
|
|
evas_object_smart_member_add(sobj, obj);
|
2010-09-13 00:56:23 -07:00
|
|
|
evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL,
|
|
|
|
_sub_obj_del, sd);
|
2009-10-22 15:10:23 -07:00
|
|
|
evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_DOWN,
|
2009-10-17 23:03:03 -07:00
|
|
|
_sub_obj_mouse_down, sd);
|
2008-10-07 23:38:20 -07:00
|
|
|
_smart_reconfigure(sd);
|
2010-03-22 14:36:59 -07:00
|
|
|
evas_object_data_set(sobj, "elm-parent", obj);
|
2008-10-07 23:38:20 -07:00
|
|
|
evas_object_smart_callback_call(obj, "sub-object-add", sobj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_hover_object_set(Evas_Object *obj, Evas_Object *sobj)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
if (sd->hover_obj)
|
2009-10-22 15:10:23 -07:00
|
|
|
{
|
|
|
|
evas_object_event_callback_del_full(sd->hover_obj, EVAS_CALLBACK_DEL,
|
|
|
|
_sub_obj_del, sd);
|
|
|
|
}
|
2008-10-07 23:38:20 -07:00
|
|
|
sd->hover_obj = sobj;
|
|
|
|
if (sd->hover_obj)
|
|
|
|
{
|
2010-09-13 00:56:23 -07:00
|
|
|
evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL,
|
|
|
|
_sub_obj_del, sd);
|
2008-10-07 23:38:20 -07:00
|
|
|
_smart_reconfigure(sd);
|
|
|
|
}
|
2008-10-06 18:23:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_can_focus_set(Evas_Object *obj, int can_focus)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->can_focus = can_focus;
|
2010-09-20 19:02:24 -07:00
|
|
|
if (can_focus)
|
|
|
|
{
|
|
|
|
evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN,
|
|
|
|
_propagate_event,
|
|
|
|
(void *)(long) EVAS_CALLBACK_KEY_DOWN);
|
|
|
|
evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_UP,
|
|
|
|
_propagate_event,
|
|
|
|
(void *)(long) EVAS_CALLBACK_KEY_UP);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
evas_object_event_callback_del(obj, EVAS_CALLBACK_KEY_DOWN,
|
|
|
|
_propagate_event);
|
|
|
|
evas_object_event_callback_del(obj, EVAS_CALLBACK_KEY_UP,
|
|
|
|
_propagate_event);
|
|
|
|
}
|
2008-10-06 18:23:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
2009-02-25 07:54:26 -08:00
|
|
|
elm_widget_can_focus_get(const Evas_Object *obj)
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return 0;
|
|
|
|
if (sd->can_focus) return 1;
|
|
|
|
if (sd->child_can_focus) return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Begins highlight on focused object.
There's still work to do here, particularly in the theme, but it has
something nice and fun to see the code working.
The idea behind this:
Window tracks focused object and sends the highlight object(s) to it. These
are simple edje objects, one on top, one below the focused widget for nice
effects. Widgets can choose to ignore the highlight and this will be sent to
the parent object, if it doesn't ignore it as well.
About the bottom object, it doesn't work now. For the most part, focused
widget will always be a member of some smart object, so stacking won't work
and the desired effect is nowhere to be seen. This will be worked out later.
To be done now:
- Let the theme for a widget define its own highlight, disabling if needed
the standard one for those objects.
- Needed base in code to allow animations when switching focus. All in theme.
- Properly test all widgets and fix some things that will most likely work
in weird ways, given the nature of Evas/Edje and how Elementary makes use
of them.
- Forgot the rest, stay tuned, test, report, give ideas, plant a tree.
Work started by glima, continued with some refactors by me when he
decided he needed vacations.
SVN revision: 52524
2010-09-20 15:18:58 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_highlight_ignore_set(Evas_Object *obj, Eina_Bool ignore)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->highlight_ignore = !!ignore;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
|
|
|
elm_widget_highlight_ignore_get(const Evas_Object *obj)
|
|
|
|
{
|
|
|
|
API_ENTRY return EINA_FALSE;
|
|
|
|
return sd->highlight_ignore;
|
|
|
|
}
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI int
|
2009-02-25 07:54:26 -08:00
|
|
|
elm_widget_focus_get(const Evas_Object *obj)
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return 0;
|
|
|
|
return sd->focused;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Evas_Object *
|
2009-02-25 07:54:26 -08:00
|
|
|
elm_widget_focused_object_get(const Evas_Object *obj)
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
2009-02-25 07:54:26 -08:00
|
|
|
const Evas_Object *subobj;
|
|
|
|
const Eina_List *l;
|
2008-10-06 18:23:49 -07:00
|
|
|
API_ENTRY return NULL;
|
2009-10-17 23:03:03 -07:00
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
if (!sd->focused) return NULL;
|
2009-02-25 07:54:26 -08:00
|
|
|
EINA_LIST_FOREACH(sd->subobjs, l, subobj)
|
|
|
|
{
|
|
|
|
Evas_Object *fobj = elm_widget_focused_object_get(subobj);
|
2008-10-06 18:23:49 -07:00
|
|
|
if (fobj) return fobj;
|
|
|
|
}
|
2009-02-25 07:54:26 -08:00
|
|
|
return (Evas_Object *)obj;
|
2008-10-06 18:23:49 -07:00
|
|
|
}
|
|
|
|
|
2008-11-18 02:11:57 -08:00
|
|
|
EAPI Evas_Object *
|
2009-02-25 07:54:26 -08:00
|
|
|
elm_widget_top_get(const Evas_Object *obj)
|
2008-11-18 02:11:57 -08:00
|
|
|
{
|
2010-03-16 18:08:39 -07:00
|
|
|
#if 1 // strict way
|
2008-11-18 02:11:57 -08:00
|
|
|
API_ENTRY return NULL;
|
|
|
|
if (sd->parent_obj) return elm_widget_top_get(sd->parent_obj);
|
2009-02-25 07:54:26 -08:00
|
|
|
return (Evas_Object *)obj;
|
2010-03-16 18:08:39 -07:00
|
|
|
#else // loose way
|
|
|
|
Smart_Data *sd = evas_object_smart_data_get(obj);
|
|
|
|
Evas_Object *par;
|
|
|
|
|
|
|
|
if (!obj) return NULL;
|
2010-03-22 14:36:59 -07:00
|
|
|
if ((sd) && _elm_widget_is(obj))
|
2010-03-16 18:08:39 -07:00
|
|
|
{
|
|
|
|
if ((sd->type) && (!strcmp(sd->type, "win")))
|
2010-09-13 00:56:23 -07:00
|
|
|
return (Evas_Object *)obj;
|
2010-03-16 18:08:39 -07:00
|
|
|
if (sd->parent_obj)
|
2010-09-13 00:56:23 -07:00
|
|
|
return elm_widget_top_get(sd->parent_obj);
|
2010-03-16 18:08:39 -07:00
|
|
|
}
|
|
|
|
par = evas_object_smart_parent_get(obj);
|
|
|
|
if (!par) return (Evas_Object *)obj;
|
|
|
|
return elm_widget_top_get(par);
|
|
|
|
#endif
|
2008-11-18 02:11:57 -08:00
|
|
|
}
|
|
|
|
|
2010-03-22 14:36:59 -07:00
|
|
|
EAPI Eina_Bool
|
|
|
|
elm_widget_is(const Evas_Object *obj)
|
|
|
|
{
|
|
|
|
return _elm_widget_is(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Evas_Object *
|
|
|
|
elm_widget_parent_widget_get(const Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object *parent;
|
|
|
|
|
|
|
|
if (_elm_widget_is(obj))
|
|
|
|
{
|
|
|
|
Smart_Data *sd = evas_object_smart_data_get(obj);
|
|
|
|
if (!sd) return NULL;
|
|
|
|
parent = sd->parent_obj;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
parent = evas_object_data_get(obj, "elm-parent");
|
2010-09-20 12:54:48 -07:00
|
|
|
if (!parent) parent = evas_object_smart_parent_get(obj);
|
2010-03-22 14:36:59 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
while (parent)
|
|
|
|
{
|
|
|
|
Evas_Object *elm_parent;
|
|
|
|
if (_elm_widget_is(parent)) break;
|
|
|
|
elm_parent = evas_object_data_get(parent, "elm-parent");
|
2010-09-13 00:56:23 -07:00
|
|
|
if (elm_parent) parent = elm_parent;
|
|
|
|
else parent = evas_object_smart_parent_get(parent);
|
2010-03-22 14:36:59 -07:00
|
|
|
}
|
|
|
|
return parent;
|
|
|
|
}
|
|
|
|
|
2010-09-20 19:02:24 -07:00
|
|
|
EAPI Eina_Bool
|
|
|
|
elm_widget_parent_event_propagate(Evas_Object *obj, Evas_Callback_Type type, void *event_info)
|
|
|
|
{
|
|
|
|
API_ENTRY return EINA_FALSE;
|
|
|
|
Evas_Object *parent = sd->parent_obj;
|
|
|
|
while (parent)
|
|
|
|
{
|
|
|
|
sd = evas_object_smart_data_get(parent);
|
|
|
|
if ((!sd) || (!_elm_widget_is(obj)))
|
|
|
|
return EINA_FALSE; //Not Elm Widget
|
|
|
|
if (sd->event_func && sd->event_func(parent, obj, type, event_info))
|
|
|
|
return EINA_TRUE;
|
|
|
|
parent = sd->parent_obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI int
|
|
|
|
elm_widget_focus_jump(Evas_Object *obj, int forward)
|
|
|
|
{
|
|
|
|
API_ENTRY return 0;
|
|
|
|
if (!elm_widget_can_focus_get(obj)) return 0;
|
2009-07-06 23:46:51 -07:00
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
/* if it has a focus func its an end-point widget like a button */
|
|
|
|
if (sd->focus_func)
|
|
|
|
{
|
2010-06-21 00:39:49 -07:00
|
|
|
if (!sd->focused)
|
|
|
|
{
|
|
|
|
focus_order++;
|
|
|
|
sd->focus_order = focus_order;
|
|
|
|
sd->focused = 1;
|
|
|
|
}
|
2008-10-06 18:23:49 -07:00
|
|
|
else sd->focused = 0;
|
|
|
|
if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
|
2008-12-30 08:19:46 -08:00
|
|
|
sd->focus_func(obj);
|
2008-10-06 18:23:49 -07:00
|
|
|
return sd->focused;
|
|
|
|
}
|
|
|
|
/* its some container */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int focus_next;
|
2009-07-06 23:46:51 -07:00
|
|
|
int noloop = 0;
|
2010-09-13 00:56:23 -07:00
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
focus_next = 0;
|
|
|
|
if (!sd->focused)
|
|
|
|
{
|
|
|
|
elm_widget_focus_set(obj, forward);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (forward)
|
|
|
|
{
|
2009-07-06 23:46:51 -07:00
|
|
|
if (elm_widget_can_focus_get(sd->resize_obj))
|
|
|
|
{
|
|
|
|
if ((focus_next) &&
|
|
|
|
(!elm_widget_disabled_get(sd->resize_obj)))
|
|
|
|
{
|
|
|
|
/* the previous focused item was unfocused - so focus
|
|
|
|
* the next one (that can be focused) */
|
2009-10-22 15:10:23 -07:00
|
|
|
if (elm_widget_focus_jump(sd->resize_obj, forward))
|
2010-09-13 00:56:23 -07:00
|
|
|
return 1;
|
2009-07-06 23:46:51 -07:00
|
|
|
else noloop = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (elm_widget_focus_get(sd->resize_obj))
|
|
|
|
{
|
|
|
|
/* jump to the next focused item or focus this item */
|
2009-10-22 15:10:23 -07:00
|
|
|
if (elm_widget_focus_jump(sd->resize_obj, forward))
|
2010-09-13 00:56:23 -07:00
|
|
|
return 1;
|
2009-07-06 23:46:51 -07:00
|
|
|
/* it returned 0 - it got to the last item and is past it */
|
|
|
|
focus_next = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!noloop)
|
|
|
|
{
|
2009-02-25 11:50:45 -08:00
|
|
|
const Eina_List *l;
|
|
|
|
Evas_Object *child;
|
|
|
|
EINA_LIST_FOREACH(sd->subobjs, l, child)
|
2009-07-06 23:46:51 -07:00
|
|
|
{
|
|
|
|
if (elm_widget_can_focus_get(child))
|
|
|
|
{
|
|
|
|
if ((focus_next) &&
|
|
|
|
(!elm_widget_disabled_get(child)))
|
|
|
|
{
|
|
|
|
/* the previous focused item was unfocused - so focus
|
|
|
|
* the next one (that can be focused) */
|
2009-10-22 15:10:23 -07:00
|
|
|
if (elm_widget_focus_jump(child, forward))
|
2010-09-13 00:56:23 -07:00
|
|
|
return 1;
|
2009-07-06 23:46:51 -07:00
|
|
|
else break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (elm_widget_focus_get(child))
|
|
|
|
{
|
|
|
|
/* jump to the next focused item or focus this item */
|
2009-10-22 15:10:23 -07:00
|
|
|
if (elm_widget_focus_jump(child, forward))
|
2010-09-13 00:56:23 -07:00
|
|
|
return 1;
|
2009-07-06 23:46:51 -07:00
|
|
|
/* it returned 0 - it got to the last item and is past it */
|
|
|
|
focus_next = 1;
|
|
|
|
}
|
|
|
|
}
|
2008-12-30 16:43:06 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-25 11:50:45 -08:00
|
|
|
const Eina_List *l;
|
|
|
|
Evas_Object *child;
|
|
|
|
|
|
|
|
EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
2009-02-25 11:50:45 -08:00
|
|
|
if (elm_widget_can_focus_get(child))
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
|
|
|
if ((focus_next) &&
|
2009-02-25 11:50:45 -08:00
|
|
|
(!elm_widget_disabled_get(child)))
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
|
|
|
/* the previous focused item was unfocused - so focus
|
|
|
|
* the next one (that can be focused) */
|
2009-10-22 15:10:23 -07:00
|
|
|
if (elm_widget_focus_jump(child, forward))
|
2010-09-13 00:56:23 -07:00
|
|
|
return 1;
|
2008-10-06 18:23:49 -07:00
|
|
|
else break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-25 11:50:45 -08:00
|
|
|
if (elm_widget_focus_get(child))
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
|
|
|
/* jump to the next focused item or focus this item */
|
2009-10-22 15:10:23 -07:00
|
|
|
if (elm_widget_focus_jump(child, forward))
|
2010-09-13 00:56:23 -07:00
|
|
|
return 1;
|
2008-10-06 18:23:49 -07:00
|
|
|
/* it returned 0 - it got to the last item and is past it */
|
|
|
|
focus_next = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-07-06 23:46:51 -07:00
|
|
|
if (!l)
|
|
|
|
{
|
2008-12-30 16:43:06 -08:00
|
|
|
if (elm_widget_can_focus_get(sd->resize_obj))
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
|
|
|
if ((focus_next) &&
|
2008-12-30 16:43:06 -08:00
|
|
|
(!elm_widget_disabled_get(sd->resize_obj)))
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
|
|
|
/* the previous focused item was unfocused - so focus
|
|
|
|
* the next one (that can be focused) */
|
2009-10-22 15:10:23 -07:00
|
|
|
if (elm_widget_focus_jump(sd->resize_obj, forward))
|
2010-09-13 00:56:23 -07:00
|
|
|
return 1;
|
2008-10-06 18:23:49 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-12-30 16:43:06 -08:00
|
|
|
if (elm_widget_focus_get(sd->resize_obj))
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
|
|
|
/* jump to the next focused item or focus this item */
|
2009-10-22 15:10:23 -07:00
|
|
|
if (elm_widget_focus_jump(sd->resize_obj, forward))
|
2010-09-13 00:56:23 -07:00
|
|
|
return 1;
|
2008-10-06 18:23:49 -07:00
|
|
|
/* it returned 0 - it got to the last item and is past it */
|
|
|
|
focus_next = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-07-06 23:46:51 -07:00
|
|
|
}
|
2008-10-06 18:23:49 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* no next item can be focused */
|
2008-12-30 08:19:46 -08:00
|
|
|
if (sd->focused)
|
|
|
|
{
|
2009-07-06 23:46:51 -07:00
|
|
|
sd->focused = 0;
|
|
|
|
if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
|
2008-12-30 08:19:46 -08:00
|
|
|
}
|
2008-10-06 18:23:49 -07:00
|
|
|
return 0;
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
|
|
|
|
2010-06-15 07:11:13 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_signal_emit(Evas_Object *obj, const char *emission, const char *source)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
if (!sd->signal_func) return;
|
|
|
|
sd->signal_func(obj, emission, source);
|
|
|
|
}
|
|
|
|
|
2010-06-25 15:38:32 -07:00
|
|
|
EAPI void
|
2010-06-28 08:32:20 -07:00
|
|
|
elm_widget_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
|
2010-06-25 15:38:32 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return;
|
2010-06-28 08:32:20 -07:00
|
|
|
if (!sd->callback_add_func) return;
|
|
|
|
sd->callback_add_func(obj, emission, source, func, data);
|
2010-06-25 15:38:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void *
|
2010-06-28 08:32:20 -07:00
|
|
|
elm_widget_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source))
|
2010-06-25 15:38:32 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return NULL;
|
2010-06-28 08:32:20 -07:00
|
|
|
if (!sd->callback_del_func) return NULL;
|
|
|
|
return sd->callback_del_func(obj, emission, source, func);
|
2010-06-25 15:38:32 -07:00
|
|
|
}
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_focus_set(Evas_Object *obj, int first)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
if (!sd->focused)
|
|
|
|
{
|
2010-06-21 00:39:49 -07:00
|
|
|
focus_order++;
|
|
|
|
sd->focus_order = focus_order;
|
2008-10-06 18:23:49 -07:00
|
|
|
sd->focused = 1;
|
|
|
|
if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
|
|
|
|
}
|
|
|
|
if (sd->focus_func)
|
|
|
|
{
|
|
|
|
sd->focus_func(obj);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (first)
|
|
|
|
{
|
2009-07-06 23:46:51 -07:00
|
|
|
if ((elm_widget_can_focus_get(sd->resize_obj)) &&
|
|
|
|
(!elm_widget_disabled_get(sd->resize_obj)))
|
|
|
|
{
|
|
|
|
elm_widget_focus_set(sd->resize_obj, first);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-25 11:50:45 -08:00
|
|
|
const Eina_List *l;
|
|
|
|
Evas_Object *child;
|
|
|
|
EINA_LIST_FOREACH(sd->subobjs, l, child)
|
2009-07-06 23:46:51 -07:00
|
|
|
{
|
|
|
|
if ((elm_widget_can_focus_get(child)) &&
|
|
|
|
(!elm_widget_disabled_get(child)))
|
|
|
|
{
|
|
|
|
elm_widget_focus_set(child, first);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-10-06 18:23:49 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-25 11:50:45 -08:00
|
|
|
const Eina_List *l;
|
|
|
|
Evas_Object *child;
|
|
|
|
EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
2009-02-25 11:50:45 -08:00
|
|
|
if ((elm_widget_can_focus_get(child)) &&
|
|
|
|
(!elm_widget_disabled_get(child)))
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
2009-02-25 11:50:45 -08:00
|
|
|
elm_widget_focus_set(child, first);
|
2008-10-06 18:23:49 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-07-06 23:46:51 -07:00
|
|
|
if (!l)
|
|
|
|
{
|
|
|
|
if ((elm_widget_can_focus_get(sd->resize_obj)) &&
|
|
|
|
(!elm_widget_disabled_get(sd->resize_obj)))
|
|
|
|
{
|
|
|
|
elm_widget_focus_set(sd->resize_obj, first);
|
|
|
|
}
|
|
|
|
}
|
2008-10-06 18:23:49 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Evas_Object *
|
2009-02-25 07:54:26 -08:00
|
|
|
elm_widget_parent_get(const Evas_Object *obj)
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return NULL;
|
|
|
|
return sd->parent_obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_focused_object_clear(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
if (!sd->focused) return;
|
2008-12-30 08:19:46 -08:00
|
|
|
if (elm_widget_focus_get(sd->resize_obj))
|
2010-09-13 00:56:23 -07:00
|
|
|
elm_widget_focused_object_clear(sd->resize_obj);
|
2008-12-30 08:19:46 -08:00
|
|
|
else
|
|
|
|
{
|
2009-02-25 11:50:45 -08:00
|
|
|
const Eina_List *l;
|
|
|
|
Evas_Object *child;
|
|
|
|
EINA_LIST_FOREACH(sd->subobjs, l, child)
|
2009-07-06 23:46:51 -07:00
|
|
|
{
|
|
|
|
if (elm_widget_focus_get(child))
|
|
|
|
{
|
|
|
|
elm_widget_focused_object_clear(child);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-10-06 18:23:49 -07:00
|
|
|
}
|
2008-12-30 08:19:46 -08:00
|
|
|
sd->focused = 0;
|
|
|
|
if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
|
2008-10-06 18:23:49 -07:00
|
|
|
if (sd->focus_func) sd->focus_func(obj);
|
2008-12-30 08:19:46 -08:00
|
|
|
}
|
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_focus_steal(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object *parent, *o;
|
|
|
|
API_ENTRY return;
|
2009-10-17 23:03:03 -07:00
|
|
|
|
2008-10-06 18:23:49 -07:00
|
|
|
if (sd->focused) return;
|
|
|
|
if (sd->disabled) return;
|
|
|
|
parent = obj;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
o = elm_widget_parent_get(parent);
|
|
|
|
if (!o) break;
|
2009-07-06 23:46:51 -07:00
|
|
|
sd = evas_object_smart_data_get(o);
|
|
|
|
if (sd->focused) break;
|
2008-10-06 18:23:49 -07:00
|
|
|
parent = o;
|
|
|
|
}
|
2008-12-30 08:19:46 -08:00
|
|
|
if (!elm_widget_parent_get(parent))
|
|
|
|
elm_widget_focused_object_clear(parent);
|
|
|
|
else
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
2009-07-06 23:46:51 -07:00
|
|
|
parent = elm_widget_parent_get(parent);
|
|
|
|
sd = evas_object_smart_data_get(parent);
|
|
|
|
if (elm_widget_focus_get(sd->resize_obj))
|
2009-10-22 05:04:55 -07:00
|
|
|
{
|
|
|
|
elm_widget_focused_object_clear(sd->resize_obj);
|
|
|
|
}
|
2009-07-06 23:46:51 -07:00
|
|
|
else
|
|
|
|
{
|
2009-02-25 11:50:45 -08:00
|
|
|
const Eina_List *l;
|
|
|
|
Evas_Object *child;
|
|
|
|
EINA_LIST_FOREACH(sd->subobjs, l, child)
|
2009-07-06 23:46:51 -07:00
|
|
|
{
|
|
|
|
if (elm_widget_focus_get(child))
|
|
|
|
{
|
|
|
|
elm_widget_focused_object_clear(child);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-10-06 18:23:49 -07:00
|
|
|
}
|
2010-09-13 00:56:23 -07:00
|
|
|
_parent_focus(obj);
|
2008-10-06 18:23:49 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_activate(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
elm_widget_change(obj);
|
|
|
|
if (sd->activate_func) sd->activate_func(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_change(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
elm_widget_change(elm_widget_parent_get(obj));
|
|
|
|
if (sd->on_change_func) sd->on_change_func(sd->on_change_data, obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_disabled_set(Evas_Object *obj, int disabled)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
2009-10-17 23:03:03 -07:00
|
|
|
|
2009-08-26 09:52:53 -07:00
|
|
|
if (sd->disabled == disabled) return;
|
2008-10-06 18:23:49 -07:00
|
|
|
sd->disabled = disabled;
|
|
|
|
if (sd->focused)
|
|
|
|
{
|
|
|
|
Evas_Object *o, *parent;
|
|
|
|
|
|
|
|
parent = obj;
|
2009-07-06 23:46:51 -07:00
|
|
|
for (;;)
|
|
|
|
{
|
2008-10-06 18:23:49 -07:00
|
|
|
o = elm_widget_parent_get(parent);
|
|
|
|
if (!o) break;
|
|
|
|
parent = o;
|
|
|
|
}
|
|
|
|
elm_widget_focus_jump(parent, 1);
|
|
|
|
}
|
|
|
|
if (sd->disable_func) sd->disable_func(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
2009-02-25 07:54:26 -08:00
|
|
|
elm_widget_disabled_get(const Evas_Object *obj)
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return 0;
|
|
|
|
return sd->disabled;
|
|
|
|
}
|
|
|
|
|
2008-10-17 07:40:54 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_show_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
if ((x == sd->rx) && (y == sd->ry) && (w == sd->rw) && (h == sd->rh)) return;
|
|
|
|
sd->rx = x;
|
|
|
|
sd->ry = y;
|
|
|
|
sd->rw = w;
|
|
|
|
sd->rh = h;
|
2009-10-22 15:10:23 -07:00
|
|
|
if (sd->on_show_region_func)
|
2010-09-13 00:56:23 -07:00
|
|
|
sd->on_show_region_func(sd->on_show_region_data, obj);
|
2008-10-17 07:40:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2009-02-25 07:54:26 -08:00
|
|
|
elm_widget_show_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
|
2008-10-17 07:40:54 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
if (x) *x = sd->rx;
|
|
|
|
if (y) *y = sd->ry;
|
|
|
|
if (w) *w = sd->rw;
|
|
|
|
if (h) *h = sd->rh;
|
|
|
|
}
|
|
|
|
|
2008-11-18 02:11:57 -08:00
|
|
|
EAPI void
|
|
|
|
elm_widget_scroll_hold_push(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->scroll_hold++;
|
2009-03-20 08:08:33 -07:00
|
|
|
if (sd->scroll_hold == 1)
|
2010-09-13 00:56:23 -07:00
|
|
|
evas_object_smart_callback_call(obj, "scroll-hold-on", obj);
|
2008-11-18 02:11:57 -08:00
|
|
|
if (sd->parent_obj) elm_widget_scroll_hold_push(sd->parent_obj);
|
2009-09-07 21:41:36 -07:00
|
|
|
// FIXME: on delete/reparent hold pop
|
2008-11-18 02:11:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_scroll_hold_pop(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->scroll_hold--;
|
2009-03-20 08:08:33 -07:00
|
|
|
if (sd->scroll_hold < 0) sd->scroll_hold = 0;
|
|
|
|
if (sd->scroll_hold == 0)
|
2010-09-13 00:56:23 -07:00
|
|
|
evas_object_smart_callback_call(obj, "scroll-hold-off", obj);
|
2008-11-18 02:11:57 -08:00
|
|
|
if (sd->parent_obj) elm_widget_scroll_hold_pop(sd->parent_obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
2009-02-25 07:54:26 -08:00
|
|
|
elm_widget_scroll_hold_get(const Evas_Object *obj)
|
2008-11-18 02:11:57 -08:00
|
|
|
{
|
|
|
|
API_ENTRY return 0;
|
|
|
|
return sd->scroll_hold;
|
|
|
|
}
|
|
|
|
|
2009-03-20 08:08:33 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_scroll_freeze_push(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->scroll_freeze++;
|
|
|
|
if (sd->scroll_freeze == 1)
|
2010-09-13 00:56:23 -07:00
|
|
|
evas_object_smart_callback_call(obj, "scroll-freeze-on", obj);
|
2009-03-20 08:08:33 -07:00
|
|
|
if (sd->parent_obj) elm_widget_scroll_freeze_push(sd->parent_obj);
|
2009-09-07 21:41:36 -07:00
|
|
|
// FIXME: on delete/reparent freeze pop
|
2009-03-20 08:08:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_scroll_freeze_pop(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->scroll_freeze--;
|
|
|
|
if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
|
|
|
|
if (sd->scroll_freeze == 0)
|
2010-09-13 00:56:23 -07:00
|
|
|
evas_object_smart_callback_call(obj, "scroll-freeze-off", obj);
|
2009-03-20 08:08:33 -07:00
|
|
|
if (sd->parent_obj) elm_widget_scroll_freeze_pop(sd->parent_obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
|
|
|
elm_widget_scroll_freeze_get(const Evas_Object *obj)
|
|
|
|
{
|
|
|
|
API_ENTRY return 0;
|
|
|
|
return sd->scroll_freeze;
|
|
|
|
}
|
|
|
|
|
2009-02-02 21:09:03 -08:00
|
|
|
EAPI void
|
|
|
|
elm_widget_scale_set(Evas_Object *obj, double scale)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
if (scale <= 0.0) scale = 0.0;
|
|
|
|
if (sd->scale != scale)
|
|
|
|
{
|
2009-07-06 23:46:51 -07:00
|
|
|
sd->scale = scale;
|
|
|
|
elm_widget_theme(obj);
|
2009-02-02 21:09:03 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI double
|
2009-02-25 07:54:26 -08:00
|
|
|
elm_widget_scale_get(const Evas_Object *obj)
|
2009-02-02 21:09:03 -08:00
|
|
|
{
|
|
|
|
API_ENTRY return 1.0;
|
2010-06-21 00:39:49 -07:00
|
|
|
// FIXME: save walking up the tree by storing/caching parent scale
|
2009-06-12 15:55:06 -07:00
|
|
|
if (sd->scale == 0.0)
|
|
|
|
{
|
|
|
|
if (sd->parent_obj)
|
2010-09-13 00:56:23 -07:00
|
|
|
return elm_widget_scale_get(sd->parent_obj);
|
2009-06-12 15:55:06 -07:00
|
|
|
else
|
2010-09-13 00:56:23 -07:00
|
|
|
return 1.0;
|
2009-06-12 15:55:06 -07:00
|
|
|
}
|
2009-02-02 21:09:03 -08:00
|
|
|
return sd->scale;
|
|
|
|
}
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
if (sd->theme != th)
|
|
|
|
{
|
|
|
|
if (sd->theme) elm_theme_free(sd->theme);
|
|
|
|
sd->theme = th;
|
|
|
|
if (th) th->ref++;
|
|
|
|
elm_widget_theme(obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Elm_Theme *
|
|
|
|
elm_widget_theme_get(const Evas_Object *obj)
|
|
|
|
{
|
|
|
|
API_ENTRY return NULL;
|
|
|
|
if (!sd->theme)
|
|
|
|
{
|
|
|
|
if (sd->parent_obj)
|
2010-09-13 00:56:23 -07:00
|
|
|
return elm_widget_theme_get(sd->parent_obj);
|
2010-05-11 18:03:46 -07:00
|
|
|
else
|
2010-09-13 00:56:23 -07:00
|
|
|
return NULL;
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
return sd->theme;
|
|
|
|
}
|
|
|
|
|
2009-04-22 21:03:27 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_style_set(Evas_Object *obj, const char *style)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
2010-09-13 00:56:23 -07:00
|
|
|
|
2010-03-13 13:01:26 -08:00
|
|
|
if (eina_stringshare_replace(&sd->style, style))
|
2010-09-13 00:56:23 -07:00
|
|
|
elm_widget_theme(obj);
|
2009-04-22 21:03:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const char *
|
|
|
|
elm_widget_style_get(const Evas_Object *obj)
|
|
|
|
{
|
2009-04-22 21:10:43 -07:00
|
|
|
API_ENTRY return "";
|
2009-04-22 21:03:27 -07:00
|
|
|
if (sd->style) return sd->style;
|
|
|
|
return "default";
|
|
|
|
}
|
|
|
|
|
2009-05-13 05:21:52 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_type_set(Evas_Object *obj, const char *type)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
2010-03-13 13:01:26 -08:00
|
|
|
eina_stringshare_replace(&sd->type, type);
|
2009-05-13 05:21:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const char *
|
|
|
|
elm_widget_type_get(const Evas_Object *obj)
|
|
|
|
{
|
|
|
|
API_ENTRY return "";
|
|
|
|
if (sd->type) return sd->type;
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI void
|
Tooltips: split owner/eventarea, allow subitems to have indepentent tooltips.
Now owner widget (elm_widget) is just used to listen for theme changes
and create/destroy the tooltip data. The actual mouse events operates
on all Evas_Object and is the one where tooltip data is actually
stored.
The public API is basically the same, just the event_info is now NULL
to avoid confusion.
The internal API introduces elm_object_sub_tooltip_content_cb_set()
and as the first parameter the eventarea. While this may be confusing,
as the second parameter is the actual elementary object, it is the one
that all other calls receive, like elm_object_tooltip_hide() or
elm_object_tooltip_unset(), thus it does make sense to have such order.
Also internal API, elm_widget_item_tooltip_* functions were
added. They are a variation of the widget API to handle its items, as
such the func() gets one more parameter: item, and the del_cb() gets
the item as event_info (that's why the public widget version got
event_info always NULL, to not confuse with this one!)
Widgets with items that makes sense to have tooltips got extra API:
* toolbar
* list
* gengrid
* genlist
SVN revision: 52173
2010-09-12 14:05:13 -07:00
|
|
|
elm_widget_tooltip_add(Evas_Object *obj, Elm_Tooltip *tt)
|
2010-09-10 17:52:33 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return;
|
Tooltips: split owner/eventarea, allow subitems to have indepentent tooltips.
Now owner widget (elm_widget) is just used to listen for theme changes
and create/destroy the tooltip data. The actual mouse events operates
on all Evas_Object and is the one where tooltip data is actually
stored.
The public API is basically the same, just the event_info is now NULL
to avoid confusion.
The internal API introduces elm_object_sub_tooltip_content_cb_set()
and as the first parameter the eventarea. While this may be confusing,
as the second parameter is the actual elementary object, it is the one
that all other calls receive, like elm_object_tooltip_hide() or
elm_object_tooltip_unset(), thus it does make sense to have such order.
Also internal API, elm_widget_item_tooltip_* functions were
added. They are a variation of the widget API to handle its items, as
such the func() gets one more parameter: item, and the del_cb() gets
the item as event_info (that's why the public widget version got
event_info always NULL, to not confuse with this one!)
Widgets with items that makes sense to have tooltips got extra API:
* toolbar
* list
* gengrid
* genlist
SVN revision: 52173
2010-09-12 14:05:13 -07:00
|
|
|
sd->tooltips = eina_list_append(sd->tooltips, tt);
|
|
|
|
}
|
|
|
|
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI void
|
Tooltips: split owner/eventarea, allow subitems to have indepentent tooltips.
Now owner widget (elm_widget) is just used to listen for theme changes
and create/destroy the tooltip data. The actual mouse events operates
on all Evas_Object and is the one where tooltip data is actually
stored.
The public API is basically the same, just the event_info is now NULL
to avoid confusion.
The internal API introduces elm_object_sub_tooltip_content_cb_set()
and as the first parameter the eventarea. While this may be confusing,
as the second parameter is the actual elementary object, it is the one
that all other calls receive, like elm_object_tooltip_hide() or
elm_object_tooltip_unset(), thus it does make sense to have such order.
Also internal API, elm_widget_item_tooltip_* functions were
added. They are a variation of the widget API to handle its items, as
such the func() gets one more parameter: item, and the del_cb() gets
the item as event_info (that's why the public widget version got
event_info always NULL, to not confuse with this one!)
Widgets with items that makes sense to have tooltips got extra API:
* toolbar
* list
* gengrid
* genlist
SVN revision: 52173
2010-09-12 14:05:13 -07:00
|
|
|
elm_widget_tooltip_del(Evas_Object *obj, Elm_Tooltip *tt)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
sd->tooltips = eina_list_remove(sd->tooltips, tt);
|
2010-09-10 17:52:33 -07:00
|
|
|
}
|
2010-05-07 06:21:45 -07:00
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_drag_lock_x_set(Evas_Object *obj, Eina_Bool lock)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
if (sd->drag_x_locked == lock) return;
|
|
|
|
sd->drag_x_locked = lock;
|
|
|
|
if (sd->drag_x_locked) _propagate_x_drag_lock(obj, 1);
|
|
|
|
else _propagate_x_drag_lock(obj, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_widget_drag_lock_y_set(Evas_Object *obj, Eina_Bool lock)
|
|
|
|
{
|
|
|
|
API_ENTRY return;
|
|
|
|
if (sd->drag_y_locked == lock) return;
|
|
|
|
sd->drag_y_locked = lock;
|
|
|
|
if (sd->drag_y_locked) _propagate_y_drag_lock(obj, 1);
|
|
|
|
else _propagate_y_drag_lock(obj, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
2010-07-10 15:05:37 -07:00
|
|
|
elm_widget_drag_lock_x_get(const Evas_Object *obj)
|
2010-05-07 06:21:45 -07:00
|
|
|
{
|
2010-06-05 06:12:45 -07:00
|
|
|
API_ENTRY return EINA_FALSE;
|
2010-05-07 06:21:45 -07:00
|
|
|
return sd->drag_x_locked;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
2010-07-10 15:05:37 -07:00
|
|
|
elm_widget_drag_lock_y_get(const Evas_Object *obj)
|
2010-05-07 06:21:45 -07:00
|
|
|
{
|
2010-06-05 06:12:45 -07:00
|
|
|
API_ENTRY return EINA_FALSE;
|
2010-05-07 06:21:45 -07:00
|
|
|
return sd->drag_y_locked;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
2010-07-10 15:05:37 -07:00
|
|
|
elm_widget_drag_child_locked_x_get(const Evas_Object *obj)
|
2010-05-07 06:21:45 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return 0;
|
|
|
|
return sd->child_drag_x_locked;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
2010-07-10 15:05:37 -07:00
|
|
|
elm_widget_drag_child_locked_y_get(const Evas_Object *obj)
|
2010-05-07 06:21:45 -07:00
|
|
|
{
|
|
|
|
API_ENTRY return 0;
|
|
|
|
return sd->child_drag_y_locked;
|
|
|
|
}
|
|
|
|
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI int
|
|
|
|
elm_widget_theme_object_set(Evas_Object *obj, Evas_Object *edj, const char *wname, const char *welement, const char *wstyle)
|
|
|
|
{
|
|
|
|
return _elm_theme_object_set(obj, edj, wname, welement, wstyle);
|
|
|
|
}
|
2010-05-07 06:21:45 -07:00
|
|
|
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI Eina_Bool
|
|
|
|
elm_widget_type_check(const Evas_Object *obj, const char *type)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2010-09-13 00:56:23 -07:00
|
|
|
const char *provided, *expected = "(unknown)";
|
|
|
|
static int abort_on_warn = -1;
|
|
|
|
provided = elm_widget_type_get(obj);
|
|
|
|
if (EINA_LIKELY(provided == type)) return EINA_TRUE;
|
|
|
|
if (type) expected = type;
|
|
|
|
if ((!provided) || (provided[0] == 0))
|
2008-10-06 18:23:49 -07:00
|
|
|
{
|
2010-09-13 00:56:23 -07:00
|
|
|
provided = evas_object_type_get(obj);
|
|
|
|
if ((!provided) || (provided[0] == 0))
|
|
|
|
provided = "(unknown)";
|
2008-10-07 23:38:20 -07:00
|
|
|
}
|
2010-09-13 00:56:23 -07:00
|
|
|
ERR("Passing Object: %p, of type: '%s' when expecting type: '%s'", obj, provided, expected);
|
|
|
|
if (abort_on_warn == -1)
|
2008-10-07 23:38:20 -07:00
|
|
|
{
|
2010-09-13 00:56:23 -07:00
|
|
|
if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
|
|
|
|
else abort_on_warn = 0;
|
2008-10-07 23:38:20 -07:00
|
|
|
}
|
2010-09-13 00:56:23 -07:00
|
|
|
if (abort_on_warn == 1) abort();
|
|
|
|
return EINA_FALSE;
|
2008-09-29 23:58:56 -07:00
|
|
|
}
|
|
|
|
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI Eina_List *
|
|
|
|
elm_widget_stringlist_get(const char *str)
|
2010-06-21 00:39:49 -07:00
|
|
|
{
|
2010-09-13 00:56:23 -07:00
|
|
|
Eina_List *list = NULL;
|
|
|
|
const char *s, *b;
|
|
|
|
if (!str) return NULL;
|
|
|
|
for (b = s = str; 1; s++)
|
2010-06-21 00:39:49 -07:00
|
|
|
{
|
2010-09-13 00:56:23 -07:00
|
|
|
if ((*s == ' ') || (*s == 0))
|
|
|
|
{
|
|
|
|
char *t = malloc(s - b + 1);
|
|
|
|
if (t)
|
|
|
|
{
|
|
|
|
strncpy(t, b, s - b);
|
|
|
|
t[s - b] = 0;
|
|
|
|
list = eina_list_append(list, eina_stringshare_add(t));
|
|
|
|
free(t);
|
|
|
|
}
|
|
|
|
b = s + 1;
|
|
|
|
}
|
|
|
|
if (*s == 0) break;
|
2010-06-21 00:39:49 -07:00
|
|
|
}
|
2010-09-13 00:56:23 -07:00
|
|
|
return list;
|
2010-06-21 00:39:49 -07:00
|
|
|
}
|
|
|
|
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI void
|
|
|
|
elm_widget_stringlist_free(Eina_List *list)
|
2010-06-23 19:54:03 -07:00
|
|
|
{
|
2010-09-13 00:56:23 -07:00
|
|
|
const char *s;
|
|
|
|
EINA_LIST_FREE(list, s) eina_stringshare_del(s);
|
2010-06-23 19:54:03 -07:00
|
|
|
}
|
|
|
|
|
2010-09-13 00:56:23 -07:00
|
|
|
/**
|
|
|
|
* Allocate a new Elm_Widget_Item-derived structure.
|
|
|
|
*
|
|
|
|
* The goal of this structure is to provide common ground for actions
|
|
|
|
* that a widget item have, such as the owner widget, callback to
|
|
|
|
* notify deletion, data pointer and maybe more.
|
|
|
|
*
|
|
|
|
* @param widget the owner widget that holds this item, must be an elm_widget!
|
|
|
|
* @param alloc_size any number greater than sizeof(Elm_Widget_Item) that will
|
|
|
|
* be used to allocate memory.
|
|
|
|
*
|
|
|
|
* @return allocated memory that is already zeroed out, or NULL on errors.
|
|
|
|
*
|
|
|
|
* @see elm_widget_item_new() convenience macro.
|
|
|
|
* @see elm_widget_item_del() to release memory.
|
|
|
|
*/
|
|
|
|
EAPI Elm_Widget_Item *
|
|
|
|
_elm_widget_item_new(Evas_Object *widget, size_t alloc_size)
|
2008-09-29 23:58:56 -07:00
|
|
|
{
|
2010-09-13 00:56:23 -07:00
|
|
|
Elm_Widget_Item *item;
|
2010-09-09 18:54:05 -07:00
|
|
|
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(alloc_size < sizeof(Elm_Widget_Item), NULL);
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(!_elm_widget_is(widget), NULL);
|
|
|
|
|
|
|
|
item = calloc(1, alloc_size);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(item, NULL);
|
|
|
|
|
|
|
|
EINA_MAGIC_SET(item, ELM_WIDGET_ITEM_MAGIC);
|
|
|
|
item->widget = widget;
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Releases widget item memory, calling back del_cb() if it exists.
|
|
|
|
*
|
|
|
|
* If there is a Elm_Widget_Item::del_cb, then it will be called prior
|
|
|
|
* to memory release. Note that elm_widget_item_pre_notify_del() calls
|
|
|
|
* this function and then unset it, thus being useful for 2 step
|
|
|
|
* cleanup whenever the del_cb may use any of the data that must be
|
|
|
|
* deleted from item.
|
|
|
|
*
|
|
|
|
* The Elm_Widget_Item::view will be deleted (evas_object_del()) if it
|
|
|
|
* is presented!
|
|
|
|
*
|
|
|
|
* @param item a valid #Elm_Widget_Item to be deleted.
|
|
|
|
* @see elm_widget_item_del() convenience macro.
|
|
|
|
*/
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI void
|
2010-09-09 18:54:05 -07:00
|
|
|
_elm_widget_item_del(Elm_Widget_Item *item)
|
|
|
|
{
|
|
|
|
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
|
|
|
|
|
|
|
|
if (item->del_cb)
|
|
|
|
item->del_cb((void *)item->data, item->widget, item);
|
|
|
|
|
|
|
|
if (item->view)
|
|
|
|
evas_object_del(item->view);
|
|
|
|
|
|
|
|
EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
|
|
|
|
free(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Notify object will be deleted without actually deleting it.
|
|
|
|
*
|
|
|
|
* This function will callback Elm_Widget_Item::del_cb if it is set
|
|
|
|
* and then unset it so it is not called twice (ie: from
|
|
|
|
* elm_widget_item_del()).
|
|
|
|
*
|
|
|
|
* @param item a valid #Elm_Widget_Item to be notified
|
|
|
|
* @see elm_widget_item_pre_notify_del() convenience macro.
|
|
|
|
*/
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI void
|
2010-09-09 18:54:05 -07:00
|
|
|
_elm_widget_item_pre_notify_del(Elm_Widget_Item *item)
|
|
|
|
{
|
|
|
|
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
|
|
|
|
if (!item->del_cb) return;
|
|
|
|
item->del_cb((void *)item->data, item->widget, item);
|
|
|
|
item->del_cb = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the function to notify when item is being deleted.
|
|
|
|
*
|
|
|
|
* This function will complain if there was a callback set already,
|
|
|
|
* however it will set the new one.
|
|
|
|
*
|
|
|
|
* The callback will be called from elm_widget_item_pre_notify_del()
|
|
|
|
* or elm_widget_item_del() will be called with:
|
|
|
|
* - data: the Elm_Widget_Item::data value.
|
|
|
|
* - obj: the Elm_Widget_Item::widget evas object.
|
|
|
|
* - event_info: the item being deleted.
|
|
|
|
*
|
|
|
|
* @param item a valid #Elm_Widget_Item to be notified
|
|
|
|
* @see elm_widget_item_del_cb_set() convenience macro.
|
|
|
|
*/
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI void
|
2010-09-09 18:54:05 -07:00
|
|
|
_elm_widget_item_del_cb_set(Elm_Widget_Item *item, Evas_Smart_Cb del_cb)
|
|
|
|
{
|
|
|
|
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
|
|
|
|
|
|
|
|
if ((item->del_cb) && (item->del_cb != del_cb))
|
|
|
|
WRN("You're replacing a previously set del_cb %p of item %p with %p",
|
|
|
|
item->del_cb, item, del_cb);
|
|
|
|
|
|
|
|
item->del_cb = del_cb;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set user-data in this item.
|
|
|
|
*
|
|
|
|
* User data may be used to identify this item or just store any
|
|
|
|
* application data. It is automatically given as the first parameter
|
|
|
|
* of the deletion notify callback.
|
|
|
|
*
|
|
|
|
* @param item a valid #Elm_Widget_Item to store data in.
|
|
|
|
* @param data user data to store.
|
|
|
|
* @see elm_widget_item_del_cb_set() convenience macro.
|
|
|
|
*/
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI void
|
2010-09-09 18:54:05 -07:00
|
|
|
_elm_widget_item_data_set(Elm_Widget_Item *item, const void *data)
|
|
|
|
{
|
|
|
|
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
|
|
|
|
if ((item->data) && (item->data != data))
|
|
|
|
DBG("Replacing item %p data %p with %p", item, item->data, data);
|
|
|
|
item->data = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves user-data of this item.
|
|
|
|
*
|
|
|
|
* @param item a valid #Elm_Widget_Item to get data from.
|
|
|
|
* @see elm_widget_item_data_set()
|
|
|
|
*/
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI void *
|
2010-09-09 18:54:05 -07:00
|
|
|
_elm_widget_item_data_get(const Elm_Widget_Item *item)
|
|
|
|
{
|
|
|
|
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
|
|
|
|
return (void *)item->data;
|
|
|
|
}
|
Tooltips: split owner/eventarea, allow subitems to have indepentent tooltips.
Now owner widget (elm_widget) is just used to listen for theme changes
and create/destroy the tooltip data. The actual mouse events operates
on all Evas_Object and is the one where tooltip data is actually
stored.
The public API is basically the same, just the event_info is now NULL
to avoid confusion.
The internal API introduces elm_object_sub_tooltip_content_cb_set()
and as the first parameter the eventarea. While this may be confusing,
as the second parameter is the actual elementary object, it is the one
that all other calls receive, like elm_object_tooltip_hide() or
elm_object_tooltip_unset(), thus it does make sense to have such order.
Also internal API, elm_widget_item_tooltip_* functions were
added. They are a variation of the widget API to handle its items, as
such the func() gets one more parameter: item, and the del_cb() gets
the item as event_info (that's why the public widget version got
event_info always NULL, to not confuse with this one!)
Widgets with items that makes sense to have tooltips got extra API:
* toolbar
* list
* gengrid
* genlist
SVN revision: 52173
2010-09-12 14:05:13 -07:00
|
|
|
|
|
|
|
typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip;
|
2010-09-13 00:56:23 -07:00
|
|
|
|
Tooltips: split owner/eventarea, allow subitems to have indepentent tooltips.
Now owner widget (elm_widget) is just used to listen for theme changes
and create/destroy the tooltip data. The actual mouse events operates
on all Evas_Object and is the one where tooltip data is actually
stored.
The public API is basically the same, just the event_info is now NULL
to avoid confusion.
The internal API introduces elm_object_sub_tooltip_content_cb_set()
and as the first parameter the eventarea. While this may be confusing,
as the second parameter is the actual elementary object, it is the one
that all other calls receive, like elm_object_tooltip_hide() or
elm_object_tooltip_unset(), thus it does make sense to have such order.
Also internal API, elm_widget_item_tooltip_* functions were
added. They are a variation of the widget API to handle its items, as
such the func() gets one more parameter: item, and the del_cb() gets
the item as event_info (that's why the public widget version got
event_info always NULL, to not confuse with this one!)
Widgets with items that makes sense to have tooltips got extra API:
* toolbar
* list
* gengrid
* genlist
SVN revision: 52173
2010-09-12 14:05:13 -07:00
|
|
|
struct _Elm_Widget_Item_Tooltip
|
|
|
|
{
|
|
|
|
Elm_Widget_Item *item;
|
|
|
|
Elm_Tooltip_Item_Content_Cb func;
|
|
|
|
Evas_Smart_Cb del_cb;
|
|
|
|
const void *data;
|
|
|
|
};
|
|
|
|
|
|
|
|
static Evas_Object *
|
|
|
|
_elm_widget_item_tooltip_label_create(void *data, Evas_Object *obj, void *item __UNUSED__)
|
|
|
|
{
|
|
|
|
Evas_Object *label = elm_label_add(obj);
|
|
|
|
if (!label)
|
|
|
|
return NULL;
|
|
|
|
elm_object_style_set(label, "tooltip");
|
|
|
|
elm_label_label_set(label, data);
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_elm_widget_item_tooltip_label_del_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the text to be shown in the widget item.
|
|
|
|
*
|
|
|
|
* @param item Target item
|
|
|
|
* @param text The text to set in the content
|
|
|
|
*
|
|
|
|
* Setup the text as tooltip to object. The item can have only one tooltip,
|
|
|
|
* so any previous tooltip data is removed.
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI void
|
Tooltips: split owner/eventarea, allow subitems to have indepentent tooltips.
Now owner widget (elm_widget) is just used to listen for theme changes
and create/destroy the tooltip data. The actual mouse events operates
on all Evas_Object and is the one where tooltip data is actually
stored.
The public API is basically the same, just the event_info is now NULL
to avoid confusion.
The internal API introduces elm_object_sub_tooltip_content_cb_set()
and as the first parameter the eventarea. While this may be confusing,
as the second parameter is the actual elementary object, it is the one
that all other calls receive, like elm_object_tooltip_hide() or
elm_object_tooltip_unset(), thus it does make sense to have such order.
Also internal API, elm_widget_item_tooltip_* functions were
added. They are a variation of the widget API to handle its items, as
such the func() gets one more parameter: item, and the del_cb() gets
the item as event_info (that's why the public widget version got
event_info always NULL, to not confuse with this one!)
Widgets with items that makes sense to have tooltips got extra API:
* toolbar
* list
* gengrid
* genlist
SVN revision: 52173
2010-09-12 14:05:13 -07:00
|
|
|
_elm_widget_item_tooltip_text_set(Elm_Widget_Item *item, const char *text)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(item);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(text);
|
|
|
|
|
|
|
|
text = eina_stringshare_add(text);
|
|
|
|
_elm_widget_item_tooltip_content_cb_set
|
|
|
|
(item, _elm_widget_item_tooltip_label_create, text,
|
|
|
|
_elm_widget_item_tooltip_label_del_cb);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Object *
|
|
|
|
_elm_widget_item_tooltip_create(void *data, Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Elm_Widget_Item_Tooltip *wit = data;
|
|
|
|
return wit->func((void *)wit->data, obj, wit->item);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_elm_widget_item_tooltip_del_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
|
|
|
|
{
|
|
|
|
Elm_Widget_Item_Tooltip *wit = data;
|
|
|
|
if (wit->del_cb) wit->del_cb((void *)wit->data, obj, wit->item);
|
|
|
|
free(wit);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the content to be shown in the tooltip item
|
|
|
|
*
|
|
|
|
* Setup the tooltip to item. The item can have only one tooltip,
|
|
|
|
* so any previous tooltip data is removed. @p func(with @p data) will
|
|
|
|
* be called every time that need show the tooltip and it should
|
|
|
|
* return a valid Evas_Object. This object is then managed fully by
|
|
|
|
* tooltip system and is deleted when the tooltip is gone.
|
|
|
|
*
|
|
|
|
* @param item the widget item being attached a tooltip.
|
|
|
|
* @param func the function used to create the tooltip contents.
|
|
|
|
* @param data what to provide to @a func as callback data/context.
|
|
|
|
* @param del_cb called when data is not needed anymore, either when
|
|
|
|
* another callback replaces @func, the tooltip is unset with
|
|
|
|
* elm_widget_item_tooltip_unset() or the owner @a item
|
|
|
|
* dies. This callback receives as the first parameter the
|
|
|
|
* given @a data, and @c event_info is the item.
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI void
|
Tooltips: split owner/eventarea, allow subitems to have indepentent tooltips.
Now owner widget (elm_widget) is just used to listen for theme changes
and create/destroy the tooltip data. The actual mouse events operates
on all Evas_Object and is the one where tooltip data is actually
stored.
The public API is basically the same, just the event_info is now NULL
to avoid confusion.
The internal API introduces elm_object_sub_tooltip_content_cb_set()
and as the first parameter the eventarea. While this may be confusing,
as the second parameter is the actual elementary object, it is the one
that all other calls receive, like elm_object_tooltip_hide() or
elm_object_tooltip_unset(), thus it does make sense to have such order.
Also internal API, elm_widget_item_tooltip_* functions were
added. They are a variation of the widget API to handle its items, as
such the func() gets one more parameter: item, and the del_cb() gets
the item as event_info (that's why the public widget version got
event_info always NULL, to not confuse with this one!)
Widgets with items that makes sense to have tooltips got extra API:
* toolbar
* list
* gengrid
* genlist
SVN revision: 52173
2010-09-12 14:05:13 -07:00
|
|
|
_elm_widget_item_tooltip_content_cb_set(Elm_Widget_Item *item, Elm_Tooltip_Item_Content_Cb func, const void *data, Evas_Smart_Cb del_cb)
|
|
|
|
{
|
|
|
|
Elm_Widget_Item_Tooltip *wit;
|
|
|
|
|
|
|
|
ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, error);
|
|
|
|
|
|
|
|
if (!func)
|
|
|
|
{
|
|
|
|
_elm_widget_item_tooltip_unset(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wit = ELM_NEW(Elm_Widget_Item_Tooltip);
|
|
|
|
if (!wit) goto error;
|
|
|
|
wit->item = item;
|
|
|
|
wit->func = func;
|
|
|
|
wit->data = data;
|
|
|
|
wit->del_cb = del_cb;
|
|
|
|
|
|
|
|
elm_object_sub_tooltip_content_cb_set
|
|
|
|
(item->view, item->widget, _elm_widget_item_tooltip_create, wit,
|
|
|
|
_elm_widget_item_tooltip_del_cb);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
|
|
|
if (del_cb) del_cb((void *)data, item->widget, item);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unset tooltip from item
|
|
|
|
*
|
|
|
|
* @param item widget item to remove previously set tooltip.
|
|
|
|
*
|
|
|
|
* Remove tooltip from item. The callback provided as del_cb to
|
|
|
|
* elm_widget_item_tooltip_content_cb_set() will be called to notify
|
|
|
|
* it is not used anymore.
|
|
|
|
*
|
|
|
|
* @see elm_widget_item_tooltip_content_cb_set()
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI void
|
Tooltips: split owner/eventarea, allow subitems to have indepentent tooltips.
Now owner widget (elm_widget) is just used to listen for theme changes
and create/destroy the tooltip data. The actual mouse events operates
on all Evas_Object and is the one where tooltip data is actually
stored.
The public API is basically the same, just the event_info is now NULL
to avoid confusion.
The internal API introduces elm_object_sub_tooltip_content_cb_set()
and as the first parameter the eventarea. While this may be confusing,
as the second parameter is the actual elementary object, it is the one
that all other calls receive, like elm_object_tooltip_hide() or
elm_object_tooltip_unset(), thus it does make sense to have such order.
Also internal API, elm_widget_item_tooltip_* functions were
added. They are a variation of the widget API to handle its items, as
such the func() gets one more parameter: item, and the del_cb() gets
the item as event_info (that's why the public widget version got
event_info always NULL, to not confuse with this one!)
Widgets with items that makes sense to have tooltips got extra API:
* toolbar
* list
* gengrid
* genlist
SVN revision: 52173
2010-09-12 14:05:13 -07:00
|
|
|
_elm_widget_item_tooltip_unset(Elm_Widget_Item *item)
|
|
|
|
{
|
|
|
|
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
|
|
|
|
elm_object_tooltip_unset(item->view);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets a different style for this item tooltip.
|
|
|
|
*
|
|
|
|
* @note before you set a style you should define a tooltip with
|
|
|
|
* elm_widget_item_tooltip_content_cb_set() or
|
|
|
|
* elm_widget_item_tooltip_text_set()
|
|
|
|
*
|
|
|
|
* @param item widget item with tooltip already set.
|
|
|
|
* @param style the theme style to use (default, transparent, ...)
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI void
|
Tooltips: split owner/eventarea, allow subitems to have indepentent tooltips.
Now owner widget (elm_widget) is just used to listen for theme changes
and create/destroy the tooltip data. The actual mouse events operates
on all Evas_Object and is the one where tooltip data is actually
stored.
The public API is basically the same, just the event_info is now NULL
to avoid confusion.
The internal API introduces elm_object_sub_tooltip_content_cb_set()
and as the first parameter the eventarea. While this may be confusing,
as the second parameter is the actual elementary object, it is the one
that all other calls receive, like elm_object_tooltip_hide() or
elm_object_tooltip_unset(), thus it does make sense to have such order.
Also internal API, elm_widget_item_tooltip_* functions were
added. They are a variation of the widget API to handle its items, as
such the func() gets one more parameter: item, and the del_cb() gets
the item as event_info (that's why the public widget version got
event_info always NULL, to not confuse with this one!)
Widgets with items that makes sense to have tooltips got extra API:
* toolbar
* list
* gengrid
* genlist
SVN revision: 52173
2010-09-12 14:05:13 -07:00
|
|
|
_elm_widget_item_tooltip_style_set(Elm_Widget_Item *item, const char *style)
|
|
|
|
{
|
|
|
|
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
|
|
|
|
elm_object_tooltip_style_set(item->view, style);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the style for this item tooltip.
|
|
|
|
*
|
|
|
|
* @param item widget item with tooltip already set.
|
|
|
|
* @return style the theme style in use, defaults to "default". If the
|
|
|
|
* object does not have a tooltip set, then NULL is returned.
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
2010-09-13 00:56:23 -07:00
|
|
|
EAPI const char *
|
Tooltips: split owner/eventarea, allow subitems to have indepentent tooltips.
Now owner widget (elm_widget) is just used to listen for theme changes
and create/destroy the tooltip data. The actual mouse events operates
on all Evas_Object and is the one where tooltip data is actually
stored.
The public API is basically the same, just the event_info is now NULL
to avoid confusion.
The internal API introduces elm_object_sub_tooltip_content_cb_set()
and as the first parameter the eventarea. While this may be confusing,
as the second parameter is the actual elementary object, it is the one
that all other calls receive, like elm_object_tooltip_hide() or
elm_object_tooltip_unset(), thus it does make sense to have such order.
Also internal API, elm_widget_item_tooltip_* functions were
added. They are a variation of the widget API to handle its items, as
such the func() gets one more parameter: item, and the del_cb() gets
the item as event_info (that's why the public widget version got
event_info always NULL, to not confuse with this one!)
Widgets with items that makes sense to have tooltips got extra API:
* toolbar
* list
* gengrid
* genlist
SVN revision: 52173
2010-09-12 14:05:13 -07:00
|
|
|
_elm_widget_item_tooltip_style_get(const Elm_Widget_Item *item)
|
|
|
|
{
|
|
|
|
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
|
|
|
|
return elm_object_tooltip_style_get(item->view);
|
|
|
|
}
|
2010-09-13 00:56:23 -07:00
|
|
|
|
2010-09-17 11:24:10 -07:00
|
|
|
EAPI void
|
|
|
|
_elm_widget_item_cursor_set(Elm_Widget_Item *item, const char *cursor)
|
|
|
|
{
|
|
|
|
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
|
|
|
|
elm_object_cursor_set(item->view, cursor);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
_elm_widget_item_cursor_unset(Elm_Widget_Item *item)
|
|
|
|
{
|
|
|
|
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
|
|
|
|
elm_object_cursor_unset(item->view);
|
|
|
|
}
|
|
|
|
|
2010-09-13 00:56:23 -07:00
|
|
|
// smart object funcs
|
|
|
|
static void
|
|
|
|
_smart_reconfigure(Smart_Data *sd)
|
|
|
|
{
|
|
|
|
if (sd->resize_obj)
|
|
|
|
{
|
|
|
|
evas_object_move(sd->resize_obj, sd->x, sd->y);
|
|
|
|
evas_object_resize(sd->resize_obj, sd->w, sd->h);
|
|
|
|
}
|
|
|
|
if (sd->hover_obj)
|
|
|
|
{
|
|
|
|
evas_object_move(sd->hover_obj, sd->x, sd->y);
|
|
|
|
evas_object_resize(sd->hover_obj, sd->w, sd->h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_add(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Smart_Data *sd;
|
|
|
|
|
|
|
|
sd = calloc(1, sizeof(Smart_Data));
|
|
|
|
if (!sd) return;
|
|
|
|
sd->obj = obj;
|
|
|
|
sd->x = sd->y = sd->w = sd->h = 0;
|
|
|
|
sd->can_focus = 1;
|
|
|
|
evas_object_smart_data_set(obj, sd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Object *
|
|
|
|
_newest_focus_order_get(Evas_Object *obj, unsigned int *newest_focus_order)
|
|
|
|
{
|
|
|
|
const Eina_List *l;
|
|
|
|
Evas_Object *child, *ret, *best;
|
|
|
|
|
|
|
|
API_ENTRY return NULL;
|
|
|
|
if (!evas_object_visible_get(obj)) return NULL;
|
|
|
|
best = NULL;
|
|
|
|
if (*newest_focus_order < sd->focus_order)
|
|
|
|
{
|
|
|
|
*newest_focus_order = sd->focus_order;
|
|
|
|
best = obj;
|
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(sd->subobjs, l, child)
|
|
|
|
{
|
|
|
|
ret = _newest_focus_order_get(child, newest_focus_order);
|
|
|
|
if (!ret) continue;
|
|
|
|
best = ret;
|
|
|
|
}
|
|
|
|
return best;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_if_focused_revert(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object *top;
|
|
|
|
Evas_Object *newest = NULL;
|
|
|
|
unsigned int newest_focus_order = 0;
|
|
|
|
|
|
|
|
INTERNAL_ENTRY;
|
|
|
|
|
|
|
|
if (!sd->focused) return;
|
|
|
|
if (!sd->parent_obj) return;
|
|
|
|
|
|
|
|
top = elm_widget_top_get(sd->parent_obj);
|
|
|
|
if (top)
|
|
|
|
{
|
|
|
|
newest = _newest_focus_order_get(top, &newest_focus_order);
|
|
|
|
if (newest)
|
|
|
|
{
|
|
|
|
elm_object_unfocus(newest);
|
|
|
|
elm_object_focus(newest);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_del(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object *sobj;
|
|
|
|
|
|
|
|
INTERNAL_ENTRY;
|
|
|
|
if (sd->del_pre_func) sd->del_pre_func(obj);
|
|
|
|
if (sd->resize_obj)
|
|
|
|
{
|
|
|
|
sobj = sd->resize_obj;
|
|
|
|
sd->resize_obj = NULL;
|
|
|
|
evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
|
|
|
|
evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
|
|
|
|
evas_object_del(sobj);
|
|
|
|
}
|
|
|
|
if (sd->hover_obj)
|
|
|
|
{
|
|
|
|
sobj = sd->hover_obj;
|
|
|
|
sd->hover_obj = NULL;
|
|
|
|
evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
|
|
|
|
evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
|
|
|
|
evas_object_del(sobj);
|
|
|
|
}
|
|
|
|
EINA_LIST_FREE(sd->subobjs, sobj)
|
|
|
|
{
|
|
|
|
evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
|
|
|
|
evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
|
|
|
|
evas_object_del(sobj);
|
|
|
|
}
|
|
|
|
eina_list_free(sd->tooltips); /* should be empty anyway */
|
|
|
|
if (sd->del_func) sd->del_func(obj);
|
|
|
|
if (sd->style) eina_stringshare_del(sd->style);
|
|
|
|
if (sd->type) eina_stringshare_del(sd->type);
|
|
|
|
if (sd->theme) elm_theme_free(sd->theme);
|
|
|
|
_if_focused_revert(obj);
|
|
|
|
free(sd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
|
|
|
|
{
|
|
|
|
INTERNAL_ENTRY;
|
|
|
|
sd->x = x;
|
|
|
|
sd->y = y;
|
|
|
|
_smart_reconfigure(sd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
|
|
|
|
{
|
|
|
|
INTERNAL_ENTRY;
|
|
|
|
sd->w = w;
|
|
|
|
sd->h = h;
|
|
|
|
_smart_reconfigure(sd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_show(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Eina_List *list, *l;
|
|
|
|
Evas_Object *o;
|
|
|
|
INTERNAL_ENTRY;
|
|
|
|
list = evas_object_smart_members_get(obj);
|
|
|
|
EINA_LIST_FOREACH(list, l, o)
|
|
|
|
{
|
|
|
|
if (evas_object_data_get(o, "_elm_leaveme")) continue;
|
|
|
|
evas_object_show(o);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_hide(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Eina_List *list, *l;
|
|
|
|
Evas_Object *o;
|
|
|
|
INTERNAL_ENTRY;
|
|
|
|
list = evas_object_smart_members_get(obj);
|
|
|
|
EINA_LIST_FOREACH(list, l, o)
|
|
|
|
{
|
|
|
|
if (evas_object_data_get(o, "_elm_leaveme")) continue;
|
|
|
|
evas_object_hide(o);
|
|
|
|
}
|
|
|
|
_if_focused_revert(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
|
|
|
|
{
|
|
|
|
Eina_List *list, *l;
|
|
|
|
Evas_Object *o;
|
|
|
|
INTERNAL_ENTRY;
|
|
|
|
list = evas_object_smart_members_get(obj);
|
|
|
|
EINA_LIST_FOREACH(list, l, o)
|
|
|
|
{
|
|
|
|
if (evas_object_data_get(o, "_elm_leaveme")) continue;
|
|
|
|
evas_object_color_set(o, r, g, b, a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
|
|
|
|
{
|
|
|
|
Eina_List *list, *l;
|
|
|
|
Evas_Object *o;
|
|
|
|
INTERNAL_ENTRY;
|
|
|
|
list = evas_object_smart_members_get(obj);
|
|
|
|
EINA_LIST_FOREACH(list, l, o)
|
|
|
|
{
|
|
|
|
if (evas_object_data_get(o, "_elm_leaveme")) continue;
|
|
|
|
evas_object_clip_set(o, clip);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_clip_unset(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Eina_List *list, *l;
|
|
|
|
Evas_Object *o;
|
|
|
|
INTERNAL_ENTRY;
|
|
|
|
// evas_object_clip_unset(sd->resize_obj);
|
|
|
|
// return;
|
|
|
|
list = evas_object_smart_members_get(obj);
|
|
|
|
EINA_LIST_FOREACH(list, l, o)
|
|
|
|
{
|
|
|
|
if (evas_object_data_get(o, "_elm_leaveme")) continue;
|
|
|
|
evas_object_clip_unset(o);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_calculate(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
INTERNAL_ENTRY;
|
|
|
|
if (sd->changed_func) sd->changed_func(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* never need to touch this */
|
|
|
|
static void
|
|
|
|
_smart_init(void)
|
|
|
|
{
|
|
|
|
if (_e_smart) return;
|
|
|
|
{
|
|
|
|
static const Evas_Smart_Class sc =
|
|
|
|
{
|
|
|
|
SMART_NAME,
|
|
|
|
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,
|
|
|
|
_smart_calculate,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
_e_smart = evas_smart_class_new(&sc);
|
|
|
|
}
|
|
|
|
}
|