* "unfocused" - keyboard focus is gone
*/
+ /* composite widgets - these basically put together basic widgets above
+ * in convenient packages that do more than basic stuff */
+ typedef enum _Elm_Text_Format
+ {
+ ELM_TEXT_FORMAT_PLAIN_UTF8,
+ ELM_TEXT_FORMAT_MARKUP_UTF8
+ } Elm_Text_Format;
+ EINA_DEPRECATED EAPI Evas_Object *elm_notepad_add(Evas_Object *parent);
+ EINA_DEPRECATED EAPI void elm_notepad_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format);
+ EINA_DEPRECATED EAPI void elm_notepad_file_save(Evas_Object *obj, const char *file, Elm_Text_Format format);
+ EINA_DEPRECATED EAPI void elm_notepad_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce);
+ EINA_DEPRECATED EAPI void elm_notepad_autosave_set(Evas_Object *obj, Eina_Bool autosave);
+
+ /* smart callbacks called:
+ */
+
typedef struct _Elm_Entry_Anchorview_Info Elm_Entry_Anchorview_Info;
struct _Elm_Entry_Anchorview_Info
{
EAPI void elm_list_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce);
EAPI void elm_list_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v);
EAPI void elm_list_scroller_policy_get(const Evas_Object *obj, Elm_Scroller_Policy *policy_h, Elm_Scroller_Policy *policy_v);
+
/* smart callbacks called:
* "clicked" - when the user double-clicked an item
* "selected" - when the user selected an item
* "longpressed" - an item in the hoversel list is long-pressed
*/
+ // FIXME: incomplete - carousel. don't use this until this comment is removed
+ typedef struct _Elm_Carousel_Item Elm_Carousel_Item;
+ EAPI Evas_Object *elm_carousel_add(Evas_Object *parent);
+ EAPI Elm_Carousel_Item *elm_carousel_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, Evas_Smart_Cb func, const void *data);
+ EAPI void elm_carousel_item_del(Elm_Carousel_Item *item);
+ EAPI void elm_carousel_item_select(Elm_Carousel_Item *item);
+ /* smart callbacks called:
+ * "clicked" - when the user clicks on a carousel item and becomes selected
+ */
+
EAPI Evas_Object *elm_slider_add(Evas_Object *parent);
EAPI void elm_slider_label_set(Evas_Object *obj, const char *label);
EAPI const char *elm_slider_label_get(const Evas_Object *obj);
* "overflowed" - when discpicker item is changed to first item from last item
* "underflowed" - when discpicker item is changed to last item from first item.
*/
+ /* available styles:
+ * default
+ */
+
+ EAPI Evas_Object *elm_timepicker_add(Evas_Object *parent);
+ EAPI void elm_timepicker_time_set(Evas_Object *obj, int hrs, int min, int sec);
+ EAPI void elm_timepicker_time_get(Evas_Object *obj, int *hrs, int *min, int *sec);
+ EAPI void elm_timepicker_show_am_pm_set(Evas_Object *obj, Eina_Bool am_pm);
+ EAPI void elm_timepicker_show_seconds_set(Evas_Object *obj, Eina_Bool seconds);
+ /* smart callback called:
+ * "changed" - when timepicker selected item is changed
+ */
+ /* available styles:
+ * default
+ */
+
+ EAPI Evas_Object *elm_datepicker_add(Evas_Object *parent);
+ EAPI void elm_datepicker_date_set(Evas_Object *obj, int year, int month, int day);
+ EAPI void elm_datepicker_date_get(const Evas_Object *obj, int *year, int *month, int *day);
+ EAPI void elm_datepicker_date_min_set(Evas_Object *obj, int year, int month, int day); // Not implemented
+ EAPI void elm_datepicker_date_min_get(const Evas_Object *obj, int *year, int *month, int *day);
+ EAPI void elm_datepicker_date_max_set(Evas_Object *obj, int year, int month, int day); // Not implemented
+ EAPI void elm_datepicker_date_max_get(const Evas_Object *obj, int *year, int *month, int *day);
+ EAPI void elm_datepicker_date_format_set(Evas_Object *obj, const char *fmt);
+ EAPI const char *elm_datepicker_date_format_get(const Evas_Object *obj);
+ /* smart callback called:
+ * "changed" - when datepicker selected item is changed
+ */
+ /* available styles:
+ * default
+ */
/* datefield */
typedef enum _Elm_Datefield_Layout
* "changed" - when datefield entry is changed, this signal is sent.
*/
+ /* titlebar */
+ EINA_DEPRECATED EAPI Evas_Object *elm_titlebar_add(Evas_Object *parent);
+ EINA_DEPRECATED EAPI void elm_titlebar_label_set(Evas_Object *obj, const char *label);
+ EINA_DEPRECATED EAPI const char *elm_titlebar_label_get(Evas_Object *obj);
+ EINA_DEPRECATED EAPI void elm_titlebar_icon_set(Evas_Object *obj, Evas_Object *icon);
+ EINA_DEPRECATED EAPI Evas_Object *elm_titlebar_icon_get(Evas_Object *obj);
+ EINA_DEPRECATED EAPI void elm_titlebar_end_set(Evas_Object *obj, Evas_Object *end);
+ EINA_DEPRECATED EAPI Evas_Object *elm_titlebar_end_get(Evas_Object *obj);
+
/* popup */
typedef enum _Elm_Popup_Response
{
EAPI Eina_Bool elm_ctxpopup_position_forced_get(Evas_Object *obj);
EAPI void elm_ctxpopup_area_set(Evas_Object *obj, Evas_Object *rect);
+ /* Tab */
+ typedef enum _Elm_Tab_Move_Type
+ {
+ ELM_TAB_MOVE_LEFT = 0,
+ ELM_TAB_MOVE_RIGHT = 1
+ } Elm_Tab_Move_Type;
+
+ typedef enum _Elm_Tab_Mode_Type
+ {
+ ELM_TAB_PORTRAIT_2 = 2,
+ ELM_TAB_PORTRAIT_3 = 3,
+ ELM_TAB_PORTRAIT_4 = 4,
+ ELM_TAB_LANDSCAPE_2 = 12,
+ ELM_TAB_LANDSCAPE_3 = 13,
+ ELM_TAB_LANDSCAPE_4 = 14,
+ ELM_TAB_LANDSCAPE_5 = 15,
+ } Elm_Tab_Mode_Type;
+
+ typedef struct _Elm_Tab_Item Elm_Tab_Item;
+
+ EINA_DEPRECATED EAPI Evas_Object *elm_tab_add(Evas_Object *parent);
+ EINA_DEPRECATED EAPI void elm_tab_set(Evas_Object *obj, int mode);
+ EINA_DEPRECATED EAPI Elm_Tab_Item *elm_tab_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data);
+ EINA_DEPRECATED EAPI void elm_tab_item_del(Elm_Tab_Item *item);
+ EINA_DEPRECATED EAPI void elm_tab_item_select(Elm_Tab_Item *item);
+ EINA_DEPRECATED EAPI Evas_Object *elm_tab_item_icon_get(Elm_Tab_Item *item);
+ EINA_DEPRECATED EAPI const char *elm_tab_item_label_get(Elm_Tab_Item *item);
+ EINA_DEPRECATED EAPI void elm_tab_item_label_set(Elm_Tab_Item *item, const char *label);
+ EINA_DEPRECATED EAPI void elm_tab_item_badge_set(Elm_Tab_Item *item, const int badge);
+ EINA_DEPRECATED EAPI Elm_Tab_Item *elm_tab_selected_item_get(Evas_Object *obj);
+ EINA_DEPRECATED EAPI Elm_Tab_Item *elm_tab_first_item_get(Evas_Object *obj);
+ EINA_DEPRECATED EAPI Elm_Tab_Item *elm_tab_last_item_get(Evas_Object *obj);
+ EINA_DEPRECATED EAPI Eina_List *elm_tab_items_get(Evas_Object *obj);
+ EINA_DEPRECATED EAPI Elm_Tab_Item *elm_tab_item_prev(Elm_Tab_Item *item);
+ EINA_DEPRECATED EAPI Elm_Tab_Item *elm_tab_item_next(Elm_Tab_Item *item);
+ EINA_DEPRECATED EAPI void elm_tab_move(Evas_Object *obj, int direction);
+ EINA_DEPRECATED EAPI void elm_tab_edit_disable_set(Evas_Object *obj, Eina_Bool disable);
+ EINA_DEPRECATED EAPI Eina_Bool elm_tab_edit_disable_get(Evas_Object *obj);
+
/* tansit */
typedef enum
{
EAPI Evas_Object *elm_navigationbar_ex_item_title_button_unset(Elm_Navigationbar_ex_Item* item, int button_type);
EAPI void elm_navigationbar_ex_animation_disable_set(Evas_Object *obj, Eina_Bool disable);
+
+ /* Tab Bar */
+ #define TAB_BAR_SYSTEM_ICON_CONTACT "elm/icon/tabbar_contact/default"
+ #define TAB_BAR_SYSTEM_ICON_GROUP "elm/icon/tabbar_group/default"
+ #define TAB_BAR_SYSTEM_ICON_SONG "elm/icon/tabbar_song/default"
+ #define TAB_BAR_SYSTEM_ICON_FAVORITES "elm/icon/tabbar_favorites/default"
+ #define TAB_BAR_SYSTEM_ICON_SEARCH "elm/icon/tabbar_search/default"
+ #define TAB_BAR_SYSTEM_ICON_MESSAGE "elm/icon/tabbar_message/default"
+ #define TAB_BAR_SYSTEM_ICON_SETTING "elm/icon/tabbar_setting/default"
+
+ EINA_DEPRECATED EAPI Evas_Object *elm_tabbar_add(Evas_Object *parent);
+ EINA_DEPRECATED EAPI Elm_Tab_Item *elm_tabbar_item_add(Evas_Object *obj, const char *icon_path, const char *label, Evas_Object *view);
+ EINA_DEPRECATED EAPI Evas_Object *elm_tabbar_item_icon_get(Elm_Tab_Item *it);
+ EINA_DEPRECATED EAPI const char *elm_tabbar_item_label_get(Elm_Tab_Item *it);
+ EINA_DEPRECATED EAPI void elm_tabbar_item_label_set(Elm_Tab_Item *it, const char *label);
+ EINA_DEPRECATED EAPI void elm_tabbar_item_select(Elm_Tab_Item *it);
+ EINA_DEPRECATED EAPI void elm_tabbar_edit_start(Evas_Object *obj);
+ EINA_DEPRECATED EAPI void elm_tabbar_item_visible_set(Elm_Tab_Item *it, Eina_Bool bar);
+
/* smart callbacks called:
* "clicked" - when item clicked
*/
EAPI void elm_searchbar_clear(Evas_Object *obj);
EAPI void elm_searchbar_boundary_rect_set(Evas_Object *obj, Eina_Bool boundary);
+ /* actionsheet */
+ typedef enum _Elm_Actionsheet_Button_Type
+ {
+ ELM_ACTIONSHEET_BT_NORMAL = 0,
+ ELM_ACTIONSHEET_BT_CANCEL,
+ ELM_ACTIONSHEET_BT_DESTRUCTIVE
+ } Elm_Actionsheet_Button_Type;
+
+ EINA_DEPRECATED EAPI Evas_Object *elm_actionsheet_add(Evas_Object *parent);
+ EINA_DEPRECATED EAPI void elm_actionsheet_title_set(Evas_Object *obj, const char *title);
+ EINA_DEPRECATED EAPI void elm_actionsheet_button_add(Evas_Object *obj, const Elm_Actionsheet_Button_Type type, const char *title, void (*button_clicked_cb) (void *data, Evas_Object *obj, void *event_info), void *event_info);
+ EINA_DEPRECATED EAPI int elm_actionsheet_button_title_get(Evas_Object *obj, const int index, char **title);
+
/* colorpicker */
EINA_DEPRECATED EAPI Evas_Object *elm_colorpicker_add(Evas_Object *parent);
EINA_DEPRECATED EAPI void elm_colorpicker_color_set(Evas_Object *obj, int r, int g , int b);
* "unfocused" - when an editfield is unfocused
*/
+
+
+ /* softkey */
+ typedef enum
+ {
+ ELM_SK_LEFT_BTN,
+ ELM_SK_RIGHT_BTN,
+ } Elm_Softkey_Type;
+
+ /* softkey */
+ typedef struct _Elm_Softkey_Item Elm_Softkey_Item;
+ EINA_DEPRECATED EAPI Evas_Object *elm_softkey_add(Evas_Object *parent);
+ EINA_DEPRECATED EAPI Elm_Softkey_Item *elm_softkey_button_add(Evas_Object *obj, Elm_Softkey_Type type, Evas_Object *icon, const char *label, void (*func)(void *data, Evas_Object *obj, void *event_info), const void *data);
+ EINA_DEPRECATED EAPI void elm_softkey_button_del(Evas_Object *obj, Elm_Softkey_Type type);
+ EINA_DEPRECATED EAPI void elm_softkey_button_show(Evas_Object *obj, Elm_Softkey_Type type);
+ EINA_DEPRECATED EAPI void elm_softkey_button_hide(Evas_Object *obj, Elm_Softkey_Type type);
+
+ EINA_DEPRECATED EAPI Elm_Softkey_Item *elm_softkey_panel_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func)(void *data, Evas_Object *obj, void *event_info), const void *data);
+ EINA_DEPRECATED EAPI int elm_softkey_panel_del(Evas_Object *obj);
+ EINA_DEPRECATED EAPI int elm_softkey_panel_close(Evas_Object *obj);
+ EINA_DEPRECATED EAPI int elm_softkey_panel_open(Evas_Object *obj);
+
+ EINA_DEPRECATED EAPI void elm_softkey_item_icon_set(Elm_Softkey_Item *item, Evas_Object *icon);
+ EINA_DEPRECATED EAPI Evas_Object *elm_softkey_item_icon_get(Elm_Softkey_Item * item);
+ EINA_DEPRECATED EAPI void elm_softkey_item_label_set(Elm_Softkey_Item *item, const char *label);
+ EINA_DEPRECATED EAPI const char *elm_softkey_item_label_get(Elm_Softkey_Item * item);
+ EINA_DEPRECATED EAPI Eina_Bool elm_softkey_item_disabled_get(Elm_Softkey_Item *item);
+ EINA_DEPRECATED EAPI void elm_softkey_item_disabled_set(Elm_Softkey_Item *item, Eina_Bool disabled);
+ EINA_DEPRECATED EAPI void elm_softkey_item_callback_set(Elm_Softkey_Item* item, void (*func)(void *data, Evas_Object *obj, void *event_info), const void *data );
+ /* smart callback called:
+ * "clicked" - the user clicked the button, event_info: Softkey item
+ * "press" - the user press the button, event_info: Softkey item
+ * "panel,show" - when the panel is shown
+ * "panel,hide" - when the panel is hidden
+ */
+
+ /* gridbox */
+ EINA_DEPRECATED EAPI Evas_Object *elm_gridbox_add(Evas_Object *parent);
+ EINA_DEPRECATED EAPI void elm_gridbox_padding_set(Evas_Object *obj, Evas_Coord horizontal, Evas_Coord vertical);
+ EINA_DEPRECATED EAPI void elm_gridbox_item_size_set(Evas_Object *obj, Evas_Coord h_itemsize, Evas_Coord v_itemsize);
+ EINA_DEPRECATED EAPI void elm_gridbox_pack(Evas_Object *obj, Evas_Object *subobj);
+ EINA_DEPRECATED EAPI Eina_Bool elm_gridbox_unpack(Evas_Object *obj, Evas_Object *subobj);
+ EINA_DEPRECATED EAPI Eina_List *elm_gridbox_children_get(Evas_Object *obj);
+ EINA_DEPRECATED EAPI void elm_gridbox_homogenous_padding_set(Evas_Object *obj, Eina_Bool homogenous);
+
/* actionslider */
typedef enum _Elm_Actionslider_Indicator_Pos
{
* "indicator,position" - when a button reaches to the special position like "left", "right" and "center".
*/
+ /* gallery */
+ struct _Elm_Gallery_Item
+ {
+ Evas_Object *parent;
+ Evas_Object *ly;
+ Evas_Object *obj;
+ const char *path;
+ int index;
+ Evas_Coord x, y, w, h;
+ Evas_Coord mw, mh;
+ Eina_Bool on_hold : 1;
+ Eina_Bool on_show : 1;
+ Eina_Bool on_highquality : 1;
+ };
+ typedef struct _Elm_Gallery_Item Elm_Gallery_Item;
+ EINA_DEPRECATED EAPI Evas_Object *elm_gallery_add(Evas_Object *parent);
+ EINA_DEPRECATED EAPI Eina_Bool elm_gallery_data_set(Evas_Object *obj, Eina_List *list);
+ EINA_DEPRECATED EAPI Elm_Gallery_Item *elm_gallery_item_append(Evas_Object *obj, const char *photo_file);
+ EINA_DEPRECATED EAPI Elm_Gallery_Item *elm_gallery_item_prepend(Evas_Object *obj, const char *photo_file);
+ EINA_DEPRECATED EAPI void elm_gallery_item_del(Elm_Gallery_Item *it);
+ EINA_DEPRECATED EAPI const char *elm_gallery_item_file_get(Elm_Gallery_Item *it);
+ EINA_DEPRECATED EAPI void elm_gallery_item_show(Elm_Gallery_Item *it);
+ EINA_DEPRECATED EAPI Eina_List *elm_gallery_item_list_get(Evas_Object *obj);
+ EINA_DEPRECATED EAPI void elm_gallery_set_type(Evas_Object *obj,int type);
+ EINA_DEPRECATED EAPI void elm_gallery_set_max_count(Evas_Object *obj,int max_value);
+
/* Sliding Drawer */
typedef enum _Elm_SlidingDrawer_Pos
{
elm_toolbar.c \
elm_searchbar.c \
elm_list.c \
+elm_carousel.c \
elm_slider.c \
elm_genlist.c \
elm_check.c \
elm_mapbuf.c \
elm_picker.c \
elm_discpicker.c \
+elm_timepicker.c \
+elm_datepicker.c \
elm_thumb.c \
elm_config.c \
+elm_titlebar.c \
elm_popup.c \
elm_diskcontroller.c \
+elm_tab.c \
elm_navigationbar.c \
elm_navigationbar_ex.c\
+elm_tabbar.c \
elm_transit.c \
elm_animator.c \
elm_editfield.c \
elm_colorselector.c \
elm_colorpalette.c \
elm_ctxpopup.c \
+elm_actionsheet.c \
+elm_gridbox.c \
+elm_softkey.c \
elm_actionslider.c \
+elm_hor_scroller.c \
+elm_autocompleteview.c \
elm_controlbar.c \
+elm_gallery.c \
elm_slidingdrawer.c \
+elm_wipercontrol.c \
elm_dialoguegroup.c \
elm_dayselector.c \
elm_cnp_helper.c \
elc_fileselector.c \
elc_fileselector_button.c \
elc_hoversel.c \
+elc_notepad.c \
elc_scrolled_entry.c \
\
els_pan.c \
els_pan.h \
els_scroller.c \
els_scroller.h \
+els_hor_scroller.c \
+els_hor_scroller.h \
els_box.c \
els_box.h \
els_icon.c \
--- /dev/null
+#include <Elementary.h>
+#include "elm_priv.h"
+/**
+ * @defgroup Notepad Notepad
+ * @ingroup Elementary
+ *
+ * The notepad is an object for quickly loading a text file, displaying it,
+ * allowing editing of it and saving of changes back to the file loaded.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * NONE
+ *
+ * A notepad object contains a scroller and an entry. It is a convenience
+ * widget that loads a text file indicated, puts it in the scrollable entry
+ * and allows the user to edit it. Changes are written back to the original
+ * file after a short delay. The file to load and save to is specified by
+ * elm_notepad_file_set().
+ */
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+ Evas_Object *scr, *entry;
+ const char *file;
+ Elm_Text_Format format;
+ Ecore_Timer *delay_write;
+ Eina_Bool can_write : 1;
+ Eina_Bool autosave : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _on_focus_hook(void *data, Evas_Object *obj);
+static void _load(Evas_Object *obj);
+static void _save(Evas_Object *obj);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (wd->file) eina_stringshare_del(wd->file);
+ if (wd->delay_write)
+ {
+ ecore_timer_del(wd->delay_write);
+ if (wd->autosave) _save(obj);
+ }
+ free(wd);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ evas_object_size_hint_min_set(obj, -1, -1);
+ evas_object_size_hint_max_set(obj, -1, -1);
+}
+
+static void
+_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (elm_widget_focus_get(obj)) elm_widget_focus_steal(wd->entry);
+}
+
+static char *
+_buf_append(char *buf, const char *str, int *len, int *alloc)
+{
+ int len2 = strlen(str);
+ if ((*len + len2) >= *alloc)
+ {
+ char *buf2 = realloc(buf, *alloc + len2 + 512);
+ if (!buf2) return NULL;
+ buf = buf2;
+ *alloc += (512 + len2);
+ }
+ strcpy(buf + *len, str);
+ *len += len2;
+ return buf;
+}
+
+static char *
+_load_file(const char *file)
+{
+ FILE *f;
+ size_t size;
+ int alloc = 0, len = 0;
+ char *text = NULL, buf[PATH_MAX];
+
+ f = fopen(file, "rb");
+ if (!f) return NULL;
+ while ((size = fread(buf, 1, sizeof(buf), f)))
+ {
+ buf[size] = 0;
+ text = _buf_append(text, buf, &len, &alloc);
+ }
+ fclose(f);
+ return text;
+}
+
+static char *
+_load_plain(const char *file)
+{
+ char *text;
+
+ text = _load_file(file);
+ if (text)
+ {
+ char *text2;
+
+ text2 = elm_entry_utf8_to_markup(text);
+ free(text);
+ return text2;
+ }
+ return NULL;
+}
+
+static void
+_load(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ char *text;
+ if (!wd) return;
+ if (!wd->file)
+ {
+ elm_entry_entry_set(wd->entry, "");
+ return;
+ }
+ switch (wd->format)
+ {
+ case ELM_TEXT_FORMAT_PLAIN_UTF8:
+ text = _load_plain(wd->file);
+ break;
+ case ELM_TEXT_FORMAT_MARKUP_UTF8:
+ text = _load_file(wd->file);
+ break;
+ default:
+ text = NULL;
+ break;
+ }
+ if (text)
+ {
+ elm_entry_entry_set(wd->entry, text);
+ free(text);
+ }
+ else
+ elm_entry_entry_set(wd->entry, "");
+}
+
+static void
+_save_markup_utf8(const char *file, const char *text)
+{
+ FILE *f;
+
+ if ((!text) || (text[0] == 0))
+ {
+ ecore_file_unlink(file);
+ return;
+ }
+ f = fopen(file, "wb");
+ if (!f)
+ {
+ // FIXME: report a write error
+ return;
+ }
+ fputs(text, f); // FIXME: catch error
+ fclose(f);
+}
+
+static void
+_save_plain_utf8(const char *file, const char *text)
+{
+ char *text2;
+
+ text2 = elm_entry_markup_to_utf8(text);
+ if (text2)
+ {
+ _save_markup_utf8(file, text2);
+ free(text2);
+ }
+}
+
+static void
+_save(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (!wd->file) return;
+ switch (wd->format)
+ {
+ case ELM_TEXT_FORMAT_PLAIN_UTF8:
+ _save_plain_utf8(wd->file, elm_entry_entry_get(wd->entry));
+ break;
+ case ELM_TEXT_FORMAT_MARKUP_UTF8:
+ _save_markup_utf8(wd->file, elm_entry_entry_get(wd->entry));
+ break;
+ default:
+ break;
+ }
+}
+
+static Eina_Bool
+_delay_write(void *data)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ if (!wd) return ECORE_CALLBACK_CANCEL;
+ _save(data);
+ wd->delay_write = NULL;
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_entry_changed(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ if (!wd) return;
+ if (wd->delay_write)
+ {
+ ecore_timer_del(wd->delay_write);
+ wd->delay_write = NULL;
+ }
+ if (!wd->autosave) return;
+ wd->delay_write = ecore_timer_add(2.0, _delay_write, data);
+}
+
+static void
+_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ elm_widget_scroll_hold_push(wd->scr);
+}
+
+static void
+_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ elm_widget_scroll_hold_pop(wd->scr);
+}
+
+static void
+_freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ elm_widget_scroll_hold_push(wd->scr);
+}
+
+static void
+_freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ elm_widget_scroll_hold_pop(wd->scr);
+}
+
+/**
+ * Add a new notepad to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Notepad
+ */
+EAPI Evas_Object *
+elm_notepad_add(Evas_Object *parent)
+{
+ Evas_Object *obj;
+ Evas *e;
+ Widget_Data *wd;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ obj = elm_widget_add(e);
+ ELM_SET_WIDTYPE(widtype, "notepad");
+ elm_widget_type_set(obj, "notepad");
+ elm_widget_sub_object_add(parent, obj);
+ elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
+ elm_widget_data_set(obj, wd);
+ elm_widget_del_hook_set(obj, _del_hook);
+ elm_widget_can_focus_set(obj, 1);
+
+ wd->scr = elm_scroller_add(parent);
+ elm_widget_resize_object_set(obj, wd->scr);
+
+ wd->entry = elm_entry_add(parent);
+ evas_object_size_hint_weight_set(wd->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(wd->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_scroller_content_set(wd->scr, wd->entry);
+ evas_object_show(wd->entry);
+
+ elm_entry_entry_set(wd->entry, "");
+ evas_object_smart_callback_add(wd->entry, "changed", _entry_changed, obj);
+
+ evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
+ evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
+ evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
+ evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
+
+ wd->autosave = EINA_TRUE;
+
+ _sizing_eval(obj);
+ return obj;
+}
+
+/**
+ * This sets the file (and implicitly loads it) for the text to display and
+ * then edit. All changes are written back to the file after a short delay if
+ * the notepad object is set to autosave.
+ *
+ * @param obj The notepad object
+ * @param file The path to the file to load and save
+ * @param format The file format
+ *
+ * @ingroup Notepad
+ */
+EAPI void
+elm_notepad_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (wd->delay_write)
+ {
+ ecore_timer_del(wd->delay_write);
+ wd->delay_write = NULL;
+ }
+ if (wd->autosave) _save(obj);
+ eina_stringshare_replace(&wd->file, file);
+ wd->format = format;
+ _load(obj);
+}
+
+/**
+ * This function writes any changes made to the file.
+ * All changes are written back to the file after a short delay.
+ *
+ * @param obj The notepad object
+ * @param file The path to the file to save
+ * @param format The file format
+ *
+ * @ingroup Notepad
+ */
+EAPI void
+elm_notepad_file_save(Evas_Object *obj, const char *file, Elm_Text_Format format)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if ((!wd) || (!file)) return;
+ if (wd->delay_write)
+ {
+ ecore_timer_del(wd->delay_write);
+ wd->delay_write = NULL;
+ }
+ wd->format = format;
+ eina_stringshare_replace(&wd->file, file);
+ wd->delay_write = ecore_timer_add(2.0, _delay_write, obj);
+}
+
+/**
+ * This will enable or disable the scroller bounce mode for the notepad. See
+ * elm_scroller_bounce_set() for details
+ *
+ * @param obj The notepad object
+ * @param h_bounce Allow bounce horizontally
+ * @param v_bounce Allow bounce vertically
+ *
+ * @ingroup Notepad
+ */
+EAPI void
+elm_notepad_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ elm_scroller_bounce_set(wd->scr, h_bounce, v_bounce);
+}
+
+/**
+ * This sets the notepad object to 'autosave' the loaded text file or not.
+ *
+ * @param obj The notepad object
+ * @param autosave Autosave the loaded file or not
+ *
+ * @ingroup Notepad
+ */
+EAPI void
+elm_notepad_autosave_set(Evas_Object *obj, Eina_Bool autosave)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ wd->autosave = autosave;
+}
--- /dev/null
+#include "Elementary.h"
+#include "elm_priv.h"
+
+#include <errno.h>
+
+/**
+ * @defgroup ActionSheet ActionSheet
+ * @ingroup Elementary
+ *
+ * Display an action sheet
+ *
+ */
+
+static const double ANIMATION_TIME = 0.4;
+
+/*
+ * object hierarchy
+ *
+ * actionsheet
+ * bg
+ * title
+ * destructive_button
+ * normal_buttons(rect)
+ * normal_button1
+ * normal_button2
+ * ...
+ * cancel_button
+ *
+ *
+ */
+
+typedef struct _Widget_Data
+{
+ Evas *e;
+ Evas_Object *parent, *win, *win_bg, *obj, *layout, *bt_box;
+
+ char *title;
+
+ /* last button delimeters: to use elm_box_pack_after() */
+ Evas_Object *bt_cancel, *bt_destructive, *bt_normal;
+ Evas_Object *bt_destructive_delim, *bt_normal_delim;
+
+ Eina_List *cb_data_list;
+
+ Evas_Coord show_x, show_y, hide_x, hide_y;
+ Evas_Coord curr_x, curr_y;
+ Ecore_Timer *layout_timer;
+
+} Widget_Data;
+
+typedef struct _Button_Cb_Data_Wrapper
+{
+ Evas_Object *obj; // elm_widget
+ void (*cb_func) (void *, Evas_Object *, void *);
+ void * cb_data;
+ char * button_title;
+} Button_Cb_Data_Wrapper;
+
+/*
+ * Internal functions
+ */
+
+/*
+ * hooks
+ */
+static void
+_button_cb_data_wrapper_free(Button_Cb_Data_Wrapper *dw)
+{
+ if (dw->button_title) free(dw->button_title);
+ free(dw);
+}
+
+static void
+_really_del(void *data, Elm_Transit* transit)
+{
+ Widget_Data *wd = (Widget_Data *) data;
+
+ evas_object_del(wd->layout);
+ evas_object_del(wd->win_bg);
+
+ /* free widget data */
+ if(wd->title) free(wd->title);
+
+ // free eina_list
+ Eina_List *l;
+ Button_Cb_Data_Wrapper *dw;
+ EINA_LIST_FOREACH(wd->cb_data_list, l, dw)
+ _button_cb_data_wrapper_free(dw);
+ eina_list_free(wd->cb_data_list);
+
+ free(wd);
+}
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ // cut sub objects
+ elm_widget_sub_object_del(obj, wd->layout);
+ elm_widget_sub_object_del(obj, wd->win_bg);
+ elm_widget_resize_object_set(obj, NULL);
+ elm_widget_hover_object_set(obj, NULL);
+ // cut from parent
+ elm_widget_sub_object_del(wd->parent, obj);
+
+ edje_object_signal_emit(elm_layout_edje_get(wd->win_bg), "hide", "actionsheet");
+}
+
+Button_Cb_Data_Wrapper *
+_button_cb_data_wrapper_add(
+ Evas_Object *obj,
+ void (*cb_func) (void *, Evas_Object *, void *),
+ void *cb_data,
+ const char* button_title)
+{
+ Button_Cb_Data_Wrapper *dw;
+
+ dw = (Button_Cb_Data_Wrapper *)calloc(1, sizeof(Button_Cb_Data_Wrapper));
+ dw->obj = obj;
+ dw->cb_func = cb_func;
+ dw->cb_data = cb_data;
+ dw->button_title = strdup(button_title);
+
+ return dw;
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ // do animation
+ Elm_Transit * transit = elm_transit_add(wd->layout);
+ elm_transit_fx_insert(transit, elm_fx_translation_add(wd->layout, wd->show_x, wd->show_y, wd->hide_x, wd->hide_y));
+ elm_transit_completion_callback_set(transit, _really_del, wd);
+ elm_transit_curve_style_set(transit, ELM_ANIMATOR_CURVE_IN);
+ elm_transit_run(transit, ANIMATION_TIME-0.1);
+ elm_transit_del(transit);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+
+}
+
+/*
+ * callbacks
+ */
+static void
+_sub_del(void *data, Evas_Object *obj, void *event_info)
+{
+
+}
+
+static void
+_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ int x, y, w, h;
+ int minw, minh;
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ // win_bg
+ evas_object_geometry_get(wd->parent, &x, &y, &w, &h); // assume parent object is a window
+ //fprintf(stderr, ">>> parent: %d %d %d %d\n", x, y, w, h);
+ evas_object_resize(wd->win_bg, w, h);
+ evas_object_move(wd->win_bg, x, y);
+
+ // layout
+ evas_object_size_hint_weight_set(wd->layout, EVAS_HINT_EXPAND, 0);
+ evas_object_size_hint_align_set(wd->layout, 0.5, 1);
+
+ edje_object_size_min_calc(elm_layout_edje_get(wd->layout), &minw, &minh);
+ fprintf(stderr, ">>> layout's min size(by calc): %d %d %d\n", minw, minh, w);
+
+ evas_object_resize(wd->layout, w, minh);
+
+ // Store show/hide location into wd
+ //evas_object_move(wd->layout, 0, h - minh);
+ wd->show_x = 0;
+ wd->show_y = h - minh;
+ wd->hide_x = 0;
+ wd->hide_y = h;
+
+ evas_object_geometry_get(wd->bt_box, &x, &y, &w, &h);
+ fprintf(stderr, ">>> bt_box: %d %d %d %d\n", x, y, w, h);
+ evas_object_size_hint_min_get(wd->bt_box, &w, &h);
+ fprintf(stderr, ">>> bt_box(size_hint_min): %d %d \n", w, h);
+
+}
+
+static inline int
+_move_layout(Widget_Data *wd, const int until, const int offset)
+{
+ wd->curr_y += offset;
+ if(offset < 0)
+ {
+ if(wd->curr_y < until) wd->curr_y = until;
+ }
+ else
+ {
+ if(wd->curr_y > until) wd->curr_y = until;
+ }
+
+ evas_object_move(wd->layout, wd->curr_x, wd->curr_y);
+
+ if(wd->curr_y == until)
+ {
+ edje_object_signal_emit(elm_layout_edje_get(wd->layout), "elm,actionsheet,event_block_off", "elm");
+ return 0;
+ }
+ else
+ return 1;
+}
+
+static void
+_show_animation_end_cb(void *data, Elm_Transit* transit)
+{
+ Widget_Data *wd = (Widget_Data *)data;
+ // unblock event
+ edje_object_signal_emit(elm_layout_edje_get(wd->layout), "elm,actionsheet,event_block_off", "elm");
+}
+
+static int
+_show_layout(void *data)
+{
+ Widget_Data *wd = (Widget_Data *)data;
+ return _move_layout(wd, wd->show_y, -90);
+}
+
+static void
+_show(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ //int x, y, w, h;
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ _resize(wd, wd->e, obj, obj);
+
+ evas_object_show(wd->win_bg);
+ evas_object_show(wd->layout);
+
+ // move to hide position
+ evas_object_move(wd->layout, wd->hide_x, wd->hide_y);
+ // block events
+ edje_object_signal_emit(elm_layout_edje_get(wd->layout), "elm,actionsheet,event_block_on", "elm");
+
+ // animate to show position
+ wd->curr_x = wd->hide_x;
+ wd->curr_y = wd->hide_y;
+
+
+ //ecore_timer_add(0.033, _show_layout, wd);
+
+ Elm_Transit * transit = elm_transit_add(wd->layout);
+ elm_transit_fx_insert(transit, elm_fx_translation_add(wd->layout, wd->hide_x, wd->hide_y, wd->show_x, wd->show_y));
+ elm_transit_completion_callback_set(transit, _show_animation_end_cb, wd);
+ elm_transit_curve_style_set(transit, ELM_ANIMATOR_CURVE_OUT);
+ elm_transit_run(transit, ANIMATION_TIME);
+ elm_transit_del(transit);
+
+ edje_object_signal_emit(elm_layout_edje_get(wd->layout), "show", "actionsheet");
+ edje_object_signal_emit(elm_layout_edje_get(wd->win_bg), "show", "actionsheet");
+}
+
+static void
+_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ evas_object_hide(wd->layout);
+}
+
+static void
+_button_cb_wrapper(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Button_Cb_Data_Wrapper *dw = (Button_Cb_Data_Wrapper *)data;
+ dw->cb_func(dw->cb_data, dw->obj, dw->button_title);
+}
+
+/**
+ * Add a new actionsheet to the parent
+ * Object constructor
+ *
+ * @param parent The parent object
+ * @return The new actionsheet object, or null if it can't be created.
+ *
+ * @ingroup ActionSheet
+ */
+EAPI Evas_Object *
+elm_actionsheet_add (Evas_Object *parent)
+{
+ Evas_Object *obj;
+ Widget_Data *wd;
+
+ /* widget data */
+ wd = ELM_NEW(Widget_Data); // allocate memory
+
+ /* widget object */
+ wd->e = evas_object_evas_get(parent);
+ obj = elm_widget_add(wd->e); // get a new smart object(=widget)
+ elm_widget_type_set(obj, "actionsheet"); // set a smart object's type name
+
+ elm_widget_sub_object_add(parent, obj);
+ elm_widget_data_set(obj, wd); // store wd pointer to smart_data->data
+
+ elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+ elm_widget_del_hook_set(obj, _del_hook);
+ elm_widget_theme_hook_set(obj, _theme_hook);
+
+ /* actionsheet layout */
+ wd->layout = elm_layout_add(parent);
+ elm_layout_theme_set(wd->layout, "actionsheet", "base", "default");
+ evas_object_size_hint_weight_set(wd->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(wd->layout, 0.5, 1);
+ elm_widget_sub_object_add(obj, wd->layout);
+ elm_widget_hover_object_set(obj, wd->layout);
+
+ /* win_bg */
+ wd->win_bg = elm_layout_add(parent);
+ elm_layout_theme_set(wd->win_bg, "actionsheet", "bg", "default");
+ elm_widget_sub_object_add(obj, wd->win_bg);
+ elm_widget_resize_object_set(obj, wd->win_bg);
+
+ /* bt_box */
+ wd->bt_box = elm_box_add(wd->layout);
+ evas_object_size_hint_weight_set(wd->bt_box, 0, EVAS_HINT_EXPAND);
+ elm_layout_content_set(wd->layout, "v_sw", wd->bt_box);
+ evas_object_show(wd->bt_box);
+
+ /* set Widget_Data */
+ wd->parent = parent;
+ wd->obj = obj;
+
+#ifdef SKIP
+#endif
+
+ /* set callbacks */
+ /* win cb */
+
+ /* obj cb */
+
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _show, obj);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _hide, obj);
+
+ _resize(wd, wd->e, obj, obj);
+
+
+ fprintf(stderr, ">>>>> after:adding layout\n");
+ return obj;
+}
+
+/**
+ * @brief Get title of button with given index
+ * @param[in] obj is an actionsheet object.
+ * @param[in] index is the index of button
+ * @param[out] title is button's title
+ * @return length of the string
+ * @retval -EINVAL Invalid index
+ */
+EAPI int
+elm_actionsheet_button_title_get (
+ Evas_Object *obj,
+ const int index,
+ char **title )
+{
+// Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
+
+ return 0;
+}
+
+/**
+ * @brief Add a button with given title.
+ * Can add normal button only.
+ * @param[in] obj An actionsheet.
+ * @param[in] type The type of the button to be added.
+ * @param[in] title Title string.
+ * @return void
+ */
+EAPI void
+elm_actionsheet_button_add (
+ Evas_Object *obj,
+ const Elm_Actionsheet_Button_Type type,
+ const char *title,
+ void (*cb_func) (void *data, Evas_Object *obj, void *event_info),
+ void *cb_data)
+{
+ Evas_Object **target = NULL;
+ char *button_style;
+ Widget_Data *wd;
+ int w, h;
+ int box_w, box_h;
+
+ wd = (Widget_Data *) elm_widget_data_get(obj);
+
+ switch(type)
+ {
+ case ELM_ACTIONSHEET_BT_CANCEL:
+ target = &(wd->bt_cancel);
+ button_style = "cancel";
+ break;
+ case ELM_ACTIONSHEET_BT_DESTRUCTIVE:
+ target = &(wd->bt_destructive);
+ button_style = "destructive";
+ break;
+ case ELM_ACTIONSHEET_BT_NORMAL:
+ target = &(wd->bt_normal);
+ button_style = "normal";
+ break;
+ default:
+ return;
+ }
+ // case: cancel, destructive
+ // if button object is already exist, just change title
+ if ( type != ELM_ACTIONSHEET_BT_NORMAL && *target != NULL )
+ {
+ elm_button_label_set(*target, title);
+ }
+ else
+ {
+ *target = elm_layout_add(obj);
+ elm_layout_theme_set(*target, "actionsheet", "button", button_style);
+ edje_object_part_text_set(elm_layout_edje_get(*target), "text", title);
+ evas_object_size_hint_weight_set(*target, 0, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(*target, EVAS_HINT_FILL, 0);
+ evas_object_show(*target);
+
+ // set callback wrapper
+ Button_Cb_Data_Wrapper *dw = _button_cb_data_wrapper_add(obj, cb_func, cb_data, title);
+ edje_object_signal_callback_add(elm_layout_edje_get(*target), "elm,action,press", "", _button_cb_wrapper, dw);
+ // store data wrapper into eina list (to free all)
+ wd->cb_data_list = eina_list_append(wd->cb_data_list, dw);
+
+ switch (type) {
+ case ELM_ACTIONSHEET_BT_DESTRUCTIVE:
+ elm_box_pack_start(wd->bt_box, *target);
+ if(NULL == wd->bt_normal_delim) {
+ wd->bt_normal_delim = *target;
+ }
+ break;
+
+ case ELM_ACTIONSHEET_BT_NORMAL:
+ if(NULL == wd->bt_normal_delim) {
+ elm_box_pack_start(wd->bt_box, *target);
+ }
+ else {
+ elm_box_pack_after(wd->bt_box, *target, wd->bt_normal_delim);
+ }
+ wd->bt_normal_delim = *target;
+ break;
+
+ case ELM_ACTIONSHEET_BT_CANCEL:
+ elm_box_pack_end(wd->bt_box, *target);
+ break;
+
+ default:
+ fprintf(stderr, ">>> wrong button type\n");
+ evas_object_del(*target);
+ return;
+ }
+
+ evas_object_size_hint_min_get(wd->bt_box, &box_w, &box_h);
+ edje_object_size_min_calc(elm_layout_edje_get(*target), &w, &h);
+ //evas_object_size_hint_min_get(*target, &w, &h);
+ fprintf(stderr, ">>> calc. box's h: %d + %d\n", box_h, h);
+ evas_object_size_hint_min_set(wd->bt_box, box_w>w?box_w:w, box_h+h);
+
+ }
+
+ _resize(wd, wd->e, obj, obj);
+}
+
+
+/**
+ * @brief Set actionsheet title
+ * Can add normal button only.
+ * @param[in] obj is an actionsheet.
+ * @param[in] title title string. If NULL, unset existing title.
+ * @return void
+ */
+EAPI void
+elm_actionsheet_title_set (
+ Evas_Object *obj,
+ const char *title)
+{
+// Widget_Data *wd = (Widget_Data *) elm_widget_data_get(obj);
+}
+
+/* end of file */
+/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
--- /dev/null
+
+
+/**
+ *
+ * @defgroup Analogclock Analogclock
+ * @ingroup Elementary
+ *
+ * This is an analogclock.
+ */
+
+
+/*
+ *
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#include "elm_priv.h"
+
+#define dbg(fmt,args...) printf("[%s:%d] "fmt"\n", __FILE__, __LINE__, ##args);
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+ Evas_Object *dial,
+ *hand_hour,
+ *hand_min;
+
+ Ecore_Timer *ticker;
+
+ int hour,
+ min;
+};
+
+
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static Eina_Bool _ticker(void *data);
+static void _time_update(Evas_Object *obj);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (wd->ticker) ecore_timer_del(wd->ticker);
+ free(wd);
+}
+
+static Eina_Bool
+_ticker(void *data)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ double t;
+ struct timeval timev;
+
+ gettimeofday(&timev, NULL);
+ t = ((double)(1000000 - timev.tv_usec)) / 1000000.0;
+ wd->ticker = ecore_timer_add(t, _ticker, data);
+ _time_update(data);
+ return 0;
+}
+
+static Eina_Bool
+_idle_draw (void *data)
+{
+ _ticker(data);
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ _time_update(data);
+}
+
+static void
+_object_rotate(Evas_Object *obj, double degree)
+{
+ const Evas_Map *m;
+ Evas_Map *m2;
+ Evas_Coord x, y, w, h;
+
+ evas_object_geometry_get (obj, &x, &y, &w, &h);
+ evas_object_hide (obj);
+
+ m = evas_object_map_get (obj);
+ if (m != NULL)
+ m2 = evas_map_dup(m);
+ else {
+ m2 = evas_map_new(4);
+ }
+
+ evas_map_util_points_populate_from_object (m2, obj);
+ evas_map_util_rotate (m2, degree, x+w/2, y+h/2);
+ evas_object_map_set (obj, m2);
+ evas_object_map_enable_set(obj, 1);
+ evas_map_free (m2);
+ evas_object_show (obj);
+}
+
+static void
+_time_update(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ double degree;
+ Evas_Coord x, y, w, h;
+ struct timeval timev;
+ struct tm *tm;
+ time_t tt;
+
+ evas_object_geometry_get (wd->dial, &x, &y, &w, &h);
+ if (w <= 0 || h <= 0) {
+ return;
+ }
+
+ gettimeofday(&timev, NULL);
+ tt = (time_t)(timev.tv_sec);
+ tzset();
+ tm = localtime(&tt);
+ if (tm)
+ {
+ wd->hour = tm->tm_hour;
+ wd->min = tm->tm_min;
+ if (wd->hour > 12) wd->hour -= 12;
+ }
+
+ degree = 6 * wd->min;
+ _object_rotate (wd->hand_min, degree);
+
+ degree = 30 * wd->hour + (wd->min / 2);
+ _object_rotate (wd->hand_hour, degree);
+}
+
+/*
+ * FIXME:
+ */
+static void
+_theme_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ _elm_theme_object_set(obj,wd->dial, "analogclock", "base", elm_widget_style_get(obj));
+
+ _sizing_eval(obj);
+
+ evas_object_show (wd->dial);
+}
+
+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;
+ Evas_Coord w, h;
+
+ if (!wd) return;
+
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ edje_object_size_min_restricted_calc(wd->dial, &minw, &minh, minw, minh);
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+
+ evas_object_size_hint_min_get(obj, &w, &h);
+ if (w > minw) minw = w;
+ if (h > minw) minh = h;
+
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+/**
+ * Add a new analog clock to the parent
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ */
+EAPI Evas_Object *
+elm_analogclock_add(Evas_Object *parent)
+{
+ Evas_Object *obj;
+ Evas *e;
+ Widget_Data *wd;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ obj = elm_widget_add(e);
+ elm_widget_type_set(obj, "analogclock");
+ 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, 0);
+
+ wd->dial = edje_object_add(e);
+
+ _elm_theme_object_set(obj,wd->dial, "analogclock", "base", "default");
+
+ wd->hand_hour = edje_object_part_object_get (wd->dial, "hour");
+ wd->hand_min = edje_object_part_object_get (wd->dial, "minute");
+
+ evas_object_event_callback_add(wd->dial, EVAS_CALLBACK_MOVE, _move, obj);
+
+ elm_widget_resize_object_set(obj, wd->dial);
+ wd->hour = 0;
+ wd->min = 0;
+
+ _sizing_eval(obj);
+
+ ecore_idler_add (_idle_draw, obj);
+
+ return obj;
+}
+
--- /dev/null
+#include <Elementary.h>\r
+#include "elm_priv.h"\r
+#include <string.h>\r
+\r
+/**\r
+ * @defgroup Autocompleteview Autocompleteview\r
+ * @ingroup Elementary\r
+ *\r
+ * This widget show's the completed strings in a dropdown list \r
+ * based on the initial few characters entered by the user.\r
+ *\r
+ */\r
+\r
+typedef struct _Widget_Data Widget_Data;\r
+\r
+struct _Widget_Data\r
+{\r
+ Evas_Object *editfield;\r
+ Evas_Object *hover;\r
+ Evas_Object *layout;\r
+ Evas_Object *list;\r
+ Evas_Object *entry;\r
+ Eina_List *data_list;\r
+ Eina_Bool text_set : 1;\r
+ elmautocompleteview_matchfunction func;\r
+ void *data;\r
+ int threshold;\r
+};\r
+\r
+static void _editfield_clicked_cb(void *data, Evas_Object *obj, void *event_info)\r
+{\r
+ evas_object_smart_callback_call(data, "clicked", NULL);\r
+}\r
+\r
+static void _entry_changed_cb(void *data, Evas_Object *obj, void *event_info)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(data);\r
+ const char *text = NULL;\r
+ int textlen = 0;\r
+ char *real = NULL,*res = NULL;\r
+ Eina_List *l;\r
+ Eina_Bool textfound = EINA_FALSE;\r
+ if(!wd) return;\r
+ if (elm_widget_disabled_get(data)) return;\r
+ if(wd->text_set)\r
+ {\r
+ evas_object_hide(wd->hover);\r
+ wd->text_set = EINA_FALSE;\r
+ return;\r
+ }\r
+ text = elm_entry_entry_get(obj);\r
+ if(text == NULL)\r
+ return; \r
+ textlen = strlen(text);\r
+ if(textlen <wd->threshold)\r
+ {\r
+ evas_object_hide(wd->hover);\r
+ return;\r
+ } \r
+ evas_object_hide(wd->hover);\r
+ if(wd->func)\r
+ {\r
+ textfound = wd->func(data,text,wd->list,wd->data);\r
+ }\r
+ else if(wd->data_list) \r
+ {\r
+ elm_list_clear(wd->list);\r
+ EINA_LIST_FOREACH(wd->data_list, l, real) \r
+ {\r
+ res = strcasestr(real,text);\r
+ if(res)\r
+ {\r
+ elm_list_item_append(wd->list, real, NULL, NULL, \r
+ NULL, NULL);\r
+ textfound=EINA_TRUE;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ return;\r
+ if(textfound)\r
+ {\r
+ elm_list_go(wd->list); \r
+ evas_object_show(wd->hover);\r
+ }\r
+\r
+}\r
+\r
+static void\r
+_del_pre_hook(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(wd->hover)\r
+ evas_object_del(wd->hover);\r
+}\r
+\r
+\r
+static void\r
+_del_hook(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ free(wd);\r
+}\r
+\r
+static void\r
+_sizing_eval(Evas_Object *obj)\r
+{\r
+ Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;\r
+\r
+ evas_object_size_hint_min_set(obj, minw, minh);\r
+ evas_object_size_hint_max_set(obj, maxw, maxh);\r
+}\r
+\r
+static void\r
+_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
+{\r
+ _sizing_eval(data);\r
+}\r
+\r
+static void\r
+_hover_clicked(void *data, Evas_Object *obj, void *event_info)\r
+{\r
+ printf("\n\ncurrently nothin to be done\n");\r
+}\r
+\r
+static void _list_click( void *data, Evas_Object *obj, void *event_info )\r
+{\r
+ Elm_List_Item *it = (Elm_List_Item *) elm_list_selected_item_get(obj);\r
+ Widget_Data *wd = elm_widget_data_get(data);\r
+ if((it==NULL)||(wd==NULL))\r
+ return;\r
+ const char *text = elm_list_item_label_get(it);\r
+ evas_object_smart_callback_call((Evas_Object *)data, "selected", (void *)text);\r
+ if(wd->data_list)\r
+ {\r
+ if(text!=NULL)\r
+ {\r
+ elm_entry_entry_set(wd->entry, text);\r
+ elm_entry_cursor_end_set(wd->entry);\r
+ wd->text_set = EINA_TRUE;\r
+ }\r
+ }\r
+}\r
+\r
+static int\r
+_eina_cmp_str(const char *a, const char *b)\r
+{\r
+ return strcasecmp(a,b);\r
+}\r
+\r
+\r
+/**\r
+ * Add a new Autocompleteview object\r
+ *\r
+ * @param parent The parent object\r
+ * @return The new object or NULL if it cannot be created\r
+ *\r
+ * @ingroup Autocompleteview\r
+ */\r
+EAPI Evas_Object *\r
+elm_autocompleteview_add(Evas_Object *parent)\r
+{\r
+ Evas_Object *obj;\r
+ Evas *e;\r
+ Widget_Data *wd;\r
+\r
+ wd = ELM_NEW(Widget_Data);\r
+ e = evas_object_evas_get(parent);\r
+ obj = elm_widget_add(e);\r
+ elm_widget_type_set(obj, "autocompleteview");\r
+ elm_widget_sub_object_add(parent, obj);\r
+ elm_widget_data_set(obj, wd);\r
+ elm_widget_del_pre_hook_set(obj, _del_pre_hook);\r
+ elm_widget_del_hook_set(obj, _del_hook);\r
+\r
+ wd->editfield = elm_editfield_add(parent);\r
+ elm_widget_resize_object_set(obj, wd->editfield);\r
+ elm_editfield_entry_single_line_set(wd->editfield, EINA_TRUE);\r
+ evas_object_size_hint_weight_set(wd->editfield, 0, EVAS_HINT_EXPAND);\r
+ evas_object_size_hint_align_set(wd->editfield, 0, EVAS_HINT_FILL);\r
+ evas_object_event_callback_add(wd->editfield,\r
+ EVAS_CALLBACK_CHANGED_SIZE_HINTS,\r
+ _changed_size_hints, obj);\r
+ wd->threshold = 1;\r
+ wd->entry = elm_editfield_entry_get(wd->editfield);\r
+\r
+ evas_object_smart_callback_add(wd->editfield, "clicked", _editfield_clicked_cb, obj);\r
+ evas_object_smart_callback_add(wd->entry, "changed", _entry_changed_cb, obj);\r
+\r
+ wd->hover = elm_hover_add(obj);\r
+ elm_hover_parent_set(wd->hover, parent);\r
+ elm_hover_target_set(wd->hover, wd->editfield);\r
+\r
+ wd->layout = elm_layout_add(wd->hover);\r
+ elm_layout_theme_set(wd->layout,"autocompleteview","base","default");\r
+ wd->list = elm_list_add(wd->layout);\r
+ evas_object_size_hint_weight_set(wd->list, EVAS_HINT_EXPAND, 0.0);\r
+ evas_object_size_hint_align_set(wd->list, EVAS_HINT_FILL, EVAS_HINT_FILL);\r
+ elm_list_horizontal_mode_set(wd->list, ELM_LIST_COMPRESS);\r
+ elm_object_style_set(wd->list,"autocompleteview");\r
+ elm_list_go(wd->list);\r
+ evas_object_smart_callback_add(wd->list, "selected", _list_click, obj);\r
+ elm_layout_content_set( wd->layout, "elm.swallow.content", wd->list );\r
+ elm_hover_content_set(wd->hover,\r
+ elm_hover_best_content_location_get(wd->hover,\r
+ ELM_HOVER_AXIS_VERTICAL),\r
+ wd->layout);\r
+ evas_object_smart_callback_add(wd->hover, "clicked", _hover_clicked, obj);\r
+\r
+ _sizing_eval(obj);\r
+ return obj;\r
+}\r
+\r
+\r
+/**\r
+ * This Get's the entry object of Autocompleteview object.\r
+ *\r
+ * @param obj The Autocompleteview object.\r
+ * @return the entry object.\r
+ *\r
+ * @ingroup Autocompleteview\r
+ */\r
+EAPI Evas_Object *\r
+elm_autocompleteview_entry_get(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd) return NULL;\r
+\r
+ return wd->entry;\r
+}\r
+\r
+/**\r
+ * This Get's the editfield object of the Autocompleteview object.\r
+ *\r
+ * @param obj The Autocompleteview object.\r
+ * @return The Editfield object.\r
+ *\r
+ * @ingroup Autocompleteview\r
+ */\r
+EAPI Evas_Object *\r
+elm_autocompleteview_editfield_get(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd) return NULL;\r
+\r
+ return wd->editfield;\r
+}\r
+\r
+\r
+/**\r
+ * This Specifies the minimum number of characters the user has to type in the editfield \r
+ * before the drop down list is shown.When threshold is less than or equals 0, a threshold of 1 is applied by default.\r
+ *\r
+ * @param obj The Autocompleteview object\r
+ * @param threshold the number of characters to type before the drop down is shown\r
+ *\r
+ * @ingroup Autocompleteview\r
+ */\r
+EAPI void\r
+elm_autocompleteview_threshold_set(Evas_Object *obj, int threshold)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd) return;\r
+\r
+ if(threshold <=0)\r
+ {\r
+ wd->threshold = 1;\r
+ }\r
+ else\r
+ {\r
+ wd->threshold = threshold;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ * This Returns the number of characters the user must type before the drop down list is shown.\r
+ *\r
+ * @param obj The Autocompleteview object.\r
+ * @return The threshold value.\r
+ *\r
+ * @ingroup Autocompleteview\r
+ */\r
+EAPI int\r
+elm_autocompleteview_threshold_get(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd) return -1;\r
+\r
+ return wd->threshold;\r
+}\r
+\r
+\r
+/**\r
+ * This Specifies the list of strings which has to be searched to get the list of completion strings.\r
+ *\r
+ * @param obj The Autocompleteview object\r
+ * @param data_list the list of static strings, which has to be searched to get the completion strings.\r
+ *\r
+ * @ingroup Autocompleteview\r
+ */\r
+EAPI void\r
+elm_autocompleteview_data_set(Evas_Object *obj, Eina_List *data_list)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd) return;\r
+\r
+ wd->data_list = data_list;\r
+\r
+ /*storing sorted list*/\r
+ wd->data_list = eina_list_sort(wd->data_list, eina_list_count(wd->data_list), EINA_COMPARE_CB(_eina_cmp_str));\r
+}\r
+\r
+\r
+/**\r
+ * This Registers the callback function that would be called whenever text is entered in to the entry.\r
+ *\r
+ * @param obj The Autocompleteview object\r
+ * @param elmautocompleteview_matchfunction completion function which list's the completion strings.\r
+ * @param data userdata that would be passed whenever the callback function is called.\r
+ *\r
+ * @ingroup Autocompleteview\r
+ */\r
+EAPI void\r
+elm_autocompleteview_match_func_set(Evas_Object *obj, elmautocompleteview_matchfunction func,void *data)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd) return;\r
+\r
+ wd->func = func;\r
+ wd->data = data;\r
+}\r
+\r
+/**\r
+ * This updates the text in to autocomplete view.\r
+ *\r
+ * @param obj The Autocompleteview object\r
+ * @param text the text to be updated in to the entry of autocompleteview.\r
+ *\r
+ * @ingroup Autocompleteview\r
+ */\r
+EAPI void\r
+elm_autocompleteview_text_update(Evas_Object *obj, char *text)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd) return;\r
+\r
+ if(text!=NULL)\r
+ {\r
+ elm_entry_entry_set(wd->entry, text);\r
+ elm_entry_cursor_end_set(wd->entry);\r
+ wd->text_set = EINA_TRUE;\r
+ }\r
+}\r
--- /dev/null
+#include <Elementary.h>
+#include "elm_priv.h"
+#include "els_scroller.h"
+
+// FIXME: this is NOT the carousel - yet!
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+ Evas_Object *scr, *bx;
+ Eina_List *items;
+ int icon_size;
+};
+
+struct _Elm_Carousel_Item
+{
+ Evas_Object *obj, *base, *icon;
+ const char *label;
+ Evas_Smart_Cb func;
+ const void *data;
+ Eina_Bool selected : 1;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+
+static void
+_item_show(Elm_Carousel_Item *it)
+{
+ Widget_Data *wd = elm_widget_data_get(it->obj);
+ Evas_Coord x, y, w, h, bx, by;
+ if (!wd) return;
+ evas_object_geometry_get(wd->bx, &bx, &by, NULL, NULL);
+ evas_object_geometry_get(it->base, &x, &y, &w, &h);
+ elm_smart_scroller_child_region_show(wd->scr, x - bx, y - by, w, h);
+}
+
+static void
+_item_select(Elm_Carousel_Item *it)
+{
+ Elm_Carousel_Item *it2;
+ Widget_Data *wd = elm_widget_data_get(it->obj);
+ Evas_Object *obj2;
+ const Eina_List *l;
+ if (!wd) return;
+ if (it->selected) return;
+ EINA_LIST_FOREACH(wd->items, l, it2)
+ {
+ if (it2->selected)
+ {
+ it2->selected = EINA_FALSE;
+ edje_object_signal_emit(it2->base, "elm,state,unselected", "elm");
+ break;
+ }
+ }
+ it->selected = EINA_TRUE;
+ edje_object_signal_emit(it->base, "elm,state,selected", "elm");
+ _item_show(it);
+ obj2 = it->obj;
+ if (it->func) it->func((void *)(it->data), it->obj, it);
+ evas_object_smart_callback_call(obj2, "clicked", it);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ const Eina_List *l;
+ const Elm_Carousel_Item *it;
+ if (!wd) return;
+ EINA_LIST_FOREACH(wd->items, l, it)
+ {
+ Evas_Coord mw, mh;
+
+ if (it->selected)
+ edje_object_signal_emit(it->base, "elm,state,selected", "elm");
+ _elm_theme_object_set(obj, it->base, "carousel", "item", elm_widget_style_get(obj));
+ edje_object_scale_set(it->base, elm_widget_scale_get(obj) * _elm_config->scale);
+ if (it->icon)
+ {
+ edje_extern_object_min_size_set(it->icon,
+ (double)wd->icon_size * _elm_config->scale,
+ (double)wd->icon_size * _elm_config->scale);
+ edje_object_part_swallow(it->base, "elm.swallow.icon", it->icon);
+ }
+ edje_object_part_text_set(it->base, "elm.text", it->label);
+ edje_object_size_min_calc(it->base, &mw, &mh);
+ evas_object_size_hint_min_set(it->base, mw, mh);
+ evas_object_size_hint_max_set(it->base, 9999, mh);
+ }
+ _sizing_eval(obj);
+}
+
+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;
+ Evas_Coord vw = 0, vh = 0;
+ if (!wd) return;
+ edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), &minw, &minh);
+ evas_object_resize(wd->scr, 500, 500);
+ evas_object_size_hint_min_get(wd->bx, &minw, &minh);
+ evas_object_resize(wd->bx, minw, minh);
+ elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+ minw = minw + (500 - vw);
+ minh = minh + (500 - vh);
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Coord mw, mh, vw, vh, w, h;
+ const Eina_List *l;
+ Elm_Carousel_Item *it;
+ if (!wd) return;
+ elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+ evas_object_size_hint_min_get(wd->bx, &mw, &mh);
+ evas_object_geometry_get(wd->bx, NULL, NULL, &w, &h);
+ if (vw >= mw)
+ {
+ if (w != vw) evas_object_resize(wd->bx, vw, h);
+ }
+ EINA_LIST_FOREACH(wd->items, l, it)
+ {
+ if (it->selected)
+ {
+ _item_show(it);
+ break;
+ }
+ }
+
+}
+
+static void
+_select(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+ _item_select(data);
+}
+
+EAPI Evas_Object *
+elm_carousel_add(Evas_Object *parent)
+{
+ Evas_Object *obj;
+ Evas *e;
+ Widget_Data *wd;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ obj = elm_widget_add(e);
+ ELM_SET_WIDTYPE(widtype, "carousel");
+ elm_widget_type_set(obj, "carousel");
+ 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, 0);
+
+ wd->scr = elm_smart_scroller_add(e);
+ elm_smart_scroller_widget_set(wd->scr, obj);
+ elm_smart_scroller_object_theme_set(obj, wd->scr, "carousel", "base", "default");
+ elm_widget_resize_object_set(obj, wd->scr);
+ elm_smart_scroller_policy_set(wd->scr,
+ ELM_SMART_SCROLLER_POLICY_AUTO,
+ ELM_SMART_SCROLLER_POLICY_OFF);
+
+ wd->icon_size = 32;
+
+ wd->bx = evas_object_box_add(e);
+ evas_object_box_layout_set(wd->bx,
+ evas_object_box_layout_homogeneous_horizontal, NULL, NULL);
+ elm_widget_sub_object_add(obj, wd->bx);
+ elm_smart_scroller_child_set(wd->scr, wd->bx);
+ evas_object_show(wd->bx);
+
+ evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE,
+ _resize, obj);
+
+ _sizing_eval(obj);
+ return obj;
+}
+
+EAPI Elm_Carousel_Item *
+elm_carousel_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, Evas_Smart_Cb func, const void *data)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+ Evas_Coord mw, mh;
+ Elm_Carousel_Item *it = calloc(1, sizeof(Elm_Carousel_Item));
+
+ if (!it) return NULL;
+ wd->items = eina_list_append(wd->items, it);
+ it->obj = obj;
+ it->label = eina_stringshare_add(label);
+ it->icon = icon;
+ it->func = func;
+ it->data = data;
+ it->base = edje_object_add(evas_object_evas_get(obj));
+ _elm_theme_object_set(obj, it->base, "carousel", "item", elm_widget_style_get(obj));
+ edje_object_signal_callback_add(it->base, "elm,action,click", "elm",
+ _select, it);
+ elm_widget_sub_object_add(obj, it->base);
+ if (it->icon)
+ {
+ edje_extern_object_min_size_set(it->icon,
+ (double)wd->icon_size * _elm_config->scale,
+ (double)wd->icon_size * _elm_config->scale);
+ edje_object_part_swallow(it->base, "elm.swallow.icon", it->icon);
+ evas_object_show(it->icon);
+ elm_widget_sub_object_add(obj, it->icon);
+ }
+ edje_object_part_text_set(it->base, "elm.text", it->label);
+ edje_object_size_min_calc(it->base, &mw, &mh);
+ evas_object_size_hint_weight_set(it->base, 0.0, 0.0);
+ evas_object_size_hint_align_set(it->base, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_min_set(it->base, mw, mh);
+ evas_object_size_hint_max_set(it->base, 9999, mh);
+ evas_object_box_append(wd->bx, it->base);
+ evas_object_show(it->base);
+ _sizing_eval(obj);
+ return it;
+}
+
+EAPI void
+elm_carousel_item_del(Elm_Carousel_Item *it)
+{
+ Widget_Data *wd = elm_widget_data_get(it->obj);
+ Evas_Object *obj2 = it->obj;
+ if (!wd) return;
+ wd->items = eina_list_remove(wd->items, it);
+ eina_stringshare_del(it->label);
+ if (it->icon) evas_object_del(it->icon);
+ evas_object_del(it->base);
+ free(it);
+ _theme_hook(obj2);
+}
+
+EAPI void
+elm_carousel_item_select(Elm_Carousel_Item *item)
+{
+ _item_select(item);
+}
--- /dev/null
+#include <Elementary.h>
+#include "elm_priv.h"
+#include <langinfo.h>
+#include <string.h>
+
+/**
+ * @defgroup Datepicker Datepicker
+ * @ingroup Elementary
+ *
+ * This is a date picker.
+ */
+
+enum {
+ PICKER_YEAR,
+ PICKER_MON,
+ PICKER_DAY,
+ PICKER_MAX
+};
+
+#define YEAR_MIN (1900)
+#define YEAR_MAX (2099)
+#define MONTH_MIN (1)
+#define MONTH_MAX (12)
+#define DAY_MIN (1)
+#define DAY_MAX (31)
+#define MONTH_MAX (12)
+#define DAY_MAX (31)
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data {
+ Evas_Object *base;
+ Evas_Object *pickers[PICKER_MAX];
+ int y_max, m_max, d_max;
+ int y_min, m_min, d_min;
+ int day_of_month;
+ int year, month, day;
+ char fmt[8];
+};
+
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _i18n(Evas_Object *obj);
+static Evas_Object *_picker_add(Evas_Object *ly, const char *part, int min, int max, const char *fmt);
+static void _pickers_del(Evas_Object *obj);
+static void _picker_item_add(Evas_Object *eo, int min, int max, const char *fmt);
+static void _picker_item_del(Evas_Object *eo);
+static void _update_day_of_month(Evas_Object *obj, int month);
+static void _update_picker(Evas_Object *picker, int nth);
+static void _changed(Evas_Object *picker, Evas_Object *child, Evas_Object *obj);
+static void _overflow_cb(void *data, Evas_Object *obj, void *event_info);
+static void _underflow_cb(void *data, Evas_Object *obj, void *event_info);
+static void _year_changed_cb(void *data, Evas_Object *obj, void *event_info);
+static void _month_changed_cb(void *data, Evas_Object *obj, void *event_info);
+static void _day_changed_cb(void *data, Evas_Object *obj, void *event_info);
+static void _pickers_add(Evas_Object *obj);
+static void _callback_init(Evas_Object *obj);
+
+static Eina_Bool
+_is_valid_date(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ int cur, min, max;
+ if (!wd) return EINA_FALSE;
+
+ cur = wd->year * 10000 + wd->month * 100 + wd->day;
+ max = wd->y_max * 10000 + wd->m_max * 100 + wd->d_max;
+ min = wd->y_min * 10000 + wd->m_min * 100 + wd->d_min;
+
+ if (cur > max || cur < min) return EINA_FALSE;
+ return EINA_TRUE;
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ _pickers_del(obj);
+ free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ _pickers_del(obj);
+ _elm_theme_object_set(obj, wd->base, "datepicker", "base", elm_widget_style_get(obj));
+ _pickers_add(obj);
+ _i18n(obj);
+
+ _update_picker(wd->pickers[PICKER_YEAR], wd->year - wd->y_min);
+ _update_picker(wd->pickers[PICKER_MON], wd->month - 1);
+ _update_picker(wd->pickers[PICKER_DAY], wd->day - 1);
+
+ _sizing_eval(obj);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+
+}
+
+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;
+
+ if (!wd) return;
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_i18n(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ const char *fmt;
+ char sig[32] = { "elm,state," };
+ int i = 0, j, k;
+
+ if (!wd) return;
+
+ j = strlen(sig);
+ k = j;
+ fmt = nl_langinfo(D_FMT);
+
+ while (fmt[i] && j < 32) {
+ if (fmt[i] == '%' && fmt[i+1]) {
+ i++;
+ switch (fmt[i]) {
+ case 'Y': case 'M': case 'D': case 'y': case 'm': case 'd':
+ sig[j++] = tolower(fmt[i]);
+ sig[j++] = tolower(fmt[i]);
+ break;
+ default:
+ break;
+ }
+ }
+ i++;
+ }
+ sig[j] = '\0';
+ edje_object_signal_emit(wd->base, sig, "elm");
+ snprintf(wd->fmt, 8, sig + k);
+}
+
+static void
+_picker_item_add(Evas_Object *eo, int min, int max, const char *fmt)
+{
+ char buf[8];
+ for (; min <= max; min++) {
+ snprintf(buf, 8, fmt, min);
+ elm_picker_item_append(eo, buf, NULL, NULL);
+ }
+}
+
+static void
+_picker_item_del(Evas_Object *eo)
+{
+ Elm_Picker_Item *item;
+ item = elm_picker_first_item_get(eo);
+ while (item) {
+ elm_picker_item_del(item);
+ item = elm_picker_first_item_get(eo);
+ }
+}
+
+static Evas_Object *
+_picker_add(Evas_Object *ly, const char *part, int min, int max, const char *fmt)
+{
+ Evas_Object *eo;
+ eo = elm_picker_add(ly);
+ _picker_item_add(eo, min, max, fmt);
+ if (part)
+ edje_object_part_swallow(ly, part, eo);
+ return eo;
+}
+
+static void
+_update_day_of_month(Evas_Object *obj, int month)
+{
+ int tmp;
+ Elm_Picker_Item *item;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ tmp = wd->day_of_month;
+ switch (month) {
+ case 4: case 6: case 9: case 11:
+ wd->day_of_month = 30;
+ break;
+ case 2:
+ if ((!(wd->year % 4) && (wd->year % 100)) || !(wd->year % 400))
+ wd->day_of_month = 29;
+ else
+ wd->day_of_month = 28;
+ break;
+ default:
+ wd->day_of_month = 31;
+ break;
+ }
+
+ if (wd->day > wd->day_of_month) {
+ wd->day = wd->day_of_month;
+ }
+
+ if (tmp == wd->day_of_month) return;
+ if (tmp > wd->day_of_month) {
+ for (; tmp > wd->day_of_month; tmp--) {
+ item = elm_picker_last_item_get(wd->pickers[PICKER_DAY]);
+ elm_picker_item_del(item);
+ }
+ } else {
+ char buf[8];
+ tmp++;
+ for (; tmp <= wd->day_of_month; tmp++) {
+ snprintf(buf, 8, "%2d", tmp);
+ elm_picker_item_append(wd->pickers[PICKER_DAY], buf, NULL, NULL);
+ }
+ }
+}
+
+static void
+_update_picker(Evas_Object *picker, int nth)
+{
+ const Eina_List *l;
+ Elm_Picker_Item *item;
+ int i;
+ l = elm_picker_items_get(picker);
+ for (i = 0; i < nth; i++) {
+ l = l->next;
+ if (!l) break;
+ }
+ item = eina_list_data_get(l);
+ elm_picker_item_selected_set(item);
+}
+
+static void
+_changed(Evas_Object *picker, Evas_Object *child, Evas_Object *obj)
+{
+ int c1, c2 = 0;
+ c1 = (int)(evas_object_data_get(picker, "carryon"));
+ evas_object_data_set(picker, "carryon", (void *)0);
+
+ if (child) {
+ c2 = (int)(evas_object_data_get(child, "carryon"));
+ evas_object_data_set(child, "carryon", (void *)0);
+ }
+
+ if (!c1 && !c2)
+ evas_object_smart_callback_call(obj, "changed", NULL);
+}
+
+static void
+_overflow_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Evas_Object *eo;
+ eo = evas_object_data_get(obj, "parent");
+ if (eo) {
+ elm_picker_next(eo);
+ evas_object_data_set(obj, "carryon", (void *)1);
+ }
+}
+
+static void
+_underflow_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Evas_Object *eo;
+ eo = evas_object_data_get(obj, "parent");
+ Widget_Data *wd = elm_widget_data_get(data);
+
+ if (eo) {
+ elm_picker_prev(eo);
+ evas_object_data_set(obj, "carryon", (void *)-1);
+ }
+
+ if (obj == wd->pickers[PICKER_DAY]) {
+ Elm_Picker_Item *item;
+ _update_day_of_month(data, wd->month - 1);
+ wd->day = wd->day_of_month;
+ item = elm_picker_last_item_get(obj);
+ elm_picker_item_selected_set(item);
+ }
+}
+
+static void
+_year_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ const char *year;
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Object *child;
+ if (!wd) return;
+
+ year = elm_picker_item_label_get(event_info);
+ wd->year = atoi(year);
+
+ if (wd->month == 2)
+ _update_day_of_month(data, wd->month);
+ child = evas_object_data_get(obj, "child");
+ _changed(obj, child, data);
+}
+
+static void
+_month_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ const char *month;
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Object *child;
+ if (!wd) return;
+
+ month = elm_picker_item_label_get(event_info);
+ wd->month = atoi(month);
+
+ _update_day_of_month(data, wd->month);
+ child = evas_object_data_get(obj, "child");
+ _changed(obj, child, data);
+}
+
+static void
+_day_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ const char *day;
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Object *child;
+ if (!wd) return;
+
+ day = elm_picker_item_label_get(event_info);
+ wd->day = atoi(day);
+
+ child = evas_object_data_get(obj, "child");
+ _changed(obj, child, data);
+}
+
+static void
+_pickers_add(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ wd->pickers[PICKER_YEAR] = _picker_add(wd->base, "elm.swallow.year", wd->y_min, wd->y_max, "%04d");
+ wd->pickers[PICKER_MON] = _picker_add(wd->base, "elm.swallow.mon", 1, 12, "%d");
+ wd->pickers[PICKER_DAY] = _picker_add(wd->base, "elm.swallow.day", 1, wd->day_of_month, "%02d");
+ _callback_init(obj);
+}
+
+static void
+_pickers_del(Evas_Object *obj)
+{
+ int i = 0;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ for (i = 0; i < PICKER_MAX; i++) {
+ if (wd->pickers[i]) {
+ evas_object_del(wd->pickers[i]);
+ wd->pickers[i] = NULL;
+ }
+ }
+}
+
+static void
+_callback_init(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ evas_object_data_set(wd->pickers[PICKER_YEAR], "child", wd->pickers[PICKER_MON]);
+ evas_object_data_set(wd->pickers[PICKER_MON], "child", wd->pickers[PICKER_DAY]);
+ evas_object_data_set(wd->pickers[PICKER_MON], "parent", wd->pickers[PICKER_YEAR]);
+ evas_object_data_set(wd->pickers[PICKER_DAY], "parent", wd->pickers[PICKER_MON]);
+
+ evas_object_smart_callback_add(wd->pickers[PICKER_MON], "overflowed", _overflow_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_MON], "underflowed", _underflow_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_DAY], "overflowed", _overflow_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_DAY], "underflowed", _underflow_cb, obj);
+
+ evas_object_smart_callback_add(wd->pickers[PICKER_YEAR], "changed", _year_changed_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_MON], "changed", _month_changed_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_DAY], "changed", _day_changed_cb, obj);
+}
+
+/**
+ * Add a new datepicker to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Datepicker
+ */
+EAPI Evas_Object *
+elm_datepicker_add(Evas_Object *parent)
+{
+ Evas_Object *obj;
+ Evas *e;
+ Widget_Data *wd;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ obj = elm_widget_add(e);
+ elm_widget_type_set(obj, "datepicker");
+ 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_disable_hook_set(obj, _disable_hook);
+
+ wd->base = edje_object_add(e);
+ _elm_theme_object_set(obj, wd->base, "datepicker", "base", "default");
+ elm_widget_resize_object_set(obj, wd->base);
+
+ wd->y_max = YEAR_MAX;
+ wd->y_min = YEAR_MIN;
+ wd->m_max = MONTH_MAX;
+ wd->m_min = MONTH_MIN;
+ wd->d_min = DAY_MIN;
+ wd->d_max = DAY_MAX;
+ wd->day_of_month = DAY_MAX;
+
+ wd->year = YEAR_MIN;
+ wd->month = 1;
+ wd->day = 1;
+
+ _pickers_add(obj);
+
+ _i18n(obj);
+
+ _sizing_eval(obj);
+ return obj;
+}
+
+/**
+ * Set selected date of the datepicker
+ *
+ * @param obj The datepicker object
+ * @param year The year to set
+ * @param month The month to set
+ * @param day The day to set
+ *
+ * @ingroup Datepicker
+ */
+EAPI void
+elm_datepicker_date_set(Evas_Object *obj, int year, int month, int day)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (year < wd->y_min || year > wd->y_max
+ || month < 1 || month > 12
+ || day < 1 || day > 31)
+ return;
+ wd->year = year;
+ wd->month = month;
+ wd->day = day;
+ _update_day_of_month(obj, month);
+ _update_picker(wd->pickers[PICKER_YEAR], wd->year - wd->y_min);
+ _update_picker(wd->pickers[PICKER_MON], wd->month - 1);
+ _update_picker(wd->pickers[PICKER_DAY], wd->day - 1);
+}
+
+/**
+ * Get selected date of the datepicker
+ *
+ * @param obj The datepicker object
+ * @param year The pointer to the variable get the selected year
+ * @param month The pointer to the variable get the selected month
+ * @param day The pointer to the variable get the selected day
+ *
+ * @ingroup Datepicker
+ */
+EAPI void
+elm_datepicker_date_get(const Evas_Object *obj, int *year, int *month, int *day)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (year)
+ *year = wd->year;
+ if (month)
+ *month = wd->month;
+ if (day)
+ *day = wd->day;
+}
+
+/**
+ * Set upper bound of the datepicker
+ *
+ * @param obj The datepicker object
+ * @param year The year to set
+ * @param month The month to set
+ * @param day The day to set
+ *
+ * @ingroup Datepicker
+ */
+EAPI void
+elm_datepicker_date_min_set(Evas_Object *obj, int year, int month, int day)
+{
+ // TODO
+}
+
+/**
+ * Get lower bound of the datepicker
+ *
+ * @param obj The datepicker object
+ * @param year The pointer to the variable get the minimum year
+ * @param month The pointer to the variable get the minimum month
+ * @param day The pointer to the variable get the minimum day
+ *
+ * @ingroup Datepicker
+ */
+EAPI void
+elm_datepicker_date_min_get(const Evas_Object *obj, int *year, int *month, int *day)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (year)
+ *year = wd->y_min;
+ if (month)
+ *month = wd->m_min;
+ if (day)
+ *day = wd->d_min;
+}
+
+/**
+ * Set lower bound of the datepicker
+ *
+ * @param obj The datepicker object
+ * @param year The year to set
+ * @param month The month to set
+ * @param day The day to set
+ *
+ * @ingroup Datepicker
+ */
+EAPI void
+elm_datepicker_date_max_set(Evas_Object *obj, int year, int month, int day)
+{
+ // TODO
+}
+
+/**
+ * Get upper bound of the datepicker
+ *
+ * @param obj The datepicker object
+ * @param year The pointer to the variable get the maximum year
+ * @param month The pointer to the variable get the maximum month
+ * @param day The pointer to the variable get the maximum day
+ *
+ * @ingroup Datepicker
+ */
+EAPI void
+elm_datepicker_date_max_get(const Evas_Object *obj, int *year, int *month, int *day)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (year)
+ *year = wd->y_max;
+ if (month)
+ *month = wd->m_max;
+ if (day)
+ *day = wd->d_max;
+}
+
+/**
+ * Set date format of datepicker
+ *
+ * @param obj The datepicker object
+ * @param fmt The date format, ex) yymmdd
+ *
+ * @ingroup Datepicker
+ */
+EAPI void
+elm_datepicker_date_format_set(Evas_Object *obj, const char *fmt)
+{
+ int i;
+ char sig[32];
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ if (!wd || !fmt) return;
+
+ for (i = 0; i < sizeof(wd->fmt); i++) {
+ if (!fmt[i]) break;
+ wd->fmt[i] = tolower(fmt[i]);
+ }
+ wd->fmt[i] = '\0';
+
+ snprintf(sig, 32, "elm,state,%s", wd->fmt);
+
+ edje_object_signal_emit(wd->base, sig, "elm");
+}
+
+/**
+ * Get date format of datepicker
+ *
+ * @param obj The datepicker object
+ * @return The date format of given datepicker
+ *
+ * @ingroup Datepicker
+ */
+EAPI const char *
+elm_datepicker_date_format_get(const Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+ return wd->fmt;
+}
--- /dev/null
+/**\r
+ *\r
+ * @defgroup Gallery\r
+ * @ingroup Elementary\r
+ *\r
+ * This is an gallery.\r
+ *\r
+ */\r
+\r
+\r
+#include <Elementary.h>\r
+#include "elm_priv.h"\r
+\r
+\r
+#define INIT_ITEM_NUM (2)\r
+#define GROUP_ITEM_NUM (3)\r
+#define PADDING_WIDTH (25)\r
+\r
+#define MULTI_TOUCH_SET (1)\r
+\r
+#define DEFAULT_STATUS 0\r
+#define TRAN_STATUS 1\r
+#define WHITE_DIM_STATUS 2\r
+\r
+typedef struct Widget_Data {\r
+ Evas_Object *obj; \r
+ Evas_Object *sc;\r
+ Evas_Object *tb;\r
+ Evas_Object *rect;\r
+ const char *widget_name;\r
+ int init_num;\r
+ int padding_w;\r
+ Eina_List *list;\r
+ Ecore_Idler *eidler; \r
+ Evas_Coord x, y, w, h;\r
+ int prex; \r
+ int item_type;\r
+ int item_count;\r
+} Widget_Data;\r
+\r
+static void gallery_add(Evas_Object *obj);\r
+static void gallery_del(Evas_Object *obj);\r
+static void gallery_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);\r
+static void gallery_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);\r
+static void gallery_show(Evas_Object *obj);\r
+static void gallery_hide(Evas_Object *obj);\r
+static void gallery_color_set(Evas_Object *obj, int r, int g, int b, int a);\r
+static void gallery_clip_set(Evas_Object *obj, Evas_Object *clip);\r
+static void gallery_clip_unset(Evas_Object *obj);\r
+static Evas_Smart *gallery_smart_get(void);\r
+static Evas_Object *gallery_new(Evas_Object *parent);\r
+static void _update_gallery(Evas_Object *obj);\r
+static void _resize_gallery(Evas_Object *obj);\r
+static void _gallery_scroller_cb(void *data, Evas_Object *obj, void *event_info);\r
+static void _gallery_animate_stop_cb(void *data, Evas_Object *obj, void *event_info);\r
+static void _gallery_move_right_cb(Evas_Object *obj, int index);\r
+static void _gallery_move_left_cb(Evas_Object *obj, int index);\r
+static void _gallery_clear_all_image(Evas_Object *obj);\r
+static void _gallery_add_image(Evas_Object *obj, int index, void *data);\r
+static void _gallery_del_image(void *data);\r
+static void _gallery_del_image_force(void *data);\r
+static Eina_Bool _gallery_idle_handler_cb(void* data);\r
+static void _gallery_auto_blight(Evas_Object *obj);\r
+static void _gallery_set_all_status(Evas_Object *obj,int status);\r
+\r
+ \r
+static void gallery_add(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+\r
+ wd = (Widget_Data *)calloc(1, sizeof(Widget_Data));\r
+ if (!wd) {\r
+ errno = ENOMEM;\r
+ } else {\r
+ evas_object_smart_data_set(obj, wd);\r
+ \r
+ wd->sc = elm_scroller_add(obj);\r
+ evas_object_size_hint_weight_set(wd->sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);\r
+ elm_scroller_bounce_set(wd->sc, 1, 0);\r
+ elm_scroller_policy_set(wd->sc, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);\r
+ evas_object_smart_callback_add(wd->sc, "scroll", _gallery_scroller_cb, wd);\r
+ evas_object_smart_callback_add(wd->sc, "scroll,anim,stop", _gallery_animate_stop_cb, wd);\r
+ \r
+ wd->tb = elm_table_add(obj);\r
+ evas_object_size_hint_weight_set(wd->tb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);\r
+ evas_object_size_hint_align_set(wd->tb, EVAS_HINT_FILL, EVAS_HINT_FILL);\r
+ elm_scroller_content_set(wd->sc, wd->tb);\r
+\r
+ wd->widget_name = eina_stringshare_add("gallery");\r
+ wd->init_num = INIT_ITEM_NUM;\r
+ wd->obj = obj;\r
+ wd->eidler = NULL;\r
+ wd->padding_w = PADDING_WIDTH;\r
+ wd->item_type = DEFAULT_STATUS;\r
+ wd->item_count = GROUP_ITEM_NUM;\r
+ }\r
+}\r
+\r
+static void gallery_del(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+\r
+ if(wd->eidler){\r
+ ecore_idler_del(wd->eidler);\r
+ wd->eidler = NULL;\r
+ }\r
+ \r
+ if(wd->sc){\r
+ evas_object_del(wd->sc);\r
+ wd->sc = NULL;\r
+ }\r
+ \r
+ if(wd->list){\r
+ eina_list_free(wd->list);\r
+ wd->list = NULL;\r
+ }\r
+ \r
+ if(wd) free(wd);\r
+}\r
+\r
+static void gallery_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) {\r
+ errno = EINVAL;\r
+ return;\r
+ }\r
+\r
+ wd->x = x;\r
+ wd->y = y;\r
+ evas_object_move(wd->sc, x, y);\r
+}\r
+\r
+static void gallery_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) {\r
+ errno = EINVAL;\r
+ return;\r
+ }\r
+\r
+ wd->w = w;\r
+ wd->h = h;\r
+ \r
+ evas_object_resize(wd->sc, w, h); \r
+\r
+ wd->padding_w = (w - ((w-2)/(wd->item_count +1))*wd->item_count )/4;\r
+\r
+ if(!(wd->item_type == WHITE_DIM_STATUS))\r
+ {\r
+ elm_table_padding_set(wd->tb, wd->padding_w, 0);\r
+ elm_scroller_page_size_set(wd->sc, (wd->w -2)/(wd->item_count +1) + wd->padding_w, wd->h);\r
+ }\r
+ else\r
+ {\r
+ elm_table_padding_set(wd->tb, 0, 0);\r
+ elm_scroller_page_size_set(wd->sc, (wd->w)/(wd->item_count ) , wd->h);\r
+ }\r
+ _resize_gallery(obj);\r
+ _update_gallery(obj); \r
+}\r
+\r
+static void gallery_show(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) {\r
+ errno = EINVAL;\r
+ return;\r
+ }\r
+\r
+ evas_object_show(wd->tb); \r
+ evas_object_show(wd->sc); \r
+ \r
+ _update_gallery(obj); \r
+\r
+ if(wd->eidler){\r
+ ecore_idler_del(wd->eidler);\r
+ wd->eidler = NULL;\r
+ }\r
+ \r
+ wd->eidler = ecore_idler_add(_gallery_idle_handler_cb, wd); \r
+}\r
+\r
+static void gallery_hide(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) {\r
+ errno = EINVAL;\r
+ return;\r
+ }\r
+ _gallery_clear_all_image(obj); \r
+ evas_object_hide(wd->sc);\r
+}\r
+\r
+static void gallery_color_set(Evas_Object *obj, int r, int g, int b, int a)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) {\r
+ errno = EINVAL;\r
+ return;\r
+ }\r
+ evas_object_color_set(wd->sc, r, g, b, a);\r
+}\r
+\r
+\r
+static void gallery_clip_set(Evas_Object *obj, Evas_Object *clip)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return;\r
+ evas_object_clip_set(wd->sc, clip);\r
+}\r
+\r
+static void gallery_clip_unset(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return;\r
+ evas_object_clip_unset(wd->sc);\r
+\r
+}\r
+\r
+static Evas_Smart *gallery_smart_get(void)\r
+{\r
+ static Evas_Smart *s = NULL;\r
+ static Evas_Smart_Class sc = EVAS_SMART_CLASS_INIT_NAME_VERSION("UI_gallery");\r
+\r
+ if (!s) {\r
+ sc.add = gallery_add;\r
+ sc.del = gallery_del;\r
+ sc.move = gallery_move;\r
+ sc.resize = gallery_resize;\r
+ sc.show = gallery_show;\r
+ sc.hide = gallery_hide;\r
+ sc.color_set = gallery_color_set;\r
+ sc.clip_set = gallery_clip_set;\r
+ sc.clip_unset = gallery_clip_unset;\r
+ s = evas_smart_class_new(&sc);\r
+ }\r
+\r
+ return s;\r
+}\r
+\r
+static Evas_Object *gallery_new(Evas_Object *parent)\r
+{\r
+ Evas_Object *obj;\r
+ Evas *e;\r
+ e = evas_object_evas_get(parent);\r
+ if (!e) {\r
+ errno = EINVAL;\r
+ return NULL;\r
+ } else {\r
+ obj = evas_object_smart_add(e, gallery_smart_get());\r
+ }\r
+ return obj;\r
+}\r
+\r
+static void _gallery_scroller_cb(void *data, Evas_Object *obj, void *event_info)\r
+{\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+ Evas_Coord ix, iy, iw, ih;\r
+\r
+ elm_scroller_region_get(obj, &ix, &iy, &iw, &ih);\r
+\r
+ int index;\r
+ if(!(wd->item_type == WHITE_DIM_STATUS))\r
+ { \r
+ index = ix/((wd->w -2)/(wd->item_count +1) + wd->padding_w);\r
+ }\r
+ else\r
+ {\r
+ index = ix/((wd->w)/(wd->item_count ) );\r
+ }\r
+\r
+ printf("scroller %d\n",index);\r
+ \r
+ if(wd->prex < ix){\r
+ _gallery_move_right_cb(wd->obj, index);\r
+ }else\r
+ _gallery_move_left_cb(wd->obj, index);\r
+\r
+ wd->prex = ix;\r
+\r
+ if(wd->item_type == WHITE_DIM_STATUS )\r
+ {\r
+ _gallery_auto_blight(wd->obj);\r
+ printf("scroller blight\n");\r
+ }\r
+}\r
+\r
+static Eina_Bool _gallery_idle_handler_cb(void* data)\r
+{\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+ Elm_Gallery_Item *it = NULL;\r
+ Evas_Coord ix, iy, iw, ih;\r
+ \r
+ elm_scroller_region_get(wd->sc, &ix, &iy, &iw, &ih);\r
+\r
+ int index;\r
+ if(!(wd->item_type == WHITE_DIM_STATUS))\r
+ {\r
+ index = ix/((wd->w -2)/(wd->item_count +1) + wd->padding_w);\r
+ }\r
+ else\r
+ {\r
+ index = ix/((wd->w )/(wd->item_count ));\r
+ }\r
+ \r
+ it = (Elm_Gallery_Item *)eina_list_nth(wd->list, index +2);\r
+ \r
+ if(it != NULL){\r
+ evas_object_smart_callback_call(wd->obj, "select", it);\r
+ }\r
+\r
+ if(wd->eidler){\r
+ ecore_idler_del(wd->eidler);\r
+ wd->eidler = NULL;\r
+ }\r
+ \r
+ return 0; \r
+}\r
+\r
+static void _gallery_animate_stop_cb(void *data, Evas_Object *obj, void *event_info)\r
+{\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+ if (!wd) return;\r
+ \r
+ if(wd->eidler){\r
+ ecore_idler_del(wd->eidler);\r
+ wd->eidler = NULL;\r
+ }\r
+\r
+ wd->eidler = ecore_idler_add(_gallery_idle_handler_cb, wd); \r
+}\r
+\r
+static void _resize_gallery(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+ int count = 0;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return;\r
+\r
+ if(wd->rect){\r
+ elm_table_unpack(wd->tb, wd->rect);\r
+ evas_object_del(wd->rect);\r
+ wd->rect = NULL;\r
+ }\r
+\r
+ count = eina_list_count(wd->list);\r
+\r
+ wd->rect = evas_object_rectangle_add(evas_object_evas_get(obj));\r
+ \r
+ if(!(wd->item_type == WHITE_DIM_STATUS))\r
+ evas_object_size_hint_min_set(wd->rect, ((wd->w -2)/(wd->item_count +1)) *count, 1);\r
+ else evas_object_size_hint_min_set(wd->rect, ((wd->w )/(wd->item_count )) *count, 1);\r
+ \r
+ elm_table_pack(wd->tb, wd->rect, 0, 0, count, 1); \r
+\r
+ if(!(wd->item_type == WHITE_DIM_STATUS))\r
+ {\r
+ evas_object_size_hint_min_set(wd->tb, ((wd->w -2)/(wd->item_count +1) + wd->padding_w) *count - wd->padding_w, wd->h -2);\r
+ elm_scroller_content_min_limit(wd->sc, ((wd->w -2)/(wd->item_count +1) + wd->padding_w) *count - wd->padding_w, wd->h -2);\r
+ }\r
+ else\r
+ {\r
+ evas_object_size_hint_min_set(wd->tb, ((wd->w )/(wd->item_count ) ) *count, wd->h );\r
+ elm_scroller_content_min_limit(wd->sc, ((wd->w )/(wd->item_count ) ) *count , wd->h);\r
+ }\r
+}\r
+\r
+static void gallery_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
+{\r
+ Elm_Gallery_Item *it = data;\r
+ Evas_Event_Mouse_Down *ev = event_info;\r
+ \r
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)\r
+ it->on_hold = EINA_TRUE;\r
+ else \r
+ it->on_hold = EINA_FALSE;\r
+\r
+\r
+ Widget_Data *wd = evas_object_smart_data_get(it->parent);\r
+ if(wd->item_type == WHITE_DIM_STATUS)\r
+ {\r
+ edje_object_signal_emit(it->ly, "set_show_red_border", "elm");\r
+ }\r
+\r
+ Evas_Coord ix, iy, iw, ih; \r
+ Evas_Coord x, y, w, h;\r
+ evas_object_geometry_get(obj, &x, &y, &w, &h);\r
+ elm_scroller_region_get(wd->sc, &ix, &iy, &iw, &ih);\r
+\r
+ int index;\r
+ if(!(wd->item_type == WHITE_DIM_STATUS))\r
+ index = (ix+x)/((wd->w -2)/(wd->item_count +1) + wd->padding_w);\r
+ else\r
+ {\r
+ index = (ix+x)/((wd->w )/(wd->item_count)); \r
+ \r
+ printf("select find index %d\n",index);\r
+ if(wd->prex < ix){\r
+ _gallery_move_right_cb(wd->obj, index);\r
+ }else\r
+ _gallery_move_left_cb(wd->obj, index);\r
+ \r
+ printf("all print point : %d %d %d %d %d %d %d %d\n",x,y,w,h,ix,iy,iw,ih);\r
+ if(index>0)\r
+ elm_scroller_region_bring_in(wd->sc,(index-1)*iw/(wd->item_count) ,y,w*(wd->item_count),h);\r
+ }\r
+}\r
+\r
+static void gallery_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
+{\r
+ Elm_Gallery_Item *it = data;\r
+ Evas_Event_Mouse_Move *ev = event_info;\r
+ \r
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)\r
+ {\r
+ if (!it->on_hold) it->on_hold = EINA_TRUE;\r
+ }\r
+}\r
+\r
+static void gallery_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
+{\r
+ Elm_Gallery_Item *it = data;\r
+ Evas_Event_Mouse_Up *ev = event_info;\r
+ Widget_Data *wd = evas_object_smart_data_get(it->parent);\r
+ Evas_Coord x, y, w, h;\r
+ Evas_Coord ix, iy, iw, ih;\r
+ \r
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) it->on_hold = EINA_TRUE;\r
+ else it->on_hold = EINA_FALSE;\r
+\r
+ if (it->on_hold)\r
+ {\r
+ it->on_hold= EINA_FALSE;\r
+ return;\r
+ }\r
+\r
+ evas_object_geometry_get(obj, &x, &y, &w, &h);\r
+ elm_scroller_region_get(wd->sc, &ix, &iy, &iw, &ih);\r
+\r
+ int index;\r
+ if(!(wd->item_type == WHITE_DIM_STATUS))\r
+ index = (ix+x)/((wd->w -2)/(wd->item_count +1) + wd->padding_w);\r
+ else index = (ix+x)/((wd->w )/(wd->item_count));\r
+ \r
+ it = (Elm_Gallery_Item *)eina_list_nth(wd->list, index);\r
+ \r
+ if(it != NULL){\r
+ evas_object_smart_callback_call(wd->obj, "select", it);\r
+ }\r
+ \r
+}\r
+\r
+static void _gallery_add_image(Evas_Object *obj, int index, void *data)\r
+{\r
+ Widget_Data *wd = NULL;\r
+ Evas_Object *ly = NULL;\r
+ Evas_Object *ic = NULL;\r
+ int w, h;\r
+ \r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return;\r
+\r
+ Elm_Gallery_Item *it = (Elm_Gallery_Item *)data;\r
+\r
+ ly = edje_object_add(evas_object_evas_get(obj));\r
+ _elm_theme_object_set(obj,ly, "gallery", "base", "default");\r
+\r
+ evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);\r
+ evas_object_show(ly);\r
+ \r
+ ic = evas_object_image_add(evas_object_evas_get(obj));\r
+ if(wd->item_type == WHITE_DIM_STATUS)\r
+ evas_object_image_load_size_set(ic, wd->w/(wd->item_count) , wd->h/(wd->item_count) );\r
+ else evas_object_image_load_size_set(ic, wd->w/(wd->item_count+1) , wd->h/(wd->item_count+1) );\r
+ \r
+ evas_object_image_file_set(ic, it->path, NULL);\r
+ evas_object_image_size_get(ic, &w, &h); \r
+\r
+\r
+ if(w>h){\r
+ evas_object_image_fill_set(ic, 0, 0, (wd->w -2)/(wd->item_count +1), ((wd->w -2)/(wd->item_count +1) )*h/w);\r
+ if(!(wd->item_type == WHITE_DIM_STATUS))\r
+ {\r
+ evas_object_size_hint_min_set(ly, (wd->w -2)/(wd->item_count+1) , ((wd->w -2)/(wd->item_count+1) )*h/w);\r
+ evas_object_size_hint_max_set(ly, (wd->w -2)/(wd->item_count+1) , ((wd->w -2)/(wd->item_count+1) )*h/w);\r
+ }\r
+ }else{\r
+ if((wd->h -2)*w/h > (wd->w -2)/(wd->item_count +1)){\r
+ evas_object_image_fill_set(ic, 0, 0, (wd->w -2)/(wd->item_count +1), ((wd->w -2)/(wd->item_count +1))*(wd->h -2)/((wd->h -2)*w/h));\r
+ if(!(wd->item_type == WHITE_DIM_STATUS))\r
+ {\r
+ evas_object_size_hint_min_set(ly, (wd->w -2)/(wd->item_count+1) , ((wd->w -2)/(wd->item_count+1) )*(wd->h -2 )/((wd->h -2)*w/h));\r
+ evas_object_size_hint_max_set(ly, (wd->w -2)/(wd->item_count+1) , ((wd->w -2)/(wd->item_count+1) )*(wd->h -2 )/((wd->h -2)*w/h));\r
+ }\r
+ }else{\r
+ evas_object_image_fill_set(ic, 0, 0, (wd->h -2)*w/h, wd->h -2);\r
+ if(!(wd->item_type == WHITE_DIM_STATUS))\r
+ {\r
+ evas_object_size_hint_min_set(ly, (wd->h -2)*w/h, wd->h -2);\r
+ evas_object_size_hint_max_set(ly, (wd->h -2)*w/h, wd->h -2);\r
+ }\r
+ }\r
+ }\r
+\r
+ if(wd->item_type == WHITE_DIM_STATUS)\r
+ {\r
+ evas_object_size_hint_min_set(ly, (wd->w )/(wd->item_count ) , ((wd->w )/(wd->item_count ) )*h/w);\r
+ evas_object_size_hint_max_set(ly, (wd->w )/(wd->item_count ), ((wd->w )/(wd->item_count ) )*h/w);\r
+ }\r
+ \r
+ evas_object_image_filled_set(ic, 1);\r
+ edje_object_part_swallow(ly, "contents", ic);\r
+ evas_object_show(ic); \r
+\r
+ evas_object_event_callback_add(ic, EVAS_CALLBACK_MOUSE_DOWN, gallery_down_cb, it);\r
+ evas_object_event_callback_add(ic, EVAS_CALLBACK_MOUSE_MOVE, gallery_move_cb, it);\r
+ evas_object_event_callback_add(ic, EVAS_CALLBACK_MOUSE_UP, gallery_up_cb, it);\r
+ \r
+ it->w = (wd->w -2)/(wd->item_count +1) ;\r
+ it->h = ((wd->w -2)/(wd->item_count +1) )*h/w;\r
+\r
+ it->mw = it->w;\r
+ it->mh = it->h;\r
+\r
+ it->on_highquality = EINA_TRUE;\r
+ it->index = index;\r
+ \r
+ elm_table_pack(wd->tb, ly, index, 1, 1, 1); \r
+\r
+ if(wd->item_type == DEFAULT_STATUS)\r
+ edje_object_signal_emit(ly, "set_bg_default", "elm");\r
+ if(wd->item_type == TRAN_STATUS)\r
+ {\r
+ edje_object_signal_emit(ly, "set_bg_tran", "elm");\r
+ edje_object_signal_emit(ly, "set_border_hide", "elm");\r
+ }\r
+ else // WHITE_DIM_STATUS\r
+ {\r
+ edje_object_signal_emit(ly, "set_bg_default", "elm");\r
+ }\r
+\r
+ it->ly = ly;\r
+ it->obj = ic; \r
+ it->on_show = EINA_TRUE; \r
+}\r
+\r
+\r
+\r
+\r
+static void _gallery_auto_blight(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+ Elm_Gallery_Item *it;\r
+ Eina_List *l;\r
+ Evas_Coord x, y, w, h;\r
+ \r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return;\r
+\r
+ int start_pos=-1;\r
+ int end_pos=-1;\r
+ int ret_pos = -1;\r
+ int count=0;\r
+ EINA_LIST_FOREACH(wd->list, l, it) \r
+ { \r
+ Elm_Gallery_Item *inner_it = (Elm_Gallery_Item *)it;\r
+ \r
+ if(inner_it->obj) \r
+ {\r
+ evas_object_geometry_get(it->obj, &x, &y, &w, &h);\r
+ if(!((x+w < 0) || (x > wd->w)))\r
+ {\r
+ if(start_pos==-1)\r
+ start_pos=count;\r
+ else end_pos= count;\r
+ }\r
+ } \r
+ count++;\r
+ }\r
+\r
+ if(start_pos!=-1)\r
+ {\r
+ if(end_pos!=-1)\r
+ {\r
+ ret_pos =(start_pos+end_pos)/2;\r
+ }\r
+ else \r
+ {\r
+ ret_pos =start_pos;\r
+ }\r
+ }\r
+ \r
+ count =0;\r
+ EINA_LIST_FOREACH(wd->list, l, it) \r
+ {\r
+ Elm_Gallery_Item *inner_it = (Elm_Gallery_Item *)it;\r
+ if(inner_it->obj) \r
+ {\r
+ if(ret_pos==count)\r
+ {\r
+ edje_object_signal_emit(inner_it->ly, "set_bg_white", "elm");\r
+ printf("auto blight select %d start %d end %d \n",ret_pos,start_pos,end_pos);\r
+ }\r
+ else \r
+ {\r
+ edje_object_signal_emit(inner_it->ly, "set_bg_default", "elm"); \r
+ printf("auto nonblight select %d start %d end %d \n",ret_pos,start_pos,end_pos);\r
+ }\r
+ }\r
+ count++;\r
+ } \r
+ printf("auto blight\n"); \r
+}\r
+\r
+static void _gallery_set_all_status(Evas_Object *obj,int status)\r
+{\r
+ Widget_Data *wd;\r
+ Elm_Gallery_Item *it;\r
+ Eina_List *l; \r
+ \r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return;\r
+ \r
+ EINA_LIST_FOREACH(wd->list, l, it) \r
+ { \r
+ Elm_Gallery_Item *inner_it = (Elm_Gallery_Item *)it;\r
+ if(status == DEFAULT_STATUS)\r
+ {\r
+ edje_object_signal_emit(inner_it->ly, "set_bg_default", "elm");\r
+ }\r
+ if(status == TRAN_STATUS)\r
+ {\r
+ edje_object_signal_emit(inner_it->ly, "set_bg_tran", "elm"); \r
+ edje_object_signal_emit(inner_it->ly, "set_border_hide", "elm"); \r
+ } \r
+ }\r
+ if(status == WHITE_DIM_STATUS)\r
+ {\r
+ _gallery_auto_blight(obj);\r
+ printf("blight\n");\r
+ } \r
+}\r
+\r
+\r
+static void _gallery_del_image_force(void *data)\r
+{\r
+ Elm_Gallery_Item *it = (Elm_Gallery_Item *)data;\r
+ Widget_Data *wd = evas_object_smart_data_get(it->parent);\r
+ Evas_Coord x, y, w, h;\r
+\r
+ if(it->on_show == EINA_TRUE){\r
+ if(it->obj) {\r
+ evas_object_geometry_get(it->obj, &x, &y, &w, &h);\r
+\r
+ elm_table_unpack(wd->tb, it->ly);\r
+ evas_object_del(it->ly);\r
+ evas_object_del(it->obj);\r
+ it->obj = NULL;\r
+ it->on_show = EINA_FALSE;\r
+ }\r
+ }\r
+ \r
+}\r
+static void _gallery_del_image(void *data)\r
+{\r
+ Elm_Gallery_Item *it = (Elm_Gallery_Item *)data;\r
+ Widget_Data *wd = evas_object_smart_data_get(it->parent);\r
+ Evas_Coord x, y, w, h;\r
+\r
+ if(it->on_show == EINA_TRUE){\r
+ if(it->obj) {\r
+ evas_object_geometry_get(it->obj, &x, &y, &w, &h);\r
+\r
+ if((x+w < 0) || (x > wd->w)){\r
+ elm_table_unpack(wd->tb, it->ly);\r
+ evas_object_del(it->ly);\r
+ evas_object_del(it->obj);\r
+ it->obj = NULL;\r
+ it->on_show = EINA_FALSE;\r
+ }\r
+ }\r
+ }\r
+ \r
+}\r
+\r
+static void _gallery_clear_all_image(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+ Elm_Gallery_Item *it;\r
+ Eina_List *l;\r
+\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return;\r
+\r
+ EINA_LIST_FOREACH(wd->list, l, it) \r
+ {\r
+ _gallery_del_image_force(it);\r
+ }\r
+}\r
+\r
+static void _update_gallery(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return;\r
+\r
+ Evas_Coord x, y, w, h; \r
+ int i = 0;\r
+ int index = 0;\r
+ \r
+ if (!wd) {\r
+ errno = EINVAL;\r
+ return;\r
+ }\r
+ \r
+ if((wd->w == 1) && (wd->h == 1)) return;\r
+\r
+ for(i =wd->init_num -3; i< wd->init_num + 4; i++)\r
+ {\r
+ Elm_Gallery_Item *it = NULL;\r
+ it = (Elm_Gallery_Item *)eina_list_nth(wd->list, i);\r
+\r
+ if(it != NULL){\r
+ if(it->on_show == EINA_FALSE){ \r
+ _gallery_add_image(obj, i, it);\r
+ }\r
+ }\r
+ }\r
+\r
+ if(wd->init_num > 2)\r
+ index = wd->init_num -2;\r
+ else\r
+ index = 0;\r
+ \r
+ elm_scroller_region_get(wd->sc, &x, &y, &w, &h);\r
+ if(!(wd->item_type == WHITE_DIM_STATUS))\r
+ elm_scroller_region_show(wd->sc, index*((wd->w -2)/(wd->item_count +1) +wd->padding_w), y, w, h); \r
+ else elm_scroller_region_show(wd->sc, index*((wd->w )/(wd->item_count )), y, w, h); \r
+}\r
+\r
+static void _gallery_move_right_cb(Evas_Object *obj, int index)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return;\r
+\r
+ Elm_Gallery_Item *nit = NULL;\r
+\r
+ nit = (Elm_Gallery_Item *)eina_list_nth(wd->list, index + wd->item_count );\r
+ if(nit != NULL){ \r
+ if(nit->on_show == EINA_FALSE){\r
+ _gallery_add_image(obj, index + wd->item_count , nit);\r
+ }\r
+ }\r
+\r
+ nit = (Elm_Gallery_Item *)eina_list_nth(wd->list, index + 2);\r
+ if(nit != NULL){ \r
+ if(nit->on_show == EINA_FALSE){\r
+ _gallery_add_image(obj, index + 2, nit);\r
+ }\r
+ }\r
+\r
+ nit = (Elm_Gallery_Item *)eina_list_nth(wd->list, index + 3);\r
+ if(nit != NULL){ \r
+ if(nit->on_show == EINA_FALSE){\r
+ _gallery_add_image(obj, index + 3, nit);\r
+ }\r
+ } \r
+\r
+ if(index > wd->item_count *2){\r
+ Elm_Gallery_Item *pit = NULL;\r
+ pit = (Elm_Gallery_Item *)eina_list_nth(wd->list, index - wd->item_count -2);\r
+ if(pit != NULL){\r
+ _gallery_del_image(pit);\r
+ }\r
+\r
+ pit = (Elm_Gallery_Item *)eina_list_nth(wd->list, index - wd->item_count -3);\r
+ if(pit != NULL){\r
+ _gallery_del_image(pit); \r
+ }\r
+\r
+ pit = (Elm_Gallery_Item *)eina_list_nth(wd->list, index - wd->item_count -4);\r
+ if(pit != NULL){\r
+ _gallery_del_image(pit); \r
+ } \r
+ }\r
+\r
+}\r
+\r
+static void _gallery_move_left_cb(Evas_Object *obj, int index)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return;\r
+\r
+ Elm_Gallery_Item *nit = NULL;\r
+\r
+ nit = (Elm_Gallery_Item *)eina_list_nth(wd->list, index - wd->item_count );\r
+ if(nit != NULL){\r
+ if(nit->on_show == EINA_FALSE){\r
+ _gallery_add_image(obj, index - wd->item_count , nit);\r
+ }\r
+ }\r
+\r
+ nit = (Elm_Gallery_Item *)eina_list_nth(wd->list, index - 2);\r
+ if(nit != NULL){\r
+ if(nit->on_show == EINA_FALSE){\r
+ _gallery_add_image(obj, index - 2, nit);\r
+ }\r
+ }\r
+\r
+ nit = (Elm_Gallery_Item *)eina_list_nth(wd->list, index - 3);\r
+ if(nit != NULL){\r
+ if(nit->on_show == EINA_FALSE){\r
+ _gallery_add_image(obj, index - 3, nit);\r
+ }\r
+ }\r
+ \r
+ if(index + wd->item_count + 4 < eina_list_count(wd->list)){\r
+ Elm_Gallery_Item *pit = NULL;\r
+ pit = (Elm_Gallery_Item *)eina_list_nth(wd->list, index + wd->item_count +2);\r
+ if(pit != NULL){\r
+ _gallery_del_image(pit);\r
+ }\r
+\r
+ pit = (Elm_Gallery_Item *)eina_list_nth(wd->list, index + wd->item_count +3);\r
+ if(pit != NULL){\r
+ _gallery_del_image(pit);\r
+ }\r
+\r
+ pit = (Elm_Gallery_Item *)eina_list_nth(wd->list, index + wd->item_count +4);\r
+ if(pit != NULL){\r
+ _gallery_del_image(pit);\r
+ } \r
+ }\r
+}\r
+\r
+\r
+/**\r
+ * This function makes a new gallery object\r
+ * @param parent The parent object\r
+ * @return new gallery object \r
+ *\r
+ * @ingroup Gallery\r
+ */\r
+EAPI Evas_Object *elm_gallery_add(Evas_Object *parent)\r
+{\r
+ Evas_Object *obj;\r
+ Widget_Data *wd;\r
+ if (!parent) {\r
+ errno = EINVAL;\r
+ return NULL;\r
+ }\r
+\r
+ if ((obj = gallery_new(parent))) {\r
+ if (!(wd = evas_object_smart_data_get(obj))) {\r
+ evas_object_del(obj);\r
+ return NULL;\r
+ }\r
+ }\r
+ \r
+ elm_widget_sub_object_add (parent, obj);\r
+ \r
+ return obj;\r
+}\r
+\r
+\r
+/**\r
+ * The function appends an item and return the item class.\r
+ * @param obj The gallery object\r
+ * @param photo_file image file name\r
+ * @return new Elm_Gallery_Item\r
+ *\r
+ * @ingroup Gallery\r
+ */\r
+EAPI Elm_Gallery_Item *elm_gallery_item_append(Evas_Object *obj, const char *photo_file)\r
+{\r
+ Widget_Data *wd;\r
+ Elm_Gallery_Item *it;\r
+ if (!obj || !(wd = evas_object_smart_data_get(obj))) {\r
+ errno = EINVAL;\r
+ return NULL;\r
+ }\r
+ \r
+ it = (Elm_Gallery_Item *)calloc(1, sizeof(Elm_Gallery_Item));\r
+ it->path = eina_stringshare_add(photo_file);\r
+ it->parent = obj;\r
+ it->obj = NULL; \r
+ it->on_show = EINA_FALSE;\r
+ \r
+ wd->list = eina_list_append(wd->list, it);\r
+\r
+ _resize_gallery(obj);\r
+\r
+ return it;\r
+}\r
+\r
+\r
+/**\r
+ * The function prepends an item and return the item class.\r
+ * @param obj The gallery object\r
+ * @param photo_file image file name\r
+ * @return new Elm_Gallery_Item\r
+ *\r
+ * @ingroup Gallery\r
+ */\r
+EAPI Elm_Gallery_Item *elm_gallery_item_prepend(Evas_Object *obj, const char *photo_file)\r
+{\r
+ Widget_Data *wd;\r
+ Elm_Gallery_Item *it;\r
+ if (!obj || !(wd = evas_object_smart_data_get(obj))) {\r
+ errno = EINVAL;\r
+ return NULL;\r
+ }\r
+\r
+ it = (Elm_Gallery_Item *)calloc(1, sizeof(Elm_Gallery_Item));\r
+ it->path = eina_stringshare_add(photo_file);\r
+ it->parent = obj;\r
+ it->obj = NULL; \r
+ it->on_show = EINA_FALSE;\r
+ \r
+ wd->list = eina_list_prepend(wd->list, it);\r
+ \r
+ _resize_gallery(obj);\r
+ \r
+ return it;\r
+}\r
+\r
+\r
+/**\r
+ * The function deletes the item\r
+ * @param it Elm_Gallery_Item\r
+ *\r
+ * @ingroup Gallery\r
+ */\r
+EAPI void elm_gallery_item_del(Elm_Gallery_Item *it)\r
+{\r
+ Widget_Data *wd;\r
+\r
+ if (!it || !(wd = evas_object_smart_data_get(it->parent))) {\r
+ errno = EINVAL;\r
+ return;\r
+ }\r
+\r
+ wd->list = eina_list_remove(wd->list, it);\r
+\r
+ _resize_gallery(wd->obj);\r
+}\r
+\r
+\r
+/**\r
+ * The function gets the file name of certain item using it's item class\r
+ * @param it Elm_Gallery_Item\r
+ * @return (char*) file name path\r
+ *\r
+ * @ingroup Gallery\r
+ */\r
+EAPI const char *elm_gallery_item_file_get(Elm_Gallery_Item *it)\r
+{\r
+ if (!it) {\r
+ errno = EINVAL;\r
+ return NULL;\r
+ }\r
+ \r
+ return it->path;\r
+}\r
+\r
+\r
+EAPI void elm_gallery_item_show(Elm_Gallery_Item *it)\r
+{\r
+ Widget_Data *wd;\r
+ Elm_Gallery_Item *_it;\r
+ Eina_List *l;\r
+ int index = 0;\r
+ \r
+ if (!it || !it->parent|| (!(wd = evas_object_smart_data_get(it->parent)))) {\r
+ errno = EINVAL;\r
+ return;\r
+ } \r
+ \r
+ EINA_LIST_FOREACH(wd->list, l, _it) \r
+ {\r
+ if (_it == it) {\r
+ break;\r
+ }\r
+ index++;\r
+ }\r
+ \r
+ wd->init_num = index;\r
+\r
+ _update_gallery(it->parent);\r
+\r
+ if(wd->eidler){\r
+ ecore_idler_del(wd->eidler);\r
+ wd->eidler = NULL;\r
+ }\r
+ \r
+ wd->eidler = ecore_idler_add(_gallery_idle_handler_cb, wd); \r
+}\r
+\r
+\r
+/**\r
+ * The function gets the list of item class\r
+ * @param obj The gallery object\r
+ * @return new Eina_List of All item\r
+ *\r
+ * @ingroup Gallery\r
+ */\r
+EAPI Eina_List *elm_gallery_item_list_get(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return NULL;\r
+ \r
+ return wd->list;\r
+}\r
+\r
+\r
+\r
+/**\r
+ * The function set the type value \r
+ * @param parent The parent object\r
+ * @param type Type 1 : image swticher type Type 2 : gallery type\r
+ *\r
+ * @ingroup Gallery\r
+ */\r
+EAPI void elm_gallery_set_type(Evas_Object *obj,int type)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return;\r
+\r
+ wd->item_type = type;\r
+ \r
+ _gallery_set_all_status(obj,type);\r
+}\r
+\r
+\r
+\r
+/**\r
+ *The function determines a max number of images to be shown in a row\r
+ * @param parent The parent object\r
+ * @param max_value the value of max\r
+ *\r
+ * @ingroup Gallery\r
+ */ \r
+EAPI void elm_gallery_set_max_count(Evas_Object *obj,int max_value)\r
+{\r
+ Widget_Data *wd;\r
+ wd = evas_object_smart_data_get(obj);\r
+ if (!wd) return;\r
+\r
+ wd->item_count = max_value;\r
+}\r
+\r
+\r
--- /dev/null
+#include <Elementary.h>
+
+#include "elm_priv.h"
+
+/**
+ * @defgroup Gridbox Gridbox
+ * @ingroup Elementary
+ *
+ * This is a gridbox widget to show multiple objects in a grid
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+ Evas_Object *tbl, *scr;
+ Evas_Coord itemsize_h, itemsize_v;
+ Evas_Coord minw, minh;
+ Evas_Coord horizontal, vertical;
+ int x, y;
+ Eina_Bool homogeneous:1;
+};
+
+static void _del_hook(Evas_Object *obj);
+
+static void _sizing_eval(Evas_Object *obj, int mode);
+
+static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _changed_size_min(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+
+static void _show_event(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ evas_object_event_callback_del_full(wd->tbl, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
+ evas_object_event_callback_del_full(wd->tbl, EVAS_CALLBACK_RESIZE, _changed_size_min, obj);
+ evas_object_del(wd->tbl);
+ wd->tbl = NULL;
+ evas_object_del(wd->scr);
+ wd->scr = NULL;
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ free(wd);
+}
+
+static Eina_Bool
+_arrange_table(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ Eina_List *l, *l_temp = NULL;
+
+ Evas_Object *item;
+
+ int i = 0;
+
+ if (wd)
+ {
+ if (wd->tbl)
+ {
+ int index = eina_list_count(evas_object_table_children_get(wd->tbl));
+ if (!index) return EINA_FALSE;
+
+ elm_gridbox_item_size_set(obj, wd->itemsize_h, wd->itemsize_v);
+ l = evas_object_table_children_get(wd->tbl);
+
+ EINA_LIST_FOREACH(l, l_temp, item)
+ {
+ evas_object_table_unpack(wd->tbl, item);
+ elm_widget_sub_object_del(wd->tbl, item);
+ evas_object_table_pack(wd->tbl, item, i % wd->x, i / wd->x, 1, 1);
+ i++;
+ }
+ }
+ }
+ return EINA_TRUE;
+}
+
+static void
+_sizing_eval(Evas_Object *obj, int mode)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+
+ Evas_Coord w, h;
+
+ evas_object_size_hint_min_get(wd->scr, &minw, &minh);
+ evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_size_hint_max_set(obj, maxw, maxh);
+ evas_object_geometry_get(wd->scr, NULL, NULL, &w, &h);
+
+ if (w < minw) w = minw;
+ if (h < minh) h = minh;
+ if ((maxw >= 0) && (w > maxw))
+ w = maxw;
+ if ((maxh >= 0) && (h > maxh))
+ h = maxh;
+ evas_object_resize(obj, w, h);
+
+ wd->minw = w;
+ wd->minh = h;
+ if (w < wd->itemsize_h || h < wd->itemsize_v)
+ return;
+ if (wd->homogeneous)
+ {
+ wd->x = w / wd->itemsize_h;
+ wd->y = h / wd->itemsize_v;
+ wd->horizontal = (wd->minw - wd->x * wd->itemsize_h) / wd->x;
+ wd->vertical = (wd->minh - wd->y * wd->itemsize_v) / wd->y;
+ elm_gridbox_padding_set(obj, wd->horizontal, wd->vertical);
+ }
+
+ if (!mode)
+ _arrange_table(obj);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ _sizing_eval(data, 0);
+}
+
+static void
+_changed_size_min(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ _sizing_eval(data, 0);
+}
+
+static void
+_sub_del(void *data, Evas_Object *obj, void *event_info)
+{
+ _sizing_eval(obj, 1);
+}
+
+static void
+_show_event(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ _sizing_eval(data, 0);
+}
+
+static void
+_freeze_on(void *data, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ if (!wd) return;
+ evas_object_smart_callback_call(wd->scr, "scroll-freeze-on", NULL);
+}
+
+static void
+_freeze_off(void *data, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ if (!wd) return;
+ evas_object_smart_callback_call(wd->scr, "scroll-freeze-off", NULL);
+}
+
+/**
+ * Add a new gridbox to the parent
+ *
+ * @param[in] parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Gridbox
+ */
+EAPI Evas_Object *
+elm_gridbox_add(Evas_Object *parent)
+{
+ Evas_Object *obj;
+
+ Evas *e;
+
+ Widget_Data *wd;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ obj = elm_widget_add(e);
+ elm_widget_type_set(obj, "gridbox");
+ elm_widget_sub_object_add(parent, obj);
+ elm_widget_data_set(obj, wd);
+ elm_widget_del_hook_set(obj, _del_hook);
+ elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+
+ wd->scr = elm_scroller_add(parent);
+ elm_widget_resize_object_set(obj, wd->scr);
+ elm_scroller_bounce_set(wd->scr, 0, 1);
+
+ wd->tbl = evas_object_table_add(e);
+ evas_object_size_hint_weight_set(wd->tbl, 0.0, 0.0);
+ elm_scroller_content_set(wd->scr, wd->tbl);
+ evas_object_show(wd->tbl);
+
+ evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
+ evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE, _changed_size_min, obj);
+ evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_SHOW, _show_event, obj);
+
+ evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+ evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
+ evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
+
+ _sizing_eval(obj, 0);
+
+ return obj;
+}
+
+/**
+ * Set padding between cells.
+ *
+ * @param[in] obj The layout object.
+ * @param[in] horizontal set the horizontal padding.
+ * @param[in] vertical set the vertical padding.
+ *
+ * @ingroup Gridbox
+ */
+EAPI void
+elm_gridbox_padding_set(Evas_Object *obj, Evas_Coord horizontal, Evas_Coord vertical)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ if (!wd) return;
+
+ wd->horizontal = horizontal;
+ wd->vertical = vertical;
+ if (wd->tbl)
+ evas_object_table_padding_set(wd->tbl, horizontal, vertical);
+}
+
+/**
+ * Set gridbox item size
+ *
+ * @param[in] obj The gridbox object
+ * @param[in] h_pagesize The horizontal item size
+ * @param[in] v_pagesize The vertical item size
+ *
+ * @ingroup Gridbox
+ */
+EAPI void
+elm_gridbox_item_size_set(Evas_Object *obj, Evas_Coord h_itemsize, Evas_Coord v_itemsize)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ Evas_Coord minw = -1, minh = -1;
+
+ Evas_Coord w, h;
+
+ if (!wd) return;
+
+ wd->itemsize_h = h_itemsize;
+ wd->itemsize_v = v_itemsize;
+ evas_object_size_hint_min_get(wd->scr, &minw, &minh);
+ evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+ if (w < minw)
+ w = minw;
+ if (h < minh)
+ h = minh;
+ wd->x = w / h_itemsize;
+ wd->y = h / v_itemsize;
+
+ if (!wd->x)
+ wd->x = 1;
+ if (!wd->y)
+ wd->y = 1;
+ _sizing_eval(obj, 1);
+}
+
+/**
+ * Add a subobject on the gridbox
+ *
+ * @param[in] obj The table object
+ * @param[in] subobj The subobject to be added to the gridbox
+ *
+ * @ingroup Gridbox
+ */
+EAPI void
+elm_gridbox_pack(Evas_Object *obj, Evas_Object *subobj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ int index = eina_list_count(evas_object_table_children_get(wd->tbl));
+
+ evas_object_size_hint_min_set(subobj, wd->itemsize_h, wd->itemsize_v);
+ evas_object_size_hint_max_set(subobj, wd->itemsize_h, wd->itemsize_v);
+ elm_widget_sub_object_add(obj, subobj);
+ evas_object_table_pack(wd->tbl, subobj, index % wd->x, index / wd->x, 1, 1);
+}
+
+/**
+ * Unpack a subobject on the gridbox
+ *
+ * @param[in] obj The gridbox object
+ * @param[in] subobj The subobject to be removed to the gridbox
+ *
+ * @ingroup Gridbox
+ */
+EAPI Eina_Bool
+elm_gridbox_unpack(Evas_Object *obj, Evas_Object *subobj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ Eina_Bool ret = 0;
+
+ elm_widget_sub_object_del(wd->tbl, subobj);
+ ret = evas_object_table_unpack(wd->tbl, subobj);
+
+ _arrange_table(obj);
+
+ return ret;
+}
+
+/**
+ * Get the list of children for the gridbox.
+ *
+ * @param[in] obj The gridbox object
+ *
+ * @ingroup Gridbox
+ */
+EAPI Eina_List *
+elm_gridbox_children_get(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ Eina_List *new_list = NULL;
+
+ new_list = evas_object_table_children_get(wd->tbl);
+
+ return new_list;
+}
+
+/**
+ * Set homogenous paddding layout
+ *
+ * @param[in] obj The gridbox object
+ * @param[in] homogenous The homogenous flag (1 = on, 0 = off)
+ *
+ * @ingroup Gridbox
+ */
+EAPI void
+elm_gridbox_homogenous_padding_set(Evas_Object *obj, Eina_Bool homogenous)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ wd->homogeneous = homogenous;
+}
--- /dev/null
+#include <Elementary.h>
+#include "elm_priv.h"
+#include "els_scroller.h"
+
+/**
+ * @defgroup Scroller Scroller
+ * @ingroup Elementary
+ *
+ * A scroller holds a single object and "scrolls it around". This means that
+ * it allows the user to use a scrollbar (or a finger) to drag the viewable
+ * region around, allowing to move through a much larger object that is
+ * contained in the scroller. The scroiller will always have a small minimum
+ * size by default as it won't be limited by the contents of the scroller.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * edge,left - the left edge of the content has been reached
+ *
+ * edge,right - the right edge of the content has been reached
+ *
+ * edge,top - the top edge of the content has been reached
+ *
+ * edge,bottom - the bottom edge of the content has been reached
+ *
+ * scroll - the content has been scrolled (moved)
+ *
+ * scroll,anim,start - scrolling animation has started
+ *
+ * scroll,anim,stop - scrolling animation has stopped
+ *
+ * scroll,drag,start - dragging the contents around has started
+ *
+ * scroll,drag,stop - dragging the contents around has stopped
+ */
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+ Evas_Object *scr;
+ Evas_Object *content;
+ const char *widget_name, *widget_base;
+ Eina_Bool min_w : 1;
+ Eina_Bool min_h : 1;
+ double pagerel_h, pagerel_v;
+ Evas_Coord pagesize_h, pagesize_v;
+};
+
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _show_region_hook(void *data, Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (wd->scr)
+ {
+// elm_smart_scroller_theme_set(wd->scr, "scroller", "base", elm_widget_style_get(obj));
+ hor_elm_smart_scroller_theme_set(obj, wd->scr,
+ wd->widget_name,
+ wd->widget_base,
+ elm_widget_style_get(obj));
+// edje_object_scale_set(wd->scr, elm_widget_scale_get(obj) * _elm_config->scale);
+ }
+ _sizing_eval(obj);
+}
+
+static void
+_show_region_hook(void *data, Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Coord x, y, w, h;
+ if (!wd) return;
+ elm_widget_show_region_get(obj, &x, &y, &w, &h);
+ hor_elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Coord vw, vh, minw, minh, maxw, maxh, w, h, vmw, vmh;
+ double xw, xy;
+
+ if (!wd) return;
+ evas_object_size_hint_min_get(wd->content, &minw, &minh);
+ evas_object_size_hint_max_get(wd->content, &maxw, &maxh);
+ evas_object_size_hint_weight_get(wd->content, &xw, &xy);
+ hor_elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
+ if (xw > 0.0)
+ {
+ if ((minw > 0) && (vw < minw)) vw = minw;
+ else if ((maxw > 0) && (vw > maxw)) vw = maxw;
+ }
+ else if (minw > 0) vw = minw;
+ if (xy > 0.0)
+ {
+ if ((minh > 0) && (vh < minh)) vh = minh;
+ else if ((maxh > 0) && (vh > maxh)) vh = maxh;
+ }
+ else if (minh > 0) vh = minh;
+ evas_object_resize(wd->content, vw, vh);
+ w = -1;
+ h = -1;
+ edje_object_size_min_calc(hor_elm_smart_scroller_edje_object_get(wd->scr), &vmw, &vmh);
+ if (wd->min_w) w = vmw + minw;
+ if (wd->min_h) h = vmh + minh;
+ evas_object_size_hint_min_set(obj, w, h);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Object *sub = event_info;
+
+ if (!wd) return;
+ if (sub == wd->content)
+ {
+ elm_widget_on_show_region_hook_set(wd->content, NULL, NULL);
+ evas_object_event_callback_del_full (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _changed_size_hints, obj);
+ wd->content = NULL;
+ _sizing_eval(obj);
+ }
+}
+
+static void
+_hold_on(void *data, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ if (!wd) return;
+ hor_elm_smart_scroller_hold_set(wd->scr, 1);
+}
+
+static void
+_hold_off(void *data, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ if (!wd) return;
+ hor_elm_smart_scroller_hold_set(wd->scr, 0);
+}
+
+static void
+_freeze_on(void *data, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ if (!wd) return;
+ hor_elm_smart_scroller_freeze_set(wd->scr, 1);
+}
+
+static void
+_freeze_off(void *data, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ if (!wd) return;
+ hor_elm_smart_scroller_freeze_set(wd->scr, 0);
+}
+
+static void
+_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ _sizing_eval(data);
+}
+
+static void
+_edge_left(void *data, Evas_Object *obj, void *event_info)
+{
+ evas_object_smart_callback_call(data, "edge,left", NULL);
+}
+
+static void
+_edge_right(void *data, Evas_Object *obj, void *event_info)
+{
+ evas_object_smart_callback_call(data, "edge,right", NULL);
+}
+
+static void
+_edge_top(void *data, Evas_Object *obj, void *event_info)
+{
+ evas_object_smart_callback_call(data, "edge,top", NULL);
+}
+
+static void
+_edge_bottom(void *data, Evas_Object *obj, void *event_info)
+{
+ evas_object_smart_callback_call(data, "edge,bottom", NULL);
+}
+
+static void
+_scroll(void *data, Evas_Object *obj, void *event_info)
+{
+ evas_object_smart_callback_call(data, "scroll", NULL);
+}
+
+static void
+_scroll_anim_start(void *data, Evas_Object *obj, void *event_info)
+{
+ evas_object_smart_callback_call(data, "scroll,anim,start", NULL);
+}
+
+static void
+_scroll_anim_stop(void *data, Evas_Object *obj, void *event_info)
+{
+ evas_object_smart_callback_call(data, "scroll,anim,stop", NULL);
+}
+
+static void
+_scroll_drag_start(void *data, Evas_Object *obj, void *event_info)
+{
+ evas_object_smart_callback_call(data, "scroll,drag,start", NULL);
+}
+
+static void
+_scroll_drag_stop(void *data, Evas_Object *obj, void *event_info)
+{
+ evas_object_smart_callback_call(data, "scroll,drag,stop", NULL);
+}
+
+/**
+ * Add a new scroller to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Scroller
+ */
+EAPI Evas_Object *
+hor_elm_scroller_add(Evas_Object *parent)
+{
+ Evas_Object *obj;
+ Evas *e;
+ Widget_Data *wd;
+ Evas_Coord minw, minh;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ obj = elm_widget_add(e);
+ elm_widget_type_set(obj, "scroller");
+ 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);
+ wd->widget_name = eina_stringshare_add("scroller");
+ wd->widget_base = eina_stringshare_add("base");
+
+ wd->scr = hor_elm_smart_scroller_add(e);
+ elm_widget_resize_object_set(obj, wd->scr);
+ evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _changed_size_hints, obj);
+
+ edje_object_size_min_calc(hor_elm_smart_scroller_edje_object_get(wd->scr), &minw, &minh);
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
+
+ evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+ evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
+ evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
+ evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
+ evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
+
+ evas_object_smart_callback_add(wd->scr, "edge,left", _edge_left, obj);
+ evas_object_smart_callback_add(wd->scr, "edge,right", _edge_right, obj);
+ evas_object_smart_callback_add(wd->scr, "edge,top", _edge_top, obj);
+ evas_object_smart_callback_add(wd->scr, "edge,bottom", _edge_bottom, obj);
+ evas_object_smart_callback_add(wd->scr, "scroll", _scroll, obj);
+ evas_object_smart_callback_add(wd->scr, "animate,start", _scroll_anim_start, obj);
+ evas_object_smart_callback_add(wd->scr, "animate,stop", _scroll_anim_stop, obj);
+ evas_object_smart_callback_add(wd->scr, "drag,start", _scroll_drag_start, obj);
+ evas_object_smart_callback_add(wd->scr, "drag,stop", _scroll_drag_stop, obj);
+
+ _sizing_eval(obj);
+ return obj;
+}
+
+/**
+ * Set the content object
+ *
+ * XXX
+ *
+ * @param obj The scroller object
+ * @param content The new content object
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+hor_elm_scroller_content_set(Evas_Object *obj, Evas_Object *content)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if ((wd->content != content) && (wd->content))
+ elm_widget_sub_object_del(obj, wd->content);
+ wd->content = content;
+ if (content)
+ {
+ elm_widget_on_show_region_hook_set(content, _show_region_hook, obj);
+ elm_widget_sub_object_add(obj, content);
+ hor_elm_smart_scroller_child_set(wd->scr, content);
+ evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _changed_size_hints, obj);
+ _sizing_eval(obj);
+ }
+}
+
+/**
+ * Set custom theme elements for the scroller
+ *
+ * @param obj The scroller object
+ * @param widget The widget name to use (default is "scroller")
+ * @param base The base name to use (default is "base")
+ */
+EAPI void
+hor_elm_scroller_custom_widget_base_theme_set(Evas_Object *obj, const char *widget, const char *base)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if ((!widget) || (!base)) return;
+ if (eina_stringshare_replace(&wd->widget_name, widget) |
+ eina_stringshare_replace(&wd->widget_base, base))
+ _theme_hook(obj);
+}
+
+/**
+ * Make the scroller minimum size limited to the minimum size of the content
+ *
+ * By default the scroller will be as small as its design allows, irrespective
+ * of its content. This will make the scroller minimum size the right size
+ * horizontally and/or vertically to perfectly fit its content.
+ *
+ * @param obj The scroller object
+ * @param w Enable limiting minimum size horizontally
+ * @param h Enable limiting minimum size vertically
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+hor_elm_scroller_content_min_limit(Evas_Object *obj, Eina_Bool w, Eina_Bool h)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ wd->min_w = w;
+ wd->min_h = h;
+ _sizing_eval(obj);
+}
+
+/**
+ * Show a specific virtual region within the scroller content object
+ *
+ * This will ensure all (or part if it does not fit) of the designated
+ * region in the virtual content object (0, 0 starting at the top-left of the
+ * virtual content object) is shown within the scroller.
+ *
+ * @param obj The scroller object
+ * @param x X coordinate of the region
+ * @param y Y coordinate of the region
+ * @param w Width of the region
+ * @param h Height of the region
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+hor_elm_scroller_region_show(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ hor_elm_smart_scroller_child_region_show(wd->scr, x, y, w, h);
+}
+
+/**
+ * Set the scroller scrollbar policy
+ *
+ * This sets the scrollbar visibility policy for the given scroller.
+ * ELM_SMART_SCROLLER_POLICY_AUTO means the scrollber is made visible if it
+ * is needed, and otherwise kept hidden. ELM_SMART_SCROLLER_POLICY_ON turns
+ * it on all the time, and ELM_SMART_SCROLLER_POLICY_OFF always keeps it off.
+ * This applies respectively for the horizontal and vertical scrollbars.
+ *
+ * @param obj The scroller object
+ * @param policy_h Horizontal scrollbar policy
+ * @param policy_v Vertical scrollbar policy
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+hor_elm_scroller_policy_set(Evas_Object *obj, Elm_Scroller_Policy policy_h, Elm_Scroller_Policy policy_v)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ const Elm_Scroller_Policy map[3] =
+ {
+ ELM_SMART_SCROLLER_POLICY_AUTO,
+ ELM_SMART_SCROLLER_POLICY_ON,
+ ELM_SMART_SCROLLER_POLICY_OFF
+ };
+ if (!wd) return;
+ if ((policy_h < 0) || (policy_h >= 3) || (policy_v < 0) || (policy_v >= 3))
+ return;
+ hor_elm_smart_scroller_policy_set(wd->scr, map[policy_h], map[policy_v]);
+}
+
+/**
+ * Get the currently visible content region
+ *
+ * This gets the current region in the content object that is visible through
+ * the scroller. Also see elm_scroller_region_show(). The region co-ordinates
+ * are returned in the @p x, @p y, @p w, @p h values pointed to.
+ *
+ * @param obj The scroller object
+ * @param x X coordinate of the region
+ * @param y Y coordinate of the region
+ * @param w Width of the region
+ * @param h Height of the region
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+hor_elm_scroller_region_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if ((x) && (y)) hor_elm_smart_scroller_child_pos_get(wd->scr, x, y);
+ if ((w) && (h)) hor_elm_smart_scroller_child_viewport_size_get(wd->scr, w, h);
+}
+
+/**
+ * Get the size of the content child object
+ *
+ * This gets the size of the child object of the scroller. Actually the
+ * content of a scroller doesn't specifically need to be an actual object
+ * as it can be virtual and defined purely by callbacks.
+ *
+ * @param obj The scroller object
+ * @param w Width return
+ * @param h Height return
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+hor_elm_scroller_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ evas_object_geometry_get(wd->content, NULL, NULL, w, h);
+}
+
+/**
+ * Set bouncing behavior
+ *
+ * When scrolling, the scroller may "bounce" when reaching an edge of the child
+ * object. This is a visual way to indicate the end has been reached. This is
+ * enabled by default for both axes. This will set if it is enabled for that
+ * axis with the boolean parameers for each axis.
+ *
+ * @param obj The scroller object
+ * @param h_bounce Will the scroller bounce horizontally or not
+ y Y coordinate of the region
+ w Width of the region
+ h Height of the region
+
+ EAPI void elm_scroller_region_show ( Evas_Object * obj, * @param v_bounce Will the scroller bounce vertically or not
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+hor_elm_scroller_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ hor_elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
+}
+
+/**
+ * Set scroll page size relative to viewport size
+ *
+ * The scroller is sapale of limiting scrolling by the user to "pages". That
+ * is to jump by and only show a "whole page" at a time as if the continuous
+ * area of the scroller conent is split into page sized pieces. This sets
+ * the size of a page relative to the viewport of the scroller. 1.0 is "1
+ * viewport" is size (horizontally or vertically). 0.0 turns it off in that
+ * axis. This is mutually exclusive with page size
+ * (see elm_scroller_page_size_set() for more information). likewise 0.5
+ * is "half a viewport". Sane usable valus are normally between 0.0 and 1.0
+ * including 1.0. If you only want 1 axis to be page "limited", use 0.0 for
+ * the other axis.
+ *
+ * @param obj The scroller object
+ * @param h_pagerel The horizontal page relative size
+ * @param v_pagerel The vertical page relative size
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+hor_elm_scroller_page_relative_set(Evas_Object *obj, double h_pagerel, double v_pagerel)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ wd->pagerel_h = h_pagerel;
+ wd->pagerel_v = v_pagerel;
+ hor_elm_smart_scroller_paging_set(wd->scr, wd->pagerel_h, wd->pagerel_v,
+ wd->pagesize_h, wd->pagesize_v);
+}
+
+/**
+ * Set scroll page size
+ *
+ * See also elm_scroller_page_relative_set(). This, instead of a page size
+ * being relaive to the viewport, sets it to an absolute fixed value, with
+ * 0 turning it off for that axis.
+ *
+ * @param obj The scroller object
+ * @param h_pagesize The horizontal page size
+ * @param v_pagesize The vertical page size
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+hor_elm_scroller_page_size_set(Evas_Object *obj, Evas_Coord h_pagesize, Evas_Coord v_pagesize)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ wd->pagesize_h = h_pagesize;
+ wd->pagesize_v = v_pagesize;
+ hor_elm_smart_scroller_paging_set(wd->scr, wd->pagerel_h, wd->pagerel_v,
+ wd->pagesize_h, wd->pagesize_v);
+}
+
+/**
+ * Show a specific virtual region within the scroller content object
+ *
+ * This will ensure all (or part if it does not fit) of the designated
+ * region in the virtual content object (0, 0 starting at the top-left of the
+ * virtual content object) is shown within the scroller. Unlike
+ * elm_scroller_region_show(), this allow the scroller to "smoothly slide"
+ * to this location (if configuration in general calls for transitions). It
+ * may not jump immediately to the new location and make take a while and
+ * show other content along the way.
+ *
+ * @param obj The scroller object
+ * @param x X coordinate of the region
+ * @param y Y coordinate of the region
+ * @param w Width of the region
+ * @param h Height of the region
+ *
+ * @ingroup Scroller
+ */
+EAPI void
+hor_elm_scroller_region_bring_in(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ hor_elm_smart_scroller_region_bring_in(wd->scr, x, y, w, h);
+}
--- /dev/null
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Ratingbar Ratingbar
+ * @ingroup Elementary
+ *
+ * This is a ratingbar.
+ */
+
+
+#define RATING_MAX 5
+
+typedef struct _Widget_Data Widget_Data;
+struct _Widget_Data {
+ Evas_Object *base;
+ Evas_Coord x, y, w, h;
+ int rating;
+ bool pressed;
+};
+
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _update_ratingbar(Evas_Object *obj);
+
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ _elm_theme_object_set(obj, wd->base, "ratingbar", "base", elm_widget_style_get(obj));
+ _update_ratingbar(obj);
+ _sizing_eval(obj);
+}
+
+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;
+ if (!wd) return;
+
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_changed(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ evas_object_smart_callback_call(obj, "changed", NULL);
+}
+
+static void
+_update_ratingbar(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ char partname[20] = {0,};
+ int i;
+ if (!wd) return;
+
+ for(i=1; i<=RATING_MAX; i++)
+ {
+ sprintf(partname, "elm.star.%d", i);
+
+ if(wd->pressed == FALSE){
+ if(i <= wd->rating) edje_object_signal_emit(wd->base, "elm,star,selected", partname);
+ else edje_object_signal_emit(wd->base, "elm,star,unselected", partname);
+ }else{
+ if(i <= wd->rating) edje_object_signal_emit(wd->base, "elm,star,pressed,on", partname);
+ else edje_object_signal_emit(wd->base, "elm,star,pressed,off", partname);
+ }
+ }
+
+ _sizing_eval(obj);
+}
+
+static int
+_determine_rating(Evas_Coord x, Evas_Coord w, Evas_Coord ev_x)
+{
+ int rating = 0;
+
+ if(ev_x < x){
+ rating = 0;
+ }else if(ev_x < x + 0.2*w){
+ rating = 1;
+ }else if(ev_x < x + 0.4*w){
+ rating = 2;
+ }else if(ev_x < x + 0.6*w){
+ rating = 3;
+ }else if(ev_x < x + 0.8*w){
+ rating = 4;
+ }else if(ev_x < x + w){
+ rating = 5;
+ }else{
+ rating = 5;
+ }
+
+ return rating;
+}
+
+static void
+_resize_cb(void *data, Evas *evas, Evas_Object *obj, void *event)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ if (!wd) return;
+
+ evas_object_geometry_get(obj, NULL, NULL, &wd->w, &wd->h);
+}
+
+static void
+_move_cb(void *data, Evas *evas, Evas_Object *obj, void *event)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ if (!wd) return;
+
+ evas_object_geometry_get(obj, &wd->x, &wd->y, NULL, NULL);
+}
+
+static void
+_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Event_Mouse_Down *ev = event_info;
+ if (!wd) return;
+ int rating_old = wd->rating;
+
+ wd->pressed = TRUE;
+ wd->rating = _determine_rating(wd->x, wd->w, ev->canvas.x);
+ _update_ratingbar(data);
+
+ if(wd->rating != rating_old)
+ _changed(data);
+}
+
+static void
+_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Event_Mouse_Move *ev = event_info;
+ if (!wd || !ev->buttons) return;
+ int rating_old = wd->rating;
+
+ wd->pressed = TRUE;
+ wd->rating = _determine_rating(wd->x, wd->w, ev->cur.canvas.x);
+ _update_ratingbar(data);
+
+ if(wd->rating != rating_old)
+ _changed(data);
+}
+
+static void
+_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Event_Mouse_Up *ev = event_info;
+ if (!wd) return;
+ int rating_old = wd->rating;
+
+ wd->pressed = FALSE;
+ wd->rating = _determine_rating(wd->x, wd->w, ev->canvas.x);
+ _update_ratingbar(data);
+
+ if(wd->rating != rating_old)
+ _changed(data);
+}
+
+static void
+_event_init(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if(!wd || !wd->base) return;
+
+ evas_object_event_callback_add(wd->base, EVAS_CALLBACK_RESIZE, _resize_cb, obj);
+ evas_object_event_callback_add(wd->base, EVAS_CALLBACK_MOVE, _move_cb, obj);
+ evas_object_event_callback_add(wd->base, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, obj);
+ evas_object_event_callback_add(wd->base, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, obj);
+ evas_object_event_callback_add(wd->base, EVAS_CALLBACK_MOUSE_UP, _mouse_up, obj);
+}
+
+/**
+ * Add a new ratingbar to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Ratingbar
+ */
+EAPI Evas_Object *
+elm_ratingbar_add(Evas_Object *parent)
+{
+ Evas_Object *obj;
+ Evas *e;
+ Widget_Data *wd;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ obj = elm_widget_add(e);
+ elm_widget_type_set(obj, "ratingbar");
+ 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);
+
+ wd->base = edje_object_add(e);
+ _elm_theme_object_set(obj, wd->base, "ratingbar", "base", "default");
+ elm_widget_resize_object_set(obj, wd->base);
+ evas_object_show(wd->base);
+
+ wd->rating = 0;
+ wd->pressed = FALSE;
+
+ _event_init(obj);
+ _update_ratingbar(obj);
+
+ return obj;
+}
+
+/**
+ * Set the current rating
+ *
+ * @param obj The ratingbar object
+ * @param rating The current rating
+ *
+ * @ingroup Ratingbar
+ */
+EAPI void
+elm_ratingbar_rating_set(Evas_Object *obj, int rating)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ if(rating < 0 || rating > RATING_MAX){
+ fprintf(stderr, "Invalid the value of rating\n");
+ return;
+ }
+
+ if(wd->rating == rating) return;
+
+ wd->rating = rating;
+ _changed(obj);
+ _update_ratingbar(obj);
+}
+
+/**
+ * Get the current rating
+ *
+ * @param obj The ratingbar object
+ * @return The current rating
+ *
+ * @ingroup Ratingbar
+ */
+EAPI int
+elm_ratingbar_rating_get(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return 0;
+
+ return wd->rating;
+}
+
+
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Grid Scrolled Grid
+ * @ingroup Elementary
+ *
+ * This widget aims to position objects in a grid layout while actually
+ * building only the visible ones, using the same idea as genlist: the user
+ * define a class for each cell, specifying functions that will be called at
+ * object creation and deletion.
+ *
+ * Signals that you can add callbacks for are:
+ *
+ * clicked - The user has double-clicked a cell. The event_info parameter is
+ * the grid cell that was double-clicked.
+ *
+ * selected - The user has made an item selected. The event_info parameter is
+ * the grid cell that was selected.
+ *
+ * unselected - The user has made an item unselected. The event_info parameter
+ * is the grid cell that was unselected.
+ *
+ * realized - This is called when the cell in the grid is created as a real
+ * evas object. event_info is the grid cell that was created. The object may be
+ * deleted at any time, so it is up to the caller to not use the object pointer
+ * from elm_scrolled_grid_cell_object_get() in a way where it may point to
+ * freed objects.
+ *
+ * drag,start,up - Called when the cell in the grid has been dragged (not
+ * scrolled) up.
+ *
+ * drag,start,down - Called when the cell in the grid has been dragged (not
+ * scrolled) down.
+ *
+ * drag,start,left - Called when the cell in the grid has been dragged (not
+ * scrolled) left.
+ *
+ * drag,start,right - Called when the cell in the grid has been dragged (not
+ * scrolled) right.
+ *
+ * drag,stop - Called when the cell in the grid has stopped being dragged.
+ *
+ * drag - Called when the cell in the grid is being dragged.
+ *
+ * scroll - called when the content has been scrolled (moved).
+ *
+ * scroll,drag,start - called when dragging the content has started.
+ *
+ * scroll,drag,stop - called when dragging the content has stopped.
+ *
+ *
+ * A cell in the grid can have 0 or more text labels (they can be regular text
+ * or textblock - that's up to the style to determine), 0 or more icons (which
+ * are simply objects swallowed into the grid cell) and 0 or more boolean states
+ * that can be used for check, radio or other indicators by the edje theme style.
+ * A cell may be one of several styles (Elementary provides 1 by default -
+ * "default", but this can be extended by system or application custom
+ * themes/overlays/extensions).
+ *
+ * In order to implement the ability to add and delete cells on the fly, Grid
+ * implements a class/callback system where the application provides a structure
+ * with information about that type of cell (grid may contain multiple different
+ * cells with different classes, states and styles). Grid will call the functions
+ * in this struct (methods) when a cell is "realized" (that is created
+ * dynamically while scrolling). All objects will simply be deleted when no
+ * longer needed with evas_object_del(). The Elm_Genlist_Item_Class structure
+ * contains the following members:
+ *
+ * cell_style - This is a constant string and simply defines the name of the
+ * cell style. It must be specified and the default should be "default".
+ *
+ * func.label_get - This function is called when an actual cell object is
+ * created. The data parameter is the one passed to elm_scrolled_grid_cell_add()
+ * and related cell creation functions. The obj parameter is the grid object and
+ * the part parameter is the string name of the text part in the edje design that
+ * is listed as one of the possible labels that can be set. This function must
+ * return a strdup'()ed string as the caller will free() it when done.
+ *
+ * func.icon_get - This function is called when an actual item object is
+ * created. The data parameter is the one passed to elm_scrolled_grid_cell_add()
+ * and related cell creation functions. The obj parameter is the grid object and
+ * the part parameter is the string name of the icon part in the edje design that
+ * is listed as one of the possible icons that can be set. This must return NULL
+ * for no object or a valid object. The object will be deleted by grid on
+ * shutdown or when the cell is unrealized.
+ *
+ * func.state_get - This function is called when an actual cell object is
+ * created. The data parameter is the one passed to elm_scrolled_grid_cell_add()
+ * and related cell creation functions. The obj parameter is the grid object and
+ * the part parameter is the string name of th state part in the edje design that
+ * is listed as one of the possible states that can be set. Return 0 for false
+ * and 1 for true. Grid will emit a signal to the edje object with
+ * "elm,state,XXX,active" "elm" when true (the default is false), where XXX is
+ * the name of the part.
+ *
+ * func.del - This is called when elm_scrolled_grid_cell_del() is called on a
+ * cell or elm_scrolled_grid_clear() is called on the grid. This is intended for
+ * use when actual grid cells are deleted, so any backing data attached to the
+ * cell (e.g. its data parameter on creation) can be deleted.
+ *
+ * If the application wants multiple cells to be able to be selected,
+ * elm_scrolled_grid_multi_select_set() can enable this. If the grid is
+ * single-selection only (the default), then elm_scrolled_grid_select_cell_get()
+ * will return the selected cell, if any, or NULL if none is selected. If the
+ * grid is multi-select then elm_scrolled_grid_selected_cells_get() will return a
+ * list (that is only valid as long as no cells are modified (added, deleted,
+ * selected or unselected).
+ *
+ * If a cell changes (state of boolean changes, label or icons change), then use
+ * elm_scrolled_grid_cell_update() to have grid update the cell with the new
+ * state. Grid will re-realize the cell thus call the functions in the
+ * _Elm_Grid_Cell_Class for that cell.
+ *
+ * To programmatically (un)select a cell use elm_scrolled_grid_cell_selected_set().
+ * To get its selected state use elm_scrolled_grid_cell_selected_get(). To make a
+ * cell disabled (unable to be selected and appear differently) use
+ * elm_scrolled_grid_cell_disable_set() to set this and
+ * elm_scrolled_grid_cell_disable_get() to get the disabled state.
+ *
+ * Cells will only call their selection func and callback when first becoming
+ * selected. Any further clicks will do nothing, unless you enable always
+ * select with elm_scrolled_grid_always_select_mode_set(). This means event if
+ * selected, every click will make the selected callbacks be called.
+ * elm_scrolled_grid_no_select_mode_set() will turn off the ability to select
+ * items entirely and they will neither appear selected nor call selected
+ * callback function.
+ *
+ * Remember that you can create new styles and add your own theme augmentation
+ * per application with elm_theme_extension_add(). If you absolutely must have a
+ * specific style that overrides any theme the user or system sets up you can use
+ * elm_theme_overlay_add() to add such a file.
+ *
+ * --
+ * TODO:
+ * * Handle non-homogeneous objects too.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Pan Pan;
+
+#define PRELOAD 1
+
+struct _Elm_Grid_Cell
+{
+ Evas_Object *base, *spacer;
+ const Elm_Grid_Cell_Class *gcc;
+ Ecore_Timer *long_timer;
+ Widget_Data *wd;
+ Eina_List *labels, *icons, *states, *icon_objs;
+ const void *data;
+ struct
+ {
+ Evas_Smart_Cb func;
+ const void *data;
+ } func;
+
+ Evas_Coord x, y, dx, dy;
+ int relcount;
+
+ Eina_Bool want_unrealize : 1;
+ Eina_Bool realized : 1;
+ Eina_Bool dragging : 1;
+ Eina_Bool down : 1;
+ Eina_Bool delete_me : 1;
+ Eina_Bool display_only : 1;
+ Eina_Bool disabled : 1;
+ Eina_Bool selected : 1;
+ Eina_Bool hilighted : 1;
+ Eina_Bool walking : 1;
+};
+
+struct _Widget_Data
+{
+ Evas_Object *self, *scr;
+ Evas_Object *pan_smart;
+ Pan *pan;
+ Eina_List *cells;
+ Ecore_Job *calc_job;
+ Eina_List *selected;
+ double align_x, align_y;
+
+ Evas_Coord pan_x, pan_y;
+ Evas_Coord cell_width, cell_height; /* Each cell size */
+ Evas_Coord minw, minh; /* Total obj size */
+ unsigned int nmax;
+
+ Eina_Bool horizontal : 1;
+ Eina_Bool on_hold : 1;
+ Eina_Bool longpressed : 1;
+ Eina_Bool multi : 1;
+ Eina_Bool no_select : 1;
+ Eina_Bool wasselected : 1;
+ Eina_Bool always_select : 1;
+};
+
+struct _Pan
+{
+ Evas_Object_Smart_Clipped_Data __clipped_data;
+ Widget_Data *wd;
+};
+
+static const char *widtype = NULL;
+static void _sizing_eval(Evas_Object *obj);
+static void _cell_hilight(Elm_Grid_Cell *cell);
+static void _cell_unrealize(Elm_Grid_Cell *cell);
+static void _cell_select(Elm_Grid_Cell *cell);
+static void _cell_unselect(Elm_Grid_Cell *cell);
+
+static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION;
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ elm_smart_scroller_object_theme_set(obj, wd->scr, "grid", "base",
+ elm_widget_style_get(obj));
+ _sizing_eval(obj);
+}
+
+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;
+ if (!wd) return;
+ evas_object_size_hint_max_get(wd->scr, &maxw, &maxh);
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (wd->calc_job) ecore_job_del(wd->calc_job);
+ evas_object_del(wd->pan_smart);
+ wd->pan_smart = NULL;
+ elm_scrolled_grid_clear(obj);
+ free(wd);
+}
+
+static void
+_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
+{
+ Elm_Grid_Cell *cell = data;
+ Evas_Event_Mouse_Move *ev = event_info;
+ Evas_Coord minw = 0, minh = 0, x, y, dx, dy, adx, ady;
+
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+ {
+ if (!cell->wd->on_hold) {
+ cell->wd->on_hold = EINA_TRUE;
+ _cell_unselect(cell);
+ }
+ }
+ if ((cell->dragging) && (cell->down))
+ {
+ if (cell->long_timer)
+ {
+ ecore_timer_del(cell->long_timer);
+ cell->long_timer = NULL;
+ }
+ evas_object_smart_callback_call(cell->wd->self, "drag", cell);
+ return;
+ }
+ if ((!cell->down) || (cell->wd->longpressed))
+ {
+ if (cell->long_timer)
+ {
+ ecore_timer_del(cell->long_timer);
+ cell->long_timer = NULL;
+ }
+ return;
+ }
+ if (!cell->display_only)
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+ x = ev->cur.canvas.x - x;
+ y = ev->cur.canvas.y - y;
+ dx = x - cell->dx;
+ adx = dx;
+ if (adx < 0) adx = -dx;
+ dy = y - cell->dy;
+ ady = dy;
+ if (ady < 0) ady = -dy;
+ minw /= 2;
+ minh /= 2;
+ if ((adx > minw) || (ady > minh))
+ {
+ cell->dragging = 1;
+ if (cell->long_timer)
+ {
+ ecore_timer_del(cell->long_timer);
+ cell->long_timer = NULL;
+ }
+ if (cell->wd->wasselected)
+ _cell_unselect(cell);
+ cell->wd->wasselected = 0;
+ if (dy < 0)
+ {
+ if (ady > adx)
+ evas_object_smart_callback_call(cell->wd->self, "drag,start,up",
+ cell);
+ else
+ {
+ if (dx < 0)
+ evas_object_smart_callback_call(cell->wd->self,
+ "drag,start,left", cell);
+ }
+ }
+ else
+ {
+ if (ady > adx)
+ evas_object_smart_callback_call(cell->wd->self,
+ "drag,start,down", cell);
+ else
+ {
+ if (dx < 0)
+ evas_object_smart_callback_call(cell->wd->self,
+ "drag,start,left", cell);
+ else
+ evas_object_smart_callback_call(cell->wd->self,
+ "drag,start,right", cell);
+ }
+ }
+ }
+}
+
+static int
+_long_press(void *data)
+{
+ Elm_Grid_Cell *cell = data;
+
+ cell->long_timer = NULL;
+ if ((cell->disabled) || (cell->dragging)) return 0;
+ cell->wd->longpressed = EINA_TRUE;
+ evas_object_smart_callback_call(cell->wd->self, "longpressed", cell);
+ return 0;
+}
+
+static void
+_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info)
+{
+ Elm_Grid_Cell *cell = data;
+ Evas_Event_Mouse_Down *ev = event_info;
+ Evas_Coord x, y;
+
+ if (ev->button != 1) return;
+ cell->down = 1;
+ cell->dragging = 0;
+ evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+ cell->dx = ev->canvas.x - x;
+ cell->dy = ev->canvas.y - y;
+ cell->wd->longpressed = EINA_FALSE;
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) cell->wd->on_hold = EINA_TRUE;
+ else cell->wd->on_hold = EINA_FALSE;
+ cell->wd->wasselected = cell->selected;
+ _cell_hilight(cell);
+ if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
+ evas_object_smart_callback_call(cell->wd->self, "clicked", cell);
+ if (cell->long_timer) ecore_timer_del(cell->long_timer);
+ if (cell->realized)
+ cell->long_timer = ecore_timer_add(1.0, _long_press, cell);
+ else
+ cell->long_timer = NULL;
+}
+
+static void
+_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Elm_Grid_Cell *cell = data;
+ Evas_Event_Mouse_Up *ev = event_info;
+ Eina_Bool dragged = EINA_FALSE;
+
+ if (ev->button != 1) return;
+ cell->down = EINA_FALSE;
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) cell->wd->on_hold = EINA_TRUE;
+ else cell->wd->on_hold = EINA_FALSE;
+ if (cell->long_timer)
+ {
+ ecore_timer_del(cell->long_timer);
+ cell->long_timer = NULL;
+ }
+ if (cell->dragging)
+ {
+ cell->dragging = EINA_FALSE;
+ evas_object_smart_callback_call(cell->wd->self, "drag,stop", cell);
+ dragged = EINA_TRUE;
+ }
+ if (cell->wd->on_hold)
+ {
+ cell->wd->longpressed = EINA_FALSE;
+ cell->wd->on_hold = EINA_FALSE;
+ return;
+ }
+ if (cell->wd->longpressed)
+ {
+ cell->wd->longpressed = EINA_FALSE;
+ if (!cell->wd->wasselected)
+ _cell_unselect(cell);
+ cell->wd->wasselected = EINA_FALSE;
+ return;
+ }
+ if (dragged)
+ {
+ if (cell->want_unrealize)
+ _cell_unrealize(cell);
+ }
+ if ((cell->disabled) || dragged) return;
+ if (cell->wd->multi)
+ {
+ if (!cell->selected)
+ {
+ _cell_hilight(cell);
+ _cell_select(cell);
+ }
+ else _cell_unselect(cell);
+ }
+ else
+ {
+ if (!cell->selected)
+ {
+ while (cell->wd->selected) _cell_unselect(cell->wd->selected->data);
+ }
+ else
+ {
+ const Eina_List *l, *l_next;
+ Elm_Grid_Cell *cell2;
+
+ EINA_LIST_FOREACH_SAFE(cell->wd->selected, l, l_next, cell2)
+ if (cell2 != cell) _cell_unselect(cell2);
+ }
+ _cell_hilight(cell);
+ _cell_select(cell);
+ }
+}
+
+static void
+_cell_hilight(Elm_Grid_Cell *cell)
+{
+ if ((cell->wd->no_select) || (cell->delete_me) || (cell->hilighted)) return;
+ edje_object_signal_emit(cell->base, "elm,state,selected", "elm");
+ cell->hilighted = EINA_TRUE;
+}
+
+static void
+_cell_realize(Elm_Grid_Cell *cell)
+{
+ char buf[1024];
+
+ if ((cell->realized) || (cell->delete_me)) return;
+ cell->base = edje_object_add(evas_object_evas_get(cell->wd->self));
+ edje_object_scale_set(cell->base, elm_widget_scale_get(cell->wd->self) *
+ _elm_config->scale);
+ evas_object_smart_member_add(cell->base, cell->wd->pan_smart);
+ elm_widget_sub_object_add(cell->wd->self, cell->base);
+ _elm_theme_object_set(cell->wd->self, cell->base, "grid", "cell/default",
+ elm_widget_style_get(cell->wd->self));
+ cell->spacer = evas_object_rectangle_add(evas_object_evas_get(cell->wd->self));
+ evas_object_color_set(cell->spacer, 0, 0, 0, 0);
+ elm_widget_sub_object_add(cell->wd->self, cell->spacer);
+ evas_object_size_hint_min_set(cell->spacer, 2 * _elm_config->scale, 1);
+ edje_object_part_swallow(cell->base, "elm.swallow.pad", cell->spacer);
+
+ if (cell->gcc->func.label_get)
+ {
+ const Eina_List *l;
+ const char *key;
+
+ cell->labels = _elm_stringlist_get(edje_object_data_get(cell->base,
+ "labels"));
+ EINA_LIST_FOREACH(cell->labels, l, key)
+ {
+ char *s = cell->gcc->func.label_get(cell->data, cell->wd->self,
+ l->data);
+ if (s)
+ {
+ edje_object_part_text_set(cell->base, l->data, s);
+ free(s);
+ }
+ }
+ }
+
+ if (cell->gcc->func.icon_get)
+ {
+ const Eina_List *l;
+ const char *key;
+
+ cell->icons = _elm_stringlist_get(edje_object_data_get(cell->base,
+ "icons"));
+ EINA_LIST_FOREACH(cell->icons, l, key)
+ {
+ Evas_Object *ic = cell->gcc->func.icon_get(cell->data,
+ cell->wd->self,
+ l->data);
+ if (ic)
+ {
+ cell->icon_objs = eina_list_append(cell->icon_objs, ic);
+ edje_object_part_swallow(cell->base, key, ic);
+ evas_object_show(ic);
+ elm_widget_sub_object_add(cell->wd->self, ic);
+ }
+ }
+ }
+
+ if (cell->gcc->func.state_get)
+ {
+ const Eina_List *l;
+ const char *key;
+
+ cell->states = _elm_stringlist_get(edje_object_data_get(cell->base,
+ "states"));
+ EINA_LIST_FOREACH(cell->states, l, key)
+ {
+ Eina_Bool on = cell->gcc->func.state_get(cell->data,
+ cell->wd->self, l->data);
+ if (on)
+ {
+ snprintf(buf, sizeof(buf), "elm,state,%s,active", key);
+ edje_object_signal_emit(cell->base, buf, "elm");
+ }
+ }
+ }
+
+ if (!cell->wd->cell_width && !cell->wd->cell_height)
+ {
+ edje_object_size_min_restricted_calc(cell->base,
+ &cell->wd->cell_width, &cell->wd->cell_height,
+ cell->wd->cell_width, cell->wd->cell_height);
+ elm_coords_finger_size_adjust(1, &cell->wd->cell_width,
+ 1, &cell->wd->cell_height);
+ }
+
+ evas_object_event_callback_add(cell->base, EVAS_CALLBACK_MOUSE_DOWN,
+ _mouse_down, cell);
+ evas_object_event_callback_add(cell->base, EVAS_CALLBACK_MOUSE_UP,
+ _mouse_up, cell);
+ evas_object_event_callback_add(cell->base, EVAS_CALLBACK_MOUSE_MOVE,
+ _mouse_move, cell);
+
+ if (cell->selected)
+ edje_object_signal_emit(cell->base, "elm,state,selected", "elm");
+ if (cell->disabled)
+ edje_object_signal_emit(cell->base, "elm,state,disabled", "elm");
+
+ evas_object_show(cell->base);
+ cell->realized = EINA_TRUE;
+ cell->want_unrealize = EINA_FALSE;
+}
+
+static void
+_cell_unrealize(Elm_Grid_Cell *cell)
+{
+ Evas_Object *icon;
+
+ if (!cell->realized) return;
+ if (cell->long_timer)
+ {
+ ecore_timer_del(cell->long_timer);
+ cell->long_timer = NULL;
+ }
+ evas_object_del(cell->base);
+ cell->base = NULL;
+ evas_object_del(cell->spacer);
+ cell->spacer = NULL;
+ _elm_stringlist_free(cell->labels);
+ cell->labels = NULL;
+ _elm_stringlist_free(cell->icons);
+ cell->icons = NULL;
+ _elm_stringlist_free(cell->states);
+
+ EINA_LIST_FREE(cell->icon_objs, icon)
+ evas_object_del(icon);
+
+ cell->states = NULL;
+ cell->realized = EINA_FALSE;
+ cell->want_unrealize = EINA_FALSE;
+}
+
+static void
+_cell_place(Elm_Grid_Cell *cell, Evas_Coord cx, Evas_Coord cy)
+{
+ Evas_Coord x, y, ox, oy, cvx, cvy, cvw, cvh;
+ Evas_Coord tch, tcw, alignw = 0, alignh = 0, vw, vh;
+
+ cell->x = cx;
+ cell->y = cy;
+ evas_object_geometry_get(cell->wd->self, &ox, &oy, &vw, &vh);
+ evas_output_viewport_get(evas_object_evas_get(cell->wd->self),
+ &cvx, &cvy, &cvw, &cvh);
+
+ /* Preload rows/columns at each side of the Grid */
+ cvx -= PRELOAD * cell->wd->cell_width;
+ cvy -= PRELOAD * cell->wd->cell_height;
+ cvw += 2 * PRELOAD * cell->wd->cell_width;
+ cvh += 2 * PRELOAD * cell->wd->cell_height;
+
+ tch = ((vh/cell->wd->cell_height)*cell->wd->cell_height);
+ alignh = (vh - tch)*cell->wd->align_y;
+
+ tcw = ((vw/cell->wd->cell_width)*cell->wd->cell_width);
+ alignw = (vw - tcw)*cell->wd->align_x;
+
+ if (cell->wd->horizontal && cell->wd->minw < vw)
+ {
+ int columns;
+
+ columns = eina_list_count(cell->wd->cells)/(vh/cell->wd->cell_height);
+ if (eina_list_count(cell->wd->cells) % (vh/cell->wd->cell_height))
+ columns++;
+
+ tcw = cell->wd->cell_width * columns;
+ alignw = (vw - tcw)*cell->wd->align_x;
+ }
+ else if (cell->wd->horizontal && cell->wd->minw > vw)
+ alignw = 0;
+ if (!cell->wd->horizontal && cell->wd->minh < vh)
+ {
+ int rows;
+
+ rows = eina_list_count(cell->wd->cells)/(vw/cell->wd->cell_width);
+ if (eina_list_count(cell->wd->cells) % (vw/cell->wd->cell_width))
+ rows++;
+
+ tch = cell->wd->cell_height * rows;
+ alignh = (vh - tch)*cell->wd->align_y;
+ }
+ else if (!cell->wd->horizontal && cell->wd->minh > vh)
+ alignh = 0;
+ x = cx * cell->wd->cell_width - cell->wd->pan_x + ox + alignw;
+ y = cy * cell->wd->cell_height - cell->wd->pan_y + oy + alignh;
+
+ if (ELM_RECTS_INTERSECT(x, y, cell->wd->cell_width, cell->wd->cell_height,
+ cvx, cvy, cvw, cvh))
+ {
+ Eina_Bool was_realized = cell->realized;
+ _cell_realize(cell);
+ if (!was_realized)
+ evas_object_smart_callback_call(cell->wd->self, "realized", cell);
+ evas_object_move(cell->base, x, y);
+ evas_object_resize(cell->base, cell->wd->cell_width,
+ cell->wd->cell_height);
+ }
+ else
+ _cell_unrealize(cell);
+}
+
+static Elm_Grid_Cell *
+_cell_create(Widget_Data *wd, const Elm_Grid_Cell_Class *gcc,
+ const void *data, Evas_Smart_Cb func, const void *func_data)
+{
+ Elm_Grid_Cell *cell;
+
+ cell = calloc(1, sizeof(*cell));
+ if (!cell) return NULL;
+ cell->wd = wd;
+ cell->gcc = gcc;
+ cell->data = data;
+ cell->func.func = func;
+ cell->func.data = func_data;
+ return cell;
+}
+
+static void
+_cell_del(Elm_Grid_Cell *cell)
+{
+ if (cell->selected)
+ cell->wd->selected = eina_list_remove(cell->wd->selected, cell);
+ if (cell->realized) _cell_unrealize(cell);
+ if ((!cell->delete_me) && (cell->gcc->func.del))
+ cell->gcc->func.del(cell->data, cell->wd->self);
+ cell->delete_me = EINA_TRUE;
+ cell->wd->cells = eina_list_remove(cell->wd->cells, cell);
+ if (cell->long_timer) ecore_timer_del(cell->long_timer);
+ free(cell);
+}
+
+static void
+_cell_select(Elm_Grid_Cell *cell)
+{
+ if ((cell->wd->no_select) || (cell->delete_me)) return;
+ if (cell->selected)
+ {
+ if (cell->wd->always_select) goto call;
+ return;
+ }
+ cell->selected = EINA_TRUE;
+ cell->wd->selected = eina_list_append(cell->wd->selected, cell);
+call:
+ cell->walking++;
+ if (cell->func.func) cell->func.func((void *)cell->func.data, cell->wd->self,
+ cell);
+ if (!cell->delete_me)
+ evas_object_smart_callback_call(cell->wd->self, "selected", cell);
+ cell->walking--;
+ if ((cell->walking == 0) && (cell->delete_me))
+ if (cell->relcount == 0) _cell_del(cell);
+}
+
+static void
+_cell_unselect(Elm_Grid_Cell *cell)
+{
+ if ((cell->delete_me) || (!cell->hilighted)) return;
+ edje_object_signal_emit(cell->base, "elm,state,unselected", "elm");
+ cell->hilighted = EINA_FALSE;
+ if (cell->selected)
+ {
+ cell->selected = EINA_FALSE;
+ cell->wd->selected = eina_list_remove(cell->wd->selected, cell);
+ evas_object_smart_callback_call(cell->wd->self, "unselected", cell);
+ }
+}
+
+static void
+_calc_job(void *data)
+{
+ Widget_Data *wd = data;
+ Evas_Coord minw = 0, minh = 0, nmax = 0, cvw, cvh;
+ int count;
+
+ evas_output_viewport_get(evas_object_evas_get(wd->self), NULL, NULL,
+ &cvw, &cvh);
+ if (wd->horizontal && wd->cell_height)
+ nmax = cvh / wd->cell_height;
+ else if (wd->cell_width)
+ nmax = cvw / wd->cell_width;
+
+ if (nmax)
+ {
+ count = eina_list_count(wd->cells);
+ if (wd->horizontal)
+ {
+ minw = ceil(count / (float)nmax) * wd->cell_width;
+ minh = nmax * wd->cell_height;
+ }
+ else
+ {
+ minw = nmax * wd->cell_width;
+ minh = ceil(count / (float)nmax) * wd->cell_height;
+ }
+ }
+
+ if ((minw != wd->minw) || (minh != wd->minh))
+ {
+ wd->minh = minh;
+ wd->minw = minw;
+ evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
+ _sizing_eval(wd->self);
+ }
+
+ wd->nmax = nmax;
+ wd->calc_job = NULL;
+ evas_object_smart_changed(wd->pan_smart);
+}
+
+static void
+_pan_add(Evas_Object *obj)
+{
+ Pan *sd;
+ Evas_Object_Smart_Clipped_Data *cd;
+
+ _pan_sc.add(obj);
+ cd = evas_object_smart_data_get(obj);
+ sd = ELM_NEW(Pan);
+ if (!sd) return;
+ sd->__clipped_data = *cd;
+ free(cd);
+ evas_object_smart_data_set(obj, sd);
+}
+
+static void
+_pan_del(Evas_Object *obj)
+{
+ Pan *sd = evas_object_smart_data_get(obj);
+
+ if (!sd) return;
+ _pan_sc.del(obj);
+}
+
+static void
+_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+ Pan *sd = evas_object_smart_data_get(obj);
+ if ((x == sd->wd->pan_x) && (y == sd->wd->pan_y)) return;
+ sd->wd->pan_x = x;
+ sd->wd->pan_y = y;
+ evas_object_smart_changed(obj);
+}
+
+static void
+_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+ Pan *sd = evas_object_smart_data_get(obj);
+ if (x) *x = sd->wd->pan_x;
+ if (y) *y = sd->wd->pan_y;
+}
+
+static void
+_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+ Pan *sd = evas_object_smart_data_get(obj);
+ if (w) *w = sd->wd->minw;
+ if (h) *h = sd->wd->minh;
+}
+
+static void
+_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+ Pan *sd = evas_object_smart_data_get(obj);
+ Evas_Coord ow, oh;
+
+ if (!sd) return;
+ evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+ if (x)
+ *x = (ow < sd->wd->minw) ? sd->wd->minw - ow : 0;
+ if (y)
+ *y = (oh < sd->wd->minh) ? sd->wd->minh - oh : 0;
+}
+
+static void
+_pan_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+ Pan *sd = evas_object_smart_data_get(obj);
+ Evas_Coord ow, oh;
+
+ evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+ if ((ow == w) && (oh == h)) return;
+ if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
+ sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
+}
+
+static void
+_pan_calculate(Evas_Object *obj)
+{
+ Pan *sd = evas_object_smart_data_get(obj);
+ Evas_Coord cx = 0, cy = 0;
+ Eina_List *l;
+ Elm_Grid_Cell *cell;
+
+ if (!sd) return;
+ if (!sd->wd->nmax) return;
+
+ EINA_LIST_FOREACH(sd->wd->cells, l, cell)
+ {
+ _cell_place(cell, cx, cy);
+ if (sd->wd->horizontal)
+ {
+ cy = (cy + 1) % sd->wd->nmax;
+ if (!cy) cx++;
+ }
+ else
+ {
+ cx = (cx + 1) % sd->wd->nmax;
+ if (!cx) cy++;
+ }
+ }
+}
+
+static void
+_pan_move(Evas_Object *obj, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
+{
+ Pan *sd = evas_object_smart_data_get(obj);
+ if (!sd) return;
+ if (sd->wd->calc_job) ecore_job_del(sd->wd->calc_job);
+ sd->wd->calc_job = ecore_job_add(_calc_job, sd->wd);
+}
+
+static void
+_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ elm_smart_scroller_hold_set(wd->scr, 1);
+}
+
+static void
+_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ elm_smart_scroller_hold_set(wd->scr, 0);
+}
+
+static void
+_freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ elm_smart_scroller_freeze_set(wd->scr, 1);
+}
+
+static void
+_freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ elm_smart_scroller_freeze_set(wd->scr, 0);
+}
+
+static void
+_scr_drag_start(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ evas_object_smart_callback_call(data, "scroll,drag,start", NULL);
+}
+
+static void
+_scr_drag_stop(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ evas_object_smart_callback_call(data, "scroll,drag,stop", NULL);
+}
+
+static void
+_scr_scroll(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ evas_object_smart_callback_call(data, "scroll", NULL);
+}
+
+/**
+ * Add a new Scrolled Grid object.
+ *
+ * @param parent The parent object.
+ * @return The new object or NULL if it cannot be created.
+ *
+ * @see elm_scrolled_grid_cell_size_set()
+ * @see elm_scrolled_grid_horizontal_set()
+ * @see elm_scrolled_grid_cell_add()
+ * @see elm_scrolled_grid_cell_del()
+ * @see elm_scrolled_grid_clear()
+ *
+ * @ingroup Grid
+ */
+EAPI Evas_Object *
+elm_scrolled_grid_add(Evas_Object *parent)
+{
+ Evas_Object *obj;
+ Evas *e;
+ Evas_Coord minw, minh;
+ Widget_Data *wd;
+ static Evas_Smart *smart = NULL;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ obj = elm_widget_add(e);
+ ELM_SET_WIDTYPE(widtype, "grid");
+ elm_widget_type_set(obj, "grid");
+ 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);
+
+ wd->scr = elm_smart_scroller_add(e);
+ elm_smart_scroller_widget_set(wd->scr, obj);
+ elm_smart_scroller_object_theme_set(obj, wd->scr, "grid", "base", "default");
+ elm_widget_resize_object_set(obj, wd->scr);
+
+ evas_object_smart_callback_add(wd->scr, "drag,start", _scr_drag_start, obj);
+ evas_object_smart_callback_add(wd->scr, "drag,stop", _scr_drag_stop, obj);
+ evas_object_smart_callback_add(wd->scr, "scroll", _scr_scroll, obj);
+
+ elm_smart_scroller_bounce_allow_set(wd->scr, 1, 1);
+
+ wd->self = obj;
+ wd->align_x = 0.5;
+ wd->align_y = 0.5;
+
+ evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj);
+ evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj);
+ evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj);
+ evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj);
+
+ if (!smart)
+ {
+ static Evas_Smart_Class sc;
+
+ evas_object_smart_clipped_smart_set(&_pan_sc);
+ sc = _pan_sc;
+ sc.name = "elm_scrolled_grid_pan";
+ sc.version = EVAS_SMART_CLASS_VERSION;
+ sc.add = _pan_add;
+ sc.del = _pan_del;
+ sc.resize = _pan_resize;
+ sc.move = _pan_move;
+ sc.calculate = _pan_calculate;
+ smart = evas_smart_class_new(&sc);
+ }
+ if (smart)
+ {
+ wd->pan_smart = evas_object_smart_add(e, smart);
+ wd->pan = evas_object_smart_data_get(wd->pan_smart);
+ wd->pan->wd = wd;
+ }
+
+ elm_smart_scroller_extern_pan_set(wd->scr, wd->pan_smart,
+ _pan_set, _pan_get,
+ _pan_max_get, _pan_child_size_get);
+
+ _sizing_eval(obj);
+
+ return obj;
+}
+
+/**
+ * Set the size for the cell of the Grid.
+ *
+ * @param obj The Grid object.
+ * @param w The cell's width.
+ * @param h The cell's height;
+ *
+ * @see elm_scrolled_grid_cell_size_get()
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_cell_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (wd->cell_width == w && wd->cell_height == h) return;
+ wd->cell_width = w;
+ wd->cell_height = h;
+ if (wd->calc_job) ecore_job_del(wd->calc_job);
+ wd->calc_job = ecore_job_add(_calc_job, wd);
+}
+
+/**
+ * Get the size of the cell of the Grid.
+ *
+ * @param obj The Grid object.
+ * @param w Pointer to the cell's width.
+ * @param h Pointer to the cell's height.
+ *
+ * @see elm_scrolled_grid_cell_size_get()
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_cell_size_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (w) *w = wd->cell_width;
+ if (h) *h = wd->cell_height;
+}
+
+/**
+ * Set cell's alignment within the scroller.
+ *
+ * @param obj The grid object.
+ * @param align_x The x alignment (0 <= x <= 1).
+ * @param align_y The y alignment (0 <= y <= 1).
+ *
+ * @see elm_scrolled_grid_align_get()
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_align_set(Evas_Object *obj, double align_x, double align_y)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ if (align_x > 1.0)
+ align_x = 1.0;
+ else if (align_x < 0.0)
+ align_x = 0.0;
+ wd->align_x = align_x;
+
+ if (align_y > 1.0)
+ align_y = 1.0;
+ else if (align_y < 0.0)
+ align_y = 0.0;
+ wd->align_y = align_y;
+}
+
+/**
+ * Get the alignenment set for the grid object.
+ *
+ * @param obj The grid object.
+ * @param align_x Pointer to x alignenment.
+ * @param align_y Pointer to y alignenment.
+ *
+ * @see elm_scrolled_grid_align_set()
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_align_get(const Evas_Object *obj, double *align_x, double *align_y)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (align_x) *align_x = wd->align_x;
+ if (align_y) *align_y = wd->align_y;
+}
+
+/**
+ * Add cell to the end of the Grid.
+ *
+ * @param obj The Grid object.
+ * @param gcc The cell class for the cell.
+ * @param data The cell data.
+ * @param func Convenience function called when cell is selected.
+ * @param func_data Data passed to @p func above.
+ * @return A handle to the cell added or NULL if not possible.
+ *
+ * @see elm_scrolled_grid_cell_del()
+ *
+ * @ingroup Grid
+ */
+EAPI Elm_Grid_Cell *
+elm_scrolled_grid_cell_add(Evas_Object *obj, const Elm_Grid_Cell_Class *gcc,
+ const void *data, Evas_Smart_Cb func,
+ const void *func_data)
+{
+ Elm_Grid_Cell *cell;
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+
+ cell = _cell_create(wd, gcc, data, func, func_data);
+ if (!cell) return NULL;
+
+ wd->cells = eina_list_append(wd->cells, cell);
+ wd->no_select = EINA_FALSE;
+
+ if (wd->calc_job) ecore_job_del(wd->calc_job);
+ wd->calc_job = ecore_job_add(_calc_job, wd);
+
+ return cell;
+}
+
+/**
+ * Remove a cell from the Grid.
+ *
+ * @param cell The cell to be removed.
+ * @return @c EINA_TRUE on success or @c EINA_FALSE otherwise.
+ *
+ * @see elm_scrolled_grid_clear() to remove all cells of the grid.
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_cell_del(Elm_Grid_Cell *cell)
+{
+ if (!cell) return;
+ if ((cell->relcount > 0) || (cell->walking > 0))
+ {
+ cell->delete_me = EINA_TRUE;
+ if (cell->selected)
+ cell->wd->selected = eina_list_remove(cell->wd->selected, cell);
+ if (cell->gcc->func.del) cell->gcc->func.del(cell->data, cell->wd->self);
+ return;
+ }
+
+ _cell_del(cell);
+
+ if (cell->wd->calc_job) ecore_job_del(cell->wd->calc_job);
+ cell->wd->calc_job = ecore_job_add(_calc_job, cell->wd);
+}
+
+/**
+ * Set for what direction the grid will expand.
+ *
+ * @param obj The Grid object.
+ * @param setting If @c EINA_TRUE the grid will expand horizontally or
+ * vertically if @c EINA_FALSE.
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_horizontal_set(Evas_Object *obj, Eina_Bool setting)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (setting == wd->horizontal) return;
+ wd->horizontal = setting;
+
+ /* Update the cells to conform to the new layout */
+ if (wd->calc_job) ecore_job_del(wd->calc_job);
+ wd->calc_job = ecore_job_add(_calc_job, wd);
+}
+
+/**
+ * Clear the Grid
+ *
+ * This clears all cells in the grid, leaving it empty.
+ *
+ * @param obj The Grid object.
+ *
+ * @see elm_scrolled_grid_cell_del() to remove just one cell.
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_clear(Evas_Object *obj)
+{
+ Eina_List *l, *l_next;
+ Elm_Grid_Cell *cell;
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ if (wd->calc_job)
+ {
+ ecore_job_del(wd->calc_job);
+ wd->calc_job = NULL;
+ }
+
+ EINA_LIST_FOREACH_SAFE(wd->cells, l, l_next, cell)
+ {
+ if (cell->realized) _cell_unrealize(cell);
+ if (cell->gcc->func.del) cell->gcc->func.del(cell->data, wd->self);
+ if (cell->long_timer) ecore_timer_del(cell->long_timer);
+ free(cell);
+ wd->cells = eina_list_remove_list(wd->cells, l);
+ }
+
+ if (wd->selected)
+ {
+ eina_list_free(wd->selected);
+ wd->selected = NULL;
+ }
+
+ wd->pan_x = 0;
+ wd->pan_y = 0;
+ wd->minw = 0;
+ wd->minh = 0;
+ evas_object_size_hint_min_set(wd->pan_smart, wd->minw, wd->minh);
+ evas_object_smart_callback_call(wd->pan_smart, "changed", NULL);
+ _sizing_eval(obj);
+}
+
+/**
+ * Get the real evas object of the grid cell
+ *
+ * This returns the actual evas object used for the specified grid cell.
+ * This may be NULL as it may not be created, and may be deleted at any time
+ * by grid. Do not modify this object (move, resize, show, hide etc.) as grid
+ * is controlling it. This function is for querying, emitting custom signals
+ * or hooking lower level callbacks for events. Do not delete this object
+ * under any circumstances.
+ *
+ * @param cell The Grid cell.
+ * @return the evas object associated to this cell.
+ *
+ * @see elm_scrolled_grid_cell_data_get()
+ *
+ * @ingroup Grid
+ */
+EAPI const Evas_Object *
+elm_scrolled_grid_cell_object_get(Elm_Grid_Cell *cell)
+{
+ if (!cell) return NULL;
+ return cell->base;
+}
+
+/**
+ * Returns the data associated to a cell
+ *
+ * This returns the data value passed on the elm_scrolled_grid_cell_add() and
+ * related cell addition calls.
+ *
+ * @param cell The Grid cell.
+ * @return the data associated to this cell.
+ *
+ * @see elm_scrolled_grid_cell_add()
+ * @see elm_scrolled_grid_cell_object_get()
+ *
+ * @ingroup Grid
+ */
+EAPI void *
+elm_scrolled_grid_cell_data_get(Elm_Grid_Cell *cell)
+{
+ if (!cell) return NULL;
+ return (void *)cell->data;
+}
+
+/**
+ * Get the cell's coordinates.
+ *
+ * This returns the logical position of the cell whithin the Grid.
+ *
+ * @param cell The Grid cell.
+ * @param x The x-axis coordinate pointer.
+ * @param y The y-axis coordinate pointer.
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_cell_pos_get(const Elm_Grid_Cell *cell, unsigned int *x, unsigned int *y)
+{
+ if (!cell) return;
+ if (x) *x = cell->x;
+ if (y) *y = cell->y;
+}
+
+/**
+ * Enable or disable multi-select in the grid.
+ *
+ * This enables (EINA_TRUE) or disables (EINA_FALSE) multi-select in the grid.
+ * This allows more than 1 cell to be selected.
+ *
+ * @param obj The grid object.
+ * @param multi Multi-select enabled/disabled
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_multi_select_set(Evas_Object *obj, Eina_Bool multi)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ wd->multi = multi;
+}
+
+/**
+ * Get if multi-select in grid is enabled or disabled
+ *
+ * @param obj The grid object
+ * @return Multi-select enable/disable
+ * (EINA_TRUE = enabled / EINA_FALSE = disabled)
+ *
+ * @ingroup Grid
+ */
+EAPI Eina_Bool
+elm_scrolled_grid_multi_select_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 wd->multi;
+}
+
+/**
+ * Get the selected cell in the grid
+ *
+ * This gets the selected cell in the grid (if multi-select is enabled only
+ * the first cell in the list is selected - which is not very useful, so see
+ * elm_scrolled_grid_selected_cells_get() for when multi-select is used).
+ *
+ * If no cell is selected, NULL is returned.
+ *
+ * @param obj The grid object.
+ * @return The selected cell, or NULL if none.
+ *
+ * @ingroup Grid
+ */
+EAPI Elm_Grid_Cell *
+elm_scrolled_grid_selected_cell_get(const Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+ if (wd->selected) return wd->selected->data;
+ return NULL;
+}
+
+/**
+ * Get a list of selected cells in the grid.
+ *
+ * This returns a list of the selected cells. This list pointer is only valid
+ * so long as no cells are selected or unselected (or unselected implictly by
+ * deletion). The list contains Elm_Grid_Cell pointers.
+ *
+ * @param obj The grid object.
+ * @return The list of selected cells, or NULL if none are selected.
+ *
+ * @ingroup Grid
+ */
+EAPI const Eina_List *
+elm_scrolled_grid_selected_cells_get(const Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+ return wd->selected;
+}
+
+/**
+ * Get the selected state of a cell.
+ *
+ * This gets the selected state of a cell (1 selected, 0 not selected).
+ *
+ * @param cell The cell
+ * @return The selected state
+ *
+ * @ingroup Grid
+ */
+EAPI Eina_Bool
+elm_scrolled_grid_cell_selected_get(const Elm_Grid_Cell *cell)
+{
+ if (!cell) return EINA_FALSE;
+ return cell->selected;
+}
+
+/**
+ * Sets the disabled state of a cell.
+ *
+ * A disabled cell cannot be selected or unselected. It will also change
+ * appearance to disabled. This sets the disabled state (1 disabled, 0 not
+ * disabled).
+ *
+ * @param cell The cell
+ * @param disabled The disabled state
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_cell_disabled_set(Elm_Grid_Cell *cell, Eina_Bool disabled)
+{
+ if (!cell) return;
+ if (cell->disabled == disabled) return;
+ if (cell->delete_me) return;
+ cell->disabled = disabled;
+ if (cell->realized)
+ {
+ if (cell->disabled)
+ edje_object_signal_emit(cell->base, "elm,state,disabled", "elm");
+ else
+ edje_object_signal_emit(cell->base, "elm,state,enabled", "elm");
+ }
+}
+
+/**
+ * Get the disabled state of a cell.
+ *
+ * This gets the disabled state of the given cell.
+ *
+ * @param cell The cell
+ * @return The disabled state
+ *
+ * @ingroup Grid
+ */
+EAPI Eina_Bool
+elm_scrolled_grid_cell_disabled_get(const Elm_Grid_Cell *cell)
+{
+ if (!cell) return EINA_FALSE;
+ if (cell->delete_me) return EINA_FALSE;
+ return cell->disabled;
+}
+
+/**
+ * Set the always select mode.
+ *
+ * Cells will only call their selection func and callback when first becoming
+ * selected. Any further clicks will do nothing, unless you enable always select
+ * with elm_scrolled_grid_always_select_mode_set(). This means even if selected,
+ * every click will make the selected callbacks be called.
+ *
+ * @param obj The grid object
+ * @param always_select The always select mode (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_always_select_mode_set(Evas_Object *obj, Eina_Bool always_select)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ wd->always_select = always_select;
+}
+
+/**
+ * Get the always select mode.
+ *
+ * @param obj The grid object.
+ * @return The always select mode (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Grid
+ */
+EAPI Eina_Bool
+elm_scrolled_grid_always_select_mode_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 wd->always_select;
+}
+
+/**
+ * Set no select mode.
+ *
+ * This will turn off the ability to select items entirely and they will
+ * neither appear selected nor call selected callback functions.
+ *
+ * @param obj The grid object
+ * @param no_select The no select mode (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_no_select_mode_set(Evas_Object *obj, Eina_Bool no_select)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ wd->no_select = no_select;
+}
+
+/**
+ * Gets no select mode.
+ *
+ * @param obj The grid object
+ * @return The no select mode (EINA_TRUE = on, EINA_FALSE = off)
+ *
+ * @ingroup Grid
+ */
+EAPI Eina_Bool
+elm_scrolled_grid_no_select_mode_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 wd->no_select;
+}
+
+/**
+ * Set bounce mode.
+ *
+ * This will enable or disable the scroller bounce mode for the grid. See
+ * elm_scroller_bounce_set() for details.
+ *
+ * @param obj The grid object
+ * @param h_bounce Allow bounce horizontally
+ * @param v_bounce Allow bounce vertically
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ elm_smart_scroller_bounce_allow_set(wd->scr, h_bounce, v_bounce);
+}
+
+/**
+ * Get the bounce mode
+ *
+ * @param obj The grid object
+ * @param h_bounce Allow bounce horizontally
+ * @param v_bounce Allow bounce vertically
+ *
+ * @ingroup Grid
+ */
+EAPI void
+elm_scrolled_grid_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ elm_smart_scroller_bounce_allow_get(wd->scr, h_bounce, v_bounce);
+}
--- /dev/null
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Softkey Softkey
+ * @ingroup Elementary
+ *
+ * This is a softkey
+ */
+
+/**
+ * internal data structure of softkey object
+ */
+#define BTN_ANIMATOR_MAX 4
+#define PANEL_ANIMATOR_MAX 1
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+ Evas_Object *lay;
+ Evas_Object *button[2];
+ Evas_Object *bg_rect;
+ Evas_Object *panel;
+ Evas_Object *glow_obj;
+
+ Evas_Coord x, y, w, h;
+ Evas_Coord glow_w, glow_h;
+ Evas_Coord win_h;
+ Evas_Coord panel_height;
+ Ecore_Animator *animator;
+ Eina_List *items;
+ unsigned int panel_btn_idx;
+ Eina_Bool button_show[2];
+ Eina_Bool show_panel :1;
+ Eina_Bool animating :1;
+ Eina_Bool is_horizontal;
+ double scale_factor;
+ int max_button;
+ Eina_Bool panel_suppported;
+};
+
+struct _Elm_Softkey_Item
+{
+ Evas_Object *obj;
+ Evas_Object *base;
+ Evas_Object *icon;
+ const char *label;
+ void
+ (*func)(void *data, Evas_Object *obj, void *event_info);
+ const void *data;
+ Eina_Bool disabled :1;
+};
+
+static void
+_item_disable(Elm_Softkey_Item *it, Eina_Bool disabled);
+static void
+_del_hook(Evas_Object *obj);
+static void
+_theme_hook(Evas_Object *obj);
+static void
+_sizing_eval(Evas_Object *obj);
+static void
+_sub_del(void *data, Evas_Object *obj, void *event_info);
+
+/*
+ * callback functions
+ */
+static void
+_softkey_down_cb(void *data, Evas_Object *obj, const char *emission,
+ const char *source);
+static void
+_softkey_up_cb(void *data, Evas_Object *obj, const char *emission,
+ const char *source);
+
+static void
+_panel_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void
+_panel_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static void
+_more_btn_click_cb(void *data, Evas_Object *obj, const char *emission,
+ const char *source);
+static void
+_close_btn_click_cb(void *data, Evas_Object *obj, const char *emission,
+ const char *source);
+static void
+_bg_click_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static Eina_Bool
+_show_button_animator_cb(void *data);
+static Eina_Bool
+_hide_button_animator_cb(void *data);
+static Eina_Bool
+_panel_up_animator_cb(void *data);
+static Eina_Bool
+_panel_down_animator_cb(void *data);
+
+/*
+ * internal function
+ */
+static int
+_show_button(Evas_Object *obj, Elm_Softkey_Type type, Eina_Bool show);
+static int
+_delete_button(Evas_Object *obj);
+
+static void
+_softkey_object_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void
+_softkey_object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void
+_softkey_object_show(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void
+_softkey_object_hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void
+_softkey_horizontal_set(Evas_Object *obj, Eina_Bool horizontal_mode);
+static void
+_icon_disable(Evas_Object *icon, Eina_Bool disabled)
+{
+ Evas_Object *edj;
+
+ if (!icon) return;
+ edj = elm_layout_edje_get(icon);
+
+ if (disabled)
+ {
+ if (!edj)
+ edje_object_signal_emit(icon, "elm,state,disabled", "elm");
+ else
+ edje_object_signal_emit(edj, "elm,state,disabled", "elm");
+ }
+ else
+ {
+ if (!edj)
+ edje_object_signal_emit(icon, "elm,state,enabled", "elm");
+ else
+ edje_object_signal_emit(edj, "elm,state,enabled", "elm");
+ }
+}
+
+static void
+_item_disable(Elm_Softkey_Item *it, Eina_Bool disabled)
+{
+ Widget_Data *wd = elm_widget_data_get(it->obj);
+ if (!wd) return;
+ if (it->disabled == disabled) return;
+ it->disabled = disabled;
+ if (it->disabled)
+ edje_object_signal_emit(it->base, "elm,state,disabled", "elm");
+ else
+ edje_object_signal_emit(it->base, "elm,state,enabled", "elm");
+
+ _icon_disable(it->icon, disabled);
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ int i;
+ Evas_Object *btn;
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ if (!wd) return;
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_RESIZE,
+ _softkey_object_resize);
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_MOVE, _softkey_object_move);
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _softkey_object_show);
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_HIDE, _softkey_object_hide);
+
+ /* delete button */
+ for (i = 0; i < 2; i++)
+ {
+ btn = wd->button[i];
+ if (btn != NULL)
+ {
+ //_delete_button(btn);
+ evas_object_del(wd->button[i]);
+ wd->button[i] = NULL;
+ }
+ }
+
+ //evas_object_smart_callback_del(obj, "sub-object-del", _sub_del);
+
+
+ /* delete panel */
+ if (wd->panel)
+ {
+ elm_softkey_panel_del(obj);
+ }
+
+ /* delete glow effect image */
+ if (wd->glow_obj)
+ {
+ evas_object_del(wd->glow_obj);
+ wd->glow_obj = NULL;
+ }
+ if (wd->lay)
+ {
+ evas_object_del(wd->lay);
+ wd->lay = NULL;
+ }
+
+ free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+ Elm_Softkey_Item* item;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Elm_Softkey_Item *it;
+ const Eina_List *l;
+
+ if (!wd) return;
+
+ _elm_theme_object_set(obj, wd->lay, "softkey", "bg",
+ elm_widget_style_get(obj));
+ _elm_theme_object_set(obj, wd->glow_obj, "softkey", "glow", "default");
+
+ if (wd->button[ELM_SK_LEFT_BTN])
+ {
+ item = evas_object_data_get(wd->button[ELM_SK_LEFT_BTN], "item_data");
+ _elm_theme_object_set(obj, wd->button[ELM_SK_LEFT_BTN], "softkey",
+ "button_left", elm_widget_style_get(obj));
+
+ elm_softkey_item_label_set(item, item->label);
+
+ }
+
+ if (wd->button[ELM_SK_RIGHT_BTN])
+ {
+
+ item = evas_object_data_get(wd->button[ELM_SK_RIGHT_BTN], "item_data");
+
+ _elm_theme_object_set(obj, wd->button[ELM_SK_RIGHT_BTN], "softkey",
+ "button_right", elm_widget_style_get(obj));
+
+ elm_softkey_item_label_set(item, item->label);
+
+ }
+
+ if (wd->panel)
+ {
+ _elm_theme_object_set(obj, wd->panel, "softkey", "panel",
+ elm_widget_style_get(obj));
+ if (wd->panel_btn_idx > 0)
+ {
+ //show more button
+ edje_object_signal_emit(wd->lay, "more_btn_show", "");
+ EINA_LIST_FOREACH (wd->items, l, it)
+ {
+ _elm_theme_object_set(obj, it->base, "softkey", "panel_button",
+ elm_widget_style_get(obj));
+ if (it->label)
+ {
+ edje_object_part_text_set(it->base, "elm.text", it->label); // set text
+ }
+ }
+ }
+ }
+
+ _sizing_eval(obj);
+}
+
+static void
+_sub_del(void *data, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Object *sub = event_info;
+ const Eina_List *l;
+ Elm_Softkey_Item *it;
+ if (!wd) return;
+
+ EINA_LIST_FOREACH(wd->items, l, it)
+ {
+ if (sub == it->icon)
+ {
+ it->icon = NULL;
+ }
+ break;
+ }
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+
+ if (!wd) return;
+
+ _softkey_object_move(obj, NULL, obj, NULL);
+ _softkey_object_resize(obj, NULL, obj, NULL);
+}
+
+static Eina_Bool
+_panel_up_animator_cb(void *data)
+{
+ int max = PANEL_ANIMATOR_MAX;
+ static int progress = 0;
+ Widget_Data *wd;
+ Evas_Coord ypos;
+
+ wd = elm_widget_data_get(data);
+ if (!wd) return 0;
+
+ progress++;
+ wd->animating = EINA_TRUE;
+
+ if (progress > max)
+ {
+ if (!wd->animator) return 0;
+ ecore_animator_del(wd->animator);
+ wd->animator = NULL;
+ wd->animating = EINA_FALSE;
+ wd->show_panel = EINA_TRUE;
+ progress = 0;
+ return 0;
+ }
+
+ /* move up panel */
+ if (wd->panel)
+ {
+ ypos = wd->win_h - (wd->panel_height * progress / max);
+ evas_object_move(wd->panel, wd->x, ypos);
+ }
+
+ return 1;
+}
+
+static Eina_Bool
+_panel_down_animator_cb(void *data)
+{
+ int max = PANEL_ANIMATOR_MAX;
+ static int progress = 0;
+ Widget_Data *wd;
+ Evas_Coord ypos;
+
+ wd = elm_widget_data_get(data);
+ if (!wd) return 0;
+
+ progress++;
+ wd->animating = EINA_TRUE;
+
+ if (progress > max)
+ {
+ if (!wd->animator) return 0;
+ ecore_animator_del(wd->animator);
+ wd->animator = NULL;
+ wd->animating = EINA_FALSE;
+ //wd->animator = ecore_animator_add(_show_button_animator_cb, data);
+ wd->show_panel = EINA_FALSE;
+ progress = 0;
+
+ evas_object_smart_callback_call(data, "panel,hide", NULL);
+
+ return 0;
+ }
+
+ /* move down panel */
+ if (wd->panel)
+ {
+ ypos = wd->win_h - wd->panel_height + (wd->panel_height * progress / max);
+ evas_object_move(wd->panel, wd->x, ypos);
+ }
+
+ return 1;
+}
+
+static Eina_Bool
+_hide_button_animator_cb(void *data)
+{
+ int max = BTN_ANIMATOR_MAX;
+ static int progress = 0;
+ Widget_Data *wd;
+ Evas_Coord btn_w, xpos;
+
+ wd = elm_widget_data_get(data);
+ if (!wd) return 0;
+
+ progress++;
+ wd->animating = EINA_TRUE;
+
+ if (progress > max)
+ {
+ if (!wd->animator) return 0;
+ ecore_animator_del(wd->animator);
+ wd->animating = EINA_FALSE;
+ wd->animator = ecore_animator_add(_panel_up_animator_cb, data);
+ progress = 0;
+ return 0;
+ }
+
+ /* move left button */
+ if (wd->button[ELM_SK_LEFT_BTN])
+ {
+ edje_object_part_geometry_get(wd->button[ELM_SK_LEFT_BTN], "button_rect",
+ NULL, NULL, &btn_w, NULL);
+ //evas_object_geometry_get(wd->button[ELM_SK_LEFT_BTN], NULL, NULL, &btn_w, NULL);
+ xpos = wd->x + -1 * btn_w * progress / max;
+ evas_object_move(wd->button[ELM_SK_LEFT_BTN], xpos, wd->y);
+ }
+
+ /* move right button */
+ if (wd->button[ELM_SK_RIGHT_BTN])
+ {
+ edje_object_part_geometry_get(wd->button[ELM_SK_RIGHT_BTN],
+ "button_rect", NULL, NULL, &btn_w, NULL);
+ //evas_object_geometry_get(wd->button[ELM_SK_RIGHT_BTN], NULL, NULL, &btn_w, NULL);
+ xpos = (wd->x + wd->w - btn_w) + (btn_w * progress / max);
+ evas_object_move(wd->button[ELM_SK_RIGHT_BTN], xpos, wd->y);
+ }
+
+ return 1;
+}
+
+static Eina_Bool
+_show_button_animator_cb(void *data)
+{
+ int max = BTN_ANIMATOR_MAX;
+ static int progress = 0;
+ Widget_Data *wd;
+ Evas_Coord btn_w, xpos;
+
+ wd = elm_widget_data_get(data);
+ if (!wd) return 0;
+
+ progress++;
+
+ wd->animating = EINA_TRUE;
+
+ if (progress > max)
+ {
+ if (!wd->animator) return 0;
+ ecore_animator_del(wd->animator);
+ wd->animating = EINA_FALSE;
+ progress = 0;
+ return 0;
+ }
+
+ /* move left button */
+ if (wd->button[ELM_SK_LEFT_BTN])
+ {
+ edje_object_part_geometry_get(wd->button[ELM_SK_LEFT_BTN], "button_rect",
+ NULL, NULL, &btn_w, NULL);
+ //evas_object_geometry_get(wd->button[ELM_SK_LEFT_BTN], NULL, NULL, &btn_w, NULL);
+ xpos = wd->x + (-1 * btn_w) + (btn_w * progress / max);
+ evas_object_move(wd->button[ELM_SK_LEFT_BTN], xpos, wd->y);
+ }
+
+ /* move right button */
+ if (wd->button[ELM_SK_RIGHT_BTN])
+ {
+ edje_object_part_geometry_get(wd->button[ELM_SK_RIGHT_BTN],
+ "button_rect", NULL, NULL, &btn_w, NULL);
+ //evas_object_geometry_get(wd->button[ELM_SK_RIGHT_BTN], NULL, NULL, &btn_w, NULL);
+ xpos = wd->x + wd->w - (btn_w * progress / max);
+ evas_object_move(wd->button[ELM_SK_RIGHT_BTN], xpos, wd->y);
+ }
+
+ return 1;
+}
+
+static void
+_more_btn_click_cb(void *data, Evas_Object *obj, const char *emission,
+ const char *source)
+{
+ Widget_Data *wd;
+ wd = elm_widget_data_get(data);
+ if (!wd) return;
+
+ evas_object_smart_callback_call(data, "panel,show", NULL);
+
+ if (!wd->panel) return;
+ evas_object_show(wd->panel);
+
+ if (wd->bg_rect)
+ {
+ evas_object_show(wd->bg_rect);
+ }
+
+ /*if (wd->animating == EINA_FALSE) {
+ wd->animator = ecore_animator_add(_hide_button_animator_cb, data);
+ }*/
+ if (wd->animating == EINA_FALSE)
+ {
+ wd->animator = ecore_animator_add(_panel_up_animator_cb, data);
+ }
+}
+
+static void
+_close_panel(Evas_Object *obj)
+{
+ Widget_Data *wd;
+ wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ if (wd->bg_rect)
+ {
+ evas_object_hide(wd->bg_rect);
+ }
+
+ if (!wd->panel) return;
+
+ if (wd->animating == EINA_FALSE)
+ {
+ wd->animator = ecore_animator_add(_panel_down_animator_cb, obj);
+ }
+}
+
+static void
+_bg_click_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ _close_panel(data);
+}
+
+static void
+_close_btn_click_cb(void *data, Evas_Object *obj, const char *emission,
+ const char *source)
+{
+ _close_panel(data);
+}
+
+static int
+_show_button(Evas_Object *obj, Elm_Softkey_Type type, Eina_Bool show)
+{
+ if (!obj) return -1;
+
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Object *btn = wd->button[type];
+ if (!btn) return -1;
+
+ /* Make visible button */
+ if (show)
+ {
+ wd->button_show[type] = EINA_TRUE;
+ evas_object_show(btn);
+ }
+ else
+ {
+ wd->button_show[type] = EINA_FALSE;
+ evas_object_hide(btn);
+ }
+
+ return 0;
+}
+
+static int
+_arrange_button(Evas_Object *obj, Elm_Softkey_Type type)
+{
+ Widget_Data *wd;
+ Evas_Coord btn_w = 0;
+ Evas_Object *btn;
+
+ if (!obj) return -1;
+ wd = elm_widget_data_get(obj);
+ if (!wd) return -1;
+
+ btn = wd->button[type];
+ if (!btn) return -1;
+
+ switch (type)
+ {
+ case ELM_SK_LEFT_BTN:
+ evas_object_move(btn, wd->x, wd->y);
+ break;
+ case ELM_SK_RIGHT_BTN:
+ edje_object_part_geometry_get(btn, "button_rect", NULL, NULL, &btn_w,
+ NULL);
+ //evas_object_geometry_get(btn, NULL, NULL, &btn_w, NULL);
+ evas_object_move(btn, wd->x + wd->w - btn_w, wd->y);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static void
+_softkey_up_cb(void *data, Evas_Object *obj, const char *emission,
+ const char *source)
+{
+ Evas_Object *edj = NULL;
+
+ Elm_Softkey_Item *it = (Elm_Softkey_Item *) data;
+ elm_softkey_panel_close(it->obj);
+ if (it->icon)
+ {
+ if(!strcmp(evas_object_type_get(it->icon), "edje"))
+ {
+ edj = it->icon;
+ }
+ else if(!strcmp(evas_object_type_get(it->icon), "elm_widget") && !strcmp(elm_widget_type_get(it->icon), "layout"))
+ {
+ edj = elm_layout_edje_get(it->icon);
+ }
+ if (edj)
+ edje_object_signal_emit(edj, "elm,state,unselected", "elm");
+ }
+
+ if (it->func)
+ it->func((void *) (it->data), it->obj, it);
+ else
+ evas_object_smart_callback_call(it->obj, "clicked", it);
+}
+
+static void
+_softkey_down_cb(void *data, Evas_Object *obj, const char *emission,
+ const char *source)
+{
+ Evas_Object *edj = NULL;
+
+ Elm_Softkey_Item *it = (Elm_Softkey_Item *) data;
+ evas_object_smart_callback_call(it->obj, "press", it);
+
+ if (!it->icon) return;
+
+ if(!strcmp(evas_object_type_get(it->icon), "edje"))
+ {
+ edj = it->icon;
+ }
+ else if(!strcmp(evas_object_type_get(it->icon), "elm_widget") && !strcmp(elm_widget_type_get(it->icon), "layout"))
+ {
+ edj = elm_layout_edje_get(it->icon);
+ }
+
+ if (edj)
+ edje_object_signal_emit(edj, "elm,state,selected", "elm");
+}
+
+static void
+_panel_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Elm_Softkey_Item *it = (Elm_Softkey_Item *) data;
+
+ Widget_Data *wd;
+ wd = elm_widget_data_get(it->obj);
+ if (wd == NULL) return;
+
+ /* hide glow effect */
+ if (wd->glow_obj)
+ {
+ evas_object_hide(wd->glow_obj);
+ }
+
+ elm_softkey_panel_close(it->obj);
+
+ if (it->func)
+ it->func((void *) (it->data), it->obj, it);
+ else
+ evas_object_smart_callback_call(it->obj, "clicked", it);
+}
+
+static void
+_panel_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Coord glow_x, glow_y;
+ Widget_Data *wd;
+
+ Elm_Softkey_Item *it = (Elm_Softkey_Item *) data;
+ wd = elm_widget_data_get(it->obj);
+ if (wd == NULL) return;
+
+ /* show glow effect */
+ if (wd->glow_obj)
+ {
+ Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *) event_info;
+ glow_x = ev->canvas.x - (wd->glow_w / 2);
+ glow_y = ev->canvas.y - (wd->glow_h / 2);
+
+ evas_object_move(wd->glow_obj, glow_x, glow_y);
+ evas_object_show(wd->glow_obj);
+ }
+
+ evas_object_smart_callback_call(it->obj, "press", it);
+}
+
+static int
+_delete_button(Evas_Object *obj)
+{
+ if (!obj) return -1;
+
+ if (obj)
+ {
+ evas_object_del(obj);
+ obj = NULL;
+ }
+
+ return 0;
+}
+
+static void
+_calc_win_height(Widget_Data *wd)
+{
+ wd->win_h = wd->y + wd->h;
+
+ if (wd->bg_rect)
+ {
+ evas_object_resize(wd->bg_rect, wd->w, wd->win_h);
+ evas_object_move(wd->bg_rect, wd->x, 0);
+ }
+
+ if (wd->panel)
+ {
+ if (wd->show_panel)
+ {
+ evas_object_move(wd->panel, wd->x, (wd->win_h - wd->panel_height));
+ }
+ else
+ {
+ evas_object_move(wd->panel, wd->x, wd->win_h);
+ }
+ }
+}
+
+static void
+_softkey_object_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd;
+ int i;
+ Evas_Coord x, y;
+
+ if (!data) return;
+ wd = elm_widget_data_get((Evas_Object *) data);
+ if (!wd) return;
+
+ evas_object_geometry_get(wd->lay, &x, &y, NULL, NULL);
+
+ wd->x = x;
+ wd->y = y;
+
+ evas_object_move(wd->lay, x, y);
+
+ for (i = 0; i < 2; i++)
+ {
+ _arrange_button((Evas_Object *) data, i);
+ }
+
+ _calc_win_height(wd);
+}
+
+static void
+_softkey_object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd;
+ Evas_Object *btn;
+ int i;
+ Evas_Coord btn_w;
+ Evas_Coord w, h;
+
+ if (!data) return;
+ wd = elm_widget_data_get((Evas_Object *) data);
+ if (!wd) return;
+
+ evas_object_geometry_get(wd->lay, NULL, NULL, &w, &h);
+
+ wd->w = w;
+ wd->h = h;
+
+ if (!wd->lay) return;
+ evas_object_resize(wd->lay, w, h);
+
+ /* resize button */
+ for (i = 0; i < 2; i++)
+ {
+ btn = wd->button[i];
+ if (btn != NULL)
+ {
+ edje_object_part_geometry_get(btn, "button_rect", NULL, NULL, &btn_w,
+ NULL);
+ evas_object_resize(btn, btn_w, h);
+ _arrange_button((Evas_Object *) data, i);
+ }
+ }
+
+ if (wd->w >= wd->win_h)
+ {
+ _softkey_horizontal_set(data, EINA_TRUE);
+ }
+ else
+ {
+ _softkey_horizontal_set(data, EINA_FALSE);
+ }
+ _calc_win_height(wd);
+}
+
+static void
+_softkey_object_show(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = NULL;
+ Evas_Object *btn;
+ int i;
+ if (data == NULL) return;
+ wd = elm_widget_data_get((Evas_Object *) data);
+ if (wd == NULL) return;
+
+ if (wd->lay)
+ {
+ evas_object_show(wd->lay);
+ }
+
+ /* show button */
+ for (i = 0; i < 2; i++)
+ {
+ btn = wd->button[i];
+ if (btn != NULL && wd->button_show[i] == EINA_TRUE)
+ {
+ evas_object_show(btn);
+ //evas_object_clip_set(btn, evas_object_clip_get((Evas_Object *)data));
+ }
+ }
+ if (wd->panel_btn_idx > 0)
+ {
+ /* show more button */
+ edje_object_signal_emit(wd->lay, "more_btn_show", "");
+ }
+}
+
+static void
+_softkey_object_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Widget_Data *wd = NULL;
+ Evas_Object *btn;
+ int i;
+
+ if (data == NULL) return;
+ wd = elm_widget_data_get((Evas_Object *) data);
+ if (wd == NULL) return;
+
+ if (wd->lay)
+ {
+ evas_object_hide(wd->lay);
+ }
+
+ /* hide button */
+ for (i = 0; i < 2; i++)
+ {
+ btn = wd->button[i];
+ if (btn != NULL)
+ {
+ evas_object_hide(btn);
+ }
+ }
+
+ if (wd->panel_btn_idx > 0)
+ {
+ /* hide more button */
+ edje_object_signal_emit(wd->lay, "more_btn_hide", "");
+ }
+}
+
+/**
+ * Add a new softkey to the parent
+
+ * @param[in] parent the parent of the smart object
+ * @return Evas_Object* pointer of softkey(evas object) or NULL
+ * @ingroup Softkey
+ */
+EAPI Evas_Object *
+elm_softkey_add(Evas_Object *parent)
+{
+ Evas_Object *obj = NULL;
+ Widget_Data *wd = NULL;
+ Evas *e;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ if (e == NULL) return NULL;
+ obj = elm_widget_add(e);
+ elm_widget_type_set(obj, "softkey");
+ 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);
+
+ /* load background edj */
+ wd->lay = edje_object_add(e);
+ _elm_theme_object_set(obj, wd->lay, "softkey", "bg", "default");
+ if (wd->lay == NULL)
+ {
+ printf("Cannot load bg edj\n");
+ return NULL;
+ }
+ elm_widget_resize_object_set(obj, wd->lay);
+ edje_object_signal_callback_add(wd->lay, "clicked", "more_btn",
+ _more_btn_click_cb, obj);
+
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
+ _softkey_object_resize, obj);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
+ _softkey_object_move, obj);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW,
+ _softkey_object_show, obj);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE,
+ _softkey_object_hide, obj);
+ wd->is_horizontal = EINA_FALSE;
+ wd->panel_suppported = EINA_TRUE;
+ wd->scale_factor = elm_scale_get();
+ if (wd->scale_factor == 0.0)
+ {
+ wd->scale_factor = 1.0;
+ }
+
+ /* load glow effect */
+ wd->glow_obj = edje_object_add(e);
+ _elm_theme_object_set(obj, wd->glow_obj, "softkey", "glow", "default");
+ evas_object_geometry_get(wd->glow_obj, NULL, NULL, &wd->glow_w, &wd->glow_h);
+ evas_object_resize(wd->glow_obj, wd->glow_w, wd->glow_h);
+
+ // FIXME
+ //evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+ wd->button[ELM_SK_LEFT_BTN] = wd->button[ELM_SK_RIGHT_BTN] = NULL;
+ wd->panel = NULL;
+ //_sizing_eval(obj);
+ wd->show_panel = EINA_FALSE;
+ wd->bg_rect = NULL;
+
+ return obj;
+}
+
+static void
+_softkey_horizontal_set(Evas_Object *obj, Eina_Bool horizontal_mode)
+{
+ Widget_Data *wd;
+ char buff[32];
+ if (!obj) return;
+ wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ wd->is_horizontal = horizontal_mode;
+ if (wd->panel)
+ {
+ if ((edje_object_data_get(wd->panel, "max_item_count") == NULL)
+ || (edje_object_data_get(wd->panel, "panel_height") == NULL)
+ || (edje_object_data_get(wd->panel, "panel_height_horizontal")
+ == NULL))
+ {
+ wd->panel_suppported = EINA_FALSE;
+ }
+ else
+ wd->panel_suppported = EINA_TRUE;
+ if (wd->panel_suppported == EINA_TRUE)
+ {
+ if (wd->is_horizontal == EINA_TRUE)
+ {
+ snprintf(buff, sizeof(buff), "button_%d", (wd->panel_btn_idx
+ + wd->max_button));
+ edje_object_signal_emit(wd->panel, buff, "panel_rect");
+ wd->panel_height
+ = (int) (atoi(edje_object_data_get(wd->panel, buff))
+ * wd->scale_factor);
+ evas_object_resize(
+ wd->panel,
+ wd->w,
+ ((int) (atoi(
+ edje_object_data_get(wd->panel,
+ "panel_height_horizontal"))
+ * wd->scale_factor)));
+ }
+ else
+ {
+ snprintf(buff, sizeof(buff), "button_%d", (wd->panel_btn_idx));
+ edje_object_signal_emit(wd->panel, buff, "panel_rect");
+ wd->panel_height
+ = (int) (atoi(edje_object_data_get(wd->panel, buff))
+ * wd->scale_factor);
+ evas_object_resize(
+ wd->panel,
+ wd->w,
+ ((int) (atoi(
+ edje_object_data_get(wd->panel,
+ "panel_height"))
+ * wd->scale_factor)));
+ }
+ }
+ _calc_win_height(wd);
+ }
+}
+
+/**
+ * add side button of softkey
+ * @param[in] obj softkey object
+ * @param[in] type softkey button type
+ * @param[in] icon The icon object to use for the item
+ * @param[in] label The text label to use for the item
+ * @param[in] func Convenience function to call when this item is selected
+ * @param[in] data Data to pass to convenience function
+ * @return A handle to the item added
+ *
+ * @ingroup Softkey
+ */
+EAPI Elm_Softkey_Item *
+elm_softkey_button_add(Evas_Object *obj, Elm_Softkey_Type type,
+ Evas_Object *icon, const char *label, void
+ (*func)(void *data, Evas_Object *obj, void *event_info),
+ const void *data)
+{
+ Widget_Data *wd;
+ Evas* evas;
+ char button_type[64];
+ Elm_Softkey_Item *it;
+
+ if (!obj) return NULL;
+ wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+
+ if (wd->button[type])
+ {
+ printf("already created.\n");
+ return NULL;
+ }
+
+ /* get evas */
+ evas = evas_object_evas_get(obj);
+ if (!evas) return NULL;
+
+ /* set item data */
+ it = ELM_NEW(Elm_Softkey_Item);
+ it->obj = obj;
+ it->func = func;
+ it->data = data;
+ it->label = NULL;
+ it->icon = NULL;
+ /* load button edj */
+ if (wd->button[type] == NULL)
+ {
+ if (type == ELM_SK_LEFT_BTN)
+ {
+ strcpy(button_type, "button_left");
+ }
+ else
+ {
+ strcpy(button_type, "button_right");
+ }
+
+ it->base = wd->button[type] = edje_object_add(evas);
+ if (!wd->button[type])
+ {
+ free(it);
+ return NULL;
+ }
+ _elm_theme_object_set(obj, wd->button[type], "softkey", button_type,
+ elm_widget_style_get(obj));
+
+ wd->button_show[type] = EINA_TRUE;
+ if (evas_object_visible_get(obj))
+ {
+ evas_object_show(wd->button[type]);
+ }
+ evas_object_smart_member_add(wd->button[type], obj);
+
+ edje_object_signal_callback_add(wd->button[type], "elm,action,down", "",
+ _softkey_down_cb, it);
+ edje_object_signal_callback_add(wd->button[type], "elm,action,click", "",
+ _softkey_up_cb, it);
+
+ evas_object_clip_set(wd->button[type], evas_object_clip_get(obj));
+ if (wd->panel) evas_object_raise(wd->panel);
+ }
+
+ _sizing_eval(obj);
+
+ elm_softkey_item_label_set(it, label);
+ elm_softkey_item_icon_set(it, icon);
+
+ if (wd->button[type])
+ evas_object_data_set(wd->button[type], "item_data", it);
+ else
+ {
+ if (it->label) eina_stringshare_del(it->label);
+ it->label = NULL;
+ free(it);
+ return NULL;
+ }
+
+ return it;
+}
+
+/**
+ * delete side button of softkey
+ * @param[in] obj softkey object
+ * @param[in] type softkey button type
+ *
+ * @ingroup Softkey
+ */
+EAPI void
+elm_softkey_button_del(Evas_Object *obj, Elm_Softkey_Type type)
+{
+ Widget_Data *wd;
+ Elm_Softkey_Item *it;
+ Evas_Object *btn;
+
+ if (!obj)
+ {
+ printf("Invalid argument: softkey object is NULL\n");
+ return;
+ }
+
+ wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ btn = wd->button[type];
+ if (!btn) return;
+
+ it = evas_object_data_get(btn, "item_data");
+ //_delete_button(btn);
+ edje_object_signal_callback_del(wd->button[type], "elm,action,down", "",
+ _softkey_down_cb);
+ edje_object_signal_callback_del(wd->button[type], "elm,action,click", "",
+ _softkey_up_cb);
+ evas_object_del(wd->button[type]);
+ if (it->label) eina_stringshare_del(it->label);
+ if (it->icon) evas_object_del(it->icon);
+ free(it);
+ wd->button[type] = NULL;
+}
+
+/**
+ * show button of softkey
+ * @param[in] obj softkey object
+ * @param[in] type softkey button type
+ *
+ * @ingroup Softkey
+ */
+EAPI void
+elm_softkey_button_show(Evas_Object *obj, Elm_Softkey_Type type)
+{
+ _show_button(obj, type, EINA_TRUE);
+}
+
+/**
+ * hide button of softkey
+ * @param[in] obj softkey object
+ * @param[in] type softkey button type
+ *
+ * @ingroup Softkey
+ */
+EAPI void
+elm_softkey_button_hide(Evas_Object *obj, Elm_Softkey_Type type)
+{
+ _show_button(obj, type, EINA_FALSE);
+}
+
+/**
+ * add item in panel
+ * @param[in] obj softkey object
+ * @param[in] icon The icon object
+ * @param[in] label The text label to use for the item
+ * @param[in] func Convenience function to call when this item is selected
+ * @param[in] data Data to pass to convenience function
+ * @return A handle to the item added
+ *
+ * @ingroup Softkey
+ */
+EAPI Elm_Softkey_Item *
+elm_softkey_panel_item_add(Evas_Object *obj, Evas_Object *icon,
+ const char *label, void
+ (*func)(void *data, Evas_Object *obj,
+ void *event_info), const void *data)
+{
+ Widget_Data *wd;
+ Evas *evas;
+ char button_name[32];
+ Evas_Object *btn;
+ Elm_Softkey_Item *it;
+ char buff[PATH_MAX];
+
+ wd = elm_widget_data_get(obj);
+ if (!wd)
+ {
+ printf("Cannot get smart data\n");
+ return NULL;
+ }
+
+ /* get evas */
+ evas = evas_object_evas_get(obj);
+ if (!evas) return NULL;
+
+ if (wd->panel == NULL)
+ {
+ /* create panel */
+ wd->bg_rect = evas_object_rectangle_add(evas);
+ if (!wd->bg_rect) return NULL;
+ evas_object_color_set(wd->bg_rect, 10, 10, 10, 150);
+ evas_object_pass_events_set(wd->bg_rect, 0);
+
+ if (wd->bg_rect)
+ {
+ evas_object_resize(wd->bg_rect, wd->w, wd->win_h);
+ evas_object_event_callback_add(wd->bg_rect, EVAS_CALLBACK_MOUSE_UP,
+ _bg_click_cb, obj);
+ evas_object_smart_member_add(wd->bg_rect, obj);
+ }
+
+ wd->panel = edje_object_add(evas);
+ if (!wd->panel) return NULL;
+ _elm_theme_object_set(obj, wd->panel, "softkey", "panel",
+ elm_widget_style_get(obj));
+
+ evas_object_move(wd->panel, 0, wd->win_h);
+ edje_object_signal_callback_add(wd->panel, "clicked", "close_btn",
+ _close_btn_click_cb, obj);
+ evas_object_smart_member_add(wd->panel, obj);
+ if (evas_object_visible_get(obj))
+ {
+ evas_object_show(wd->panel);
+ }
+ wd->panel_height = 0;
+ if ((edje_object_data_get(wd->panel, "max_item_count") == NULL)
+ || (edje_object_data_get(wd->panel, "panel_height") == NULL)
+ || (edje_object_data_get(wd->panel, "panel_height_horizontal")
+ == NULL))
+ {
+ //If this key is not found in data section, then it means the panel won't come.
+ wd->max_button = 0;
+ // delete panel
+ if (wd->panel)
+ {
+ elm_softkey_panel_del(obj);
+ }
+ wd->panel_suppported = EINA_FALSE;
+ return NULL;
+ }
+ else
+ {
+ wd->max_button = (int) (atoi(edje_object_data_get(wd->panel,
+ "max_item_count")));
+ if (wd->is_horizontal)
+ {
+ evas_object_resize(
+ wd->panel,
+ wd->w,
+ ((int) (atoi(
+ edje_object_data_get(wd->panel,
+ "panel_height_horizontal"))
+ * wd->scale_factor)));
+ }
+ else
+ {
+ evas_object_resize(
+ wd->panel,
+ wd->w,
+ ((int) (atoi(
+ edje_object_data_get(wd->panel,
+ "panel_height"))
+ * wd->scale_factor)));
+ }
+ }
+
+ evas_object_clip_set(wd->panel, evas_object_clip_get(obj));
+ }
+
+ wd->panel_btn_idx++;
+ if (wd->panel_btn_idx >= wd->max_button) return NULL;
+
+ /* set item data */
+ it = ELM_NEW(Elm_Softkey_Item);
+ it->obj = obj;
+ if (label) it->label = eina_stringshare_add(label);
+ it->icon = icon;
+ it->func = func;
+ it->data = data;
+ /* load panel button */
+ it->base = btn = edje_object_add(evas);
+ if (!btn)
+ {
+ if (it->label) eina_stringshare_del(it->label);
+ free(it);
+ wd->panel_btn_idx--;
+ return NULL;
+ }
+ _elm_theme_object_set(obj, btn, "softkey", "panel_button",
+ elm_widget_style_get(obj));
+
+ edje_object_part_text_set(btn, "elm.text", label); /* set text */
+ //edje_object_message_signal_process(btn);
+
+ if (wd->panel)
+ {
+ /* swallow button */
+ snprintf(button_name, sizeof(button_name), "panel_button_area_%d",
+ wd->panel_btn_idx);
+ edje_object_part_swallow(wd->panel, button_name, btn);
+
+ if (wd->is_horizontal)
+ {
+ snprintf(buff, sizeof(buff), "button_%d", wd->max_button
+ + wd->panel_btn_idx);
+ edje_object_signal_emit(wd->panel, buff, "panel_rect");
+ const char* val = edje_object_data_get(wd->panel, buff);
+ if (val)
+ wd->panel_height = (int) (atoi(val) * wd->scale_factor);
+ else
+ {
+ if (it->label) eina_stringshare_del(it->label);
+ evas_object_del(it->base);
+ free(it);
+ wd->panel_btn_idx--;
+ return NULL;
+ }
+ }
+ else
+ {
+ snprintf(buff, sizeof(buff), "button_%d", wd->panel_btn_idx);
+ edje_object_signal_emit(wd->panel, buff, "panel_rect");
+ const char* val = edje_object_data_get(wd->panel, buff);
+ if (val)
+ wd->panel_height = (int) (atoi(val) * wd->scale_factor);
+ else
+ {
+ if (it->label) eina_stringshare_del(it->label);
+ evas_object_del(it->base);
+ free(it);
+ wd->panel_btn_idx--;
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ wd->panel_btn_idx--;
+ return NULL;
+ }
+ evas_object_event_callback_add(btn, EVAS_CALLBACK_MOUSE_DOWN,
+ _panel_down_cb, it);
+ evas_object_event_callback_add(btn, EVAS_CALLBACK_MOUSE_UP, _panel_up_cb, it);
+ wd->items = eina_list_append(wd->items, it);
+ if (evas_object_visible_get(obj))
+ {
+ /* show more button */
+ edje_object_signal_emit(wd->lay, "more_btn_show", "");
+ }
+ return it;
+}
+
+/**
+ * delete panel
+
+ * @param[in] obj softkey object
+ * @return int 0 (SUCCESS) or -1 (FAIL)
+ *
+ * @ingroup Softkey
+ */
+EAPI int
+elm_softkey_panel_del(Evas_Object *obj)
+{
+ Widget_Data *wd;
+ char button_name[32];
+ Evas_Object *btn;
+ int i;
+ Elm_Softkey_Item *it;
+
+ wd = elm_widget_data_get(obj);
+ if (!wd) return -1;
+ if (wd->panel == NULL) return -1;
+ if (wd->animator)
+ {
+ ecore_animator_del(wd->animator);
+ wd->animator = NULL;
+ wd->animating = EINA_FALSE;
+ }
+ /* delete background */
+ if (wd->bg_rect)
+ {
+ //evas_object_event_callback_del(wd->bg_rect, EVAS_CALLBACK_MOUSE_UP, _bg_click_cb);
+ evas_object_del(wd->bg_rect);
+ wd->bg_rect = NULL;
+ }
+
+ for (i = 1; i <= wd->panel_btn_idx; i++)
+ {
+ snprintf(button_name, sizeof(button_name), "panel_button_area_%d", i);
+ btn = edje_object_part_swallow_get(wd->panel, button_name);
+ //_delete_button(btn);
+ if (btn)
+ {
+ //edje_object_part_unswallow(wd->panel, btn);
+ //evas_object_event_callback_del(btn, EVAS_CALLBACK_MOUSE_DOWN, _panel_down_cb);
+ //evas_object_event_callback_del(btn, EVAS_CALLBACK_MOUSE_UP, _panel_up_cb);
+ evas_object_del(btn);
+ }
+ }
+
+ EINA_LIST_FREE(wd->items, it)
+ {
+ if (it->label) eina_stringshare_del(it->label);
+ it->base = NULL;
+ if (it->icon) it->icon = NULL;
+ free(it);
+ }
+
+ wd->panel_btn_idx = 0;
+ wd->panel_height = 0;
+
+ //hide more button
+ edje_object_signal_emit(wd->lay, "more_btn_hide", "");
+
+ if (wd->panel)
+ {
+ //evas_object_move(wd->panel, 0, wd->win_h);
+ evas_object_clip_unset(wd->panel);
+ evas_object_del(wd->panel);
+ wd->show_panel = EINA_FALSE;
+ wd->panel = NULL;
+ }
+
+ return 0;
+}
+
+/**
+ * sliding up panel if it is closed
+
+ * @param[in] obj softkey object
+ * @return int 0 (SUCCESS) or -1 (FAIL)
+ *
+ * @ingroup Softkey
+ */
+EAPI int
+elm_softkey_panel_open(Evas_Object *obj)
+{
+ Widget_Data *wd;
+ wd = elm_widget_data_get(obj);
+
+ if (!wd) return -1;
+ if (!wd->panel) return -1;
+
+ if (wd->show_panel == EINA_FALSE)
+ {
+ _more_btn_click_cb(obj, NULL, NULL, NULL);
+ }
+
+ return 0;
+}
+
+/**
+ * sliding down panel if it is opened
+
+ * @param[in] obj softkey object
+ * @return int 0 (SUCCESS) or -1 (FAIL)
+ *
+ * @ingroup Softkey
+ */
+EAPI int
+elm_softkey_panel_close(Evas_Object *obj)
+{
+ Widget_Data *wd;
+ wd = elm_widget_data_get(obj);
+ if (!wd) return -1;
+
+ if (wd->panel == NULL) return -1;
+
+ if (wd->show_panel == EINA_TRUE)
+ {
+ _close_btn_click_cb(obj, obj, NULL, NULL);
+ }
+
+ return 0;
+}
+
+/**
+ * Set the icon of an softkey item
+ *
+ * @param[in] it The item to set the icon
+ * @param[in] icon The icon object
+ *
+ * @ingroup Softkey
+ */
+EAPI void
+elm_softkey_item_icon_set(Elm_Softkey_Item *it, Evas_Object *icon)
+{
+ if (!it) return;
+
+ if ((it->icon != icon) && (it->icon))
+ {
+ //elm_widget_sub_object_del(it->obj, it->icon);
+ evas_object_del(it->icon);
+ it->icon = NULL;
+ }
+
+ if ((icon) && (it->icon != icon))
+ {
+ it->icon = icon;
+ //elm_widget_sub_object_add(it->obj, icon);
+ edje_object_part_swallow(it->base, "elm.swallow.icon", icon);
+ edje_object_signal_emit(it->base, "elm,state,icon,visible", "elm");
+ //edje_object_message_signal_process(it->base);
+ _sizing_eval(it->obj);
+ }
+ else
+ it->icon = icon;
+}
+
+/**
+ * Get the icon of an softkey item
+ *
+ * @param[in] it The item to get the icon
+ * @return The icon object
+ *
+ * @ingroup Softkey
+ */
+EAPI Evas_Object *
+elm_softkey_item_icon_get(Elm_Softkey_Item *it)
+{
+ if (!it) return NULL;
+ return it->icon;
+}
+
+/**
+ * Get the text label of an softkey item
+ *
+ * @param[in] it The item to set the label
+ * @param[in] label label
+ *
+ * @ingroup Softkey
+ */
+EAPI void
+elm_softkey_item_label_set(Elm_Softkey_Item *it, const char *label)
+{
+ if (!it) return;
+ if (it->label) eina_stringshare_del(it->label);
+
+ if (label)
+ {
+ it->label = eina_stringshare_add(label);
+ edje_object_signal_emit(it->base, "elm,state,text,visible", "elm");
+
+ /* set text */
+ edje_object_part_text_set(it->base, "elm.text", label == NULL ? ""
+ : label);
+ }
+ else
+ {
+ it->label = NULL;
+ edje_object_signal_emit(it->base, "elm,state,text,hidden", "elm");
+ }
+ //edje_object_message_signal_process(it->base);
+}
+
+/**
+ * Set the item callback function
+ *
+ * @param[in] it Item to set callback function.
+ * @param[in] func callback function pointer.
+ * @param[in] data callback function argument data.
+ *
+ * @ingroup Softkey
+ */
+EAPI void
+elm_softkey_item_callback_set(Elm_Softkey_Item* item, void
+(*func)(void *data, Evas_Object *obj, void *event_info), const void *data)
+{
+ if (!item) return;
+
+ item->func = func;
+ item->data = data;
+}
+
+/**
+ * Get the text label of an softkey item
+ *
+ * @param[in] it The item to get the label
+ * @return The text label of the softkey item
+ *
+ * @ingroup Softkey
+ */
+EAPI const char *
+elm_softkey_item_label_get(Elm_Softkey_Item *it)
+{
+ if (!it) return NULL;
+ return it->label;
+}
+
+EAPI Eina_Bool
+elm_softkey_item_disabled_get(Elm_Softkey_Item *it)
+{
+ if (!it) return EINA_FALSE;
+ return it->disabled;
+}
+
+EAPI void
+elm_softkey_item_disabled_set(Elm_Softkey_Item *it, Eina_Bool disabled)
+{
+ if (!it) return;
+ _item_disable(it, disabled);
+}
--- /dev/null
+/*\r
+ * SLP\r
+ * Copyright (c) 2009 Samsung Electronics, Inc.\r
+ * All rights reserved.\r
+ *\r
+ * This software is a confidential and proprietary information\r
+ * of Samsung Electronics, Inc. ("Confidential Information"). You\r
+ * shall not disclose such Confidential Information and shall use\r
+ * it only in accordance with the terms of the license agreement\r
+ * you entered into with Samsung Electronics.\r
+ */\r
+\r
+\r
+/**\r
+ * @addtogroup Tab Tab\r
+ * @ingroup Elementary\r
+ *\r
+ * This is a Tab. It can contain label and icon objects.\r
+ * You can change the location of items.\r
+ */\r
+\r
+\r
+#include <string.h>\r
+#include <math.h>\r
+\r
+#include <Elementary.h>\r
+#include "elm_priv.h"\r
+\r
+#ifndef EAPI\r
+#define EAPI __attribute__ ((visibility("default")))\r
+#endif\r
+\r
+#define MAX_ITEM 8\r
+#define BASIC_SLOT_NUMBER 3\r
+#define KEYDOWN_INTERVAL 0.6\r
+\r
+#define PORTRAIT 0\r
+#define LANDSCAPE 1\r
+#define LANDSCAPE_GAP 10\r
+\r
+#define MAX_ARGS 512\r
+\r
+#define _EDJ(x) (Evas_Object *)elm_layout_edje_get(x)\r
+#define ELM_MAX(v1, v2) (((v1) > (v2)) ? (v1) : (v2))\r
+\r
+\r
+// internal data structure of tab object\r
+typedef struct _Widget_Data Widget_Data;\r
+\r
+struct _Widget_Data\r
+{\r
+ Evas *evas;\r
+ Evas_Object *object;\r
+ Evas_Object *parent;\r
+ Evas_Object *edje;\r
+ Evas_Object *moving_obj;\r
+ Evas_Object *box[MAX_ITEM];\r
+ Evas_Object *ebx;\r
+\r
+ Evas_Coord x, y, w, h;\r
+\r
+ int cur_first_slot;\r
+ int mode;\r
+ int view_slot_num;\r
+ int tab_down_x;\r
+ int tab_down_y;\r
+ int num;\r
+ int edit_from;\r
+ int edit_to;\r
+ double time;\r
+\r
+ Eina_List *items;\r
+\r
+ Ecore_Timer *timer;\r
+ Eina_Bool flag;\r
+ Eina_Bool edit_disable;\r
+\r
+ Ecore_Event_Handler *move_event;\r
+ Ecore_Event_Handler *up_event;\r
+};\r
+\r
+struct _Elm_Tab_Item\r
+ {\r
+ Evas_Object *obj;\r
+ Evas_Object *base;\r
+ Evas_Object *icon;\r
+ const char *label;\r
+ int slot;\r
+ int badge;\r
+ void (*func)(void *data, Evas_Object *obj, void *event_info);\r
+ const void *data;\r
+ Eina_Bool selected : 1;\r
+ };\r
+\r
+static void _del_hook(Evas_Object *obj);\r
+static void _theme_hook(Evas_Object *obj);\r
+static void _sizing_eval(Evas_Object *obj);\r
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);\r
+\r
+static void _tab_object_move(void *data, Evas *e, Evas_Object *obj, void *event_info);\r
+static void _tab_object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);\r
+static void _tab_object_show(void *data, Evas *e, Evas_Object *obj, void *event_info);\r
+static void _tab_object_hide(void *data, Evas *e, Evas_Object *obj, void *event_info);\r
+\r
+static void light_check(Widget_Data *wd);\r
+static void select_check(Widget_Data *wd);\r
+static void edit_up_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);\r
+static int _selected_box(Elm_Tab_Item *it);\r
+static int _move_obj_to_left(Widget_Data *wd);\r
+static int _move_obj_to_right(Widget_Data *wd);\r
+static void item_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);\r
+static void press_move_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);\r
+static void press_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);\r
+static void press_up_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);\r
+void tab_item_cb(void *data, Evas_Object *obj, const char *emission, const char *source);\r
+\r
+static void\r
+_del_hook(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ Elm_Tab_Item *item;\r
+\r
+ if (!wd) return;\r
+\r
+ if (wd->edje) {\r
+ evas_object_smart_member_del(wd->edje);\r
+ evas_object_del(wd->edje);\r
+ wd->edje = NULL;\r
+ }\r
+\r
+ EINA_LIST_FREE(wd->items, item){\r
+ eina_stringshare_del(item->label);\r
+ if (item->icon) evas_object_del(item->icon);\r
+ if(item->base) evas_object_del(item->base);\r
+ free(item);\r
+ }\r
+\r
+ if (wd->ebx) {\r
+ evas_object_smart_member_del(wd->ebx);\r
+ evas_object_del(wd->ebx);\r
+ wd->ebx = NULL;\r
+ }\r
+\r
+ free(wd);\r
+}\r
+\r
+static void\r
+_theme_hook(Evas_Object *obj)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+ char buf[MAX_ARGS];\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if (!wd) return;\r
+\r
+ if(wd->mode == PORTRAIT){\r
+ snprintf(buf, sizeof(buf), "bg_portrait_%d", wd->view_slot_num);\r
+ }else if(wd->mode == LANDSCAPE){\r
+ snprintf(buf, sizeof(buf), "bg_landscape_%d", wd->view_slot_num);\r
+ }\r
+ _elm_theme_object_set(obj, wd->edje, "tab", buf, elm_widget_style_get(obj));\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ _elm_theme_object_set(obj, item->base, "tab", "item", elm_widget_style_get(item->obj));\r
+ if (item->label){\r
+ edje_object_part_text_set(item->base, "elm.text", item->label);\r
+ }\r
+\r
+ if (item->icon){\r
+ // int ms = 0;\r
+\r
+ // ms = ((double)wd->icon_size * _elm_config->scale);\r
+ evas_object_size_hint_min_set(item->icon, 24, 24);\r
+ evas_object_size_hint_max_set(item->icon, 40, 40);\r
+ edje_object_part_swallow(item->base, "elm.swallow.icon", item->icon);\r
+ evas_object_show(item->icon);\r
+ elm_widget_sub_object_add(obj, item->icon);\r
+ }\r
+\r
+ if (item->label && item->icon){\r
+ edje_object_signal_emit(item->base, "elm,state,icon_text", "elm");\r
+ }\r
+ }\r
+ select_check(wd);\r
+}\r
+\r
+static void\r
+_sub_del(void *data, Evas_Object *obj, void *event_info)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ //Evas_Object *sub = event_info;\r
+ if (!wd) return;\r
+ /*\r
+ if (sub == wd->icon)\r
+ {\r
+ edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");\r
+ evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,\r
+ _changed_size_hints, obj);\r
+ wd->icon = NULL;\r
+ edje_object_message_signal_process(wd->btn);\r
+ _sizing_eval(obj);\r
+ }\r
+ */\r
+}\r
+\r
+static void\r
+_sizing_eval(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+\r
+ if (!wd) return;\r
+\r
+ DBG("[%s]\n", __func__);\r
+\r
+ _tab_object_move(obj, NULL, obj, NULL);\r
+ _tab_object_resize(obj, NULL, obj, NULL);\r
+}\r
+\r
+/**\r
+ * Add a new tab object\r
+ *\r
+ * @param parent The parent object\r
+ * @return The new object or NULL if it cannot be created\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Evas_Object *elm_tab_add(Evas_Object *parent) {\r
+ Evas_Object *obj = NULL;\r
+ Widget_Data *wd = NULL;\r
+ Evas_Coord x, y, w, h;\r
+ char buf[MAX_ARGS];\r
+\r
+ wd = ELM_NEW(Widget_Data);\r
+ wd->evas = evas_object_evas_get(parent);\r
+ if (wd->evas == NULL) return NULL;\r
+ obj = elm_widget_add(wd->evas);\r
+ if(obj == NULL) return NULL;\r
+ elm_widget_type_set(obj, "tab");\r
+ elm_widget_sub_object_add(parent, obj);\r
+ elm_widget_data_set(obj, wd);\r
+ elm_widget_del_hook_set(obj, _del_hook);\r
+ elm_widget_theme_hook_set(obj, _theme_hook);\r
+\r
+ // initialization\r
+ wd->parent = parent;\r
+ evas_object_geometry_get(parent, &x, &y, &w, &h);\r
+ wd->object = obj;\r
+ wd->x = x;\r
+ wd->y = y;\r
+ wd->w = w;\r
+ wd->h = h;\r
+ wd->num = 0;\r
+ wd->edit_disable = EINA_FALSE;\r
+ wd->cur_first_slot = 1;\r
+ //wd->view_slot_num = BASIC_SLOT_NUMBER;\r
+ wd->view_slot_num = 3;\r
+\r
+ // initialization\r
+ // edit box\r
+ wd->ebx = edje_object_add(wd->evas);\r
+ if(wd->ebx == NULL)\r
+ return NULL;\r
+ _elm_theme_object_set(obj, wd->ebx, "tab", "dim", "default");\r
+ evas_object_resize(wd->ebx, wd->w, wd->h);\r
+ evas_object_move(wd->ebx, wd->x, wd->y);\r
+ evas_object_hide(wd->ebx);\r
+ evas_object_event_callback_add(wd->ebx, EVAS_CALLBACK_MOUSE_UP, edit_up_cb, wd);\r
+\r
+ // initialization\r
+ /* load background edj */\r
+ wd->edje = edje_object_add(wd->evas);\r
+ snprintf(buf, sizeof(buf), "bg_portrait_%d", wd->view_slot_num);\r
+ _elm_theme_object_set(obj, wd->edje, "tab", buf, "default");\r
+ if(wd->edje == NULL) {\r
+ printf("Cannot load bg edj\n");\r
+ return NULL;\r
+ }\r
+ // initialization\r
+ evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_DOWN, press_down_cb, wd);\r
+ evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_UP, press_up_cb, wd);\r
+ evas_object_show(wd->edje);\r
+\r
+ // initialization\r
+ evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_RESIZE, _tab_object_resize, obj);\r
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _tab_object_move, obj);\r
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _tab_object_show, obj);\r
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _tab_object_hide, obj);\r
+\r
+ // initialization\r
+ //FIXME\r
+ // evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);\r
+\r
+ evas_object_smart_member_add(wd->ebx, obj);\r
+ elm_widget_resize_object_set(obj, wd->edje);\r
+\r
+ // initialization\r
+ _sizing_eval(obj);\r
+\r
+ return obj;\r
+}\r
+\r
+\r
+/**\r
+ * Set the mode of tab object\r
+ *\r
+ * @param obj The tab object\r
+ * @param mode The mode of tab\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tab_set(Evas_Object *obj, int mode)\r
+{\r
+ int i = 1;\r
+ char buf[MAX_ARGS];\r
+ Widget_Data *wd;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ if(obj == NULL) {\r
+ printf("Invalid argument: tab object is NULL\n");\r
+ return;\r
+ }\r
+ wd = elm_widget_data_get(obj);\r
+ if(wd == NULL) {\r
+ printf("Cannot get smart data\n");\r
+ return;\r
+ }\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ edje_object_part_unswallow(wd->edje, item->base);\r
+ }\r
+\r
+ evas_object_del(wd->edje);\r
+\r
+ evas_object_smart_member_del(wd->ebx);\r
+// elm_widget_resize_object_set(obj, wd->edje);\r
+\r
+ // load edj\r
+ if(mode >= ELM_TAB_PORTRAIT_2 && mode <= ELM_TAB_PORTRAIT_4){\r
+ snprintf(buf, sizeof(buf), "bg_portrait_%d", mode);\r
+ }else if(mode >= ELM_TAB_LANDSCAPE_2 && mode <= ELM_TAB_LANDSCAPE_5){\r
+ snprintf(buf, sizeof(buf), "bg_landscape_%d", mode - LANDSCAPE_GAP);\r
+ }\r
+ wd->edje = edje_object_add(wd->evas);\r
+ if(wd->edje == NULL) {\r
+ printf("Cannot load bg edj\n");\r
+ return;\r
+ }\r
+\r
+ _elm_theme_object_set(obj, wd->edje, "tab", buf, elm_widget_style_get(obj));\r
+\r
+ evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_DOWN, press_down_cb, wd);\r
+ evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_UP, press_up_cb, wd);\r
+ evas_object_show(wd->edje);\r
+\r
+ evas_object_smart_member_add(wd->ebx, obj);\r
+ elm_widget_resize_object_set(obj, wd->edje);\r
+\r
+ evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_RESIZE, _tab_object_resize, obj);\r
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _tab_object_move, obj);\r
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _tab_object_show, obj);\r
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _tab_object_hide, obj);\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ snprintf(buf, sizeof(buf), "slot_%d", item->slot);\r
+ edje_object_part_swallow(wd->edje, buf, item->base);\r
+ i++;\r
+ }\r
+\r
+ // set current mode\r
+ if(mode < 10) wd->mode = PORTRAIT;\r
+ else wd->mode = LANDSCAPE;\r
+\r
+ wd->view_slot_num = mode % LANDSCAPE_GAP;\r
+\r
+ light_check(wd);\r
+\r
+ evas_object_resize(wd->edje, wd->w, wd->h);\r
+}\r
+\r
+/**\r
+ * Add new item\r
+ *\r
+ * @param obj The tab object\r
+ * @param icon The icon of item\r
+ * @param label The label of item\r
+ * @param func Callback function of item\r
+ * @param data The data of callback function\r
+ * @return The item of tab\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Elm_Tab_Item *elm_tab_item_add(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data)\r
+{\r
+ char buf[MAX_ARGS];\r
+ Elm_Tab_Item *it;\r
+ Widget_Data *wd;\r
+\r
+ if(obj == NULL) {\r
+ printf("Invalid argument: tab object is NULL\n");\r
+ return NULL;\r
+ }\r
+ wd = elm_widget_data_get(obj);\r
+ if(wd == NULL) {\r
+ printf("Cannot get smart data\n");\r
+ return NULL;\r
+ }\r
+\r
+ it = ELM_NEW(Elm_Tab_Item);\r
+ if(it == NULL) {\r
+ printf("Cannot add item");\r
+ return NULL;\r
+ }\r
+ wd->items = eina_list_append(wd->items, it);\r
+ it->obj = obj;\r
+ it->label = eina_stringshare_add(label);\r
+ it->icon = icon;\r
+ it->badge = 0;\r
+ it->func = func;\r
+ it->data = data;\r
+ it->base = edje_object_add(evas_object_evas_get(obj));\r
+ if(it->base == NULL) {\r
+ printf("Cannot load bg edj\n");\r
+ return NULL;\r
+ }\r
+ _elm_theme_object_set(obj, it->base, "tab", "item", elm_widget_style_get(obj));\r
+ elm_widget_sub_object_add(obj, it->base);\r
+\r
+ edje_object_signal_callback_add(it->base, "elm,action,click", "elm", tab_item_cb, (void *)it);\r
+\r
+ if (it->label){\r
+ edje_object_part_text_set(it->base, "elm.text", it->label);\r
+ }\r
+\r
+ if (it->icon){\r
+ // int ms = 0;\r
+\r
+ // ms = ((double)wd->icon_size * _elm_config->scale);\r
+ evas_object_size_hint_min_set(it->icon, 24, 24);\r
+ evas_object_size_hint_max_set(it->icon, 40, 40);\r
+ edje_object_part_swallow(it->base, "elm.swallow.icon", it->icon);\r
+ evas_object_show(it->icon);\r
+ elm_widget_sub_object_add(obj, it->icon);\r
+ }\r
+\r
+ if (it->label && it->icon){\r
+ edje_object_signal_emit(it->base, "elm,state,icon_text", "elm");\r
+ }\r
+\r
+ wd->num += 1;\r
+ it->slot = wd->num;\r
+ snprintf(buf, sizeof(buf), "slot_%d", wd->num);\r
+ edje_object_part_swallow(wd->edje, buf, it->base);\r
+\r
+ light_check(wd);\r
+\r
+ return it;\r
+}\r
+\r
+/**\r
+ * Delete item from tab by index\r
+ *\r
+ * @param it The item of tab\r
+\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tab_item_del(Elm_Tab_Item *it)\r
+{\r
+ int check = 0;\r
+ int i = 1;\r
+ char buf[MAX_ARGS];\r
+ Widget_Data *wd;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ if(it->obj == NULL) {\r
+ printf("Invalid argument: tab object is NULL\n");\r
+ return;\r
+ }\r
+ wd = elm_widget_data_get(it->obj);\r
+ if(wd == NULL) {\r
+ printf("Cannot get smart data\n");\r
+ return;\r
+ }\r
+\r
+ edje_object_part_unswallow(wd->edje, it->base);\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(check){\r
+ edje_object_part_unswallow(wd->edje, item->base);\r
+ snprintf(buf, sizeof(buf), "slot_%d", i-1);\r
+ edje_object_part_swallow(wd->edje, buf, item->base);\r
+ }\r
+ if(it == item){\r
+ check = 1;\r
+ }\r
+ i++;\r
+ }\r
+\r
+ eina_stringshare_del(it->label);\r
+ if (it->icon) evas_object_del(it->icon);\r
+ evas_object_del(it->base);\r
+ wd->items = eina_list_remove(wd->items, it);\r
+ wd->num = wd->num - 1;\r
+}\r
+\r
+/**\r
+ * Select item in tab\r
+ *\r
+ * @param it The item of tab\r
+\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tab_item_select(Elm_Tab_Item *it)\r
+{\r
+ _selected_box(it);\r
+}\r
+\r
+/**\r
+ * Get the icon of item\r
+ *\r
+ * @param it The item of tab\r
+ * @return The icon object\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Evas_Object *elm_tab_item_icon_get(Elm_Tab_Item *it)\r
+{\r
+ return it->icon;\r
+}\r
+\r
+/**\r
+ * Get the label of item\r
+ *\r
+ * @param it The item of tab\r
+ * @return the label of item\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI const char *elm_tab_item_label_get(Elm_Tab_Item *it)\r
+{\r
+ return it->label;\r
+}\r
+\r
+/**\r
+ * Set the label of item\r
+ *\r
+ * @param it The item of tab\r
+ * @param label The label of item\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tab_item_label_set(Elm_Tab_Item *it, const char *label)\r
+{\r
+ if(!it->base) return;\r
+\r
+ edje_object_part_text_set(it->base, "elm.text", label);\r
+}\r
+\r
+/**\r
+ * Set the badge of item.\r
+ *\r
+ * @param it The item of tab\r
+ * @param badge The number in item badge. If -1, badge is not visible. Otherwise, it is just number.\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tab_item_badge_set(Elm_Tab_Item *it, const int badge)\r
+{\r
+ char buf[MAX_ARGS];\r
+\r
+ if(!it->base) return;\r
+\r
+ if(it->badge == badge) return;\r
+\r
+ if(badge < -1) {\r
+ printf("elm_tab_item_badge_set : second parameter range not availble. (-1 <= badge < 1000)\n");\r
+ return;\r
+ }\r
+\r
+ it->badge = badge;\r
+\r
+ if(badge == -1){\r
+ edje_object_signal_emit(it->base, "elm,badge,unvisible", "elm");\r
+ }else{\r
+ if(it->badge > 1000) {\r
+ printf("Badge Number is too large. ( badge < 1000)\n");\r
+ return;\r
+ }\r
+\r
+ snprintf(buf, sizeof(buf), "%d", it->badge);\r
+ edje_object_part_text_set(it->base, "elm.text.badge", buf);\r
+\r
+ if(it->badge > 100){\r
+ edje_object_signal_emit(it->base, "elm,badge,text_normal", "elm");\r
+ }else{\r
+ edje_object_signal_emit(it->base, "elm,badge,text_small", "elm");\r
+ }\r
+ edje_object_signal_emit(it->base, "elm,badge,visible", "elm");\r
+ }\r
+}\r
+\r
+/**\r
+ * Get the selected item.\r
+ *\r
+ * @param obj The tab object\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Elm_Tab_Item *elm_tab_selected_item_get(Evas_Object *obj)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ if(obj == NULL) return NULL;\r
+\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd || !wd->items) return NULL;\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item->selected) return item;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ * Get the first item.\r
+ *\r
+ * @param obj The tab object\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Elm_Tab_Item *elm_tab_first_item_get(Evas_Object *obj)\r
+{\r
+ if(obj == NULL) return NULL;\r
+\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd || !wd->items) return NULL;\r
+\r
+ return eina_list_data_get(wd->items);\r
+}\r
+\r
+/**\r
+ * Get the last item.\r
+ *\r
+ * @param obj The tab object\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Elm_Tab_Item *elm_tab_last_item_get(Evas_Object *obj)\r
+{\r
+ if(obj == NULL) return NULL;\r
+\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd || !wd->items) return NULL;\r
+\r
+ return eina_list_data_get(eina_list_last(wd->items));\r
+}\r
+\r
+/**\r
+ * Get the items.\r
+ *\r
+ * @param obj The tab object\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Eina_List *elm_tab_items_get(Evas_Object *obj)\r
+{\r
+ if(obj == NULL) return NULL;\r
+\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd || !wd->items) return NULL;\r
+\r
+ return wd->items;\r
+}\r
+\r
+/**\r
+ * Get the previous item.\r
+ *\r
+ * @param it The item of tab\r
+ * @return The previous item of the parameter item\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Elm_Tab_Item *elm_tab_item_prev(Elm_Tab_Item *it)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ if(it->obj == NULL) return NULL;\r
+\r
+ Widget_Data *wd = elm_widget_data_get(it->obj);\r
+ if(!wd || !wd->items) return NULL;\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(it == item){\r
+ l = eina_list_prev(l);\r
+ if(!l) return NULL;\r
+ return eina_list_data_get(l);\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ * Get the next item.\r
+ *\r
+ * @param obj The tab object\r
+ * @return The next item of the parameter item\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Elm_Tab_Item *elm_tab_item_next(Elm_Tab_Item *it)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ if(it->obj == NULL) return NULL;\r
+\r
+ Widget_Data *wd = elm_widget_data_get(it->obj);\r
+ if(!wd || !wd->items) return NULL;\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(it == item){\r
+ l = eina_list_next(l);\r
+ if(!l) return NULL;\r
+ return eina_list_data_get(l);\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ * Move the tab object\r
+ *\r
+ * @param obj The tab object\r
+ * @param direction the direction of movement\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tab_move(Evas_Object *obj, int direction)\r
+{\r
+ Widget_Data *wd;\r
+\r
+ if(obj == NULL) {\r
+ printf("Invalid argument: tab object is NULL\n");\r
+ return;\r
+ }\r
+ wd = elm_widget_data_get(obj);\r
+ if(wd == NULL) {\r
+ printf("Cannot get smart data\n");\r
+ return;\r
+ }\r
+\r
+ if(direction == ELM_TAB_MOVE_LEFT){\r
+ _move_obj_to_left(wd);\r
+ }else if(direction == ELM_TAB_MOVE_RIGHT){\r
+ _move_obj_to_right(wd);\r
+ }\r
+}\r
+\r
+/**\r
+ * Set the edit mode of the tab disable\r
+ *\r
+ * @param obj The tab object\r
+ * @param disable if 1, edit mode is disable.\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tab_edit_disable_set(Evas_Object *obj, Eina_Bool disable)\r
+{\r
+ Widget_Data *wd;\r
+\r
+ if(obj == NULL) {\r
+ printf("Invalid argument: tab object is NULL\n");\r
+ return;\r
+ }\r
+ wd = elm_widget_data_get(obj);\r
+ if(wd == NULL) {\r
+ printf("Cannot get smart data\n");\r
+ return;\r
+ }\r
+\r
+ wd->edit_disable = disable;\r
+}\r
+\r
+/**\r
+ * Get the availability for the edit mode of the tab\r
+ *\r
+ * @param obj The tab object\r
+ * @return disable or not\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Eina_Bool elm_tab_edit_disable_get(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+\r
+ if(obj == NULL) {\r
+ printf("Invalid argument: tab object is NULL\n");\r
+ return -1;\r
+ }\r
+\r
+ wd = elm_widget_data_get(obj);\r
+ if(wd == NULL) {\r
+ printf("Cannot get smart data\n");\r
+ return -1;\r
+ }\r
+\r
+ return wd->edit_disable;\r
+}\r
+\r
+\r
+\r
+///////////////////////////////////////////////////////////////////\r
+//\r
+// basic utility function\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+static void light_check(Widget_Data *wd)\r
+{\r
+ edje_object_signal_emit(wd->edje, "off_light", "light");\r
+\r
+ if(wd->view_slot_num > wd->num) return;\r
+\r
+ if(wd->cur_first_slot > 1){\r
+ edje_object_signal_emit(wd->edje, "left", "light");\r
+ }\r
+ if(wd->cur_first_slot + wd->view_slot_num - 1 != wd->num){\r
+ edje_object_signal_emit(wd->edje, "right", "light");\r
+ }\r
+}\r
+\r
+static void select_check(Widget_Data *wd)\r
+{\r
+ int i = 1;\r
+// int selected = -1;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(wd->cur_first_slot <= i && wd->cur_first_slot + wd->view_slot_num > i){\r
+ if(item->selected){\r
+ edje_object_signal_emit(item->base, "selected", "elm");\r
+ \r
+ }\r
+// selected = i;\r
+// }else{\r
+// snprintf(buf, sizeof(buf), "show_partition_%d_%d", i, i+1);\r
+// edje_object_signal_emit(wd->edje, buf, "elm");\r
+// }\r
+ }else{\r
+ edje_object_signal_emit(item->base, "unselected", "elm");\r
+ }\r
+ i++;\r
+ }\r
+\r
+// snprintf(buf, sizeof(buf), "hide_partition_%d_%d", selected, selected+1);\r
+// edje_object_signal_emit(wd->edje, buf, "elm");\r
+// snprintf(buf, sizeof(buf), "hide_partition_%d_%d", selected-1, selected);\r
+// edje_object_signal_emit(wd->edje, buf, "elm");\r
+}\r
+\r
+static int _selected_box(Elm_Tab_Item *it)\r
+{\r
+ int i = 1;\r
+ int check = 0;\r
+ Evas_Object *icon;\r
+ char buf[MAX_ARGS];\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+ Widget_Data *wd = elm_widget_data_get(it->obj);\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ edje_object_signal_emit(item->base, "unselected", "elm");\r
+ item->selected = EINA_FALSE;\r
+\r
+ icon = edje_object_part_swallow_get(item->base, "elm.swallow.icon");\r
+ if(icon){\r
+ if(strcmp(evas_object_type_get(icon), "edje") == 0){\r
+ edje_object_signal_emit(icon, "elm,state,unselected", "elm");\r
+ }else{\r
+ if(_EDJ(icon))\r
+ edje_object_signal_emit(_EDJ(icon), "elm,state,unselected", "elm");\r
+ }\r
+ }\r
+\r
+ if(it == item){\r
+ edje_object_signal_emit(it->base, "selected", "elm");\r
+ snprintf(buf, sizeof(buf), "selected_%d", i);\r
+ edje_object_signal_emit(wd->edje, buf, "elm");\r
+\r
+ if(icon){\r
+ if(strcmp(evas_object_type_get(icon), "edje") == 0){\r
+ edje_object_signal_emit(icon, "elm,state,selected", "elm");\r
+ }else{\r
+ if(_EDJ(icon))\r
+ edje_object_signal_emit(_EDJ(icon), "elm,state,selected", "elm");\r
+ }\r
+ }\r
+ item->selected = EINA_TRUE;\r
+\r
+ check = 1;\r
+ }\r
+ i++;\r
+ }\r
+\r
+ if(!check) return EXIT_FAILURE;\r
+\r
+ if (it->func) it->func((void *)(it->data), it->obj, it);\r
+ evas_object_smart_callback_call(it->obj, "clicked", it);\r
+\r
+// select_check(wd);\r
+\r
+ return EXIT_SUCCESS;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////\r
+//\r
+// general function\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+static int _move_obj_to_left(Widget_Data *wd)\r
+{\r
+ char buf[MAX_ARGS];\r
+ int first_slot;\r
+\r
+ first_slot = wd->cur_first_slot + wd->view_slot_num;\r
+ if(first_slot + wd->view_slot_num > wd->num){\r
+ first_slot = wd->num - wd->view_slot_num +1;\r
+ }\r
+\r
+ snprintf(buf, sizeof(buf), "step_%d", first_slot);\r
+ edje_object_signal_emit(wd->edje, buf, "elm");\r
+ wd->cur_first_slot = first_slot;\r
+\r
+ select_check(wd);\r
+\r
+ light_check(wd);\r
+\r
+ return EXIT_SUCCESS;\r
+}\r
+\r
+static int _move_obj_to_right(Widget_Data *wd)\r
+{\r
+ char buf[MAX_ARGS];\r
+ int first_slot;\r
+\r
+ first_slot = wd->cur_first_slot - wd->view_slot_num;\r
+ if(first_slot < 1){\r
+ first_slot = 1;\r
+ }\r
+\r
+ snprintf(buf, sizeof(buf), "step_%d", first_slot);\r
+ edje_object_signal_emit(wd->edje, buf, "elm");\r
+ wd->cur_first_slot = first_slot;\r
+\r
+ select_check(wd);\r
+\r
+ light_check(wd);\r
+\r
+ return EXIT_SUCCESS;\r
+}\r
+\r
+static void edit_up_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)\r
+{\r
+ char buf[MAX_ARGS];\r
+ Evas_Object *icon;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item->selected){\r
+ edje_object_signal_emit(item->base, "selected", "elm");\r
+ icon = edje_object_part_swallow_get(item->base, "elm.swallow.icon");\r
+ if(icon){\r
+ if(strcmp(evas_object_type_get(icon), "edje") == 0){\r
+ edje_object_signal_emit(icon, "elm,state,selected", "elm");\r
+ }else{\r
+ if(_EDJ(icon))\r
+ edje_object_signal_emit(_EDJ(icon), "elm,state,selected", "elm");\r
+ }\r
+ }\r
+ }\r
+ edje_object_signal_callback_add(item->base, "elm,action,click", "elm", tab_item_cb, item);\r
+ evas_object_event_callback_del(item->base, EVAS_CALLBACK_MOUSE_DOWN, item_down_cb);\r
+ }\r
+\r
+ evas_object_event_callback_del(wd->edje, EVAS_CALLBACK_MOUSE_DOWN, press_down_cb);\r
+ evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_DOWN, press_down_cb, wd);\r
+ evas_object_event_callback_del(wd->edje, EVAS_CALLBACK_MOUSE_UP, press_up_cb);\r
+ evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_UP, press_up_cb, wd);\r
+\r
+ snprintf(buf, sizeof(buf), "step_%d", wd->cur_first_slot);\r
+ edje_object_signal_emit(wd->edje, buf, "elm");\r
+\r
+ light_check(wd);\r
+ evas_object_hide(wd->ebx);\r
+}\r
+\r
+static Eina_Bool item_move_cb(void *data, int type, void *event_info)\r
+{\r
+ Evas_Object *obj;\r
+ Ecore_Event_Mouse_Move *ev = event_info;\r
+ Evas_Coord x, y, w, h, mx, my, mw, mh, ex, ey;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+ obj = wd->moving_obj;\r
+\r
+ evas_object_geometry_get(obj, NULL, NULL ,&w, &h);\r
+ evas_object_geometry_get(wd->edje, &ex, &ey , NULL, NULL);\r
+ edje_object_part_geometry_get(wd->edje, "bg_b", &mx, &my ,&mw, &mh);\r
+\r
+ if(ev->x < ex + mx + w/2) x = ex + mx;\r
+ else if(ev->x > ex + mx + mw - w/2) x = ex + mx + mw - w;\r
+ else x = ev->x - w/2;\r
+\r
+ if(ev->y < ey + my + h) y = ey + my;\r
+ else if(ev->y > ey + my + mh) y = ey + my + mh - h;\r
+ else y = ev->y - h;\r
+\r
+ evas_object_move(obj, x, y);\r
+\r
+ return 1;\r
+}\r
+\r
+static int sort_cb(const void *d1, const void *d2)\r
+{\r
+ Elm_Tab_Item *item1, *item2;\r
+\r
+ item1 = (Elm_Tab_Item *)d1;\r
+ item2 = (Elm_Tab_Item *)d2;\r
+\r
+ return item1->slot > item2->slot ? 1 : -1;\r
+}\r
+\r
+static Eina_Bool item_up_cb(void *data, int type, void *event_info)\r
+{\r
+ Evas_Object *obj;\r
+ Ecore_Event_Mouse_Button *ev = event_info;\r
+ char buf[MAX_ARGS];\r
+ Evas_Coord x, y, w, h;\r
+ int i = 0;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+ Elm_Tab_Item *edit_to_item, *edit_from_item;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+ obj = wd->moving_obj;\r
+\r
+ wd->edit_to = 0;\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ i++;\r
+ if(item->base == obj) continue;\r
+ evas_object_geometry_get(item->base, &x, &y, &w, &h);\r
+ if(x < ev->x && ev->x < x+w && y < ev->y && ev->y < y+h){\r
+ wd->edit_to = i;\r
+ }\r
+ }\r
+\r
+ if(wd->edit_to > 0 && wd->edit_to <= wd->num){\r
+\r
+ edit_to_item = eina_list_nth(wd->items, wd->edit_to-1);\r
+ edit_from_item = eina_list_nth(wd->items, wd->edit_from-1);\r
+\r
+ edje_object_part_unswallow(wd->edje, edit_to_item->base);\r
+ snprintf(buf, sizeof(buf), "slot_%d", wd->edit_from);\r
+ edje_object_part_swallow(wd->edje, buf, edit_to_item->base);\r
+ edit_to_item->slot = wd->edit_from;\r
+\r
+ snprintf(buf, sizeof(buf), "slot_%d", wd->edit_to);\r
+ edje_object_part_swallow(wd->edje, buf, edit_from_item->base);\r
+ edit_from_item->slot = wd->edit_to;\r
+\r
+ wd->items = eina_list_sort(wd->items, eina_list_count(wd->items), sort_cb);\r
+\r
+ }else{\r
+ wd->edit_to = wd->edit_from;\r
+ snprintf(buf, sizeof(buf), "slot_%d", wd->edit_from);\r
+ edje_object_part_swallow(wd->edje, buf, obj);\r
+ }\r
+\r
+ ecore_event_handler_del(wd->move_event);\r
+ wd->move_event = NULL;\r
+ ecore_event_handler_del(wd->up_event);\r
+ wd->up_event = NULL;\r
+\r
+ return EXIT_SUCCESS;\r
+}\r
+\r
+static void item_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)\r
+{\r
+ Evas_Event_Mouse_Down *ev = event_info;\r
+ Evas_Coord x, y, w, h;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ wd->moving_obj = obj;\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item->base == obj) wd->edit_from = item->slot;\r
+ }\r
+\r
+ edje_object_part_unswallow(wd->edje, obj);\r
+ evas_object_geometry_get(obj, &x, &y, &w, &h);\r
+ evas_object_move(obj, ev->output.x - w/2 , ev->output.y - h);\r
+ edje_object_signal_emit(obj, "edit", "elm");\r
+\r
+ wd->up_event = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, item_up_cb, (void *)wd);\r
+ wd->move_event = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, item_move_cb, (void *)wd);\r
+}\r
+\r
+static void edit_mode(void *data)\r
+{\r
+ Evas_Object *icon;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+ edje_object_signal_emit(wd->edje, "edit", "elm");\r
+\r
+ if((int)(wd->num/wd->view_slot_num) < 2){\r
+ edje_object_signal_emit(wd->edje, "edit_2", "elm");\r
+ }else{\r
+ edje_object_signal_emit(wd->edje, "edit_3", "elm");\r
+ }\r
+\r
+ // delete normal mode callback & add normal mode callback\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ edje_object_signal_emit(item->base, "unselected", "elm");\r
+ icon = edje_object_part_swallow_get(item->base, "elm.swallow.icon");\r
+ if(icon){\r
+ if(strcmp(evas_object_type_get(icon), "edje") == 0){\r
+ edje_object_signal_emit(icon, "elm,state,unselected", "elm");\r
+ }else{\r
+ if(_EDJ(icon))\r
+ edje_object_signal_emit(_EDJ(icon), "elm,state,unselected", "elm");\r
+ }\r
+ }\r
+ edje_object_signal_callback_del(item->base, "elm,action,click", "elm", tab_item_cb);\r
+ evas_object_event_callback_add(item->base, EVAS_CALLBACK_MOUSE_DOWN, item_down_cb, wd);\r
+ }\r
+ evas_object_event_callback_del(wd->edje, EVAS_CALLBACK_MOUSE_DOWN, press_down_cb);\r
+ evas_object_event_callback_del(wd->edje, EVAS_CALLBACK_MOUSE_UP, press_up_cb);\r
+ evas_object_show(wd->ebx);\r
+\r
+ edje_object_signal_emit(wd->edje, "off_light", "light");\r
+}\r
+\r
+\r
+static Eina_Bool tab_timer_cb(void* data)\r
+{\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+ if(wd->time > KEYDOWN_INTERVAL){\r
+ evas_object_event_callback_del(wd->edje, EVAS_CALLBACK_MOUSE_MOVE, press_move_cb);\r
+\r
+ if(!wd->edit_disable) edit_mode(wd);\r
+\r
+ if(wd->timer){\r
+ ecore_timer_del(wd->timer);\r
+ wd->timer = NULL;\r
+ }\r
+\r
+ } else {\r
+ wd->time += 0.1;\r
+ }\r
+\r
+ return EXIT_FAILURE;\r
+}\r
+\r
+static void press_move_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)\r
+{\r
+ Evas_Event_Mouse_Down *ev = event_info;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+ if(abs(wd->tab_down_x-ev->output.x) > 10 || abs(wd->tab_down_y-ev->output.y) > 10){\r
+ if(wd->timer){\r
+ ecore_timer_del(wd->timer);\r
+ wd->timer = NULL;\r
+ }\r
+ }\r
+}\r
+\r
+static void press_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)\r
+{\r
+ Evas_Event_Mouse_Down *ev = event_info;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+ wd->flag = EINA_TRUE;\r
+ wd->tab_down_x = ev->output.x;\r
+ wd->tab_down_y = ev->output.y;\r
+\r
+ wd->time = 0;\r
+ wd->timer = ecore_timer_add(0.1, tab_timer_cb, wd);\r
+\r
+ evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_MOUSE_MOVE, press_move_cb, wd);\r
+}\r
+\r
+static void press_up_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)\r
+{\r
+ Evas_Event_Mouse_Up *ev = event_info;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+ Evas_Coord x, y, w, h;\r
+\r
+ evas_object_event_callback_del(wd->edje, EVAS_CALLBACK_MOUSE_MOVE, press_move_cb);\r
+\r
+ if(wd->time < KEYDOWN_INTERVAL){\r
+ if(wd->timer){\r
+ ecore_timer_del(wd->timer);\r
+ wd->timer = NULL;\r
+ }\r
+ } else {\r
+ return;\r
+ }\r
+\r
+ evas_object_geometry_get(wd->edje, &x, &y, &w, &h);\r
+\r
+ if(ev->output.y > y+(h*1.5) && abs(ev->output.x - wd->tab_down_x) < wd->w/10){\r
+ if(!wd->edit_disable) edit_mode(wd);\r
+ }else{\r
+ // return if dont need to move\r
+ if(wd->num <= wd->view_slot_num) return;\r
+\r
+ if(wd->flag == EINA_TRUE){\r
+ if(abs(wd->tab_down_y - ev->output.y) < wd->h){\r
+ if((wd->tab_down_x - ev->output.x ) > wd->w / 4){\r
+ _move_obj_to_left(wd);\r
+ }else if((ev->output.x - wd->tab_down_x) > wd->w / 4){\r
+ _move_obj_to_right(wd);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ wd->flag = EINA_FALSE;\r
+}\r
+\r
+void tab_item_cb(void *data, Evas_Object *obj, const char *emission, const char *source)\r
+{\r
+ Elm_Tab_Item *it = (Elm_Tab_Item *)data;\r
+ if(it->obj == NULL)\r
+ return;\r
+ Widget_Data *wd = elm_widget_data_get(it->obj);\r
+ if(wd == NULL)\r
+ return;\r
+\r
+ if(wd->time > KEYDOWN_INTERVAL) return;\r
+ _selected_box(it);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////\r
+//\r
+// Smart Object basic function\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+static void _tab_object_move(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
+{\r
+ DBG("%s", __func__);\r
+\r
+ Widget_Data *wd;\r
+ Evas_Coord x, y;\r
+\r
+ if(!data) return;\r
+ wd = elm_widget_data_get((Evas_Object *)data);\r
+ if(!wd) return;\r
+\r
+ evas_object_geometry_get(wd->edje, &x, &y, NULL, NULL);\r
+\r
+ wd->x = x;\r
+ wd->y = y;\r
+\r
+ evas_object_move(wd->edje, x, y);\r
+}\r
+\r
+\r
+static void _tab_object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
+{\r
+ DBG("%s", __func__);\r
+\r
+ Widget_Data *wd;\r
+ Evas_Coord w, h;\r
+\r
+ if(!data) return;\r
+ wd = elm_widget_data_get((Evas_Object *)data);\r
+ if(!wd) return;\r
+\r
+ evas_object_geometry_get(wd->edje, NULL, NULL, &w, &h);\r
+\r
+ wd->w = w;\r
+ wd->h = h;\r
+\r
+ evas_object_resize(wd->edje, w, h);\r
+\r
+ evas_object_geometry_get(wd->parent, NULL, NULL, &w, &h);\r
+ evas_object_resize(wd->ebx, w, h);\r
+}\r
+\r
+\r
+static void _tab_object_show(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
+{\r
+ DBG("%s", __func__);\r
+\r
+ Widget_Data *wd;\r
+\r
+ if(!data) return;\r
+ wd = elm_widget_data_get((Evas_Object *)data);\r
+ if(!wd) return;\r
+\r
+ edit_up_cb(wd, NULL, NULL, NULL);\r
+\r
+ evas_object_show(wd->edje);\r
+}\r
+\r
+\r
+\r
+static void _tab_object_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
+{\r
+ DBG("%s", __func__);\r
+\r
+ Widget_Data *wd;\r
+\r
+ if(!data) return;\r
+ wd = elm_widget_data_get((Evas_Object *)data);\r
+ if(!wd) return;\r
+\r
+ evas_object_hide(wd->edje);\r
+ evas_object_hide(wd->ebx);\r
+}\r
+\r
--- /dev/null
+/*\r
+ * SLP\r
+ * Copyright (c) 2009 Samsung Electronics, Inc.\r
+ * All rights reserved.\r
+ *\r
+ * This software is a confidential and proprietary information\r
+ * of Samsung Electronics, Inc. ("Confidential Information"). You\r
+ * shall not disclose such Confidential Information and shall use\r
+ * it only in accordance with the terms of the license agreement\r
+ * you entered into with Samsung Electronics.\r
+ */\r
+\r
+\r
+/**\r
+ * @defgroup Tab Tab\r
+ * @ingroup Elementary\r
+ *\r
+ * This is a Tab. It can contain label and icon objects.\r
+ * You can change the location of items.\r
+ */\r
+\r
+\r
+#include <string.h>\r
+#include <math.h>\r
+\r
+#include <Elementary.h>\r
+#include "elm_priv.h"\r
+\r
+#ifndef EAPI\r
+#define EAPI __attribute__ ((visibility("default")))\r
+#endif\r
+\r
+#define MAX_ARGS 512\r
+\r
+#define ELM_MAX(v1, v2) (((v1) > (v2)) ? (v1) : (v2))\r
+#define _EDJ(x) (Evas_Object *)elm_layout_edje_get(x)\r
+\r
+#define AQUA_THEME_FILE "/usr/share/elementary/themes/aqua.edj"\r
+ \r
+Evas_Object *btn;\r
+\r
+// internal data structure of tab object\r
+typedef struct _Widget_Data Widget_Data;\r
+\r
+struct _Widget_Data\r
+{\r
+ Evas *evas;\r
+ Evas_Object *object;\r
+ Evas_Object *parent;\r
+ Evas_Object *view;\r
+ Evas_Object *edit_box;\r
+ Evas_Object *edit_table;\r
+ Evas_Object *navigation;\r
+ Evas_Object *edje;\r
+ Evas_Object *box;\r
+ Evas_Object *rect;\r
+ Evas_Object *moving_obj;\r
+ Elm_Tab_Item *moving_item;\r
+\r
+ Evas_Coord x, y, w, h;\r
+\r
+ Eina_Bool edit_mode;\r
+\r
+ int empty_num;\r
+ int num;\r
+\r
+ Eina_List *items;\r
+\r
+ int animating;\r
+\r
+ Ecore_Event_Handler *move_event;\r
+ Ecore_Event_Handler *up_event;\r
+ Ecore_Event_Handler *bar_move_event;\r
+ Ecore_Event_Handler *bar_up_event;\r
+};\r
+\r
+struct _Elm_Tab_Item\r
+ {\r
+ Evas_Object *obj;\r
+ Evas_Object *base;\r
+ Evas_Object *edit_item;\r
+ Evas_Object *view;\r
+ Evas_Object *icon;\r
+ const char *icon_path;\r
+ const char *label;\r
+ int order;\r
+ int badge;\r
+ Eina_Bool selected : 1;\r
+ Eina_Bool editable : 1;\r
+ Eina_Bool in_bar : 1;\r
+ };\r
+\r
+typedef struct _Animation_Data Animation_Data;\r
+\r
+struct _Animation_Data\r
+ {\r
+ Evas_Object *obj;\r
+ Evas_Coord fx;\r
+ Evas_Coord fy;\r
+ Evas_Coord fw;\r
+ Evas_Coord fh;\r
+ Evas_Coord tx;\r
+ Evas_Coord ty;\r
+ Evas_Coord tw;\r
+ Evas_Coord th;\r
+ unsigned int start_time;\r
+ double time;\r
+ void (*func)(void *data, Evas_Object *obj);\r
+ void *data;\r
+ Ecore_Animator *timer;\r
+ };\r
+\r
+///////////////////////////////////////////////////////////////////\r
+//\r
+// Smart Object basic function\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+static void _tab_object_move(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
+{\r
+ DBG("%s", __func__);\r
+\r
+ Widget_Data *wd;\r
+ Evas_Coord x, y;\r
+\r
+ if(!data) return;\r
+ wd = elm_widget_data_get((Evas_Object *)data);\r
+ if(!wd) return;\r
+\r
+ evas_object_geometry_get(wd->edje, &x, &y, NULL, NULL);\r
+\r
+ wd->x = x;\r
+ wd->y = y;\r
+\r
+ evas_object_move(wd->edje, x, y);\r
+// evas_object_move(wd->box, x, y);\r
+ evas_object_move(wd->view, x, y);\r
+ \r
+ evas_object_geometry_get(wd->parent, &x, &y, NULL, NULL);\r
+ evas_object_move(wd->edit_box, x, y);\r
+}\r
+\r
+\r
+static void _tab_object_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
+{\r
+ DBG("%s", __func__);\r
+\r
+ Widget_Data *wd;\r
+ Evas_Coord y, y_, w, h, height;\r
+\r
+ if(!data) return;\r
+ wd = elm_widget_data_get((Evas_Object *)data);\r
+ if(!wd) return;\r
+\r
+ evas_object_geometry_get(wd->edje, NULL, &y, &w, &h);\r
+\r
+ wd->w = w;\r
+ wd->h = h;\r
+\r
+ evas_object_resize(wd->edje, w, h);\r
+\r
+ evas_object_geometry_get(edje_object_part_object_get(wd->edje, "bg_image"), NULL, NULL, NULL, &height);\r
+ evas_object_resize(wd->view, w, h - height + 1);\r
+ evas_object_geometry_get(wd->parent, NULL, &y_, NULL, NULL);\r
+ evas_object_resize(wd->edit_box, w, h + y - y_);\r
+}\r
+\r
+\r
+static void _tab_object_show(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
+{\r
+ DBG("%s", __func__);\r
+\r
+ Widget_Data *wd;\r
+\r
+ if(!data) return;\r
+ wd = elm_widget_data_get((Evas_Object *)data);\r
+ if(!wd) return;\r
+\r
+ evas_object_show(wd->view);\r
+ evas_object_show(wd->edit_box);\r
+ evas_object_show(wd->edje);\r
+// evas_object_show(wd->box);\r
+}\r
+\r
+\r
+\r
+static void _tab_object_hide(void *data, Evas *e, Evas_Object *obj, void *event_info)\r
+{\r
+ DBG("%s", __func__);\r
+\r
+ Widget_Data *wd;\r
+\r
+ if(!data) return;\r
+ wd = elm_widget_data_get((Evas_Object *)data);\r
+ if(!wd) return;\r
+\r
+ evas_object_hide(wd->view);\r
+ evas_object_hide(wd->edit_box);\r
+ evas_object_hide(wd->edje);\r
+// evas_object_hide(wd->box);\r
+}\r
+\r
+static void\r
+_del_hook(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ Elm_Tab_Item *item;\r
+\r
+ if (!wd) return;\r
+\r
+ if (wd->view) {\r
+ evas_object_smart_member_del(wd->view);\r
+ evas_object_del(wd->view);\r
+ wd->view = NULL;\r
+ }\r
+\r
+ if (wd->edit_box) {\r
+ evas_object_smart_member_del(wd->edit_box);\r
+ evas_object_del(wd->edit_box);\r
+ wd->edit_box = NULL;\r
+ }\r
+\r
+ if (wd->navigation) {\r
+ evas_object_smart_member_del(wd->navigation);\r
+ evas_object_del(wd->navigation);\r
+ wd->navigation = NULL;\r
+ }\r
+\r
+ if (wd->edje) {\r
+ evas_object_smart_member_del(wd->edje);\r
+ evas_object_del(wd->edje);\r
+ wd->edje = NULL;\r
+ }\r
+\r
+ if (wd->box) {\r
+ evas_object_smart_member_del(wd->box);\r
+ evas_object_del(wd->box);\r
+ wd->box = NULL;\r
+ }\r
+\r
+ EINA_LIST_FREE(wd->items, item){\r
+ eina_stringshare_del(item->label);\r
+ if (item->icon) evas_object_del(item->icon);\r
+ if(item->base) evas_object_del(item->base);\r
+ if(item->edit_item) evas_object_del(item->edit_item);\r
+ free(item);\r
+ }\r
+\r
+ free(wd);\r
+}\r
+\r
+static void\r
+_theme_hook(Evas_Object *obj)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+ char buf[MAX_ARGS];\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if (!wd) return;\r
+\r
+ _elm_theme_object_set(obj, wd->edje, "tab", buf, elm_widget_style_get(obj));\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ _elm_theme_object_set(obj, item->base, "tab", "item", elm_widget_style_get(item->obj));\r
+ if (item->label){\r
+ edje_object_part_text_set(item->base, "elm.text", item->label);\r
+ }\r
+\r
+ if (item->icon){\r
+ // int ms = 0;\r
+\r
+ // ms = ((double)wd->icon_size * _elm_config->scale);\r
+ evas_object_size_hint_min_set(item->icon, 40, 40);\r
+ evas_object_size_hint_max_set(item->icon, 100, 100);\r
+ edje_object_part_swallow(item->base, "elm.swallow.icon", item->icon);\r
+ evas_object_show(item->icon);\r
+ elm_widget_sub_object_add(obj, item->icon);\r
+ }\r
+ }\r
+}\r
+\r
+static void\r
+_sub_del(void *data, Evas_Object *obj, void *event_info)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ //Evas_Object *sub = event_info;\r
+ if (!wd) return;\r
+ /*\r
+ if (sub == wd->icon)\r
+ {\r
+ edje_object_signal_emit(wd->btn, "elm,state,icon,hidden", "elm");\r
+ evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,\r
+ _changed_size_hints, obj);\r
+ wd->icon = NULL;\r
+ edje_object_message_signal_process(wd->btn);\r
+ _sizing_eval(obj);\r
+ }\r
+ */\r
+}\r
+\r
+\r
+static void\r
+_sizing_eval(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+\r
+ if (!wd) return;\r
+\r
+ DBG("[%s]\n", __func__);\r
+\r
+ _tab_object_move(obj, NULL, obj, NULL);\r
+ _tab_object_resize(obj, NULL, obj, NULL);\r
+}\r
+\r
+/////////////////////////////////////////////////////////////\r
+//\r
+// animation function\r
+//\r
+/////////////////////////////////////////////////////////////\r
+\r
+static unsigned int _current_time_get()\r
+{\r
+ struct timeval timev;\r
+\r
+ gettimeofday(&timev, NULL);\r
+ return ((timev.tv_sec * 1000) + ((timev.tv_usec) / 1000));\r
+}\r
+\r
+static void set_evas_map(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)\r
+{\r
+ if(obj == NULL) {\r
+ return;\r
+ }\r
+\r
+ Evas_Map *map = evas_map_new(4);\r
+ if(map == NULL) return;\r
+\r
+ evas_map_smooth_set( map, EINA_TRUE );\r
+ evas_map_util_points_populate_from_object_full( map, obj, 0 );\r
+ evas_object_map_enable_set( obj, EINA_TRUE );\r
+\r
+ evas_map_util_3d_perspective( map, x + w/2, y + h/2, 0, w * 10 );\r
+ evas_map_util_points_populate_from_geometry( map, x, y, w, h, 0 );\r
+\r
+ evas_object_map_set( obj, map );\r
+ evas_map_free( map );\r
+}\r
+\r
+static Eina_Bool move_evas_map(void *data)\r
+{\r
+ double t;\r
+ int dx, dy, dw, dh;\r
+ int px, py, pw, ph;\r
+ int x, y, w, h;\r
+ Animation_Data *ad = (Animation_Data *)data;\r
+ \r
+ t = ELM_MAX(0.0, _current_time_get() - ad->start_time) / 1000;\r
+ dx = ad->tx - ad->fx;\r
+ dy = ad->ty - ad->fy;\r
+ dw = ad->tw - ad->fw;\r
+ dh = ad->th - ad->fh;\r
+\r
+ if (t <= ad->time){\r
+ x = (1 * sin((t / ad->time) * (M_PI / 2)) * dx);\r
+ y = (1 * sin((t / ad->time) * (M_PI / 2)) * dy);\r
+ w = (1 * sin((t / ad->time) * (M_PI / 2)) * dw);\r
+ h = (1 * sin((t / ad->time) * (M_PI / 2)) * dh);\r
+ } else {\r
+ x = dx;\r
+ y = dy;\r
+ w = dw;\r
+ h = dh;\r
+ }\r
+\r
+ px = ad->fx + x;\r
+ py = ad->fy + y;\r
+ pw = ad->fw + w;\r
+ ph = ad->fh + h;\r
+\r
+ if( x == dx && y == dy && w == dw && h == dh ){\r
+ ecore_animator_del(ad->timer);\r
+ ad->timer = NULL;\r
+\r
+ set_evas_map(ad->obj, px, py, pw, ph);\r
+\r
+ if(ad->func != NULL) ad->func(ad->data, ad->obj);\r
+ }else{ \r
+ set_evas_map(ad->obj, px, py, pw, ph);\r
+ }\r
+\r
+ return EXIT_FAILURE;\r
+}\r
+\r
+static void move_object_with_animation(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Evas_Coord x_, Evas_Coord y_, Evas_Coord w_, Evas_Coord h_, double time, void (*func) (void *data, Evas_Object *obj), void *data)\r
+{\r
+ Animation_Data *ad = (Animation_Data *)malloc(sizeof(Animation_Data));\r
+\r
+ ad->obj = obj;\r
+ ad->fx = x;\r
+ ad->fy = y;\r
+ ad->fw = w;\r
+ ad->fh = h;\r
+ ad->tx = x_;\r
+ ad->ty = y_;\r
+ ad->tw = w_;\r
+ ad->th = h_;\r
+ ad->start_time = _current_time_get();\r
+ ad->time = time;\r
+ ad->func = func;\r
+ ad->data = data;\r
+ ad->timer = ecore_animator_add( move_evas_map , ad);\r
+}\r
+\r
+\r
+/////////////////////////////////////////////////////////////\r
+//\r
+// callback function\r
+//\r
+/////////////////////////////////////////////////////////////\r
+\r
+static void print_all_item(Widget_Data *wd)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+ Evas_Coord x, y, w, h;\r
+\r
+ printf("=========\n");\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ evas_object_geometry_get(item->base, &x, &y, &w, &h);\r
+ printf("label: %s order: %d %d %d %d %d\n", item->label, item->order, x, y, w, h);\r
+ evas_object_show(item->base);\r
+ }\r
+ printf("=========\n");\r
+}\r
+\r
+\r
+static void done_button_cb(void *data, Evas_Object *obj, void *event_info)\r
+{\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+// print_all_item(wd);\r
+ edje_object_signal_emit(wd->edit_box, "elm,state,hide,edit_box", "elm");\r
+\r
+ wd->edit_mode = EINA_FALSE;\r
+}\r
+\r
+\r
+\r
+///////////////////////////////////////////////////////////////////\r
+//\r
+// basic utility function\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+ \r
+static void item_insert_in_bar(Elm_Tab_Item *it, int order)\r
+{ \r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+ Widget_Data *wd = elm_widget_data_get(it->obj);\r
+ int check = 0;\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item->order == order && item != it) check = 1;\r
+ }\r
+\r
+ if(check){\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item->order > 0 ) elm_table_unpack(wd->box, item->base);\r
+ }\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item->order > 0){\r
+ if(item->order >= order) item->order += 1;\r
+ elm_table_pack(wd->box, item->base, item->order-1, 0, 1, 1);\r
+ evas_object_show(item->base);\r
+ }\r
+ }\r
+ }\r
+ it->order = order;\r
+ elm_table_pack(wd->box, it->base, order-1, 0, 1, 1);\r
+ evas_object_show(it->base);\r
+}\r
+\r
+static void item_delete_in_bar(Elm_Tab_Item *it)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+ Widget_Data *wd = elm_widget_data_get(it->obj);\r
+ int i = 1;\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item == it){\r
+ it->order = 0;\r
+ elm_table_unpack(wd->box, it->base);\r
+ evas_object_hide(it->base);\r
+ }else{\r
+ if(item->order > 0){\r
+ item->order = i;\r
+ i++;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+static void item_exchange_animation_cb(void *data, Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+ wd->animating--;\r
+ if(wd->animating < 0){\r
+ printf("animation error\n");\r
+ wd->animating = 0;\r
+ }\r
+// printf("animation end : %d\n", wd->animating);\r
+}\r
+\r
+static void item_exchange_in_bar(Elm_Tab_Item *it1, Elm_Tab_Item *it2)\r
+{\r
+ int order;\r
+ Evas_Coord x, y, w, h;\r
+ Evas_Coord x_, y_, w_, h_;\r
+ Widget_Data *wd = elm_widget_data_get(it1->obj);\r
+\r
+ evas_object_geometry_get(wd->moving_item->edit_item, &x, &y, &w, &h);\r
+\r
+// evas_render_updates_free(evas_render_updates(evas_object_evas_get(wd->moving_obj)));\r
+\r
+ set_evas_map(wd->moving_obj, (wd->x+wd->w/2), (wd->y+wd->h/2), 0, 0);\r
+// evas_object_del(wd->moving_obj);\r
+// wd->moving_obj = NULL;\r
+ \r
+ evas_object_geometry_get(it1->base, &x, &y, &w, &h);\r
+ evas_object_geometry_get(it2->base, &x_, &y_, &w_, &h_);\r
+\r
+ wd->animating++;\r
+ move_object_with_animation(it1->base, x, y, w, h, x_, y_, w_, h_, 0.25, item_exchange_animation_cb, wd);\r
+ wd->animating++;\r
+ move_object_with_animation(it2->base, x_, y_, w_, h_, x, y, w, h, 0.25, item_exchange_animation_cb, wd);\r
+\r
+ elm_table_unpack(wd->box, it1->base);\r
+ elm_table_unpack(wd->box, it2->base);\r
+\r
+ order = it1->order;\r
+ it1->order = it2->order;\r
+ it2->order = order;\r
+\r
+ elm_table_pack(wd->box, it1->base, it1->order-1, 0, 1, 1);\r
+ elm_table_pack(wd->box, it2->base, it2->order-1, 0, 1, 1);\r
+}\r
+\r
+static void item_change_animation_cb(void *data, Evas_Object *obj)\r
+{\r
+ Evas_Coord x, y, w, h;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+ wd->animating--;\r
+ if(wd->animating < 0){\r
+ printf("animation error\n");\r
+ wd->animating = 0;\r
+ }\r
+//printf("animation end : %d\n", wd->animating);\r
+\r
+ evas_object_geometry_get(obj, &x, &y, &w, &h);\r
+ set_evas_map(obj, x, y, 0, 0);\r
+ evas_object_move(obj, -1000, -1000);\r
+\r
+ evas_object_geometry_get(wd->moving_item->base, &x, &y, &w, &h);\r
+\r
+ evas_object_move(wd->moving_obj, -1000, -1000);\r
+ evas_object_del(wd->moving_obj);\r
+}\r
+\r
+static void item_change_in_bar(Elm_Tab_Item *it)\r
+{\r
+ Evas_Coord x, y, w, h;\r
+ Evas_Coord x_, y_, w_, h_;\r
+ Widget_Data *wd = elm_widget_data_get(it->obj);\r
+ if(wd == NULL) return;\r
+ if(wd->moving_item == NULL) return;\r
+\r
+ evas_object_geometry_get(wd->moving_item->edit_item, &x, &y, &w, &h);\r
+// evas_object_geometry_get(it->base, &x, &y, &w, &h);\r
+ set_evas_map(wd->moving_obj, x, y, w, h);\r
+// evas_object_del(wd->moving_obj);\r
+\r
+ elm_table_unpack(wd->box, it->base);\r
+\r
+ wd->moving_item->order = it->order;\r
+ it->order = 0;\r
+\r
+ elm_table_pack(wd->box, wd->moving_item->base, wd->moving_item->order-1, 0, 1, 1);\r
+ \r
+ evas_object_show(wd->moving_item->base);\r
+ \r
+ evas_render_updates_free(evas_render_updates(evas_object_evas_get(wd->moving_item->base)));\r
+\r
+ evas_object_geometry_get(it->base, &x, &y, &w, &h);\r
+ evas_object_geometry_get(it->edit_item, &x_, &y_, &w_, &h_);\r
+\r
+ wd->animating++;\r
+ move_object_with_animation(it->base, x, y, w, h, x_, y_, w_, h_, 0.25, item_change_animation_cb, wd);\r
+\r
+ evas_object_geometry_get(wd->moving_item->base, &x, &y, &w, &h);\r
+ set_evas_map(wd->moving_item->base, x, y, w, h);\r
+}\r
+\r
+static int selected_box(Elm_Tab_Item *it)\r
+{\r
+ int i = 1;\r
+ int check = 0;\r
+ Evas_Object *icon;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+ Widget_Data *wd = elm_widget_data_get(it->obj);\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ edje_object_signal_emit(_EDJ(item->base), "elm,state,unselected", "elm");\r
+ item->selected = EINA_FALSE;\r
+ edje_object_part_unswallow(wd->view, item->view);\r
+ evas_object_hide(item->view);\r
+\r
+ icon = edje_object_part_swallow_get(_EDJ(item->base), "elm.swallow.icon");\r
+ if(icon){\r
+// if(strcmp(evas_object_type_get(icon), "edje") == 0){\r
+// edje_object_signal_emit(icon, "elm,state,unselected", "elm");\r
+// }else{\r
+// if(_EDJ(icon))\r
+// edje_object_signal_emit(_EDJ(icon), "elm,state,unselected", "elm");\r
+ evas_object_color_set(icon, 255, 255, 255, 255);\r
+// }\r
+ }\r
+\r
+ if(it == item){\r
+ edje_object_signal_emit(_EDJ(it->base), "elm,state,selected", "elm");\r
+ edje_object_part_swallow(wd->view, "elm.swallow.view", it->view);\r
+ evas_object_show(it->view);\r
+\r
+ if(icon){\r
+// if(strcmp(evas_object_type_get(icon), "edje") == 0){\r
+// edje_object_signal_emit(icon, "elm,state,selected", "elm");\r
+// }else{\r
+// if(_EDJ(icon))\r
+// edje_object_signal_emit(_EDJ(icon), "elm,state,selected", "elm");\r
+ evas_object_color_set(icon, 0, 151, 222, 15);\r
+// }\r
+ }\r
+ item->selected = EINA_TRUE;\r
+\r
+ check = 1;\r
+ }\r
+ i++;\r
+ }\r
+\r
+ if(!check) return EXIT_FAILURE;\r
+\r
+ evas_object_smart_callback_call(it->obj, "clicked", it);\r
+\r
+ return EXIT_SUCCESS;\r
+}\r
+\r
+static int sort_cb(const void *d1, const void *d2)\r
+{\r
+ Elm_Tab_Item *item1, *item2;\r
+\r
+ item1 = (Elm_Tab_Item *)d1;\r
+ item2 = (Elm_Tab_Item *)d2;\r
+\r
+ return item1->order > item2->order ? 1 : -1;\r
+}\r
+\r
+static Evas_Object *create_item_layout(Evas_Object *parent, Elm_Tab_Item *it)\r
+{\r
+ Evas_Object *obj;\r
+ Evas_Object *icon;\r
+\r
+ obj = elm_layout_add(parent);\r
+ if(obj == NULL){\r
+ fprintf(stderr, "Cannot load bg edj\n");\r
+ return NULL;\r
+ }\r
+ elm_layout_theme_set(obj, "tabbar", "item", elm_widget_style_get(it->obj));\r
+ evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);\r
+ evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL);\r
+ elm_widget_sub_object_add(it->obj, obj);\r
+\r
+ if (it->label){\r
+ edje_object_part_text_set(_EDJ(obj), "elm.text", it->label);\r
+ }\r
+\r
+ if (it->icon_path){\r
+ icon = elm_icon_add(obj);\r
+ elm_icon_file_set(icon, AQUA_THEME_FILE, it->icon_path);\r
+\r
+ evas_object_size_hint_min_set(icon, 40, 40);\r
+ evas_object_size_hint_max_set(icon, 100, 100);\r
+ evas_object_show(icon);\r
+ edje_object_part_swallow(_EDJ(obj), "elm.swallow.icon", icon);\r
+ it->icon = icon;\r
+ }\r
+\r
+ return obj;\r
+}\r
+\r
+static void edit_item_down_end_cb (void *data, Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+// evas_render_updates(evas_object_evas_get(wd->moving_obj));\r
+\r
+ wd->animating--;\r
+ if(wd->animating < 0){\r
+ printf("animation error\n");\r
+ wd->animating = 0;\r
+ }\r
+//printf("animation end : %d\n", wd->animating);\r
+}\r
+\r
+static void edit_item_return_cb (void *data, Evas_Object *obj)\r
+{\r
+ Evas_Coord x, y, w, h;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+// evas_render_updates(evas_object_evas_get(obj));\r
+ evas_object_geometry_get(wd->moving_item->edit_item, &x, &y, &w, &h);\r
+ set_evas_map(obj, x, y, 0, 0);\r
+\r
+ if(wd->move_event != NULL) {\r
+ ecore_event_handler_del(wd->move_event);\r
+ wd->move_event = NULL;\r
+ }\r
+ if(wd->up_event != NULL) {\r
+ ecore_event_handler_del(wd->up_event);\r
+ wd->up_event = NULL;\r
+ }\r
+\r
+ evas_object_data_set(wd->moving_obj, "returning", 0);\r
+\r
+ wd->animating--;\r
+ if(wd->animating < 0){\r
+ printf("animation error\n");\r
+ wd->animating = 0;\r
+ }\r
+//printf("animation end : %d\n", wd->animating);\r
+}\r
+\r
+static Eina_Bool edit_item_move_cb(void *data, int type, void *event_info)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+ Ecore_Event_Mouse_Move *ev = event_info;\r
+ Evas_Coord x, y, w, h;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+ if(wd->animating) return EXIT_FAILURE;\r
+\r
+ evas_object_geometry_get( wd->moving_obj, &x, &y, &w, &h );\r
+\r
+ w *= 2.0;\r
+ h *= 2.0;\r
+\r
+ x = ev->x - w/2;\r
+ y = ev->y - h;\r
+\r
+ set_evas_map(wd->moving_obj, x, y, w, h);\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(wd->moving_item->edit_item == item->edit_item) continue;\r
+ evas_object_geometry_get(item->base, &x, &y, &w, &h);\r
+ if(ev->x > x && ev->x < x+w && ev->y > y && ev->y < y+h){\r
+ edje_object_signal_emit(_EDJ(item->base), "elm,state,show,glow", "elm");\r
+ }else{\r
+ edje_object_signal_emit(_EDJ(item->base), "elm,state,hide,glow", "elm");\r
+ }\r
+ }\r
+\r
+ return EXIT_SUCCESS;\r
+}\r
+\r
+static Eina_Bool edit_item_up_cb(void *data, int type, void *event_info)\r
+{\r
+ Ecore_Event_Mouse_Button *ev = event_info;\r
+ Evas_Coord x, y, w, h;\r
+ Evas_Coord x_, y_, w_, h_;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+ if(wd->moving_obj)\r
+ if(evas_object_data_get(wd->moving_obj, "returning") == 1) return EXIT_FAILURE; \r
+\r
+ evas_object_color_set(wd->moving_item->edit_item, 255, 255, 255, 255);\r
+\r
+ // check which change or not\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(wd->moving_item->edit_item == item->edit_item) continue;\r
+ if(item->order <= 0) continue;\r
+ evas_object_geometry_get(item->base, &x, &y, &w, &h);\r
+ if(ev->x > x && ev->x < x+w && ev->y > y && ev->y < y+h){\r
+ edje_object_signal_emit(_EDJ(item->base), "elm,state,hide,glow", "elm");\r
+ break; \r
+ }\r
+ }\r
+\r
+ if(item != NULL) { \r
+ if(wd->moving_item->order > 0){\r
+ item_exchange_in_bar(wd->moving_item, item);\r
+ }else{\r
+ item_change_in_bar(item);\r
+ }\r
+\r
+ if(wd->move_event != NULL) {\r
+ ecore_event_handler_del(wd->move_event);\r
+ wd->move_event = NULL;\r
+ }\r
+ if(wd->up_event != NULL) {\r
+ ecore_event_handler_del(wd->up_event);\r
+ wd->up_event = NULL;\r
+ }\r
+ }else{\r
+ // return moving object to original location\r
+ evas_object_geometry_get(wd->moving_item->edit_item, &x_, &y_, &w_, &h_);\r
+ evas_object_geometry_get( wd->moving_obj, &x, &y, &w, &h );\r
+\r
+ w *= 2.0;\r
+ h *= 2.0;\r
+ x = ev->x - w/2;\r
+ y = ev->y - h;\r
+\r
+ evas_object_data_set(wd->moving_obj, "returning", (void *)1);\r
+ wd->animating++;\r
+ move_object_with_animation(wd->moving_obj, x, y, w, h, x_, y_, w_, h_, 0.25, edit_item_return_cb, wd);\r
+ }\r
+\r
+ return EXIT_SUCCESS;\r
+}\r
+\r
+static void edit_item_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)\r
+{\r
+ Evas_Event_Mouse_Down *ev = event_info;\r
+ Evas_Coord x, y, w, h;\r
+ Evas_Coord x_, y_, w_, h_;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ if(wd->animating) return;\r
+\r
+ if(wd->up_event == NULL)\r
+ wd->up_event = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, edit_item_up_cb, (void *)wd);\r
+ if(wd->move_event == NULL)\r
+ wd->move_event = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, edit_item_move_cb, (void *)wd);\r
+\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item->edit_item == obj) break;\r
+ }\r
+ if(item == NULL) return;\r
+\r
+ wd->moving_item = item;\r
+\r
+ evas_object_color_set(item->edit_item, 100, 100, 100, 255);\r
+ \r
+ if(wd->moving_obj) evas_object_del(wd->moving_obj);\r
+ wd->moving_obj = NULL;\r
+\r
+ wd->moving_obj = create_item_layout(obj, item); \r
+ evas_object_geometry_get(obj, &x, &y, &w, &h);\r
+ evas_object_move(wd->moving_obj, -1000 , -1000);\r
+ evas_object_resize(wd->moving_obj, w, h);\r
+ evas_object_show(wd->moving_obj);\r
+\r
+ w_ = w * 2.0;\r
+ h_ = h * 2.0;\r
+ x_ = ev->output.x - w_/2;\r
+ y_ = ev->output.y - h_;\r
+\r
+ wd->animating++;\r
+ move_object_with_animation(wd->moving_obj, x, y, w, h, x_, y_, w_, h_, 0.1, edit_item_down_end_cb, wd);\r
+}\r
+\r
+static void bar_item_move_end_cb (void *data, Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+// evas_render_updates(evas_object_evas_get(obj));\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item->base == obj) break;\r
+ }\r
+\r
+ wd->animating--;\r
+ if(wd->animating < 0){\r
+ printf("animation error\n");\r
+ wd->animating = 0;\r
+ }\r
+ evas_object_data_set(obj, "animating", 0);\r
+//printf("animation end : %d\n", wd->animating);\r
+}\r
+\r
+\r
+static Eina_Bool bar_item_animation_end_check(void *data)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+// Evas_Coord x, y, w, h;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+\r
+ if(wd->animating) return EXIT_FAILURE;\r
+\r
+// evas_object_geometry_get(wd->moving_obj, &x, &y, &w, &h);\r
+// set_evas_map(wd->moving_obj, x, y, w, h);\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item->base == wd->moving_obj) break;\r
+ }\r
+ if(item == NULL) {\r
+ printf("item is NULL\n");\r
+ }else{\r
+ item->order = wd->empty_num;\r
+ wd->empty_num = 0;\r
+ wd->moving_obj = NULL;\r
+ }\r
+ if(wd->bar_move_event != NULL) {\r
+ ecore_event_handler_del(wd->bar_move_event);\r
+ wd->bar_move_event = NULL;\r
+ }\r
+ if(wd->bar_up_event != NULL) {\r
+ ecore_event_handler_del(wd->bar_up_event);\r
+ wd->bar_up_event = NULL;\r
+ }\r
+\r
+ return EXIT_SUCCESS;\r
+}\r
+\r
+static Eina_Bool bar_item_move_cb(void *data, int type, void *event_info)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item, *it;\r
+ Ecore_Event_Mouse_Move *ev = event_info;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+ Evas_Coord x, y, w, h, x_, y_, w_, h_;\r
+ int tmp;\r
+\r
+ if(wd->moving_obj == NULL) {\r
+ printf("%s : moving_obj is NULL\n", __func__);\r
+ return EXIT_FAILURE;\r
+ }\r
+ evas_object_geometry_get(wd->moving_obj, &x, &y, &w, &h);\r
+ x = ev->x - w/2;\r
+\r
+ set_evas_map(wd->moving_obj, x, y, w, h);\r
+// evas_render_updates(evas_object_evas_get(wd->moving_obj));\r
+ \r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item->base == wd->moving_obj) {\r
+ it = item;\r
+ continue;\r
+ }\r
+ if(evas_object_data_get(item->base, "animating") == 1) continue;\r
+ evas_object_geometry_get(item->base, &x, &y, &w, &h);\r
+ if(ev->x > x && ev->x < x+w){\r
+ evas_object_geometry_get(wd->moving_obj, &x_, &y_, &w_, &h_);\r
+ evas_object_move(wd->moving_obj, x, y);\r
+\r
+ tmp = wd->empty_num;\r
+ wd->empty_num = item->order;\r
+ item->order = tmp;\r
+\r
+ elm_table_unpack(wd->box, item->base);\r
+ elm_table_unpack(wd->box, wd->moving_obj);\r
+ elm_table_pack(wd->box, item->base, item->order-1, 0, 1, 1);\r
+ elm_table_pack(wd->box, wd->moving_obj, wd->empty_num-1, 0, 1, 1);\r
+\r
+ wd->animating++;\r
+ evas_object_data_set(item->base, "animating", (void *)1);\r
+ move_object_with_animation(item->base, x, y, w, h, x_, y_, w_, h_, 0.25, bar_item_move_end_cb, wd);\r
+ }\r
+ }\r
+ \r
+ return EXIT_SUCCESS;\r
+}\r
+\r
+static Eina_Bool bar_item_up_cb(void *data, int type, void *event_info)\r
+{\r
+ Evas_Coord tx, x, y, w, h;\r
+ Ecore_Event_Mouse_Button *ev = event_info;\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+\r
+ evas_object_geometry_get(wd->moving_obj, &x, &y, &w, &h);\r
+ tx = ev->x - w/2;\r
+ move_object_with_animation(wd->moving_obj, tx, y, w, h, x, y, w, h, 0.25, NULL, NULL);\r
+// set_evas_map(wd->moving_obj, x, y, w, h);\r
+ \r
+ ecore_timer_add(0.1, bar_item_animation_end_check, wd);\r
+\r
+ return EXIT_SUCCESS;\r
+}\r
+\r
+static void bar_item_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)\r
+{\r
+ Widget_Data *wd = (Widget_Data *)data;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ if(wd->animating) return;\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item->base == obj) break;\r
+ }\r
+\r
+ if(wd->edit_mode){\r
+ if(wd->bar_up_event != NULL || wd->bar_move_event != NULL) return;\r
+ \r
+ wd->moving_obj = obj;\r
+\r
+ wd->empty_num = item->order;\r
+\r
+ if(wd->bar_up_event == NULL)\r
+ wd->bar_up_event = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, bar_item_up_cb, (void *)wd);\r
+ if(wd->bar_move_event == NULL)\r
+ wd->bar_move_event = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, bar_item_move_cb, (void *)wd);\r
+ }else{\r
+ selected_box(item);\r
+ }\r
+}\r
+\r
+\r
+///////////////////////////////////////////////////////////////////\r
+//\r
+// API function\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+/**\r
+ * Add a new tab object\r
+ *\r
+ * @param parent The parent object\r
+ * @return The new object or NULL if it cannot be created\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Evas_Object *elm_tabbar_add(Evas_Object *parent) {\r
+ Evas_Object *obj = NULL;\r
+ Widget_Data *wd = NULL;\r
+ Evas_Coord x, y, w, h;\r
+ Evas_Object *r_button;\r
+\r
+ wd = ELM_NEW(Widget_Data);\r
+ wd->evas = evas_object_evas_get(parent);\r
+ if (wd->evas == NULL) return NULL;\r
+ obj = elm_widget_add(wd->evas);\r
+ if(obj == NULL) return NULL;\r
+ elm_widget_type_set(obj, "tabbar");\r
+ elm_widget_sub_object_add(parent, obj);\r
+ elm_widget_data_set(obj, wd);\r
+ elm_widget_del_hook_set(obj, _del_hook);\r
+ elm_widget_theme_hook_set(obj, _theme_hook);\r
+\r
+ // initialization\r
+ wd->parent = parent;\r
+ evas_object_geometry_get(parent, &x, &y, &w, &h);\r
+ wd->object = obj;\r
+ wd->x = x;\r
+ wd->y = y;\r
+ wd->w = w;\r
+ wd->h = h;\r
+ wd->num = 0;\r
+ wd->animating = 0;\r
+ wd->edit_mode = EINA_FALSE;\r
+\r
+ wd->view = edje_object_add(wd->evas);\r
+ _elm_theme_object_set(obj, wd->view, "tabbar", "view", "default");\r
+ if(wd->view == NULL) {\r
+ printf("Cannot load bg edj\n");\r
+ return NULL;\r
+ }\r
+ evas_object_show(wd->view);\r
+\r
+ // edit box\r
+ wd->edit_box = edje_object_add(wd->evas);\r
+ _elm_theme_object_set(obj, wd->edit_box, "tabbar", "edit_box", "default");\r
+ if(wd->edit_box == NULL) {\r
+ printf("Cannot load bg edj\n");\r
+ return NULL;\r
+ }\r
+ evas_object_show(wd->edit_box);\r
+\r
+ wd->navigation = elm_navigationbar_add(wd->edit_box);\r
+ r_button = elm_button_add(wd->navigation);\r
+ elm_button_label_set(r_button, "Done");\r
+ evas_object_smart_callback_add(r_button, "clicked", done_button_cb, wd);\r
+ elm_navigationbar_push(wd->navigation, "Configure", NULL, r_button, NULL, NULL);\r
+ edje_object_part_swallow(wd->edit_box, "elm.swallow.navigation", wd->navigation);\r
+ \r
+ wd->edit_table = elm_table_add(wd->edit_box);\r
+ edje_object_part_swallow(wd->edit_box, "elm.swallow.table", wd->edit_table);\r
+\r
+ /* load background edj */\r
+ wd->edje = edje_object_add(wd->evas);\r
+// snprintf(buf, sizeof(buf), "bg_portrait_%d", wd->view_slot_num);\r
+ _elm_theme_object_set(obj, wd->edje, "tabbar", "base", "default");\r
+ if(wd->edje == NULL) {\r
+ printf("Cannot load bg edj\n");\r
+ return NULL;\r
+ }\r
+ evas_object_show(wd->edje);\r
+\r
+ // initialization\r
+ evas_object_event_callback_add(wd->edje, EVAS_CALLBACK_RESIZE, _tab_object_resize, obj);\r
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _tab_object_move, obj);\r
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _tab_object_show, obj);\r
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _tab_object_hide, obj);\r
+\r
+ // items container\r
+ wd->box = elm_table_add(wd->edje);\r
+ evas_object_size_hint_weight_set(wd->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);\r
+ evas_object_size_hint_align_set(wd->box, EVAS_HINT_FILL, EVAS_HINT_FILL);\r
+ edje_object_part_swallow(wd->edje, "elm.swallow.items", wd->box); \r
+ elm_widget_sub_object_add(obj, wd->box);\r
+\r
+ //FIXME\r
+ // evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);\r
+\r
+ evas_object_smart_member_add(wd->view, obj);\r
+ evas_object_smart_member_add(wd->edit_box, obj);\r
+ elm_widget_resize_object_set(obj, wd->edje);\r
+ evas_object_smart_member_add(wd->box, obj);\r
+\r
+ // initialization\r
+ _sizing_eval(obj);\r
+\r
+ return obj;\r
+}\r
+\r
+/**\r
+ * Add new item\r
+ *\r
+ * @param obj The tab object\r
+ * @param icon The icon of item\r
+ * @param label The label of item\r
+ * @param func Callback function of item\r
+ * @param data The data of callback function\r
+ * @return The item of tab\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Elm_Tab_Item *elm_tabbar_item_add(Evas_Object *obj, const char *icon_path, const char *label, Evas_Object *view)\r
+{\r
+ Elm_Tab_Item *it;\r
+ Widget_Data *wd;\r
+\r
+ if(obj == NULL) {\r
+ fprintf(stderr, "Invalid argument: tab object is NULL\n");\r
+ return NULL;\r
+ }\r
+ wd = elm_widget_data_get(obj);\r
+ if(wd == NULL) {\r
+ fprintf(stderr, "Cannot get smart data\n");\r
+ return NULL;\r
+ }\r
+\r
+ it = ELM_NEW(Elm_Tab_Item);\r
+ if(it == NULL) return NULL;\r
+ wd->items = eina_list_append(wd->items, it);\r
+ it->obj = obj;\r
+ it->label = eina_stringshare_add(label);\r
+ it->icon_path = icon_path;\r
+ it->badge = 0;\r
+ it->view = view;\r
+\r
+ it->base = create_item_layout(wd->edje, it);\r
+ evas_object_event_callback_add(it->base, EVAS_CALLBACK_MOUSE_DOWN, bar_item_down_cb, wd); \r
+ evas_object_show(it->base);\r
+\r
+ it->edit_item = create_item_layout(wd->edje, it);\r
+ evas_object_event_callback_add(it->edit_item, EVAS_CALLBACK_MOUSE_DOWN, edit_item_down_cb, wd);\r
+ evas_object_show(it->edit_item);\r
+\r
+ wd->num += 1;\r
+ it->order = wd->num;\r
+ \r
+ elm_table_pack(wd->box, it->base, wd->num-1, 0, 1, 1);\r
+\r
+ elm_table_pack(wd->edit_table, it->edit_item, (wd->num-1)%4, (wd->num-1)/4, 1, 1);\r
+ \r
+ if(wd->num == 1) selected_box(it);\r
+\r
+ return it;\r
+}\r
+\r
+#if 0\r
+\r
+/**\r
+ * Delete item from tab by index\r
+ *\r
+ * @param it The item of tab\r
+\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tabbar_item_del(Elm_Tab_Item *it)\r
+{\r
+ int check = 0;\r
+ int i = 1;\r
+ char buf[MAX_ARGS];\r
+ Widget_Data *wd;\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+\r
+ if(it->obj == NULL){\r
+ printf("Invalid argument: tab object is NULL\n");\r
+ return;\r
+ }\r
+ wd = elm_widget_data_get(it->obj);\r
+ if(wd == NULL){\r
+ printf("Cannot get smart data\n");\r
+ return;\r
+ }\r
+\r
+ edje_object_part_unswallow(wd->edje, it->base);\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(check){\r
+ edje_object_part_unswallow(wd->edje, item->base);\r
+ snprintf(buf, sizeof(buf), "slot_%d", i-1);\r
+ edje_object_part_swallow(wd->edje, buf, item->base);\r
+ }\r
+ if(it == item){\r
+ check = 1;\r
+ }\r
+ i++;\r
+ }\r
+\r
+ eina_stringshare_del(it->label);\r
+ if (it->icon) evas_object_del(it->icon);\r
+ evas_object_del(it->base);\r
+ evas_object_del(it->edit_item);\r
+ wd->items = eina_list_remove(wd->items, it);\r
+ wd->num = wd->num - 1;\r
+}\r
+\r
+#endif\r
+\r
+/**\r
+ * Select item in tabbar\r
+ *\r
+ * @param it The item of tabbar\r
+\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tabbar_item_select(Elm_Tab_Item *it)\r
+{\r
+ if(it->obj == NULL) return;\r
+ Widget_Data *wd = elm_widget_data_get(it->obj);\r
+ if(wd == NULL) return;\r
+\r
+ if(!wd->edit_mode){\r
+ selected_box(it);\r
+ }\r
+}\r
+\r
+/**\r
+ * Get the icon of item\r
+ *\r
+ * @param it The item of tabbar\r
+ * @return The icon object\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Evas_Object *elm_tabbar_item_icon_get(Elm_Tab_Item *it)\r
+{\r
+ return it->icon;\r
+}\r
+\r
+/**\r
+ * Get the label of item\r
+ *\r
+ * @param it The item of tabbar\r
+ * @return the label of item\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI const char *elm_tabbar_item_label_get(Elm_Tab_Item *it)\r
+{\r
+ return it->label;\r
+}\r
+\r
+/**\r
+ * Set the label of item\r
+ *\r
+ * @param it The item of tabbar\r
+ * @param label The label of item\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tabbar_item_label_set(Elm_Tab_Item *it, const char *label)\r
+{\r
+ if(!it->base) return;\r
+\r
+ edje_object_part_text_set(it->base, "elm.text", label);\r
+}\r
+\r
+#if 0\r
+\r
+/**\r
+ * Set the badge of item.\r
+ *\r
+ * @param it The item of tab\r
+ * @param badge The number in item badge. If -1, badge is not visible. Otherwise, it is just number.\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tab_item_badge_set(Elm_Tab_Item *it, const int badge)\r
+{\r
+ char buf[MAX_ARGS];\r
+\r
+ if(!it->base) return;\r
+\r
+ if(it->badge == badge) return;\r
+\r
+ if(badge < -1) {\r
+ printf("elm_tab_item_badge_set : second parameter range not availble. (-1 <= badge < 1000)\n");\r
+ return;\r
+ }\r
+\r
+ it->badge = badge;\r
+\r
+ if(badge == -1){\r
+ edje_object_signal_emit(it->base, "elm,badge,unvisible", "elm");\r
+ }else{\r
+ if(it->badge > 1000) {\r
+ printf("Badge Number is too large. ( badge < 1000)\n");\r
+ return;\r
+ }\r
+\r
+ snprintf(buf, sizeof(buf), "%d", it->badge);\r
+ edje_object_part_text_set(it->base, "elm.text.badge", buf);\r
+\r
+ if(it->badge > 100){\r
+ edje_object_signal_emit(it->base, "elm,badge,text_normal", "elm");\r
+ }else{\r
+ edje_object_signal_emit(it->base, "elm,badge,text_small", "elm");\r
+ }\r
+ edje_object_signal_emit(it->base, "elm,badge,visible", "elm");\r
+ }\r
+}\r
+\r
+/**\r
+ * Get the selected item.\r
+ *\r
+ * @param obj The tab object\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Elm_Tab_Item *elm_tab_selected_item_get(Evas_Object *obj)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ if(obj == NULL) return NULL;\r
+\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd || !wd->items) return NULL;\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(item->selected) return item;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ * Get the first item.\r
+ *\r
+ * @param obj The tab object\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Elm_Tab_Item *elm_tab_first_item_get(Evas_Object *obj)\r
+{\r
+ if(obj == NULL) return NULL;\r
+\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd || !wd->items) return NULL;\r
+\r
+ return eina_list_data_get(wd->items);\r
+}\r
+\r
+/**\r
+ * Get the last item.\r
+ *\r
+ * @param obj The tab object\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Elm_Tab_Item *elm_tab_last_item_get(Evas_Object *obj)\r
+{\r
+ if(obj == NULL) return NULL;\r
+\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd || !wd->items) return NULL;\r
+\r
+ return eina_list_data_get(eina_list_last(wd->items));\r
+}\r
+\r
+/**\r
+ * Get the items.\r
+ *\r
+ * @param obj The tab object\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Eina_List *elm_tab_items_get(Evas_Object *obj)\r
+{\r
+ if(obj == NULL) return NULL;\r
+\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if(!wd || !wd->items) return NULL;\r
+\r
+ return wd->items;\r
+}\r
+\r
+/**\r
+ * Get the previous item.\r
+ *\r
+ * @param it The item of tab\r
+ * @return The previous item of the parameter item\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Elm_Tab_Item *elm_tab_item_prev(Elm_Tab_Item *it)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ if(it->obj == NULL) return NULL;\r
+\r
+ Widget_Data *wd = elm_widget_data_get(it->obj);\r
+ if(!wd || !wd->items) return NULL;\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(it == item){\r
+ l = eina_list_prev(l);\r
+ if(!l) return NULL;\r
+ return eina_list_data_get(l);\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ * Get the next item.\r
+ *\r
+ * @param obj The tab object\r
+ * @return The next item of the parameter item\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Elm_Tab_Item *elm_tab_item_next(Elm_Tab_Item *it)\r
+{\r
+ const Eina_List *l;\r
+ Elm_Tab_Item *item;\r
+\r
+ if(it->obj == NULL) return NULL;\r
+\r
+ Widget_Data *wd = elm_widget_data_get(it->obj);\r
+ if(!wd || !wd->items) return NULL;\r
+\r
+ EINA_LIST_FOREACH(wd->items, l, item){\r
+ if(it == item){\r
+ l = eina_list_next(l);\r
+ if(!l) return NULL;\r
+ return eina_list_data_get(l);\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ * Move the tab object\r
+ *\r
+ * @param obj The tab object\r
+ * @param direction the direction of movement\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tab_move(Evas_Object *obj, int direction)\r
+{\r
+ Widget_Data *wd;\r
+\r
+ retm_if(obj == NULL, "Invalid argument: tab object is NULL\n");\r
+ wd = elm_widget_data_get(obj);\r
+ retm_if(wd == NULL, "Cannot get smart data\n");\r
+\r
+ if(direction == ELM_TAB_MOVE_LEFT){\r
+ _move_obj_to_left(wd);\r
+ }else if(direction == ELM_TAB_MOVE_RIGHT){\r
+ _move_obj_to_right(wd);\r
+ }\r
+}\r
+\r
+/**\r
+ * Set the edit mode of the tab disable\r
+ *\r
+ * @param obj The tab object\r
+ * @param disable if 1, edit mode is disable.\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tab_edit_disable_set(Evas_Object *obj, Eina_Bool disable)\r
+{\r
+ Widget_Data *wd;\r
+\r
+ retm_if(obj == NULL, "Invalid argument: tab object is NULL\n");\r
+ wd = elm_widget_data_get(obj);\r
+ retm_if(wd == NULL, "Cannot get smart data\n");\r
+\r
+ wd->edit_disable = disable;\r
+}\r
+\r
+/**\r
+ * Get the availability for the edit mode of the tab\r
+ *\r
+ * @param obj The tab object\r
+ * @return disable or not\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI Eina_Bool elm_tab_edit_disable_get(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+\r
+ if(obj == NULL) {\r
+ printf("Invalid argument: tab object is NULL\n");\r
+ return -1;\r
+ }\r
+ wd = elm_widget_data_get(obj);\r
+ if(wd == NULL) {\r
+ printf("Cannot get smart data\n");\r
+ return -1;\r
+ }\r
+\r
+ return wd->edit_disable;\r
+}\r
+\r
+#endif\r
+\r
+/**\r
+ * Start edit mode\r
+ *\r
+ * @param The tab object\r
+\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tabbar_edit_start(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd;\r
+\r
+ if(obj == NULL){\r
+ fprintf(stderr, "Invalid argument: tab object is NULL\n");\r
+ return;\r
+ }\r
+ wd = elm_widget_data_get(obj);\r
+ if(wd == NULL){\r
+ fprintf(stderr, "Cannot get smart data\n");\r
+ return;\r
+ }\r
+\r
+ edje_object_signal_emit(wd->edit_box, "elm,state,show,edit_box", "elm");\r
+\r
+ wd->edit_mode = EINA_TRUE;\r
+}\r
+\r
+/**\r
+ * Set item in bar\r
+ *\r
+ * @param it The item of tab\r
+ * @param bar EINA_TRUE or EINA_FALSE\r
+ *\r
+ * @ingroup Tab\r
+ */\r
+EAPI void elm_tabbar_item_visible_set(Elm_Tab_Item *it, Eina_Bool bar)\r
+{\r
+ Eina_Bool check = EINA_TRUE;\r
+ \r
+ if(it->order <= 0) check = EINA_FALSE;\r
+ \r
+ if(check == bar) return;\r
+\r
+ if(bar){\r
+ item_insert_in_bar(it, 0);\r
+ }else{\r
+ item_delete_in_bar(it); \r
+ }\r
+}\r
--- /dev/null
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Timepicker Timepicker
+ * @ingroup Elementary
+ *
+ * This is a time picker.
+ */
+
+
+#define PICKER_DRAG_BOUND (10)
+
+#define MAX_HOUR (12)
+#define MAX_HOUR2 (23)
+#define MAX_DIGIT (9)
+#define MAX_DIGIT2 (59)
+
+enum {
+ PICKER_HRS,
+ PICKER_MIN,
+ PICKER_SUB,
+ PICKER_AMPM,
+ PICKER_MAX
+};
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data {
+ Evas_Object *base;
+ Evas_Object *pickers[PICKER_MAX];
+
+ int hrs, min, sec;
+ Eina_Bool is_pm;
+
+ Eina_Bool ampm;
+ Eina_Bool seconds;
+};
+
+static inline Eina_Bool _is_time_valid(int hrs, int min, int sec);
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _update_ampm(Evas_Object *obj);
+static void _update_seconds(Evas_Object *obj);
+static void _update_picker(Evas_Object *picker, int nth);
+static void _update_all(Evas_Object *obj);
+static void _hrs_reload(Evas_Object *picker, Eina_Bool ampm);
+static void _digit_reload(Evas_Object *picker, Eina_Bool seconds, int max);
+static Evas_Object *_hrs_add(Evas_Object *ly, const char *part, Eina_Bool ampm);
+static Evas_Object *_digit_add(Evas_Object *ly, const char *part, unsigned char max);
+static Evas_Object *_ampm_add(Evas_Object *ly, const char *part);
+static void _callback_init(Evas_Object *obj);
+static void _pickers_add(Evas_Object *obj);
+static void _pickers_del(Evas_Object *obj);
+static void _changed(Evas_Object *picker, Evas_Object *child, Evas_Object *obj);
+static void _overflow_cb(void *data, Evas_Object *obj, void *event_info);
+static void _underflow_cb(void *data, Evas_Object *obj, void *event_info);
+static void _hrs_changed_cb(void *data, Evas_Object *obj, void *event_info);
+static void _min_changed_cb(void *data, Evas_Object *obj, void *event_info);
+static void _sub_changed_cb(void *data, Evas_Object *obj, void *event_info);
+static void _ampm_changed_cb(void *data, Evas_Object *obj, void *event_info);
+
+static inline Eina_Bool
+_is_time_valid(int hrs, int min, int sec)
+{
+ if (hrs < 0 || hrs > 23 || min < 0 || min > 59 || sec < 0 || sec > 59)
+ return EINA_FALSE;
+ return EINA_TRUE;
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ _pickers_del(obj);
+ free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ _pickers_del(obj);
+ _elm_theme_object_set(obj, wd->base, "timepicker", "base", elm_widget_style_get(obj));
+ _pickers_add(obj);
+
+ _update_ampm(obj);
+ _update_seconds(obj);
+ _sizing_eval(obj);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+
+}
+
+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;
+
+ if (!wd) return;
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_update_ampm(Evas_Object *obj)
+{
+ const char *sig;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ if (wd->ampm)
+ sig = "elm,state,ampm,visible";
+
+ else
+ sig = "elm,state,ampm,hidden";
+
+ _hrs_reload(wd->pickers[PICKER_HRS], wd->ampm);
+ edje_object_signal_emit(wd->base, sig, "elm");
+ _update_all(obj);
+}
+
+static void
+_update_seconds(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ const char *sig;
+ if (!wd) return;
+
+ if (wd->seconds)
+ sig = "elm,state,sec,visible";
+ else
+ sig = "elm,state,sec,hidden";
+
+ _digit_reload(wd->pickers[PICKER_MIN], wd->seconds, 5);
+ _digit_reload(wd->pickers[PICKER_SUB], wd->seconds, MAX_DIGIT);
+
+ edje_object_signal_emit(wd->base, sig, "elm");
+ _update_all(obj);
+}
+
+static void
+_update_picker(Evas_Object *picker, int nth)
+{
+ const Eina_List *l;
+ Elm_Picker_Item *item;
+ int i;
+ l = elm_picker_items_get(picker);
+ for (i = 0; i < nth; i++) {
+ l = l->next;
+ if (!l) break;
+ }
+
+ item = eina_list_data_get(l);
+
+ elm_picker_item_selected_set(item);
+}
+
+static void
+_update_all(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ int hrs;
+ if (!wd) return;
+
+ hrs = wd->hrs;
+ if (wd->ampm)
+ hrs = wd->hrs % 12;
+
+ _update_picker(wd->pickers[PICKER_HRS], hrs);
+ if (wd->hrs >= 12)
+ wd->is_pm = 1;
+ else
+ wd->is_pm = 0;
+ _update_picker(wd->pickers[PICKER_AMPM], wd->is_pm);
+
+ if (wd->seconds) {
+ _update_picker(wd->pickers[PICKER_MIN], wd->min);
+ _update_picker(wd->pickers[PICKER_SUB], wd->sec);
+ } else {
+ _update_picker(wd->pickers[PICKER_MIN], wd->min / 10);
+ _update_picker(wd->pickers[PICKER_SUB], wd->min % 10);
+ }
+ _sizing_eval(obj);
+}
+
+static void
+_hrs_reload(Evas_Object *picker, Eina_Bool ampm)
+{
+ int i, max;
+ char buf[8];
+ Elm_Picker_Item *item;
+
+ item = elm_picker_first_item_get(picker);
+
+ while (item) {
+ elm_picker_item_del(item);
+ item = elm_picker_first_item_get(picker);
+ }
+
+ if (ampm) {
+ i = 1;
+ snprintf(buf, 8, "%02d", MAX_HOUR);
+ elm_picker_item_append(picker, buf, NULL, NULL);
+ max = MAX_HOUR - 1;
+ } else {
+ i = 0;
+ max = MAX_HOUR2;
+ }
+
+ for (; i <= max; i++) {
+ snprintf(buf, 8, "%02d", i);
+ elm_picker_item_append(picker, buf, NULL, NULL);
+ }
+}
+
+static void
+_digit_reload(Evas_Object *picker, Eina_Bool seconds, int max)
+{
+ int i;
+ char buf[8];
+ Elm_Picker_Item *item;
+ const char *exp;
+
+ item = elm_picker_first_item_get(picker);
+
+ while (item) {
+ elm_picker_item_del(item);
+ item = elm_picker_first_item_get(picker);
+ }
+
+ if (seconds) max = MAX_DIGIT2;
+ if (max >= 10) exp = "%02d";
+ else exp = "%d";
+
+ for (i = 0; i <= max; i++) {
+ snprintf(buf, 8, exp, i);
+ elm_picker_item_append(picker, buf, NULL, NULL);
+ }
+}
+
+static Evas_Object *
+_hrs_add(Evas_Object *ly, const char *part, Eina_Bool ampm)
+{
+ int i, max;
+ char buf[8];
+ Evas_Object *eo;
+ eo = elm_picker_add(ly);
+
+ if (ampm) {
+ i = 1;
+ snprintf(buf, 8, "%02d", MAX_HOUR);
+ elm_picker_item_append(eo, buf, NULL, NULL);
+ max = MAX_HOUR - 1;
+ } else {
+ i = 0;
+ max = MAX_HOUR2;
+ }
+
+ for (; i <= max; i++) {
+ snprintf(buf, 8, "%02d", i);
+ elm_picker_item_append(eo, buf, NULL, NULL);
+ }
+ if (part)
+ edje_object_part_swallow(ly, part, eo);
+ return eo;
+}
+
+static Evas_Object *
+_digit_add(Evas_Object *ly, const char *part, unsigned char max)
+{
+ int i;
+ char buf[8];
+ Evas_Object *eo;
+ eo = elm_picker_add(ly);
+ for (i = 0; i <= max; i++) {
+ snprintf(buf, 8, "%d", i);
+ elm_picker_item_append(eo, buf, NULL, NULL);
+ }
+ if (part)
+ edje_object_part_swallow(ly, part, eo);
+ return eo;
+}
+
+static Evas_Object *
+_ampm_add(Evas_Object *ly, const char *part)
+{
+ Evas_Object *eo;
+ eo = elm_picker_add(ly);
+ elm_object_style_set(eo, "timepicker/ampm");
+ elm_picker_item_append(eo, "AM", NULL, NULL);
+ elm_picker_item_append(eo, "PM", NULL, NULL);
+ if (part)
+ edje_object_part_swallow(ly, part, eo);
+ return eo;
+}
+
+static void
+_callback_init(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ evas_object_data_set(wd->pickers[PICKER_HRS], "child", wd->pickers[PICKER_MIN]);
+ evas_object_data_set(wd->pickers[PICKER_MIN], "child", wd->pickers[PICKER_SUB]);
+ evas_object_data_set(wd->pickers[PICKER_SUB], "child", NULL);
+ evas_object_data_set(wd->pickers[PICKER_AMPM], "child", wd->pickers[PICKER_HRS]);
+ evas_object_data_set(wd->pickers[PICKER_HRS], "parent", wd->pickers[PICKER_AMPM]);
+ evas_object_data_set(wd->pickers[PICKER_MIN], "parent", wd->pickers[PICKER_HRS]);
+ evas_object_data_set(wd->pickers[PICKER_SUB], "parent", wd->pickers[PICKER_MIN]);
+
+ evas_object_smart_callback_add(wd->pickers[PICKER_HRS], "overflowed", _overflow_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_HRS], "underflowed", _underflow_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_MIN], "overflowed", _overflow_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_MIN], "underflowed", _underflow_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_SUB], "overflowed", _overflow_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_SUB], "underflowed", _underflow_cb, obj);
+
+ evas_object_smart_callback_add(wd->pickers[PICKER_HRS], "changed", _hrs_changed_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_MIN], "changed", _min_changed_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_SUB], "changed", _sub_changed_cb, obj);
+ evas_object_smart_callback_add(wd->pickers[PICKER_AMPM], "changed", _ampm_changed_cb, obj);
+}
+
+static void
+_pickers_add(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ wd->pickers[PICKER_HRS] = _hrs_add(wd->base, "elm.swallow.hour", EINA_TRUE);
+ wd->pickers[PICKER_MIN] = _digit_add(wd->base, "elm.swallow.min", 5);
+ wd->pickers[PICKER_SUB] = _digit_add(wd->base, "elm.swallow.sub", MAX_DIGIT);
+ wd->pickers[PICKER_AMPM] = _ampm_add(wd->base, "elm.swallow.ampm");
+ edje_object_signal_emit(wd->base, "elm,state,ampm,visible", "elm");
+ wd->ampm = EINA_TRUE;
+
+ _callback_init(obj);
+}
+
+static void
+_pickers_del(Evas_Object *obj)
+{
+ int i = 0;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ for (i = 0; i < PICKER_MAX; i++) {
+ if (wd->pickers[i]) {
+ evas_object_del(wd->pickers[i]);
+ wd->pickers[i] = NULL;
+ }
+ }
+}
+
+static void
+_changed(Evas_Object *picker, Evas_Object *child, Evas_Object *obj)
+{
+ int c1, c2 = 0;
+ c1 = (int)(evas_object_data_get(picker, "carryon"));
+ evas_object_data_set(picker, "carryon", (void *)0);
+
+ if (child) {
+ c2 = (int)(evas_object_data_get(child, "carryon"));
+ evas_object_data_set(child, "carryon", (void *)0);
+ }
+
+ if (!c1 && !c2)
+ evas_object_smart_callback_call(obj, "changed", NULL);
+}
+
+static void
+_overflow_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Evas_Object *eo;
+ eo = evas_object_data_get(obj, "parent");
+ if (eo) {
+ elm_picker_next(eo);
+ evas_object_data_set(obj, "carryon", (void *)1);
+ }
+}
+
+static void
+_underflow_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Evas_Object *eo;
+ eo = evas_object_data_get(obj, "parent");
+ if (eo) {
+ elm_picker_prev(eo);
+ evas_object_data_set(obj, "carryon", (void *)1);
+ }
+}
+
+static void
+_hrs_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ const char *hrs;
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Object *child;
+ if (!wd) return;
+
+ hrs = elm_picker_item_label_get(event_info);
+ wd->hrs = atoi(hrs);
+
+ if (wd->ampm) {
+ wd->hrs %= 12;
+ if (wd->is_pm)
+ wd->hrs += 12;
+ }
+
+ child = evas_object_data_get(obj, "child");
+ _changed(obj, child, data);
+}
+
+static void
+_min_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ const char *min;
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Object *child;
+ if (!wd) return;
+
+ min = elm_picker_item_label_get(event_info);
+
+ if (wd->seconds) {
+ wd->min = atoi(min);
+ } else {
+ wd->min = wd->min % 10;
+ wd->min += atoi(min) * 10;
+ }
+
+ child = evas_object_data_get(obj, "child");
+ _changed(obj, child, data);
+}
+
+static void
+_sub_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ const char *sub;
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Object *child;
+ if (!wd) return;
+
+ sub = elm_picker_item_label_get(event_info);
+
+ if (wd->seconds) {
+ wd->sec = atoi(sub);
+ } else {
+ wd->min = wd->min - wd->min % 10;
+ wd->min += atoi(sub);
+ }
+
+ child = evas_object_data_get(obj, "child");
+ _changed(obj, child, data);
+}
+
+static void
+_ampm_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ const char *ampm;
+ Widget_Data *wd = elm_widget_data_get(data);
+ Evas_Object *child;
+ if (!wd) return;
+
+ ampm = elm_picker_item_label_get(event_info);
+
+ wd->hrs = (wd->hrs) % 12;
+ if (!strcmp(ampm, "AM")) {
+ wd->is_pm = 0;
+ } else {
+ wd->is_pm = 1;
+ wd->hrs += 12;
+ }
+
+ child = evas_object_data_get(obj, "child");
+ _changed(obj, child, data);
+}
+
+/**
+ * Add a new timepicker to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Timepicker
+ */
+EAPI Evas_Object *
+elm_timepicker_add(Evas_Object *parent)
+{
+ Evas_Object *obj;
+ Evas *e;
+ Widget_Data *wd;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ obj = elm_widget_add(e);
+ elm_widget_type_set(obj, "timepicker");
+ 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_disable_hook_set(obj, _disable_hook);
+
+ wd->base = edje_object_add(e);
+ _elm_theme_object_set(obj, wd->base, "timepicker", "base", "default");
+ elm_widget_resize_object_set(obj, wd->base);
+ _pickers_add(obj);
+ _sizing_eval(obj);
+ return obj;
+}
+
+/**
+ * Set selected time of the timepicker
+ *
+ * @param obj The timepicker object
+ * @param hrs The hours to set
+ * @param min The minutes to set
+ * @param sec The seconds to set
+ *
+ * @ingroup Timepicker
+ */
+EAPI void
+elm_timepicker_time_set(Evas_Object *obj, int hrs, int min, int sec)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (!_is_time_valid(hrs, min, sec)) return;
+
+ wd->hrs = hrs;
+ wd->min = min;
+ wd->sec = sec;
+
+ _update_all(obj);
+}
+
+/**
+ * Get selected time of the timepicker
+ *
+ * @param obj The timepicker object
+ * @param hrs The Pointer to the variable to get the selected hours
+ * @param min The Pointer to the variable to get the selected minute
+ * @param sec The Pointer to the variable to get the selected seconds
+ *
+ * @ingroup Timepicker
+ */
+EAPI void
+elm_timepicker_time_get(Evas_Object *obj, int *hrs, int *min, int *sec)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ if (hrs)
+ *hrs = wd->hrs;
+ if (min)
+ *min = wd->min;
+ if (sec)
+ *sec = wd->sec;
+}
+
+/**
+ * Set if the timepicker show hours in military or am/pm mode
+ *
+ * @param obj The timepicker object
+ * @param am_pm Bool option for the hours mode
+ *
+ * @ingroup Timepicker
+ */
+EAPI void
+elm_timepicker_show_am_pm_set(Evas_Object *obj, Eina_Bool am_pm)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ if (wd->ampm != am_pm) {
+ wd->ampm = am_pm;
+ _update_ampm(obj);
+ }
+}
+
+/**
+ * Set if the timepicker show seconds picker or not
+ *
+ * @param obj The timepicker object
+ * @param am_pm Bool option for the show seconds picker
+ *
+ * @ingroup Timepicker
+ */
+EAPI void
+elm_timepicker_show_seconds_set(Evas_Object *obj, Eina_Bool seconds)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ if (wd->seconds != seconds) {
+ wd->seconds = seconds;
+ _update_seconds(obj);
+ }
+}
--- /dev/null
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Titlebar Titlebar
+ * @ingroup Elementary
+ *
+ * This is a titlebar widget. It can contain simple label,icon
+ * and other objects.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+ Evas_Object *tbar;
+ Evas_Object *icon;
+ Evas_Object *end;
+ const char *label;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object * obj);
+static void _theme_hook(Evas_Object * obj);
+static void _sizing_eval(Evas_Object * obj);
+static void _changed_size_hints(void *data, Evas * e, Evas_Object * obj, void *event_info);
+static void _sub_del(void *data, Evas_Object * obj, void *event_info);
+
+static void
+_del_hook(Evas_Object * obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (wd->label) eina_stringshare_del(wd->label);
+ free(wd);
+}
+
+static void
+_theme_hook(Evas_Object * obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ _elm_theme_object_set(obj, wd->tbar, "titlebar", "base", elm_widget_style_get(obj));
+ edje_object_part_text_set(wd->tbar, "elm.text", wd->label);
+ edje_object_scale_set(wd->tbar, elm_widget_scale_get(obj) * _elm_config->scale);
+ _sizing_eval(obj);
+}
+
+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;
+ if (!wd) return;
+ edje_object_size_min_calc(wd->tbar, &minw, &minh);
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_changed_size_hints(void *data, Evas * e __UNUSED__, Evas_Object * obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ if (!wd) return;
+ _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data __UNUSED__, Evas_Object * obj, void *event_info)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Object *sub = event_info;
+ if (!wd) return;
+ evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _changed_size_hints, obj);
+ if (sub == wd->icon)
+ {
+ edje_object_signal_emit(wd->tbar, "elm,state,icon,hidden", "elm");
+ wd->icon = NULL;
+ edje_object_message_signal_process(wd->tbar);
+ }
+ else if (sub == wd->end) wd->end = NULL;
+ _sizing_eval(obj);
+}
+
+/**
+ * Add a new titlebar object.
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Titlebar
+ */
+EAPI Evas_Object *
+elm_titlebar_add(Evas_Object * parent)
+{
+ Evas_Object *obj;
+ Evas *e;
+ Widget_Data *wd;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ obj = elm_widget_add(e);
+ ELM_SET_WIDTYPE(widtype, "titlebar");
+ elm_widget_type_set(obj, "titlebar");
+ 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);
+
+ wd->tbar = edje_object_add(e);
+ _elm_theme_object_set(obj, wd->tbar, "titlebar", "base", "default");
+ elm_widget_resize_object_set(obj, wd->tbar);
+
+ evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
+
+ _sizing_eval(obj);
+ return obj;
+}
+
+/**
+ * This set's the label in titlebar object.
+ *
+ * @param obj The titlebar object
+ * @param label The label text
+ *
+ * @ingroup Titlebar
+ */
+EAPI void
+elm_titlebar_label_set(Evas_Object * obj, const char *label)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ eina_stringshare_replace(&wd->label, label);
+ edje_object_part_text_set(wd->tbar, "elm.text", label);
+ _sizing_eval(obj);
+}
+
+/**
+ * This get's the label packed in titlebar object.
+ *
+ * @param obj The titlebar object
+ * @return label text
+ *
+ * @ingroup Titlebar
+ */
+EAPI const char *
+elm_titlebar_label_get(Evas_Object * obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+ return wd->label;
+}
+
+/**
+ * This set's the icon object in titlebar object.
+ *
+ * @param obj The titlebar object
+ * @param icon The icon object
+ *
+ * @ingroup Titlebar
+ */
+EAPI void
+elm_titlebar_icon_set(Evas_Object * obj, Evas_Object * icon)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (wd->icon == icon) return;
+ if (wd->icon) evas_object_del(wd->icon);
+ wd->icon = icon;
+ if (icon)
+ {
+ elm_widget_sub_object_add(obj, icon);
+ edje_object_part_swallow(wd->tbar, "elm.swallow.icon", icon);
+ evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _changed_size_hints, obj);
+ edje_object_signal_emit(wd->tbar, "elm,state,icon,visible", "elm");
+ edje_object_message_signal_process(wd->tbar);
+ }
+ _sizing_eval(obj);
+}
+
+/**
+ * This get's the icon object packed in titlebar object.
+ *
+ * @param obj The titlebar object
+ * @return The icon object
+ *
+ * @ingroup Titlebar
+ */
+EAPI Evas_Object *
+elm_titlebar_icon_get(Evas_Object * obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+ return wd->icon;
+}
+
+/**
+ * This set's the end object in titlebar object.
+ *
+ * @param obj The titlebar object
+ * @param end The end object
+ *
+ * @ingroup Titlebar
+ */
+EAPI void
+elm_titlebar_end_set(Evas_Object * obj, Evas_Object * end)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ if (wd->end == end) return;
+ if (wd->end) evas_object_del(wd->end);
+ wd->end = end;
+ if (end)
+ {
+ elm_widget_sub_object_add(obj, end);
+ evas_object_event_callback_add(end, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+ _changed_size_hints, obj);
+ edje_object_part_swallow(wd->tbar, "elm.swallow.end", end);
+ }
+ _sizing_eval(obj);
+}
+
+/**
+ * This get's the end object packed in titlebar object.
+ *
+ * @param obj The titlebar object
+ * @return The icon object
+ *
+ * @ingroup Titlebar
+ */
+EAPI Evas_Object *
+elm_titlebar_end_get(Evas_Object * obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return NULL;
+ return wd->end;
+}
--- /dev/null
+/*\r
+ * @defgroup WiperControl WiperControl\r
+ * @ingroup Elementary\r
+ *\r
+ * This is a wipercontrol.\r
+ */\r
+\r
+#include <Elementary.h>\r
+#include "elm_priv.h"\r
+\r
+typedef struct _Widget_Data Widget_Data;\r
+\r
+struct _Widget_Data\r
+{\r
+ Evas_Object *sd;\r
+};\r
+\r
+static void _del_hook(Evas_Object *obj);\r
+static void _theme_hook(Evas_Object *obj);\r
+static void _disable_hook(Evas_Object *obj);\r
+static void _sizing_eval(Evas_Object *obj);\r
+\r
+static void\r
+_del_hook(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if (!wd) return;\r
+ free(wd);\r
+}\r
+\r
+\r
+/*\r
+ * FIXME:\r
+ */\r
+static void\r
+_theme_hook(Evas_Object *obj)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if (!wd) return;\r
+\r
+ _elm_theme_object_set(obj,wd->sd, "wipercontrol", "base", elm_widget_style_get(obj));\r
+\r
+ _sizing_eval(obj);\r
+\r
+ evas_object_show (wd->sd);\r
+}\r
+\r
+static void\r
+_sizing_eval(Evas_Object *obj)\r
+{\r
+// Widget_Data *wd = elm_widget_data_get(obj);\r
+}\r
+\r
+/**\r
+ * Set below content to the wipercontrol\r
+ *\r
+ * @param[in] obj Wipercontrol object\r
+ * @param[in] content Custom object\r
+ * @ingroup WiperControl\r
+ */\r
+EAPI void\r
+elm_wipercontrol_below_content_set (Evas_Object *obj, Evas_Object *content)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if (!wd) return;\r
+ if (!content) return;\r
+\r
+ edje_object_part_swallow (wd->sd, "content.below.swallow", content);\r
+}\r
+\r
+/**\r
+ * Set above content to the wipercontrol\r
+ *\r
+ * @param[in] obj Wipercontrol object\r
+ * @param[in] content Custom object\r
+ * @ingroup WiperControl\r
+ */\r
+EAPI void\r
+elm_wipercontrol_above_content_set (Evas_Object *obj, Evas_Object *content)\r
+{\r
+ Widget_Data *wd = elm_widget_data_get(obj);\r
+ if (!wd) return;\r
+ if (!content) return;\r
+\r
+ edje_object_part_swallow (wd->sd, "content.above.swallow", content);\r
+}\r
+\r
+/**\r
+ * Add a new wipercontrol to the parent\r
+ * @param parent The parent object\r
+ * @return The new object or NULL if it cannot be created\r
+ * @ingroup WiperControl\r
+ */\r
+EAPI Evas_Object *\r
+elm_wipercontrol_add(Evas_Object *parent)\r
+{\r
+ Evas_Object *obj;\r
+ Evas *e;\r
+ Widget_Data *wd;\r
+\r
+ wd = ELM_NEW(Widget_Data);\r
+ e = evas_object_evas_get(parent);\r
+ obj = elm_widget_add(e);\r
+ elm_widget_type_set(obj, "wipercontrol");\r
+ elm_widget_sub_object_add(parent, obj);\r
+ elm_widget_data_set(obj, wd);\r
+ elm_widget_del_hook_set(obj, _del_hook);\r
+ elm_widget_theme_hook_set(obj, _theme_hook);\r
+ elm_widget_can_focus_set(obj, 0);\r
+\r
+ wd->sd = edje_object_add(e);\r
+\r
+ _elm_theme_object_set(obj,wd->sd, "wipercontrol", "base", "default");\r
+\r
+ elm_widget_resize_object_set(obj, wd->sd);\r
+\r
+ _sizing_eval(obj);\r
+\r
+ return obj;\r
+}\r
--- /dev/null
+/*
+ *
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include <Elementary.h>
+#include "elm_priv.h"
+
+#define ZC_DEFAULT_RANGE 5
+/**
+ * @defgroup ZoomControls ZoomControls
+ * @ingroup Elementary
+ *
+ * This is a zoomcontrols. Press it and run some function.
+ */
+
+typedef struct _Widget_Data Widget_Data;
+
+struct _Widget_Data
+{
+ Evas_Object *base;
+ int count;
+ int range;
+ int downdefaultstate;
+ int updefaultstate;
+ int downdisabledstate;
+ int updisabledstate;
+ int downdisabledfocusedstate;
+ int updisabledfocusedstate;
+};
+
+
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _disable_hook(Evas_Object *obj);
+static void _sizing_eval(Evas_Object *obj);
+static void _signal_down_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _signal_up_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
+
+static void
+_del_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+ free(wd);
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (!wd) return;
+
+ _elm_theme_object_set(obj, wd->base, "zoomcontrols", "base", elm_widget_style_get(obj));
+ edje_object_message_signal_process(wd->base);
+ edje_object_scale_set(wd->base, elm_widget_scale_get(obj) * _elm_config->scale);
+ _sizing_eval(obj);
+}
+
+static void
+_disable_hook(Evas_Object *obj)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if(wd->downdisabledstate)
+ {
+ edje_object_signal_emit(obj, "elm,state,down,disabled", "elm");
+ }
+ else if(wd->downdefaultstate)
+ {
+ edje_object_signal_emit(wd->base, "elm,state,down,enabled", "elm");
+ }
+
+ if(wd->updisabledstate)
+ {
+ edje_object_signal_emit(obj, "elm,state,up,disabled", "elm");
+ }
+ else if(wd->updefaultstate)
+ {
+ edje_object_signal_emit(wd->base, "elm,state,up,enabled", "elm");
+ }
+}
+
+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;
+ Evas_Coord w, h;
+
+ if (!wd) return;
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ edje_object_size_min_restricted_calc(wd->base, &minw, &minh, minw, minh);
+ elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+
+ evas_object_size_hint_min_get(obj, &w, &h);
+ if (w > minw) minw = w;
+ if (h > minw) minh = h;
+
+ evas_object_size_hint_min_set(obj, minw, minh);
+ evas_object_size_hint_max_set(obj, maxw, maxh);
+}
+
+static void
+_signal_down_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ if (!wd) return;
+
+ if((wd->downdefaultstate == 0) && (wd->downdisabledstate == 1))
+ {
+ return;
+ }
+ else
+ {
+ edje_object_signal_emit(wd->base, "elm,state,down,selected", "elm");
+ }
+
+ if(wd->range <= 0)
+ wd->range = ZC_DEFAULT_RANGE;
+
+ if(wd->count > -(wd->range))
+ {
+ if(wd->count == wd->range)
+ {
+ wd->updisabledstate = 0;
+ wd->updefaultstate = 1;
+ edje_object_signal_emit(wd->base, "elm,state,up,enabled", "elm");
+
+ }
+ wd->count--;
+ printf("smart callback call (down)\n");
+ evas_object_smart_callback_call(data, "down_clicked", NULL);
+ }
+
+ printf("count %d\n", wd->count);
+
+ if(wd->count == -(wd->range))
+ {
+ printf("down disabled \n");
+ wd->downdisabledstate = 1;
+ wd->downdefaultstate = 0;
+ edje_object_signal_emit(wd->base, "elm,state,down,disabled", "elm");
+ }
+}
+static void
+_signal_up_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+ if (!wd) return;
+
+ if((wd->updefaultstate == 0) && (wd->updisabledstate == 1))
+ {
+ return;
+ }
+ else
+ {
+ edje_object_signal_emit(wd->base, "elm,state,up,selected", "elm");
+ }
+
+ if(wd->range <= 0)
+ wd->range = ZC_DEFAULT_RANGE;
+
+ if(wd->count < wd->range)
+ {
+ if(wd->count == -(wd->range))
+ {
+ wd->downdisabledstate = 0;
+ wd->downdefaultstate = 1;
+ edje_object_signal_emit(wd->base, "elm,state,down,enabled", "elm");
+ }
+ wd->count++;
+ printf("smart callback call (up)\n");
+ evas_object_smart_callback_call(data, "up_clicked", NULL);
+
+ }
+
+ printf("count %d\n", wd->count);
+}
+static void
+_signal_down_unclicked(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+
+ if(wd->range <= 0)
+ wd->range = ZC_DEFAULT_RANGE;
+
+ if(wd->count == -(wd->range))
+ {
+ printf("down enabled \n");
+ wd->downdisabledstate = 1;
+ wd->downdefaultstate = 0;
+ edje_object_signal_emit(wd->base, "elm,state,down,disabled", "elm");
+ }
+ else if(wd->count > -(wd->range))
+ {
+ edje_object_signal_emit(wd->base, "elm,state,down,enabled", "elm");
+ }
+}
+static void
+_signal_up_unclicked(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Widget_Data *wd = elm_widget_data_get(data);
+
+ if(wd->range <= 0)
+ wd->range = ZC_DEFAULT_RANGE;
+
+ if(wd->count == wd->range)
+ {
+ printf("up enabled\n");
+ wd->updisabledstate = 1;
+ wd->updefaultstate = 0;
+ edje_object_signal_emit(wd->base, "elm,state,up,disabled", "elm");
+ }
+ else if(wd->count < wd->range)
+ {
+ edje_object_signal_emit(wd->base, "elm,state,up,enabled", "elm");
+ }
+}
+
+/**
+ * Add a new zoomcontrols to the parent
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup ZoomControls
+ */
+EAPI Evas_Object *
+elm_zoomcontrols_add(Evas_Object *parent)
+{
+ Evas_Object *obj;
+ Evas *e;
+ Widget_Data *wd;
+
+ wd = ELM_NEW(Widget_Data);
+ e = evas_object_evas_get(parent);
+ obj = elm_widget_add(e);
+ elm_widget_type_set(obj, "zoomcontrols");
+ 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_disable_hook_set(obj, _disable_hook);
+
+ wd->base = edje_object_add(e);
+ _elm_theme_object_set(obj, wd->base, "zoomcontrols", "base", "default");
+
+ wd->count = 0;
+ wd->range = 0;
+ wd->downdefaultstate = 1;
+ wd->updefaultstate = 1;
+ wd->downdisabledstate = 0;
+ wd->updisabledstate = 0;
+ wd->downdisabledfocusedstate = 0;
+ wd->updisabledfocusedstate = 0;
+
+ edje_object_signal_callback_add(wd->base, "elm,action,down,click", "", _signal_down_clicked, obj);
+ edje_object_signal_callback_add(wd->base, "elm,action,up,click", "", _signal_up_clicked, obj);
+ edje_object_signal_callback_add(wd->base, "elm,action,down,unclick", "", _signal_down_unclicked, obj);
+ edje_object_signal_callback_add(wd->base, "elm,action,up,unclick", "", _signal_up_unclicked, obj);
+
+ elm_widget_resize_object_set(obj, wd->base);
+
+ _sizing_eval(obj);
+ return obj;
+}
+
+/**
+ * Set the range used in the zoomcontrols
+ *
+ * @param obj The zoomcontrols object
+ * @param range The value will limit count that each button of zoomcontrols is clicked
+ *
+ * @ingroup ZoomControls
+ */
+EAPI void
+elm_zoomcontrols_range_set(Evas_Object *obj, int range)
+{
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if(!wd)
+ return;
+
+ if(range <= 0)
+ return;
+
+ wd->range = range;
+}
--- /dev/null
+#include <Elementary.h>
+#include "elm_priv.h"
+#include "els_pan.h"
+#include "els_hor_scroller.h"
+
+#define SMART_NAME "els_hor_scroller"
+#define API_ENTRY Hor_Smart_Data *sd; sd = evas_object_smart_data_get(obj); if ((!obj) || (!sd) || (evas_object_type_get(obj) && strcmp(evas_object_type_get(obj), SMART_NAME)))
+#define INTERNAL_ENTRY Hor_Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return;
+typedef struct _Hor_Smart_Data Hor_Smart_Data;
+
+#define EVTIME 1
+//#define SCROLLDBG 1
+#define SMART_SCROLLER 1
+#define SMART_MOVE_THRESHOLD 100
+
+#ifdef SMART_SCROLLER
+ #define EVENT_Q_MAX 200
+ #define NR_OF_FRAMES 60.0f
+ #define GEOMETRY_TAG "geo"
+ #define DATA_TAG "data"
+ //#define NUMBERS_OF_AVERAGE_QUEUE "NUMBERS_OF_AVERAGE_QUEUE"
+ #define NUMBERS_OF_AVERAGE_QUEUE 4
+#endif
+
+#define ENABLE_MULITPAGE_MOVING 0
+
+struct _Hor_Smart_Data
+{
+ Evas_Coord x, y, w, h;
+
+ Evas_Object *smart_obj;
+ Evas_Object *child_obj;
+ Evas_Object *pan_obj;
+ Evas_Object *edje_obj;
+ Evas_Object *event_obj;
+
+ Elm_Very_Smart_Scroller_Policy hbar_flags, vbar_flags;
+
+ struct {
+ Evas_Coord x, y;
+ Evas_Coord sx, sy;
+ Evas_Coord dx, dy;
+ Evas_Coord bx, by;
+ Evas_Coord ax, ay;
+ Evas_Coord bx0, by0;
+ Evas_Coord b0x, b0y;
+ Evas_Coord b2x, b2y;
+ struct {
+ Evas_Coord x, y;
+ double timestamp;
+ } history[20];
+ double anim_start;
+ double anim_start2;
+ double anim_start3;
+ double onhold_vx, onhold_vy, onhold_tlast, onhold_vxe, onhold_vye;
+ Evas_Coord hold_x, hold_y;
+ Ecore_Timer *hold_animator;
+ Ecore_Animator *onhold_animator;
+ Ecore_Animator *momentum_animator;
+ Ecore_Animator *bounce_x_animator;
+ Ecore_Animator *bounce_y_animator;
+ Evas_Coord locked_x, locked_y;
+ unsigned char now : 1;
+ unsigned char dragged : 1;
+ unsigned char dir_x : 1;
+ unsigned char dir_y : 1;
+ unsigned char dir_none : 1;
+ unsigned char locked : 1;
+ unsigned char bounce_x_hold : 1;
+ unsigned char bounce_y_hold : 1;
+ } down;
+
+ struct {
+ Evas_Coord w, h;
+ } child;
+ struct {
+ Evas_Coord x, y;
+ } step, page;
+
+ struct {
+ void (*set) (Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+ void (*get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+ void (*max_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+ void (*child_size_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+ } pan_func;
+
+ struct {
+ struct {
+ Evas_Coord start, end;
+ double t_start, t_end;
+ Ecore_Animator *animator;
+ } x, y;
+ } scrollto;
+
+ double pagerel_h, pagerel_v;
+ Evas_Coord pagesize_h, pagesize_v;
+
+ unsigned char hbar_visible : 1;
+ unsigned char vbar_visible : 1;
+ unsigned char extern_pan : 1;
+ unsigned char one_dir_at_a_time : 1;
+ unsigned char hold : 1;
+ unsigned char freeze : 1;
+ unsigned char bouncemex : 1;
+ unsigned char bouncemey : 1;
+ unsigned char bounce_horiz : 1;
+ unsigned char bounce_vert : 1;
+
+#ifdef SMART_SCROLLER
+ int event_queue[EVENT_Q_MAX];
+ int consumer_queue[EVENT_Q_MAX];
+ int producer;
+ int resaler;
+ int consumer;
+ int status;
+ int pprev_x;
+ int prev_x;
+ int cur_x;
+ int total_width;
+ int special_prev_x;
+ int special_cur_x;
+ int resaler_continue;
+ int move_cnt;
+ int x_pos;
+ int done;
+ Ecore_Timer *timer;
+ Ecore_Timer *special_timer;
+#endif
+};
+
+/* local subsystem functions */
+static void _smart_child_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _smart_pan_changed_hook(void *data, Evas_Object *obj, void *event_info);
+static void _smart_pan_pan_changed_hook(void *data, Evas_Object *obj, void *event_info);
+static void _smart_event_wheel(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _smart_event_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static Eina_Bool _smart_hold_animator(void *data);
+static Eina_Bool _smart_momentum_animator(void *data);
+static void _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static Eina_Bool _smart_onhold_animator(void *data);
+static void _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _smart_event_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _smart_edje_drag_v_start(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _smart_edje_drag_v_stop(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _smart_edje_drag_v(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _smart_edje_drag_h_start(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _smart_edje_drag_h_stop(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _smart_edje_drag_h(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _smart_scrollbar_read(Hor_Smart_Data *sd);
+static void _smart_scrollbar_reset(Hor_Smart_Data *sd);
+static int _smart_scrollbar_bar_h_visibility_adjust(Hor_Smart_Data *sd);
+static int _smart_scrollbar_bar_v_visibility_adjust(Hor_Smart_Data *sd);
+static void _smart_scrollbar_bar_visibility_adjust(Hor_Smart_Data *sd);
+static void _smart_scrollbar_size_adjust(Hor_Smart_Data *sd);
+static void _smart_reconfigure(Hor_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);
+static void _smart_init(void);
+
+/* local subsystem globals */
+static Evas_Smart *_smart = NULL;
+
+/* externally accessible functions */
+Evas_Object *
+hor_elm_smart_scroller_add(Evas *evas)
+{
+ _smart_init();
+ return evas_object_smart_add(evas, _smart);
+}
+
+void
+hor_elm_smart_scroller_child_set(Evas_Object *obj, Evas_Object *child)
+{
+ Evas_Coord w, h;
+ Evas_Object *o;
+
+ API_ENTRY return;
+ if (sd->child_obj)
+ {
+ _elm_smart_pan_child_set(sd->pan_obj, NULL);
+ evas_object_event_callback_del_full(sd->child_obj, EVAS_CALLBACK_DEL, _smart_child_del_hook, sd);
+ }
+
+ sd->child_obj = child;
+ if (!child) return;
+
+ if (!sd->pan_obj)
+ {
+ o = _elm_smart_pan_add(evas_object_evas_get(obj));
+ sd->pan_obj = o;
+ evas_object_smart_callback_add(o, "changed", _smart_pan_changed_hook, sd);
+ evas_object_smart_callback_add(o, "pan_changed", _smart_pan_pan_changed_hook, sd);
+ evas_object_show(o);
+ edje_object_part_swallow(sd->edje_obj, "elm.swallow.content", o);
+ }
+
+ sd->pan_func.set = _elm_smart_pan_set;
+ sd->pan_func.get = _elm_smart_pan_get;
+ sd->pan_func.max_get = _elm_smart_pan_max_get;
+ sd->pan_func.child_size_get = _elm_smart_pan_child_size_get;
+
+ evas_object_event_callback_add(child, EVAS_CALLBACK_DEL, _smart_child_del_hook, sd);
+ _elm_smart_pan_child_set(sd->pan_obj, sd->child_obj);
+ sd->pan_func.child_size_get(sd->pan_obj, &w, &h);
+ sd->child.w = w;
+ sd->child.h = h;
+ _smart_scrollbar_size_adjust(sd);
+ _smart_scrollbar_reset(sd);
+}
+
+void
+hor_elm_smart_scroller_extern_pan_set(Evas_Object *obj, Evas_Object *pan,
+ void (*pan_set) (Evas_Object *obj, Evas_Coord x, Evas_Coord y),
+ void (*pan_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y),
+ void (*pan_max_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y),
+ void (*pan_child_size_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y))
+{
+ API_ENTRY return;
+
+ hor_elm_smart_scroller_child_set(obj, NULL);
+ if (sd->extern_pan)
+ {
+ if (sd->pan_obj)
+ {
+ edje_object_part_unswallow(sd->edje_obj, sd->pan_obj);
+ sd->pan_obj = NULL;
+ }
+ }
+ else
+ {
+ if (sd->pan_obj)
+ {
+ evas_object_del(sd->pan_obj);
+ sd->pan_obj = NULL;
+ }
+ }
+ if (!pan)
+ {
+ sd->extern_pan = 0;
+ return;
+ }
+
+ sd->pan_obj = pan;
+ sd->pan_func.set = pan_set;
+ sd->pan_func.get = pan_get;
+ sd->pan_func.max_get = pan_max_get;
+ sd->pan_func.child_size_get = pan_child_size_get;
+ sd->extern_pan = 1;
+ evas_object_smart_callback_add(sd->pan_obj, "changed", _smart_pan_changed_hook, sd);
+ evas_object_smart_callback_add(sd->pan_obj, "pan_changed", _smart_pan_pan_changed_hook, sd);
+ edje_object_part_swallow(sd->edje_obj, "elm.swallow.content", sd->pan_obj);
+ evas_object_show(sd->pan_obj);
+}
+
+void
+hor_elm_smart_scroller_custom_edje_file_set(Evas_Object *obj, char *file, char *group)
+{
+ API_ENTRY return;
+
+ edje_object_file_set(sd->edje_obj, file, group);
+ if (sd->pan_obj)
+ edje_object_part_swallow(sd->edje_obj, "elm.swallow.content", sd->pan_obj);
+ sd->vbar_visible = !sd->vbar_visible;
+ sd->hbar_visible = !sd->hbar_visible;
+ _smart_scrollbar_bar_visibility_adjust(sd);
+ if (sd->hbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_ON)
+ edje_object_signal_emit(sd->edje_obj, "elm,action,show_always,hbar", "elm");
+ else if (sd->hbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_OFF)
+ edje_object_signal_emit(sd->edje_obj, "elm,action,hide,hbar", "elm");
+ else
+ edje_object_signal_emit(sd->edje_obj, "elm,action,show_notalways,hbar", "elm");
+ if (sd->vbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_ON)
+ edje_object_signal_emit(sd->edje_obj, "elm,action,show_always,vbar", "elm");
+ else if (sd->vbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_OFF)
+ edje_object_signal_emit(sd->edje_obj, "elm,action,hide,vbar", "elm");
+ else
+ edje_object_signal_emit(sd->edje_obj, "elm,action,show_notalways,vbar", "elm");
+}
+
+static void
+_smart_anim_start(Evas_Object *obj)
+{
+ evas_object_smart_callback_call(obj, "animate,start", NULL);
+}
+
+static void
+_smart_anim_stop(Evas_Object *obj)
+{
+ evas_object_smart_callback_call(obj, "animate,stop", NULL);
+}
+
+static void
+_smart_drag_start(Evas_Object *obj)
+{
+ evas_object_smart_callback_call(obj, "drag,start", NULL);
+}
+
+static void
+_smart_drag_stop(Evas_Object *obj)
+{
+ evas_object_smart_callback_call(obj, "drag,stop", NULL);
+}
+
+static Eina_Bool
+_smart_scrollto_x_animator(void *data)
+{
+ Hor_Smart_Data *sd = data;
+ Evas_Coord px, py;
+ double t, tt;
+
+ t = ecore_loop_time_get();
+ tt = (t - sd->scrollto.x.t_start) / (sd->scrollto.x.t_end - sd->scrollto.x.t_start);
+ tt = 1.0 - tt;
+ tt = 1.0 - (tt * tt);
+ sd->pan_func.get(sd->pan_obj, &px, &py);
+ px = (sd->scrollto.x.start * (1.0 - tt)) +
+ (sd->scrollto.x.end * tt);
+ if (t >= sd->scrollto.x.t_end)
+ {
+ px = sd->scrollto.x.end;
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, px, py);
+ sd->scrollto.x.animator = NULL;
+ if (!sd->scrollto.y.animator)
+ _smart_anim_stop(sd->smart_obj);
+ return 0;
+ }
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, px, py);
+ return 1;
+}
+
+static void
+_smart_scrollto_x(Hor_Smart_Data *sd, double t_in, Evas_Coord pos_x)
+{
+ Evas_Coord px, py, x, y, w, h;
+ double t;
+
+ if (sd->freeze) return;
+ if (t_in <= 0.0)
+ {
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ hor_elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+ x = pos_x;
+ hor_elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
+ return;
+ }
+ t = ecore_loop_time_get();
+ sd->pan_func.get(sd->pan_obj, &px, &py);
+ sd->scrollto.x.start = px;
+ sd->scrollto.x.end = pos_x;
+ sd->scrollto.x.t_start = t;
+ sd->scrollto.x.t_end = t + t_in;
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ hor_elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+ hor_elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
+ if (!sd->scrollto.x.animator)
+ {
+ if (!sd->scrollto.y.animator)
+ _smart_anim_start(sd->smart_obj);
+ sd->scrollto.x.animator = ecore_animator_add(_smart_scrollto_x_animator, sd);
+ }
+ if (sd->down.bounce_x_animator)
+ {
+ ecore_animator_del(sd->down.bounce_x_animator);
+ sd->down.bounce_x_animator = NULL;
+ }
+ sd->bouncemex = 0;
+}
+
+static Eina_Bool
+_smart_scrollto_y_animator(void *data)
+{
+ Hor_Smart_Data *sd = data;
+ Evas_Coord px, py;
+ double t, tt;
+
+ t = ecore_loop_time_get();
+ tt = (t - sd->scrollto.y.t_start) / (sd->scrollto.y.t_end - sd->scrollto.y.t_start);
+ tt = 1.0 - tt;
+ tt = 1.0 - (tt * tt);
+ sd->pan_func.get(sd->pan_obj, &px, &py);
+ py = (sd->scrollto.y.start * (1.0 - tt)) +
+ (sd->scrollto.y.end * tt);
+ if (t >= sd->scrollto.y.t_end)
+ {
+ py = sd->scrollto.y.end;
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, px, py);
+ sd->scrollto.y.animator = NULL;
+ if (!sd->scrollto.x.animator)
+ _smart_anim_stop(sd->smart_obj);
+ return 0;
+ }
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, px, py);
+
+ return 1;
+}
+
+static void
+_smart_scrollto_y(Hor_Smart_Data *sd, double t_in, Evas_Coord pos_y)
+{
+ Evas_Coord px, py, x, y, w, h;
+ double t;
+
+ if (sd->freeze) return;
+ if (t_in <= 0.0)
+ {
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ hor_elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+ y = pos_y;
+ hor_elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
+ return;
+ }
+ t = ecore_loop_time_get();
+ sd->pan_func.get(sd->pan_obj, &px, &py);
+ sd->scrollto.y.start = py;
+ sd->scrollto.y.end = pos_y;
+ sd->scrollto.y.t_start = t;
+ sd->scrollto.y.t_end = t + t_in;
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ hor_elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+ hor_elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
+ if (!sd->scrollto.y.animator)
+ {
+ if (!sd->scrollto.x.animator)
+ _smart_anim_start(sd->smart_obj);
+ sd->scrollto.y.animator = ecore_animator_add(_smart_scrollto_y_animator, sd);
+ }
+ if (sd->down.bounce_y_animator)
+ {
+ ecore_animator_del(sd->down.bounce_y_animator);
+ sd->down.bounce_y_animator = NULL;
+ }
+ sd->bouncemey = 0;
+}
+
+static Eina_Bool
+_smart_do_page(Hor_Smart_Data *sd)
+{
+ if ((sd->pagerel_h == 0.0) && (sd->pagesize_h == 0) &&
+ (sd->pagerel_v == 0.0) && (sd->pagesize_v == 0))
+ return 0;
+ return 1;
+}
+
+static Evas_Coord
+_smart_page_x_get(Hor_Smart_Data *sd, int offset)
+{
+ Evas_Coord x, y, w, h, cw, ch;
+
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ hor_elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+ sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch);
+
+// HERE:: One-page moving
+#if 0
+ printf("before offset : %d, x : %d\n", offset, x);
+ if (offset > 0)
+ {
+ x = x + (sd->pagesize_h);
+ x = x / (sd->pagesize_h);
+ x = x * (sd->pagesize_h);
+ }
+ else if (offset < 0)
+ {
+ if ((x % sd->pagesize_h) == 0) x -= (sd->pagesize_h / 2);
+ x = x / (sd->pagesize_h);
+ x = x * (sd->pagesize_h);
+ }
+ else
+ {
+ printf("offset = 0 -----> cur_x - prev_x [%d]\n", sd->cur_x - sd->prev_x);
+ if (sd->cur_x - sd->prev_x < 0) x += (sd->pagesize_h);
+ else if (sd->cur_x - sd->prev_x > 0) x -= (sd->pagesize_h) / 2;
+ x = x / (sd->pagesize_h);
+ x = x * (sd->pagesize_h);
+ }
+#endif
+
+ x += offset;
+
+ if (sd->pagerel_h > 0.0)
+ {
+ x = x + (w * sd->pagerel_h * 0.5);
+ x = x / (w * sd->pagerel_h);
+ x = x * (w * sd->pagerel_h);
+ }
+ else if (sd->pagesize_h > 0)
+ {
+ x = x + (sd->pagesize_h * 0.5);
+ x = x / (sd->pagesize_h);
+ x = x * (sd->pagesize_h);
+ }
+ if (x < 0) x = 0;
+ else if ((x + w) > cw) x = cw - w;
+ return x;
+}
+
+static Evas_Coord
+_smart_page_y_get(Hor_Smart_Data *sd, int offset)
+{
+ Evas_Coord x, y, w, h, cw, ch;
+
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ hor_elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+ sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch);
+
+ y += offset;
+
+ if (sd->pagerel_v > 0.0)
+ {
+ y = y + (h * sd->pagerel_v * 0.5);
+ y = y / (h * sd->pagerel_v);
+ y = y * (h * sd->pagerel_v);
+ }
+ else if (sd->pagesize_v > 0)
+ {
+ y = y + (sd->pagesize_v * 0.5);
+ y = y / (sd->pagesize_v);
+ y = y * (sd->pagesize_v);
+ }
+ if (y < 0) y = 0;
+ else if ((y + h) > ch) y = ch - h;
+ return y;
+}
+
+static void
+_smart_page_adjust(Hor_Smart_Data *sd)
+{
+ Evas_Coord x, y, w, h;
+
+ if (!_smart_do_page(sd)) return;
+
+ hor_elm_smart_scroller_child_viewport_size_get(sd->smart_obj, &w, &h);
+
+ x = _smart_page_x_get(sd, 0);
+ y = _smart_page_y_get(sd, 0);
+
+ hor_elm_smart_scroller_child_region_show(sd->smart_obj, x, y, w, h);
+}
+
+static Eina_Bool
+_smart_bounce_x_animator(void *data)
+{
+ Hor_Smart_Data *sd;
+ Evas_Coord x, y, dx;
+ double t, p, dt;
+
+ sd = data;
+ t = ecore_loop_time_get();
+ dt = t - sd->down.anim_start2;
+ if (dt >= 0.0)
+ {
+ dt = dt / _elm_config->thumbscroll_bounce_friction;
+ if (dt > 1.0) dt = 1.0;
+ p = 1.0 - ((1.0 - dt) * (1.0 - dt));
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ dx = sd->down.b2x - sd->down.bx;
+ dx = (dx * p);
+ x = sd->down.bx + dx;
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+ if (dt >= 1.0)
+ {
+ if (sd->down.momentum_animator)
+ sd->down.bounce_x_hold = 1;
+ sd->down.bounce_x_animator = NULL;
+ sd->bouncemex = 0;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static Eina_Bool
+_smart_bounce_y_animator(void *data)
+{
+ Hor_Smart_Data *sd;
+ Evas_Coord x, y, dy;
+ double t, p, dt;
+
+ sd = data;
+ t = ecore_loop_time_get();
+ dt = t - sd->down.anim_start3;
+ if (dt >= 0.0)
+ {
+ dt = dt / _elm_config->thumbscroll_bounce_friction;
+ if (dt > 1.0) dt = 1.0;
+ p = 1.0 - ((1.0 - dt) * (1.0 - dt));
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ dy = sd->down.b2y - sd->down.by;
+ dy = (dy * p);
+ y = sd->down.by + dy;
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+ if (dt >= 1.0)
+ {
+ if (sd->down.momentum_animator)
+ sd->down.bounce_y_hold = 1;
+ sd->down.bounce_y_animator = NULL;
+ sd->bouncemey = 0;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static Eina_Bool
+_smart_momentum_animator(void *data)
+{
+ Hor_Smart_Data *sd;
+ double t, dt, p;
+ Evas_Coord x, y, dx, dy, px, py;
+
+ sd = data;
+ t = ecore_loop_time_get();
+ dt = t - sd->down.anim_start;
+ if (dt >= 0.0)
+ {
+ dt = dt / _elm_config->thumbscroll_friction;
+ if (dt > 1.0) dt = 1.0;
+ p = 1.0 - ((1.0 - dt) * (1.0 - dt));
+ dx = (sd->down.dx * _elm_config->thumbscroll_friction * p);
+ dy = (sd->down.dy * _elm_config->thumbscroll_friction * p);
+ sd->down.ax = dx;
+ sd->down.ay = dy;
+ x = sd->down.sx - dx;
+ y = sd->down.sy - dy;
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &px, &py);
+ if ((sd->down.bounce_x_animator) ||
+ (sd->down.bounce_x_hold))
+ {
+ sd->down.bx = sd->down.bx0 - dx + sd->down.b0x;
+ x = px;
+ }
+ if ((sd->down.bounce_y_animator) ||
+ (sd->down.bounce_y_hold))
+ {
+ sd->down.by = sd->down.by0 - dy + sd->down.b0y;
+ y = py;
+ }
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+ if (dt >= 1.0)
+ {
+ _smart_anim_stop(sd->smart_obj);
+ sd->down.momentum_animator = NULL;
+ sd->down.bounce_x_hold = 0;
+ sd->down.bounce_y_hold = 0;
+ sd->down.ax = 0;
+ sd->down.ay = 0;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void
+bounce_eval(Hor_Smart_Data *sd)
+{
+ Evas_Coord mx, my, px, py, bx, by, b2x, b2y;
+
+ if (sd->freeze) return;
+ if ((!sd->bouncemex) && (!sd->bouncemey)) return;
+ if (sd->down.now) return; // down bounce while still held down
+ if (sd->down.onhold_animator)
+ {
+ ecore_animator_del(sd->down.onhold_animator);
+ sd->down.onhold_animator = NULL;
+ }
+ if (sd->down.hold_animator)
+ {
+ ecore_timer_del(sd->down.hold_animator);
+ sd->down.hold_animator = NULL;
+ }
+ sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+ sd->pan_func.get(sd->pan_obj, &px, &py);
+ bx = px;
+ by = py;
+ if (px < 0) px = 0;
+ if (px > mx) px = mx;
+ if (py < 0) py = 0;
+ if (py > my) py = my;
+ b2x = px;
+ b2y = py;
+ if (!sd->down.bounce_x_animator)
+ {
+ if (sd->bouncemex)
+ {
+ if (sd->scrollto.x.animator)
+ {
+ ecore_animator_del(sd->scrollto.x.animator);
+ sd->scrollto.x.animator = NULL;
+ }
+ sd->down.bounce_x_animator = ecore_animator_add(_smart_bounce_x_animator, sd);
+ sd->down.anim_start2 = ecore_loop_time_get();
+ sd->down.bx = bx;
+ sd->down.bx0 = bx;
+ sd->down.b2x = b2x;
+ if (sd->down.momentum_animator) sd->down.b0x = sd->down.ax;
+ else sd->down.b0x = 0;
+ }
+ }
+ if (!sd->down.bounce_y_animator)
+ {
+ if (sd->bouncemey)
+ {
+ if (sd->scrollto.y.animator)
+ {
+ ecore_animator_del(sd->scrollto.y.animator);
+ sd->scrollto.y.animator = NULL;
+ }
+ sd->down.bounce_y_animator = ecore_animator_add(_smart_bounce_y_animator, sd);
+ sd->down.anim_start3 = ecore_loop_time_get();
+ sd->down.by = by;
+ sd->down.by0 = by;
+ sd->down.b2y = b2y;
+ if (sd->down.momentum_animator) sd->down.b0y = sd->down.ay;
+ else sd->down.b0y = 0;
+ }
+ }
+}
+
+void
+hor_elm_smart_scroller_child_pos_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+ Evas_Coord mx = 0, my = 0, px, py;
+ double vx, vy;
+
+ API_ENTRY return;
+ // FIXME: allow for bounce outside of range
+ sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+ if (mx > 0) vx = (double)x / (double)mx;
+ else vx = 0.0;
+ if (vx < 0.0) vx = 0.0;
+ else if (vx > 1.0) vx = 1.0;
+ if (my > 0) vy = (double)y / (double)my;
+ else vy = 0.0;
+ if (vy < 0.0) vy = 0.0;
+ else if (vy > 1.0) vy = 1.0;
+ edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.vbar", 0.0, vy);
+ edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.hbar", vx, 0.0);
+ sd->pan_func.get(sd->pan_obj, &px, &py);
+ if (!_elm_config->thumbscroll_bounce_enable)
+ {
+ if (x < 0) x = 0;
+ if (x > mx) x = mx;
+ if (y < 0) y = 0;
+ if (y > my) y = my;
+ }
+
+ if (!sd->bounce_horiz)
+ {
+ if (x < 0) x = 0;
+ if (x > mx) x = mx;
+ }
+ if (!sd->bounce_vert)
+ {
+ if (y < 0) y = 0;
+ if (y > my) y = my;
+ }
+
+ sd->pan_func.set(sd->pan_obj, x, y);
+ if ((px != x) || (py != y))
+ edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm");
+ if (!sd->down.bounce_x_animator)
+ {
+ if ((x < 0) || (x > mx))
+ {
+ sd->bouncemex = 1;
+ bounce_eval(sd);
+ }
+ }
+ if (!sd->down.bounce_y_animator)
+ {
+ if ((y < 0) || (y > my))
+ {
+ sd->bouncemey = 1;
+ bounce_eval(sd);
+ }
+ }
+ if ((x != px) || (y != py))
+ {
+ evas_object_smart_callback_call(obj, "scroll", NULL);
+ }
+ if ((x != px)/* && (!sd->bouncemex)*/)
+ {
+ if (x == 0)
+ evas_object_smart_callback_call(obj, "edge,left", NULL);
+ if (x == mx)
+ evas_object_smart_callback_call(obj, "edge,right", NULL);
+ }
+ if ((y != py)/* && (!sd->bouncemey)*/)
+ {
+ if (y == 0)
+ evas_object_smart_callback_call(obj, "edge,top", NULL);
+ if (y == my)
+ evas_object_smart_callback_call(obj, "edge,bottom", NULL);
+ }
+}
+
+void
+hor_elm_smart_scroller_child_pos_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+ API_ENTRY return;
+ sd->pan_func.get(sd->pan_obj, x, y);
+}
+
+void
+hor_elm_smart_scroller_child_region_show(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
+{
+ Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny;
+
+ API_ENTRY return;
+ sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+ sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch);
+ sd->pan_func.get(sd->pan_obj, &px, &py);
+
+ nx = px;
+ if (x < px) nx = x;
+ else if ((x + w) > (px + (cw - mx)))
+ {
+ nx = x + w - (cw - mx);
+ if (nx > x) nx = x;
+ }
+ ny = py;
+ if (y < py) ny = y;
+ else if ((y + h) > (py + (ch - my)))
+ {
+ ny = y + h - (ch - my);
+ if (ny > y) ny = y;
+ }
+ if ((nx == px) && (ny == py)) return;
+ if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+ (sd->scrollto.x.animator) || (sd->scrollto.y.animator))
+ {
+ _smart_anim_stop(sd->smart_obj);
+ }
+ if (sd->scrollto.x.animator)
+ {
+ ecore_animator_del(sd->scrollto.x.animator);
+ sd->scrollto.x.animator = NULL;
+ }
+ if (sd->scrollto.y.animator)
+ {
+ ecore_animator_del(sd->scrollto.y.animator);
+ sd->scrollto.y.animator = NULL;
+ }
+ if (sd->down.bounce_x_animator)
+ {
+ ecore_animator_del(sd->down.bounce_x_animator);
+ sd->down.bounce_x_animator = NULL;
+ sd->bouncemex = 0;
+ }
+ if (sd->down.bounce_y_animator)
+ {
+ ecore_animator_del(sd->down.bounce_y_animator);
+ sd->down.bounce_y_animator = NULL;
+ sd->bouncemey = 0;
+ }
+ if (sd->down.hold_animator)
+ {
+ ecore_timer_del(sd->down.hold_animator);
+ sd->down.hold_animator = NULL;
+ _smart_drag_stop(sd->smart_obj);
+ }
+ if (sd->down.momentum_animator)
+ {
+ ecore_animator_del(sd->down.momentum_animator);
+ sd->down.momentum_animator = NULL;
+ sd->down.bounce_x_hold = 0;
+ sd->down.bounce_y_hold = 0;
+ sd->down.ax = 0;
+ sd->down.ay = 0;
+ }
+ hor_elm_smart_scroller_child_pos_set(obj, nx, ny);
+}
+
+void
+hor_elm_smart_scroller_child_viewport_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+ API_ENTRY return;
+ edje_object_calc_force(sd->edje_obj);
+ evas_object_geometry_get(sd->pan_obj, NULL, NULL, w, h);
+}
+
+void
+hor_elm_smart_scroller_step_size_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+ API_ENTRY return;
+ if (x < 1) x = 1;
+ if (y < 1) y = 1;
+ sd->step.x = x;
+ sd->step.y = y;
+ _smart_scrollbar_size_adjust(sd);
+}
+
+void
+hor_elm_smart_scroller_step_size_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+ API_ENTRY return;
+ if (x) *x = sd->step.x;
+ if (y) *y = sd->step.y;
+}
+
+void
+hor_elm_smart_scroller_page_size_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+ API_ENTRY return;
+ sd->page.x = x;
+ sd->page.y = y;
+ _smart_scrollbar_size_adjust(sd);
+}
+
+void
+hor_elm_smart_scroller_page_size_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
+{
+ API_ENTRY return;
+ if (x) *x = sd->page.x;
+ if (y) *y = sd->page.y;
+}
+
+void
+hor_elm_smart_scroller_policy_set(Evas_Object *obj, Elm_Very_Smart_Scroller_Policy hbar, Elm_Very_Smart_Scroller_Policy vbar)
+{
+ API_ENTRY return;
+ if ((sd->hbar_flags == hbar) && (sd->vbar_flags == vbar)) return;
+ sd->hbar_flags = hbar;
+ sd->vbar_flags = vbar;
+ if (sd->hbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_ON)
+ edje_object_signal_emit(sd->edje_obj, "elm,action,show_always,hbar", "elm");
+ else if (sd->hbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_OFF)
+ edje_object_signal_emit(sd->edje_obj, "elm,action,hide,hbar", "elm");
+ else
+ edje_object_signal_emit(sd->edje_obj, "elm,action,show_notalways,hbar", "elm");
+ if (sd->vbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_ON)
+ edje_object_signal_emit(sd->edje_obj, "elm,action,show_always,vbar", "elm");
+ else if (sd->vbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_OFF)
+ edje_object_signal_emit(sd->edje_obj, "elm,action,hide,vbar", "elm");
+ else
+ edje_object_signal_emit(sd->edje_obj, "elm,action,show_notalways,vbar", "elm");
+ _smart_scrollbar_size_adjust(sd);
+}
+
+void
+hor_elm_smart_scroller_policy_get(Evas_Object *obj, Elm_Very_Smart_Scroller_Policy *hbar, Elm_Very_Smart_Scroller_Policy *vbar)
+{
+ API_ENTRY return;
+ if (hbar) *hbar = sd->hbar_flags;
+ if (vbar) *vbar = sd->vbar_flags;
+}
+
+Evas_Object *
+hor_elm_smart_scroller_edje_object_get(Evas_Object *obj)
+{
+ API_ENTRY return NULL;
+ return sd->edje_obj;
+}
+
+void
+hor_elm_smart_scroller_single_dir_set(Evas_Object *obj, Eina_Bool single_dir)
+{
+ API_ENTRY return;
+ sd->one_dir_at_a_time = single_dir;
+}
+
+Eina_Bool
+hor_elm_smart_scroller_single_dir_get(Evas_Object *obj)
+{
+ API_ENTRY return EINA_FALSE;
+ return sd->one_dir_at_a_time;
+}
+
+void
+hor_elm_smart_scroller_theme_set(Evas_Object *parent, Evas_Object *obj, const char *clas, const char *group, const char *style)
+{
+ API_ENTRY return;
+ _elm_theme_object_set(parent, sd->edje_obj, clas, group, style);
+ if (sd->pan_obj)
+ edje_object_part_swallow(sd->edje_obj, "elm.swallow.content", sd->pan_obj);
+ sd->vbar_visible = !sd->vbar_visible;
+ sd->hbar_visible = !sd->hbar_visible;
+ _smart_scrollbar_bar_visibility_adjust(sd);
+}
+
+void
+hor_elm_smart_scroller_hold_set(Evas_Object *obj, Eina_Bool hold)
+{
+ API_ENTRY return;
+ sd->hold = hold;
+}
+
+void
+hor_elm_smart_scroller_freeze_set(Evas_Object *obj, Eina_Bool freeze)
+{
+ API_ENTRY return;
+ sd->freeze = freeze;
+ if (sd->freeze)
+ {
+ if (sd->down.onhold_animator)
+ {
+ ecore_animator_del(sd->down.onhold_animator);
+ sd->down.onhold_animator = NULL;
+ }
+ }
+}
+
+void
+hor_elm_smart_scroller_bounce_allow_set(Evas_Object *obj, Eina_Bool horiz, Eina_Bool vert)
+{
+ API_ENTRY return;
+ sd->bounce_horiz = horiz;
+ sd->bounce_vert = vert;
+}
+
+void
+hor_elm_smart_scroller_paging_set(Evas_Object *obj, double pagerel_h, double pagerel_v, Evas_Coord pagesize_h, Evas_Coord pagesize_v)
+{
+ API_ENTRY return;
+ sd->pagerel_h = pagerel_h;
+ sd->pagerel_v = pagerel_v;
+ sd->pagesize_h = pagesize_h;
+ sd->pagesize_v = pagesize_v;
+ _smart_page_adjust(sd);
+}
+
+void
+hor_elm_smart_scroller_region_bring_in(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
+{
+ Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny;
+
+ API_ENTRY return;
+ sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+ sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch);
+ sd->pan_func.get(sd->pan_obj, &px, &py);
+
+ nx = px;
+ if (x < px) nx = x;
+ else if ((x + w) > (px + (cw - mx)))
+ {
+ nx = x + w - (cw - mx);
+ if (nx > x) nx = x;
+ }
+ ny = py;
+ if (y < py) ny = y;
+ else if ((y + h) > (py + (ch - my)))
+ {
+ ny = y + h - (ch - my);
+ if (ny > y) ny = y;
+ }
+ if ((nx == px) && (ny == py)) return;
+ if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+ (sd->scrollto.x.animator) || (sd->scrollto.y.animator))
+ {
+ _smart_anim_stop(sd->smart_obj);
+ }
+ if (sd->scrollto.x.animator)
+ {
+ ecore_animator_del(sd->scrollto.x.animator);
+ sd->scrollto.x.animator = NULL;
+ }
+ if (sd->scrollto.y.animator)
+ {
+ ecore_animator_del(sd->scrollto.y.animator);
+ sd->scrollto.y.animator = NULL;
+ }
+ if (sd->down.bounce_x_animator)
+ {
+ ecore_animator_del(sd->down.bounce_x_animator);
+ sd->down.bounce_x_animator = NULL;
+ sd->bouncemex = 0;
+ }
+ if (sd->down.bounce_y_animator)
+ {
+ ecore_animator_del(sd->down.bounce_y_animator);
+ sd->down.bounce_y_animator = NULL;
+ sd->bouncemey = 0;
+ }
+ if (sd->down.hold_animator)
+ {
+ ecore_timer_del(sd->down.hold_animator);
+ sd->down.hold_animator = NULL;
+ _smart_drag_stop(sd->smart_obj);
+ }
+ if (sd->down.momentum_animator)
+ {
+ ecore_animator_del(sd->down.momentum_animator);
+ sd->down.momentum_animator = NULL;
+ sd->down.bounce_x_hold = 0;
+ sd->down.bounce_y_hold = 0;
+ sd->down.ax = 0;
+ sd->down.ay = 0;
+ }
+ x = nx;
+ if (x < 0) x = 0;
+ else if ((x + w) > cw) x = cw - w;
+ _smart_scrollto_x(sd, _elm_config->bring_in_scroll_friction, x);
+ y = ny;
+ if (y < 0) y = 0;
+ else if ((y + h) > ch) y = ch - h;
+ _smart_scrollto_y(sd, _elm_config->bring_in_scroll_friction, y);
+}
+
+/* local subsystem functions */
+static void
+_smart_edje_drag_v_start(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Hor_Smart_Data *sd;
+
+ sd = data;
+ _smart_scrollbar_read(sd);
+ _smart_drag_start(sd->smart_obj);
+}
+
+static void
+_smart_edje_drag_v_stop(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Hor_Smart_Data *sd;
+
+ sd = data;
+ _smart_scrollbar_read(sd);
+ _smart_drag_stop(sd->smart_obj);
+}
+
+static void
+_smart_edje_drag_v(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Hor_Smart_Data *sd;
+
+ sd = data;
+ _smart_scrollbar_read(sd);
+}
+
+static void
+_smart_edje_drag_h_start(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Hor_Smart_Data *sd;
+
+ sd = data;
+ _smart_scrollbar_read(sd);
+ _smart_drag_start(sd->smart_obj);
+}
+
+static void
+_smart_edje_drag_h_stop(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Hor_Smart_Data *sd;
+
+ sd = data;
+ _smart_scrollbar_read(sd);
+ _smart_drag_stop(sd->smart_obj);
+}
+
+static void
+_smart_edje_drag_h(void *data, Evas_Object *obj, const char *emission, const char *source)
+{
+ Hor_Smart_Data *sd;
+
+ sd = data;
+ _smart_scrollbar_read(sd);
+}
+
+static void
+_smart_child_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Hor_Smart_Data *sd;
+
+ sd = data;
+ sd->child_obj = NULL;
+ _smart_scrollbar_size_adjust(sd);
+ _smart_scrollbar_reset(sd);
+}
+
+static void
+_smart_pan_changed_hook(void *data, Evas_Object *obj, void *event_info)
+{
+ Evas_Coord x, y;
+ Evas_Coord w, h;
+ Hor_Smart_Data *sd;
+
+ sd = data;
+ sd->pan_func.get(sd->pan_obj, &x, &y);
+ sd->pan_func.child_size_get(sd->pan_obj, &w, &h);
+ if ((w != sd->child.w) || (h != sd->child.h))
+ {
+ sd->child.w = w;
+ sd->child.h = h;
+ _smart_scrollbar_size_adjust(sd);
+ evas_object_size_hint_min_set(sd->smart_obj, sd->child.w, sd->child.h);
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+ }
+}
+
+static void
+_smart_pan_pan_changed_hook(void *data, Evas_Object *obj, void *event_info)
+{
+ Evas_Coord x, y;
+ Hor_Smart_Data *sd;
+
+ sd = data;
+ sd->pan_func.get(sd->pan_obj, &x, &y);
+ if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+ (sd->scrollto.x.animator) || (sd->scrollto.y.animator))
+ {
+ _smart_anim_stop(sd->smart_obj);
+ }
+ if (sd->scrollto.x.animator)
+ {
+ ecore_animator_del(sd->scrollto.x.animator);
+ sd->scrollto.x.animator = NULL;
+ }
+ if (sd->scrollto.y.animator)
+ {
+ ecore_animator_del(sd->scrollto.y.animator);
+ sd->scrollto.y.animator = NULL;
+ }
+ if (sd->down.bounce_x_animator)
+ {
+ ecore_animator_del(sd->down.bounce_x_animator);
+ sd->down.bounce_x_animator = NULL;
+ sd->bouncemex = 0;
+ }
+ if (sd->down.bounce_y_animator)
+ {
+ ecore_animator_del(sd->down.bounce_y_animator);
+ sd->down.bounce_y_animator = NULL;
+ sd->bouncemey = 0;
+ }
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+}
+
+static void
+_smart_event_wheel(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Wheel *ev;
+ Hor_Smart_Data *sd;
+ Evas_Coord x = 0, y = 0;
+
+ sd = data;
+ ev = event_info;
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+ if (evas_key_modifier_is_set(ev->modifiers, "Control") ||
+ evas_key_modifier_is_set(ev->modifiers, "Alt") ||
+ evas_key_modifier_is_set(ev->modifiers, "Shift") ||
+ evas_key_modifier_is_set(ev->modifiers, "Meta") ||
+ evas_key_modifier_is_set(ev->modifiers, "Hyper") ||
+ evas_key_modifier_is_set(ev->modifiers, "Super"))
+ return;
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+ (sd->scrollto.x.animator) || (sd->scrollto.y.animator))
+ {
+ _smart_anim_stop(sd->smart_obj);
+ }
+ if (sd->scrollto.x.animator)
+ {
+ ecore_animator_del(sd->scrollto.x.animator);
+ sd->scrollto.x.animator = NULL;
+ }
+ if (sd->scrollto.y.animator)
+ {
+ ecore_animator_del(sd->scrollto.y.animator);
+ sd->scrollto.y.animator = NULL;
+ }
+ if (sd->down.bounce_x_animator)
+ {
+ ecore_animator_del(sd->down.bounce_x_animator);
+ sd->down.bounce_x_animator = NULL;
+ sd->bouncemex = 0;
+ }
+ if (sd->down.bounce_y_animator)
+ {
+ ecore_animator_del(sd->down.bounce_y_animator);
+ sd->down.bounce_y_animator = NULL;
+ sd->bouncemey = 0;
+ }
+ if (ev->direction == 0)
+ y += ev->z * sd->step.y;
+ else if (ev->direction == 1)
+ x += ev->z * sd->step.x;
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+}
+
+static void
+_smart_event_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Down *ev;
+ Hor_Smart_Data *sd;
+ Evas_Coord x = 0, y = 0;
+
+ sd = data;
+ ev = event_info;
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+ if (_elm_config->thumbscroll_enable)
+ {
+ if ((sd->down.bounce_x_animator) || (sd->down.bounce_y_animator) ||
+ (sd->down.momentum_animator) || (sd->scrollto.x.animator) ||
+ (sd->scrollto.y.animator))
+ {
+ _smart_anim_stop(sd->smart_obj);
+ }
+ if (sd->scrollto.x.animator)
+ {
+ ecore_animator_del(sd->scrollto.x.animator);
+ sd->scrollto.x.animator = NULL;
+ }
+ if (sd->scrollto.y.animator)
+ {
+ ecore_animator_del(sd->scrollto.y.animator);
+ sd->scrollto.y.animator = NULL;
+ }
+ if (sd->down.bounce_x_animator)
+ {
+ ecore_animator_del(sd->down.bounce_x_animator);
+ sd->down.bounce_x_animator = NULL;
+ sd->bouncemex = 0;
+ }
+ if (sd->down.bounce_y_animator)
+ {
+ ecore_animator_del(sd->down.bounce_y_animator);
+ sd->down.bounce_y_animator = NULL;
+ sd->bouncemey = 0;
+ }
+ if (sd->down.hold_animator)
+ {
+ ecore_timer_del(sd->down.hold_animator);
+ sd->down.hold_animator = NULL;
+ _smart_drag_stop(sd->smart_obj);
+ }
+ if (sd->down.momentum_animator)
+ {
+ ecore_animator_del(sd->down.momentum_animator);
+ sd->down.momentum_animator = NULL;
+ sd->down.bounce_x_hold = 0;
+ sd->down.bounce_y_hold = 0;
+ sd->down.ax = 0;
+ sd->down.ay = 0;
+ }
+ if (ev->button == 1)
+ {
+ sd->down.now = 1;
+ sd->down.dragged = 0;
+ sd->down.dir_x = 0;
+ sd->down.dir_y = 0;
+ sd->down.dir_none = 0;
+ sd->down.x = ev->canvas.x;
+ sd->down.y = ev->canvas.y;
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ sd->down.sx = x;
+ sd->down.sy = y;
+ sd->down.locked = 0;
+ memset(&(sd->down.history[0]), 0, sizeof(sd->down.history[0]) * 20);
+#ifdef EVTIME
+ sd->down.history[0].timestamp = ev->timestamp / 1000.0;
+#else
+ sd->down.history[0].timestamp = ecore_loop_time_get();
+#endif
+ sd->down.history[0].x = ev->canvas.x;
+ sd->down.history[0].y = ev->canvas.y;
+
+#ifdef SMART_SCROLLER
+
+ int i;
+ if(sd->timer) {
+ ecore_timer_del(sd->timer);
+ sd->timer = NULL;
+ }
+ if(sd->special_timer) {
+ ecore_timer_del(sd->special_timer);
+ sd->special_timer = NULL;
+ }
+
+ for ( i =0; i < EVENT_Q_MAX; i++)
+ sd->event_queue[i] = 0;
+
+ sd->producer = 0;
+ sd->resaler = 0;
+ sd->consumer = 0;
+ sd->special_prev_x = sd->special_cur_x = ev->canvas.x;
+ sd->resaler_continue = 1;
+ sd->move_cnt = 0;
+ sd->x_pos = x * -1;
+
+#endif
+ }
+ }
+}
+
+static Eina_Bool
+_smart_hold_animator(void *data)
+{
+ Hor_Smart_Data *sd = data;
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, sd->down.hold_x, sd->down.hold_y);
+ return 1;
+}
+
+static void
+_smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Down *ev;
+ Hor_Smart_Data *sd;
+ Evas_Coord x = 0, y = 0, ox = 0, oy = 0;
+
+ sd = data;
+ ev = event_info;
+
+ #ifdef SMART_SCROLLER
+ sd->resaler_continue = 0;
+ if (sd->freeze) sd->hold = 0;
+
+#endif
+
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+ // FIXME: respect elm_widget_scroll_hold_get of parent container
+ if (_elm_config->thumbscroll_enable)
+ {
+ if (ev->button == 1)
+ {
+
+
+
+ if (sd->down.onhold_animator)
+ {
+ ecore_animator_del(sd->down.onhold_animator);
+ sd->down.onhold_animator = NULL;
+ }
+ x = ev->canvas.x - sd->down.x;
+ y = ev->canvas.y - sd->down.y;
+ if (sd->down.dragged)
+ {
+ _smart_drag_stop(sd->smart_obj);
+ if ((!sd->hold) && (!sd->freeze))
+ {
+ double t, at, dt;
+ int i;
+ Evas_Coord ax, ay, dx, dy, vel;
+
+#ifdef EVTIME
+ t = ev->timestamp / 1000.0;
+#else
+ t = ecore_loop_time_get();
+#endif
+ ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+ ax = ev->canvas.x;
+ ay = ev->canvas.y;
+ at = 0.0;
+#ifdef SCROLLDBG
+ printf("------ %i %i\n", ev->canvas.x, ev->canvas.y);
+#endif
+ for (i = 0; i < 20; i++)
+ {
+ dt = t - sd->down.history[i].timestamp;
+ if (dt > 0.2) break;
+#ifdef SCROLLDBG
+ printf("H: %i %i @ %1.3f\n",
+ sd->down.history[i].x,
+ sd->down.history[i].y, dt);
+#endif
+ at += dt;
+ ax += sd->down.history[i].x;
+ ay += sd->down.history[i].y;
+ }
+ ax /= (i + 1);
+ ay /= (i + 1);
+ at /= (i + 1);
+ at *= 4.0;
+ dx = ev->canvas.x - ax;
+ dy = ev->canvas.y - ay;
+ if (at > 0)
+ {
+ vel = sqrt((dx * dx) + (dy * dy)) / at;
+ if ((_elm_config->thumbscroll_friction > 0.0) &&
+ (vel > _elm_config->thumbscroll_momentum_threshhold) &&
+ (!sd->freeze))
+ {
+ sd->down.dx = ((double)dx / at);
+ sd->down.dy = ((double)dy / at);
+ ox = -sd->down.dx;
+ oy = -sd->down.dy;
+ if (!_smart_do_page(sd))
+ {
+ if (!sd->down.momentum_animator)
+ {
+ sd->down.momentum_animator = ecore_animator_add(_smart_momentum_animator, sd);
+ _smart_anim_start(sd->smart_obj);
+ }
+ sd->down.anim_start = ecore_loop_time_get();
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ sd->down.sx = x;
+ sd->down.sy = y;
+ sd->down.b0x = 0;
+ sd->down.b0y = 0;
+ }
+ }
+ }
+
+ if (sd->down.hold_animator)
+ {
+ ecore_timer_del(sd->down.hold_animator);
+ sd->down.hold_animator = NULL;
+ }
+ }
+ evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
+ if (_smart_do_page(sd))
+ {
+ Evas_Coord pgx, pgy;
+
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ pgx = _smart_page_x_get(sd, ox);
+ // HERE::modify pgx for moving one page
+ //if (pgx != x) _smart_scrollto_x(sd, _elm_config->page_scroll_friction, pgx);
+ _smart_scrollto_x(sd, _elm_config->page_scroll_friction, pgx);
+ pgy = _smart_page_y_get(sd, oy);
+ if (pgy != y) _smart_scrollto_y(sd, _elm_config->page_scroll_friction, pgy);
+ //_smart_scrollto_y(sd, _elm_config->page_scroll_friction, pgy);
+ }
+ }
+ else
+ {
+ if (_smart_do_page(sd))
+ {
+ Evas_Coord pgx, pgy;
+
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ pgx = _smart_page_x_get(sd, ox);
+ if (pgx != x) _smart_scrollto_x(sd, _elm_config->page_scroll_friction, pgx);
+ pgy = _smart_page_y_get(sd, oy);
+ if (pgy != y) _smart_scrollto_y(sd, _elm_config->page_scroll_friction, pgy);
+ }
+ }
+ sd->down.dragged = 0;
+ sd->down.now = 0;
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+ if (!_smart_do_page(sd))
+ bounce_eval(sd);
+ }
+ }
+}
+
+static Eina_Bool
+_smart_onhold_animator(void *data)
+{
+ Hor_Smart_Data *sd;
+ double t, td;
+ double vx, vy;
+ Evas_Coord x, y, ox, oy;
+
+ sd = data;
+ t = ecore_loop_time_get();
+ if (sd->down.onhold_tlast > 0.0)
+ {
+ td = t - sd->down.onhold_tlast;
+ vx = sd->down.onhold_vx * td * (double)_elm_config->thumbscroll_threshhold * 2.0;
+ vy = sd->down.onhold_vy * td * (double)_elm_config->thumbscroll_threshhold * 2.0;
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &ox, &oy);
+ sd->down.onhold_vxe += vx;
+ sd->down.onhold_vye += vy;
+ x = ox + (int)sd->down.onhold_vxe;
+ y = oy + (int)sd->down.onhold_vye;
+ sd->down.onhold_vxe -= (int)sd->down.onhold_vxe;
+ sd->down.onhold_vye -= (int)sd->down.onhold_vye;
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+// printf("scroll %i %i\n", sd->down.hold_x, sd->down.hold_y);
+ }
+ sd->down.onhold_tlast = t;
+ return 1;
+}
+
+#ifdef SMART_SCROLLER
+static int
+get_average(void *d)
+{
+ Hor_Smart_Data *sd = d;
+ int number = 0;
+ int key = 0;
+ int sum = 0;
+ int weight = 0;
+ int number_square;
+ int sum_of_weight = 0;
+ register int i = 1;
+
+// if (getenv(NUMBERS_OF_AVERAGE_QUEUE))
+// number = atoi(getenv(NUMBERS_OF_AVERAGE_QUEUE));
+// else return false;
+ number = NUMBERS_OF_AVERAGE_QUEUE;
+ number_square = number * number * number;
+
+ // i <= number : origin, but i'll try to process cur_x-prev_x in consumer_timer
+ // FIXME
+ for (i = 1; i <= number; i++)
+ {
+ if ((key = sd->producer-i) < 0) key = EVENT_Q_MAX + key;
+ weight = (number_square / (i*i*i)) + 1;
+
+ sum += sd->event_queue[key] * weight;
+ sum_of_weight += weight;
+ }
+ sd->consumer_queue[sd->resaler] = (int) sum / sum_of_weight;
+ sd->resaler = (sd->resaler+1) % EVENT_Q_MAX;
+
+ return 1;
+}
+
+
+static Eina_Bool special_timer_cb(void *d)
+{
+ Hor_Smart_Data *sd = d;
+
+ sd->special_prev_x = sd->special_cur_x;
+ sd->special_cur_x = sd->cur_x;
+ sd->event_queue[sd->producer] = sd->special_cur_x - sd->special_prev_x;
+ sd->producer = ((sd->producer + 1) % EVENT_Q_MAX);
+
+ if (sd->resaler_continue) if (!get_average(sd)) return ECORE_CALLBACK_RENEW;
+
+ if (sd->resaler == sd->consumer) {
+ sd->done = 1;
+ sd->special_timer = NULL;
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool consumer_timer_cb(void *d)
+{
+ Hor_Smart_Data *sd = d;
+ int tmp_movement = 0;
+
+// TODO: OPTIMIZE ME
+ tmp_movement = sd->consumer_queue[sd->consumer-1];
+
+ sd->x_pos += tmp_movement;
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, sd->x_pos * -1, sd->down.hold_y);
+
+ //if (sd->resaler == sd->consumer) {
+ if (sd->done == 1) {
+ sd->done = 0;
+ sd->timer = NULL;
+ memset(sd->event_queue, 0x00, EVENT_Q_MAX);
+ return ECORE_CALLBACK_CANCEL;
+ }
+ sd->consumer = (sd->consumer + 1) % EVENT_Q_MAX;
+
+ return ECORE_CALLBACK_RENEW;
+}
+#endif
+
+static void
+_smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Move *ev;
+ Hor_Smart_Data *sd;
+ Evas_Coord x = 0, y = 0;
+
+ sd = data;
+ ev = event_info;
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
+ // FIXME: respect elm_widget_scroll_hold_get of parent container
+ if (_elm_config->thumbscroll_enable)
+ {
+ if (sd->down.now)
+ {
+ int faildir = 0;
+
+#ifdef SCROLLDBG
+ printf("::: %i %i\n", ev->cur.canvas.x, ev->cur.canvas.y);
+#endif
+ memmove(&(sd->down.history[1]), &(sd->down.history[0]),
+ sizeof(sd->down.history[0]) * 19);
+#ifdef EVTIME
+ sd->down.history[0].timestamp = ev->timestamp / 1000.0;
+#else
+ sd->down.history[0].timestamp = ecore_loop_time_get();
+#endif
+ sd->down.history[0].x = ev->cur.canvas.x;
+ sd->down.history[0].y = ev->cur.canvas.y;
+
+ x = ev->cur.canvas.x - sd->down.x;
+ if (x < 0) x = -x; y = ev->cur.canvas.y - sd->down.y;
+ if (y < 0) y = -y;
+
+#if 0
+#ifdef SMART_SCROLLER
+ sd->cur_x = ev->cur.canvas.x;
+ sd->prev_x = ev->prev.canvas.x;
+ sd->move_cnt++;
+
+ if (!sd->special_timer)
+ {
+
+ sd->special_timer = ecore_timer_add(1.0f / NR_OF_FRAMES, special_timer_cb, data);
+ }
+
+ if (!sd->timer)
+ {
+ sd->timer = ecore_timer_add(1.0f / NR_OF_FRAMES, consumer_timer_cb, data);
+ }
+
+#endif
+#endif
+
+
+ if ((sd->one_dir_at_a_time) &&
+ (!sd->down.dir_x) && (!sd->down.dir_y) && (!sd->down.dir_none))
+ {
+ if (x > _elm_config->thumbscroll_threshhold)
+ {
+ if (x > (y * 2))
+ {
+ sd->down.dir_x = 1;
+ sd->down.dir_y = 0;
+ }
+ else faildir++;
+ }
+ if (y > _elm_config->thumbscroll_threshhold)
+ {
+ if (y > (x * 2))
+ {
+ sd->down.dir_x = 0;
+ sd->down.dir_y = 1;
+ }
+ else faildir++;
+ }
+ if (faildir) sd->down.dir_none = 1;
+ }
+ if ((!sd->hold) && (!sd->freeze))
+ {
+#ifdef SMART_SCROLLER
+ sd->cur_x = ev->cur.canvas.x;
+ sd->prev_x = ev->prev.canvas.x;
+ sd->move_cnt++;
+
+ if (!sd->special_timer)
+ {
+
+ sd->special_timer = ecore_timer_add(1.0f / NR_OF_FRAMES, special_timer_cb, data);
+ }
+
+ if (!sd->timer)
+ {
+ sd->timer = ecore_timer_add(1.0f / NR_OF_FRAMES, consumer_timer_cb, data);
+ }
+#endif
+
+
+ if ((sd->down.dragged) ||
+ (((x * x) + (y * y)) >
+ (_elm_config->thumbscroll_threshhold *
+ _elm_config->thumbscroll_threshhold)) )
+ //|| x < SMART_MOVE_THRESHOLD)
+ {
+ if (!sd->down.dragged)
+ {
+ evas_event_feed_hold(e, 1, ev->timestamp, ev->data);
+ _smart_drag_start(sd->smart_obj);
+ }
+ ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+ sd->down.dragged = 1;
+ x = sd->down.sx - (ev->cur.canvas.x - sd->down.x);
+ y = sd->down.sy - (ev->cur.canvas.y - sd->down.y);
+ if ((sd->down.dir_x) || (sd->down.dir_y))
+ {
+ if (!sd->down.locked)
+ {
+ sd->down.locked_x = x;
+ sd->down.locked_y = y;
+ sd->down.locked = 1;
+ }
+ if (sd->down.dir_x) y = sd->down.locked_y;
+ else x = sd->down.locked_x;
+ }
+ sd->down.hold_x = x;
+ sd->down.hold_y = y;
+#ifndef SMART_SCROLLER
+ if (!sd->down.hold_animator)
+ {
+ sd->down.hold_animator = ecore_timer_add(1.0f / 60.0f,_smart_hold_animator, sd);
+ }
+#endif
+// printf("a %i %i\n", sd->down.hold_x, sd->down.hold_y);
+// _smart_onhold_animator(sd);
+// hor_elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+ }
+ }
+ else if (!sd->freeze)
+ {
+ Evas_Coord ex, ey, ew, eh;
+ double vx = 0.0, vy = 0.0;
+
+
+ evas_object_geometry_get(sd->event_obj, &ex, &ey, &ew, &eh);
+ x = ev->cur.canvas.x - ex;
+ y = ev->cur.canvas.y - ey;
+ if (x < _elm_config->thumbscroll_threshhold)
+ {
+ if (_elm_config->thumbscroll_threshhold > 0.0)
+ vx = -(double)(_elm_config->thumbscroll_threshhold - x) /
+ _elm_config->thumbscroll_threshhold;
+ else
+ vx = -1.0;
+ }
+ else if (x > (ew - _elm_config->thumbscroll_threshhold))
+ {
+ if (_elm_config->thumbscroll_threshhold > 0.0)
+ vx = (double)(_elm_config->thumbscroll_threshhold - (ew - x)) /
+ _elm_config->thumbscroll_threshhold;
+ else
+ vx = 1.0;
+ }
+ if (y < _elm_config->thumbscroll_threshhold)
+ {
+ if (_elm_config->thumbscroll_threshhold > 0.0)
+ vy = -(double)(_elm_config->thumbscroll_threshhold - y) /
+ _elm_config->thumbscroll_threshhold;
+ else
+ vy = -1.0;
+ }
+ else if (y > (eh - _elm_config->thumbscroll_threshhold))
+ {
+ if (_elm_config->thumbscroll_threshhold > 0.0)
+ vy = (double)(_elm_config->thumbscroll_threshhold - (eh - y)) /
+ _elm_config->thumbscroll_threshhold;
+ else
+ vy = 1.0;
+ }
+ if ((vx != 0.0) || (vy != 0.0))
+ {
+ sd->down.onhold_vx = vx;
+ sd->down.onhold_vy = vy;
+ if (!sd->down.onhold_animator)
+ {
+ sd->down.onhold_vxe = 0.0;
+ sd->down.onhold_vye = 0.0;
+ sd->down.onhold_tlast = 0.0;
+ sd->down.onhold_animator = ecore_animator_add(_smart_onhold_animator, sd);
+ }
+// printf("b %i %i\n", sd->down.hold_x, sd->down.hold_y);
+ }
+ else
+ {
+ if (sd->down.onhold_animator)
+ {
+ ecore_animator_del(sd->down.onhold_animator);
+ //ecore_timer_del(sd->down.onhold_animator);
+ sd->down.onhold_animator = NULL;
+ }
+ }
+ }
+ else if (sd->freeze)
+ {
+ if(sd->timer) {
+ ecore_timer_del(sd->timer);
+ sd->timer = NULL;
+ }
+ if(sd->special_timer) {
+ ecore_timer_del(sd->special_timer);
+ sd->special_timer = NULL;
+ }
+ }
+ }
+
+ }
+}
+
+static void
+_smart_event_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Key_Down *ev;
+ Hor_Smart_Data *sd;
+ Evas_Coord x = 0, y = 0, vw = 0, vh = 0, mx = 0, my = 0;
+ int xch = 0, ych = 0;
+
+ sd = data;
+ ev = event_info;
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+ hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &x, &y);
+ sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+ evas_object_geometry_get(sd->pan_obj, NULL, NULL, &vw, &vh);
+ if (!strcmp(ev->keyname, "Left"))
+ {
+ x -= sd->step.x;
+ xch = 1;
+ }
+ else if (!strcmp(ev->keyname, "Right"))
+ {
+ x += sd->step.x;
+ xch = 1;
+ }
+ else if (!strcmp(ev->keyname, "Up"))
+ {
+ y -= sd->step.y;
+ ych = 1;
+ }
+ else if (!strcmp(ev->keyname, "Home"))
+ {
+ y = 0;
+ ych = 1;
+ }
+ else if (!strcmp(ev->keyname, "End"))
+ {
+ y = my;
+ ych = 1;
+ }
+ else if (!strcmp(ev->keyname, "Down"))
+ {
+ y += sd->step.y;
+ ych = 1;
+ }
+ else if (!strcmp(ev->keyname, "Prior"))
+ {
+ if (sd->page.y < 0)
+ y -= -(sd->page.y * vh) / 100;
+ else
+ y -= sd->page.y;
+ ych = 1;
+ }
+ else if (!strcmp(ev->keyname, "Next"))
+ {
+ if (sd->page.y < 0)
+ y += -(sd->page.y * vh) / 100;
+ else
+ y += sd->page.y;
+ ych = 1;
+ }
+ if (xch)
+ {
+ if (sd->scrollto.x.animator)
+ {
+ ecore_animator_del(sd->scrollto.x.animator);
+ sd->scrollto.x.animator = NULL;
+ }
+ if (sd->down.bounce_x_animator)
+ {
+ ecore_animator_del(sd->down.bounce_x_animator);
+ sd->down.bounce_x_animator = NULL;
+ sd->bouncemex = 0;
+ }
+ }
+ if (ych)
+ {
+ if (sd->scrollto.y.animator)
+ {
+ ecore_animator_del(sd->scrollto.y.animator);
+ sd->scrollto.y.animator = NULL;
+ }
+ if (sd->down.bounce_y_animator)
+ {
+ ecore_animator_del(sd->down.bounce_y_animator);
+ sd->down.bounce_y_animator = NULL;
+ sd->bouncemey = 0;
+ }
+ }
+
+ hor_elm_smart_scroller_child_pos_set(sd->smart_obj, x, y);
+}
+
+static void
+_smart_scrollbar_read(Hor_Smart_Data *sd)
+{
+ Evas_Coord x, y, mx = 0, my = 0, px, py;
+ double vx, vy;
+
+ edje_object_part_drag_value_get(sd->edje_obj, "elm.dragable.vbar", NULL, &vy);
+ edje_object_part_drag_value_get(sd->edje_obj, "elm.dragable.hbar", &vx, NULL);
+ sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+ x = vx * (double)mx;
+ y = vy * (double)my;
+ sd->pan_func.get(sd->pan_obj, &px, &py);
+ sd->pan_func.set(sd->pan_obj, x, y);
+ if ((px != x) || (py != y))
+ edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm");
+}
+
+static void
+_smart_scrollbar_reset(Hor_Smart_Data *sd)
+{
+ Evas_Coord px = 0, py = 0;
+
+ edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
+ edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
+ if ((!sd->child_obj) && (!sd->extern_pan))
+ {
+ edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
+ edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
+ }
+ sd->pan_func.get(sd->pan_obj, &px, &py);
+ sd->pan_func.set(sd->pan_obj, 0, 0);
+ if ((px != 0) || (py != 0))
+ edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm");
+}
+
+static int
+_smart_scrollbar_bar_v_visibility_adjust(Hor_Smart_Data *sd)
+{
+ int scroll_v_vis_change = 0;
+ Evas_Coord w, h, vw, vh;
+
+ w = sd->child.w;
+ h = sd->child.h;
+ evas_object_geometry_get(sd->pan_obj, NULL, NULL, &vw, &vh);
+ if (sd->vbar_visible)
+ {
+ if (sd->vbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_AUTO)
+ {
+ if ((sd->child_obj) || (sd->extern_pan))
+ {
+ if (h <= vh)
+ {
+ scroll_v_vis_change = 1;
+ sd->vbar_visible = 0;
+ }
+ }
+ else
+ {
+ scroll_v_vis_change = 1;
+ sd->vbar_visible = 0;
+ }
+ }
+ else if (sd->vbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_OFF)
+ {
+ scroll_v_vis_change = 1;
+ sd->vbar_visible = 0;
+ }
+ }
+ else
+ {
+ if (sd->vbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_AUTO)
+ {
+ if ((sd->child_obj) || (sd->extern_pan))
+ {
+ if (h > vh)
+ {
+ scroll_v_vis_change = 1;
+ sd->vbar_visible = 1;
+ }
+ }
+ }
+ else if (sd->vbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_ON)
+ {
+ scroll_v_vis_change = 1;
+ sd->vbar_visible = 1;
+ }
+ }
+ if (scroll_v_vis_change)
+ {
+ if (sd->vbar_flags != ELM_VERY_SMART_SCROLLER_POLICY_OFF)
+ {
+ if (sd->vbar_visible)
+ edje_object_signal_emit(sd->edje_obj, "elm,action,show,vbar", "elm");
+ else
+ edje_object_signal_emit(sd->edje_obj, "elm,action,hide,vbar", "elm");
+ edje_object_message_signal_process(sd->edje_obj);
+ _smart_scrollbar_size_adjust(sd);
+ }
+ else
+ edje_object_signal_emit(sd->edje_obj, "elm,action,hide,vbar", "elm");
+ }
+ return scroll_v_vis_change;
+}
+
+static int
+_smart_scrollbar_bar_h_visibility_adjust(Hor_Smart_Data *sd)
+{
+ int scroll_h_vis_change = 0;
+ Evas_Coord w, h, vw, vh;
+
+ w = sd->child.w;
+ h = sd->child.h;
+ evas_object_geometry_get(sd->pan_obj, NULL, NULL, &vw, &vh);
+ if (sd->hbar_visible)
+ {
+ if (sd->hbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_AUTO)
+ {
+ if ((sd->child_obj) || (sd->extern_pan))
+ {
+ if (w <= vw)
+ {
+ scroll_h_vis_change = 1;
+ sd->hbar_visible = 0;
+ }
+ }
+ else
+ {
+ scroll_h_vis_change = 1;
+ sd->hbar_visible = 0;
+ }
+ }
+ else if (sd->hbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_OFF)
+ {
+ scroll_h_vis_change = 1;
+ sd->hbar_visible = 0;
+ }
+ }
+ else
+ {
+ if (sd->hbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_AUTO)
+ {
+ if ((sd->child_obj) || (sd->extern_pan))
+ {
+ if (w > vw)
+ {
+ scroll_h_vis_change = 1;
+ sd->hbar_visible = 1;
+ }
+ }
+ }
+ else if (sd->hbar_flags == ELM_VERY_SMART_SCROLLER_POLICY_ON)
+ {
+ scroll_h_vis_change = 1;
+ sd->hbar_visible = 1;
+ }
+ }
+ if (scroll_h_vis_change)
+ {
+ if (sd->hbar_flags != ELM_VERY_SMART_SCROLLER_POLICY_OFF)
+ {
+ if (sd->hbar_visible)
+ edje_object_signal_emit(sd->edje_obj, "elm,action,show,hbar", "elm");
+ else
+ edje_object_signal_emit(sd->edje_obj, "elm,action,hide,hbar", "elm");
+ edje_object_message_signal_process(sd->edje_obj);
+ _smart_scrollbar_size_adjust(sd);
+ }
+ else
+ edje_object_signal_emit(sd->edje_obj, "elm,action,hide,hbar", "elm");
+ _smart_scrollbar_size_adjust(sd);
+ }
+ return scroll_h_vis_change;
+}
+
+static void
+_smart_scrollbar_bar_visibility_adjust(Hor_Smart_Data *sd)
+{
+ int changed = 0;
+
+ changed |= _smart_scrollbar_bar_h_visibility_adjust(sd);
+ changed |= _smart_scrollbar_bar_v_visibility_adjust(sd);
+ if (changed)
+ {
+ _smart_scrollbar_bar_h_visibility_adjust(sd);
+ _smart_scrollbar_bar_v_visibility_adjust(sd);
+ }
+}
+
+static void
+_smart_scrollbar_size_adjust(Hor_Smart_Data *sd)
+{
+ if ((sd->child_obj) || (sd->extern_pan))
+ {
+ Evas_Coord x, y, w, h, mx = 0, my = 0, vw = 0, vh = 0, px, py;
+ double vx, vy, size;
+
+ edje_object_part_geometry_get(sd->edje_obj, "elm.swallow.content",
+ NULL, NULL, &vw, &vh);
+ w = sd->child.w;
+ if (w < 1) w = 1;
+ size = (double)vw / (double)w;
+ if (size > 1.0)
+ {
+ size = 1.0;
+ edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.hbar", 0.0, 0.0);
+ }
+ edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.hbar", size, 1.0);
+
+ h = sd->child.h;
+ if (h < 1) h = 1;
+ size = (double)vh / (double)h;
+ if (size > 1.0)
+ {
+ size = 1.0;
+ edje_object_part_drag_value_set(sd->edje_obj, "elm.dragable.vbar", 0.0, 0.0);
+ }
+ edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.vbar", 1.0, size);
+
+ edje_object_part_drag_value_get(sd->edje_obj, "elm.dragable.hbar", &vx, NULL);
+ edje_object_part_drag_value_get(sd->edje_obj, "elm.dragable.vbar", NULL, &vy);
+ sd->pan_func.max_get(sd->pan_obj, &mx, &my);
+ x = vx * mx;
+ y = vy * my;
+
+ edje_object_part_drag_step_set(sd->edje_obj, "elm.dragable.hbar", (double)sd->step.x / (double)w, 0.0);
+ edje_object_part_drag_step_set(sd->edje_obj, "elm.dragable.vbar", 0.0, (double)sd->step.y / (double)h);
+ if (sd->page.x > 0)
+ edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.hbar", (double)sd->page.x / (double)w, 0.0);
+ else
+ edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.hbar", -((double)sd->page.x * ((double)vw / (double)w)) / 100.0, 0.0);
+ if (sd->page.y > 0)
+ edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.vbar", 0.0, (double)sd->page.y / (double)h);
+ else
+ edje_object_part_drag_page_set(sd->edje_obj, "elm.dragable.vbar", 0.0, -((double)sd->page.y * ((double)vh / (double)h)) / 100.0);
+
+ sd->pan_func.get(sd->pan_obj, &px, &py);
+ if (vx != mx) x = px;
+ if (vy != my) y = py;
+ sd->pan_func.set(sd->pan_obj, x, y);
+// if ((px != 0) || (py != 0))
+// edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm");
+ }
+ else
+ {
+ Evas_Coord px = 0, py = 0;
+
+ edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.vbar", 1.0, 1.0);
+ edje_object_part_drag_size_set(sd->edje_obj, "elm.dragable.hbar", 1.0, 1.0);
+ sd->pan_func.get(sd->pan_obj, &px, &py);
+ sd->pan_func.set(sd->pan_obj, 0, 0);
+ if ((px != 0) || (py != 0))
+ edje_object_signal_emit(sd->edje_obj, "elm,action,scroll", "elm");
+ }
+ _smart_scrollbar_bar_visibility_adjust(sd);
+}
+
+static void
+_smart_reconfigure(Hor_Smart_Data *sd)
+{
+ evas_object_move(sd->edje_obj, sd->x, sd->y);
+ evas_object_resize(sd->edje_obj, sd->w, sd->h);
+ evas_object_move(sd->event_obj, sd->x, sd->y);
+ evas_object_resize(sd->event_obj, sd->w, sd->h);
+ _smart_scrollbar_size_adjust(sd);
+}
+
+static void
+_smart_add(Evas_Object *obj)
+{
+ Hor_Smart_Data *sd;
+ Evas_Object *o;
+
+ sd = calloc(1, sizeof(Hor_Smart_Data));
+ if (!sd) return;
+ evas_object_smart_data_set(obj, sd);
+
+ sd->smart_obj = obj;
+ sd->x = 0;
+ sd->y = 0;
+ sd->w = 0;
+ sd->h = 0;
+ sd->step.x = 32;
+ sd->step.y = 32;
+ sd->page.x = -50;
+ sd->page.y = -50;
+ sd->hbar_flags = ELM_VERY_SMART_SCROLLER_POLICY_AUTO;
+ sd->vbar_flags = ELM_VERY_SMART_SCROLLER_POLICY_AUTO;
+ sd->hbar_visible = 1;
+ sd->vbar_visible = 1;
+
+ sd->bounce_horiz = 1;
+ sd->bounce_vert = 1;
+
+ sd->one_dir_at_a_time = 1;
+
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _smart_event_key_down, sd);
+ evas_object_propagate_events_set(obj, 0);
+
+ o = edje_object_add(evas_object_evas_get(obj));
+ sd->edje_obj = o;
+ _elm_theme_object_set(NULL, o, "scroller", "base", "default");
+ edje_object_signal_callback_add(o, "drag", "elm.dragable.vbar", _smart_edje_drag_v, sd);
+ edje_object_signal_callback_add(o, "drag,start", "elm.dragable.vbar", _smart_edje_drag_v_start, sd);
+ edje_object_signal_callback_add(o, "drag,stop", "elm.dragable.vbar", _smart_edje_drag_v_stop, sd);
+ edje_object_signal_callback_add(o, "drag,step", "elm.dragable.vbar", _smart_edje_drag_v, sd);
+ edje_object_signal_callback_add(o, "drag,page", "elm.dragable.vbar", _smart_edje_drag_v, sd);
+ edje_object_signal_callback_add(o, "drag", "elm.dragable.hbar", _smart_edje_drag_h, sd);
+ edje_object_signal_callback_add(o, "drag,start", "elm.dragable.hbar", _smart_edje_drag_h_start, sd);
+ edje_object_signal_callback_add(o, "drag,stop", "elm.dragable.hbar", _smart_edje_drag_h_stop, sd);
+ edje_object_signal_callback_add(o, "drag,step", "elm.dragable.hbar", _smart_edje_drag_h, sd);
+ edje_object_signal_callback_add(o, "drag,page", "elm.dragable.hbar", _smart_edje_drag_h, sd);
+ evas_object_smart_member_add(o, obj);
+
+ o = evas_object_rectangle_add(evas_object_evas_get(obj));
+ sd->event_obj = o;
+ evas_object_color_set(o, 0, 0, 0, 0);
+ evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL, _smart_event_wheel, sd);
+ evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _smart_event_mouse_down, sd);
+ evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _smart_event_mouse_up, sd);
+ evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _smart_event_mouse_move, sd);
+ evas_object_smart_member_add(o, obj);
+ evas_object_repeat_events_set(o, 1);
+
+ sd->pan_func.set = _elm_smart_pan_set;
+ sd->pan_func.get = _elm_smart_pan_get;
+ sd->pan_func.max_get = _elm_smart_pan_max_get;
+ sd->pan_func.child_size_get = _elm_smart_pan_child_size_get;
+
+ _smart_scrollbar_reset(sd);
+}
+
+static void
+_smart_del(Evas_Object *obj)
+{
+ INTERNAL_ENTRY;
+ hor_elm_smart_scroller_child_set(obj, NULL);
+ if (!sd->extern_pan) evas_object_del(sd->pan_obj);
+ evas_object_del(sd->edje_obj);
+ evas_object_del(sd->event_obj);
+ if (sd->down.hold_animator) ecore_timer_del(sd->down.hold_animator);
+ if (sd->down.onhold_animator) ecore_animator_del(sd->down.onhold_animator);
+ if (sd->down.momentum_animator) ecore_animator_del(sd->down.momentum_animator);
+ if (sd->down.bounce_x_animator) ecore_animator_del(sd->down.bounce_x_animator);
+ if (sd->down.bounce_y_animator) ecore_animator_del(sd->down.bounce_y_animator);
+ if (sd->scrollto.x.animator) ecore_animator_del(sd->scrollto.x.animator);
+ if (sd->scrollto.y.animator) ecore_animator_del(sd->scrollto.y.animator);
+ free(sd);
+ evas_object_smart_data_set(obj, NULL);
+}
+
+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)
+{
+ INTERNAL_ENTRY;
+ evas_object_show(sd->edje_obj);
+ evas_object_show(sd->event_obj);
+}
+
+static void
+_smart_hide(Evas_Object *obj)
+{
+ INTERNAL_ENTRY;
+ evas_object_hide(sd->edje_obj);
+ evas_object_hide(sd->event_obj);
+}
+
+static void
+_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
+{
+ INTERNAL_ENTRY;
+ evas_object_color_set(sd->edje_obj, r, g, b, a);
+}
+
+static void
+_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
+{
+ INTERNAL_ENTRY;
+ evas_object_clip_set(sd->edje_obj, clip);
+ evas_object_clip_set(sd->event_obj, clip);
+}
+
+static void
+_smart_clip_unset(Evas_Object *obj)
+{
+ INTERNAL_ENTRY;
+ evas_object_clip_unset(sd->edje_obj);
+ evas_object_clip_unset(sd->event_obj);
+}
+
+/* never need to touch this */
+
+static void
+_smart_init(void)
+{
+ if (_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,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ _smart = evas_smart_class_new(&sc);
+ }
+}
+
--- /dev/null
+typedef enum _Elm_Very_Smart_Scroller_Policy
+{
+ ELM_VERY_SMART_SCROLLER_POLICY_AUTO,
+ ELM_VERY_SMART_SCROLLER_POLICY_ON,
+ ELM_VERY_SMART_SCROLLER_POLICY_OFF
+}
+
+Elm_Very_Smart_Scroller_Policy;
+Evas_Object *hor_elm_smart_scroller_add (Evas *evas);
+void hor_elm_smart_scroller_child_set (Evas_Object *obj, Evas_Object *child);
+void hor_elm_smart_scroller_extern_pan_set (Evas_Object *obj, Evas_Object *pan, void (*pan_set) (Evas_Object *obj, Evas_Coord x, Evas_Coord y), void (*pan_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y), void (*pan_max_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y), void (*pan_child_size_get) (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y));
+void hor_elm_smart_scroller_custom_edje_file_set (Evas_Object *obj, char *file, char *group);
+void hor_elm_smart_scroller_child_pos_set (Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+void hor_elm_smart_scroller_child_pos_get (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+void hor_elm_smart_scroller_child_region_show (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+void hor_elm_smart_scroller_child_viewport_size_get (Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
+void hor_elm_smart_scroller_step_size_set (Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+void hor_elm_smart_scroller_step_size_get (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+void hor_elm_smart_scroller_page_size_set (Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+void hor_elm_smart_scroller_page_size_get (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
+void hor_elm_smart_scroller_policy_set (Evas_Object *obj, Elm_Very_Smart_Scroller_Policy hbar, Elm_Very_Smart_Scroller_Policy vbar);
+void hor_elm_smart_scroller_policy_get (Evas_Object *obj, Elm_Very_Smart_Scroller_Policy *hbar, Elm_Very_Smart_Scroller_Policy *vbar);
+Evas_Object *hor_elm_smart_scroller_edje_object_get (Evas_Object *obj);
+void hor_elm_smart_scroller_single_dir_set (Evas_Object *obj, Eina_Bool single_dir);
+Eina_Bool hor_elm_smart_scroller_single_dir_get (Evas_Object *obj);
+void hor_elm_smart_scroller_theme_set (Evas_Object *parent, Evas_Object *obj, const char *clas, const char *group, const char *style);
+void hor_elm_smart_scroller_hold_set (Evas_Object *obj, Eina_Bool hold);
+void hor_elm_smart_scroller_freeze_set (Evas_Object *obj, Eina_Bool freeze);
+void hor_elm_smart_scroller_bounce_allow_set (Evas_Object *obj, Eina_Bool horiz, Eina_Bool vert);
+void hor_elm_smart_scroller_paging_set (Evas_Object *obj, double pagerel_h, double pagerel_v, Evas_Coord pagesize_h, Evas_Coord pagesize_v);
+void hor_elm_smart_scroller_region_bring_in (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+