images {
image: "bg_keypad.jpg" COMP;
+ image: "bt_edit.png" COMP;
}
parts {
}
part {
+ name: "button.area.clipper";
+ type: RECT;
+ description {
+ state: "default" 0.0;
+ rel1.to: "bg.buttons";
+ rel2 {
+ to: "bg.buttons";
+ offset: -1 SEPARATOR_HEIGHT;
+ }
+ }
+ }
+
+
+ part {
+ name: "button.clipper";
+ type: RECT;
+ clip_to: "button.area.clipper";
+ description {
+ state: "default" 0.0;
+ rel1.to: "button.area.clipper";
+ rel2.to: "button.area.clipper";
+ }
+ description {
+ state: "alternate" 0.0;
+ color: 255 255 255 0;
+ visible: 0;
+ }
+ }
+
+ part {
+ name: "edit-button.clipper";
+ type: RECT;
+ clip_to: "button.area.clipper";
+ description {
+ state: "default" 0.0;
+ color: 255 255 255 0;
+ visible: 0;
+ rel1.to: "button.area.clipper";
+ rel2.to: "button.area.clipper";
+ }
+ description {
+ state: "alternate" 0.0;
+ color: 255 255 255 255;
+ visible: 1;
+ }
+ }
+
+ part {
+ name: "edit.clipper";
+ type: RECT;
+ description {
+ state: "default" 0.0;
+ rel1.to: "bg.edit";
+ rel2 {
+ to: "bg.edit";
+ offset: -1 SEPARATOR_HEIGHT;
+ }
+ }
+ }
+
+ part {
name: "bg.buttons";
type: RECT;
mouse_events: 0;
+ clip_to: "button.clipper";
description {
state: "default" 0.0;
color: 0 0 0 0;
- min: WIDTH (ACTION_HEIGHT / 2);
+ min: 0 (ACTION_HEIGHT / 2);
+ rel2 {
+ to_x: "bg.edit";
+ relative: 0.0 0.0;
+ offset: (-ITEM_PADDING - 1) (ACTION_HEIGHT / 2 - 1);
+ }
+ }
+ }
+
+ part {
+ name: "bg.edit";
+ type: RECT;
+ mouse_events: 0;
+ clip_to: "edit.clipper";
+ description {
+ state: "default" 0.0;
+ color: 0 0 0 0;
+ min: 0 (ACTION_HEIGHT / 2);
+ rel1 {
+ relative: 1.0 0.0;
+ offset: (-LIST_ICON_SIZE - ITEM_PADDING - BORDER_PADDING) 0;
+ }
rel2 {
relative: 1.0 0.0;
- offset: -1.0 (ACTION_HEIGHT / 2 - 1);
+ offset: -1 (ACTION_HEIGHT / 2 - 1);
}
}
}
-#define SEPARATOR(id, rely, offy, relto) \
+
+#define SEPARATOR(id, clip, rely, offy, relto) \
part { \
name: "separator.dark."##id; \
type: RECT; \
mouse_events: 0; \
+ clip_to: clip; \
description { \
state: "default" 0.0; \
color: 255 255 255 255; \
name: "separator.bg."##id; \
type: RECT; \
mouse_events: 0; \
+ clip_to: clip; \
description { \
state: "default" 0.0; \
color: 255 255 255 255; \
} \
}
- SEPARATOR("button", 1.0, 0, "bg.buttons");
+ SEPARATOR("button", "button.area.clipper", 1.0, 0, "bg.buttons");
+ SEPARATOR("edit-button", "button.area.clipper", 1.0, 0, "bg.buttons");
+ SEPARATOR("edit", "edit.clipper", 1.0, 0, "bg.edit");
#undef SEPARATOR
part {
}
}
-#define BUTTON(id, label, ccls, r1, r2) \
+#define BUTTON(id, label, ccls, clip, r1, r2) \
part { \
name: "button."##id; \
type: RECT; \
mouse_events: 1; \
+ clip_to: clip; \
description { \
state: "default" 0.0; \
color: 255 255 255 0; \
name: "label."##id; \
type: TEXT; \
mouse_events: 0; \
+ clip_to: clip; \
description { \
state: "default" 0.0; \
color: 255 255 255 255; \
} \
text { \
text: label; \
- font: FONT_NORMAL; \
- size: SIZE_MEDIUM; \
+ font: FONT_NORMAL; \
+ size: SIZE_MEDIUM; \
align: 0.5 0.5; \
} \
} \
} \
}
- BUTTON("all", "All", "action", 0.0 0.0, 0.5 1.0);
- BUTTON("missed", "Missed", "action", 0.5 0.0, 1.0 1.0);
+ BUTTON("all", "All", "action", "button.clipper", 0.0 0.0, 0.5 1.0);
+ BUTTON("missed", "Missed", "action", "button.clipper", 0.5 0.0, 1.0 1.0);
+
+ BUTTON("clear", "Clear", "caution", "edit-button.clipper", 0.0 0.0, 0.5 1.0);
+ BUTTON("edit,done", "Done", "action", "edit-button.clipper", 0.5 0.0, 1.0 1.0);
#undef BUTTON
+
+ part {
+ name: "button.edit";
+ type: RECT;
+ mouse_events: 1;
+ clip_to: "edit.clipper";
+ description {
+ state: "default" 0.0;
+ color: 255 255 255 0;
+ color_class: "action";
+ rel1.to: "bg.edit";
+ rel2.to: "bg.edit";
+ }
+ description {
+ state: "pressed" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "ico.edit";
+ type: IMAGE;
+ mouse_events: 0;
+ clip_to: "edit.clipper";
+ description {
+ state: "default" 0.0;
+ min: LIST_ICON_SIZE LIST_ICON_SIZE;
+ max: LIST_ICON_SIZE LIST_ICON_SIZE;
+ align: 0.0 0.5;
+ color: 255 255 255 255;
+ color_class: "action";
+ rel1 {
+ to: "button.edit";
+ offset: ITEM_PADDING 0;
+ }
+ rel2 {
+ to: "button.edit";
+ offset: (-BORDER_PADDING - 1) -1;
+ }
+ image {
+ normal: "bt_edit.png";
+ scale_hint: STATIC;
+ }
+ }
+ description {
+ state: "pressed" 0.0;
+ inherit: "default" 0.0;
+ color: 16 16 16 255;
+ }
+ }
+ part {
+ name: "button.over.edit";
+ type: RECT;
+ mouse_events: 1;
+ clip_to: "edit.clipper";
+ description {
+ state: "default" 0.0;
+ color: 0 0 0 0;
+ visible: 0;
+ rel1.to: "bg.edit";
+ rel2.to: "bg.edit";
+ }
+ description {
+ state: "pressed" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ }
+ }
+
+ programs {
+ program {
+ signal: "toggle,on,edit";
+ source: "gui";
+ action: STATE_SET "pressed" 0.0;
+ target: "button.edit";
+ target: "button.over.edit";
+ target: "ico.edit";
+ after: "show_edit_buttons";
+ }
+ program {
+ name: "show_edit_buttons";
+ action: STATE_SET "alternate" 0.0;
+ transition: ACCELERATE 0.3;
+ target: "button.clipper";
+ target: "edit-button.clipper";
+ }
+
+ program {
+ signal: "toggle,off,edit";
+ source: "gui";
+ action: STATE_SET "default" 0.0;
+ target: "button.edit";
+ target: "button.over.edit";
+ target: "ico.edit";
+ after: "hide_edit_buttons";
+ }
+ program {
+ name: "hide_edit_buttons";
+ action: STATE_SET "default" 0.0;
+ transition: ACCELERATE 0.3;
+ target: "button.clipper";
+ target: "edit-button.clipper";
+ }
+
+ program {
+ signal: "mouse,clicked,1";
+ source: "button.edit";
+ action: SIGNAL_EMIT "clicked,edit" "gui";
+ api: "edit was clicked";
+ }
+ program {
+ signal: "mouse,clicked,1";
+ source: "button.over.edit";
+ action: SIGNAL_EMIT "clicked,edit,done" "gui";
+ api: "edit_done was clicked";
+ }
+ }
}
- programs {
+ programs {
program {
name: "show_all";
signal: "show,all";
}
}
- images.image: "bt_arrow_right.png" COMP;
+ images {
+ image: "bt_arrow_right.png" COMP;
+ image: "bt_del.png" COMP;
+ }
parts{
part {
rel2 {
to_x: "call.swallow.more";
relative: 0.0 1.0;
- offset: -ITEM_PADDING (-ITEM_PADDING - 1);
+ offset: (-ITEM_PADDING - ITEM_PADDING) (-ITEM_PADDING - 1);
}
text {
font: FONT_NORMAL;
}
}
}
+
+group {
+ name: "elm/genlist/item/history-delete/default";
+ alias: "elm/genlist/item_odd/history-delete/default";
+
+ data {
+ item: "contents" "call.swallow.delete";
+ item: "mode_part" "elm.swallow.decorate.content";
+ }
+
+ parts {
+ part {
+ name: "content.clipper";
+ type: RECT;
+ description {
+ state: "default" 0.0;
+ }
+ description {
+ state: "decorated" 0.0;
+ inherit: "default" 0.0;
+ rel2 {
+ offset: (-BORDER_PADDING - LIST_ICON_SIZE - ITEM_PADDING - 1) -1;
+ }
+ }
+ }
+
+ part {
+ name: "elm.swallow.decorate.content";
+ type: SWALLOW;
+ mouse_events: 1;
+ scale: 1;
+ clip_to: "content.clipper";
+ description {
+ state: "default" 0.0;
+ }
+ }
+
+ part {
+ name: "call.swallow.delete";
+ type: SWALLOW;
+ mouse_events: 1;
+ scale: 1;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ fixed: 1 0;
+ align: 0.0 0.5;
+ rel1 {
+ relative: 1.0 0.0;
+ }
+ }
+ description {
+ state: "decorated" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ align: 1.0 0.5;
+ rel1 {
+ relative: 1.0 0.0;
+ offset: -BORDER_PADDING 0;
+ }
+ rel2 {
+ relative: 1.0 1.0;
+ offset: -BORDER_PADDING -1;
+ }
+ }
+ }
+
+ programs {
+ program {
+ name: "animate_decorated";
+ signal: "elm,state,decorate,enabled,effect";
+ source: "elm";
+ action: STATE_SET "decorated" 0.0;
+ target: "content.clipper";
+ after: "animate_decorated2";
+ }
+ program {
+ name: "animate_decorated2";
+ action: STATE_SET "decorated" 0.0;
+ transition: ACCELERATE 0.15;
+ target: "call.swallow.delete";
+ }
+
+ program {
+ name: "animate_default";
+ signal: "elm,state,decorate,disabled,effect";
+ source: "elm";
+ action: STATE_SET "default" 0.0;
+ transition: ACCELERATE 0.15;
+ target: "call.swallow.delete";
+ after: "animate_default2";
+ }
+ program {
+ name: "animate_default2";
+ action: STATE_SET "default" 0.0;
+ target: "content.clipper";
+ }
+
+ program {
+ signal: "elm,state,decorate,enabled";
+ source: "elm";
+ action: STATE_SET "decorated" 0.0;
+ target: "content.clipper";
+ target: "call.swallow.delete";
+ }
+ program {
+ signal: "elm,state,decorate,disabled";
+ source: "elm";
+ action: STATE_SET "default" 0.0;
+ target: "content.clipper";
+ target: "call.swallow.delete";
+ }
+
+ program {
+ signal: "elm,state,slide,active";
+ source: "elm";
+ after: "animate_decorated";
+ }
+ program {
+ signal: "elm,state,slide,passive";
+ source: "elm";
+ after: "animate_default";
+ }
+ }
+ }
+}
+
+group {
+ name: "elm/button/base/history-delete";
+
+ parts {
+ part {
+ name: "area";
+ type: IMAGE;
+ description {
+ state: "default" 0.0;
+ min: LIST_ICON_SIZE LIST_ICON_SIZE;
+ max: LIST_ICON_SIZE LIST_ICON_SIZE;
+ color: 255 255 255 255;
+ color_class: "caution";
+ image {
+ normal: "bt_del.png";
+ scale_hint: STATIC;
+ }
+ }
+ description {
+ state: "pressed" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 128;
+ }
+ }
+ }
+ programs {
+ program {
+ signal: "mouse,down,1";
+ source: "area";
+ action: SIGNAL_EMIT "elm,action,press" "";
+ }
+ program {
+ signal: "mouse,up,1";
+ source: "area";
+ action: SIGNAL_EMIT "elm,action,unpress" "";
+ }
+ program {
+ signal: "mouse,clicked,1";
+ source: "area";
+ action: SIGNAL_EMIT "elm,action,click" "";
+ }
+
+ program {
+ signal: "mouse,up,1";
+ source: "area";
+ action: STATE_SET "default" 0.0;
+ transition: ACCELERATE 0.1;
+ target: "area";
+ }
+
+ program {
+ signal: "mouse,down,1";
+ source: "area";
+ action: STATE_SET "pressed" 0.0;
+ transition: ACCELERATE 0.1;
+ target: "area";
+ }
+ }
+}
Call_Info_List *calls;
Elm_Genlist_Item_Class *itc;
Evas_Object *self;
+ Evas_Object *clear_popup;
Evas_Object *genlist_all, *genlist_missed;
Ecore_Poller *updater;
double last_update;
Eina_Bool completed;
Eina_Bool incoming;
const OFono_Call *call; /* not in edd */
+ History *history;
Elm_Object_Item *it_all; /*not in edd */
Elm_Object_Item *it_missed; /*not in edd */
} Call_Info;
* uselessly update all the thousand items.
*/
+ if (!ctx->calls->list) {
+ ctx->updater = NULL;
+ return EINA_FALSE;
+ }
+
if (now - ctx->last_update < interval_threshold)
return EINA_TRUE;
ctx->last_update = now;
history->updater, win_focused, obj_visible);
if (history->updater)
return;
+ if (!history->calls->list)
+ return;
if ((!win_focused) || (!obj_visible))
return;
elm_genlist_item_show
(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
call_info->it_missed = it;
+ call_info->history = history;
+ _history_time_updater_start(history);
}
}
}
call_info->line_id);
elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_IN);
call_info->it_all = it;
+ call_info->history = history;
+ _history_time_updater_start(history);
}
}
_on_item_clicked,
call_info->line_id);
call_info->it_all = it;
+ call_info->history = history;
if (call_info->completed)
continue;
_on_item_clicked,
call_info->line_id);
call_info->it_missed = it;
+ call_info->history = history;
}
it = elm_genlist_first_item_get(history->genlist_all);
elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_TOP);
}
+static void _history_call_info_del(Call_Info *call_info)
+{
+ History *ctx = call_info->history;
+
+ EINA_SAFETY_ON_NULL_RETURN(ctx);
+
+ call_info->call = NULL;
+ if (call_info->it_all)
+ elm_object_item_del(call_info->it_all);
+ if (call_info->it_missed)
+ elm_object_item_del(call_info->it_missed);
+
+ ctx->calls->list = eina_list_remove(ctx->calls->list, call_info);
+ ctx->calls->dirty = EINA_TRUE;
+ _history_call_log_save(ctx);
+
+ if ((!ctx->calls->list) && (ctx->updater)) {
+ ecore_poller_del(ctx->updater);
+ ctx->updater = NULL;
+ }
+
+ _call_info_free(call_info);
+}
+
+static void _history_clear_do(void *data, Evas_Object *obj __UNUSED__,
+ void *event_info __UNUSED__)
+{
+ History *ctx = data;
+ Call_Info *call_info;
+
+ DBG("ctx=%p, deleting %u entries",
+ ctx, eina_list_count(ctx->calls->list));
+
+ evas_object_del(ctx->clear_popup);
+ ctx->clear_popup = NULL;
+
+ elm_genlist_clear(ctx->genlist_all);
+ elm_genlist_clear(ctx->genlist_missed);
+
+ EINA_LIST_FREE(ctx->calls->list, call_info)
+ _call_info_free(call_info);
+
+ ctx->calls->dirty = EINA_TRUE;
+ _history_call_log_save(ctx);
+
+ if (ctx->updater) {
+ ecore_poller_del(ctx->updater);
+ ctx->updater = NULL;
+ }
+
+ elm_object_signal_emit(ctx->self, "toggle,off,edit", "gui");
+}
+
+static void _history_clear_cancel(void *data, Evas_Object *obj __UNUSED__,
+ void *event_info __UNUSED__)
+{
+ History *ctx = data;
+
+ DBG("ctx=%p", ctx);
+
+ evas_object_del(ctx->clear_popup);
+ ctx->clear_popup = NULL;
+}
+
+static void _history_clear(History *ctx)
+{
+ Evas_Object *p, *bt;
+
+ EINA_SAFETY_ON_TRUE_RETURN(ctx->clear_popup != NULL);
+
+ ctx->clear_popup = p = elm_popup_add(ctx->self);
+ evas_object_size_hint_weight_set(p, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_object_part_text_set(p, "title,text", "Clear History");
+ elm_object_text_set(p, "Do you want to clear all history entries?");
+
+ bt = elm_button_add(p);
+ elm_object_text_set(bt, "No");
+ elm_object_part_content_set(p, "button1", bt);
+ evas_object_smart_callback_add(bt, "clicked",
+ _history_clear_cancel, ctx);
+
+ bt = elm_button_add(p);
+ elm_object_text_set(bt, "Yes, Clear");
+ elm_object_part_content_set(p, "button2", bt);
+ evas_object_smart_callback_add(bt, "clicked", _history_clear_do, ctx);
+
+ evas_object_show(p);
+}
+
static char *_item_label_get(void *data, Evas_Object *obj __UNUSED__,
const char *part)
{
return EINA_FALSE;
}
-static void _on_clicked(void *data __UNUSED__, Evas_Object *obj __UNUSED__,
+static void _on_clicked(void *data, Evas_Object *obj __UNUSED__,
const char *emission, const char *source __UNUSED__)
{
+ History *ctx = data;
+
EINA_SAFETY_ON_NULL_RETURN(emission);
emission += strlen("clicked,");
+ DBG("ctx=%p, signal: %s", ctx, emission);
+
if (!strcmp(emission, "all"))
elm_object_signal_emit(obj, "show,all", "gui");
- else
+ else if (!strcmp(emission, "missed"))
elm_object_signal_emit(obj, "show,missed", "gui");
+ else if (!strcmp(emission, "clear"))
+ _history_clear(ctx);
+ else if (!strcmp(emission, "edit")) {
+ elm_object_signal_emit(obj, "toggle,on,edit", "gui");
+ elm_genlist_decorate_mode_set(ctx->genlist_all, EINA_TRUE);
+ elm_genlist_decorate_mode_set(ctx->genlist_missed, EINA_TRUE);
+ } else if (!strcmp(emission, "edit,done")) {
+ elm_object_signal_emit(obj, "toggle,off,edit", "gui");
+ elm_genlist_decorate_mode_set(ctx->genlist_all, EINA_FALSE);
+ elm_genlist_decorate_mode_set(ctx->genlist_missed, EINA_FALSE);
+ }
}
static void _on_more_clicked(void *data __UNUSED__, Evas_Object *obj __UNUSED__,
DBG("TODO");
}
-static Evas_Object *_item_content_get(void *data __UNUSED__, Evas_Object *obj,
- const char *part __UNUSED__)
+static void _on_del_clicked(void *data, Evas_Object *obj __UNUSED__,
+ void *event_info __UNUSED__)
{
- Evas_Object *btn;
+ Call_Info *call_info = data;
+ DBG("call_info=%p, items all=%p missed=%p",
+ call_info, call_info->it_all, call_info->it_missed);
+ _history_call_info_del(call_info);
+}
- btn = gui_layout_add(obj, "history/img");
- EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
- elm_object_signal_callback_add(btn, "clicked,more", "gui",
- _on_more_clicked, NULL);
- evas_object_propagate_events_set(btn, EINA_FALSE);
+static Evas_Object *_item_content_get(void *data, Evas_Object *obj,
+ const char *part)
+{
+ Evas_Object *btn = NULL;
+
+ if (strcmp(part, "call.swallow.more") == 0) {
+ btn = gui_layout_add(obj, "history/img");
+ EINA_SAFETY_ON_NULL_RETURN_VAL(btn, NULL);
+ elm_object_signal_callback_add(btn, "clicked,more", "gui",
+ _on_more_clicked, NULL);
+ evas_object_propagate_events_set(btn, EINA_FALSE);
+ } else if (strcmp(part, "call.swallow.delete") == 0) {
+ btn = elm_button_add(obj);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(btn, NULL);
+ elm_object_style_set(btn, "history-delete");
+ elm_object_text_set(btn, "delete");
+ evas_object_smart_callback_add(btn, "clicked", _on_del_clicked,
+ data);
+ evas_object_propagate_events_set(btn, EINA_FALSE);
+ } else
+ ERR("unknown content part '%s'", part);
return btn;
}
+static void _on_list_slide_enter(void *data __UNUSED__,
+ Evas_Object *obj,
+ void *event_info)
+{
+ Elm_Object_Item *it = elm_genlist_decorated_item_get(obj);
+ DBG("cancel decorated item=%p", it);
+ if (it)
+ elm_genlist_item_decorate_mode_set(it, "slide", EINA_FALSE);
+
+ it = event_info;
+ EINA_SAFETY_ON_NULL_RETURN(it);
+ DBG("it=%p", it);
+ elm_genlist_item_decorate_mode_set(it, "slide", EINA_TRUE);
+}
+
+static void _on_list_slide_cancel(void *data __UNUSED__,
+ Evas_Object *obj,
+ void *event_info __UNUSED__)
+{
+ Elm_Object_Item *it = elm_genlist_decorated_item_get(obj);
+ DBG("it=%p", it);
+ if (it)
+ elm_genlist_item_decorate_mode_set(it, "slide", EINA_FALSE);
+}
+
Evas_Object *history_add(Evas_Object *parent)
{
int r;
EINA_SAFETY_ON_NULL_GOTO(genlist_all, err_object_new);
elm_object_style_set(genlist_all, "history");
+ /* TODO: */
+ evas_object_smart_callback_add(genlist_all, "drag,start,right",
+ _on_list_slide_enter, history);
+ evas_object_smart_callback_add(genlist_all, "drag,start,left",
+ _on_list_slide_cancel, history);
+ evas_object_smart_callback_add(genlist_all, "drag,start,down",
+ _on_list_slide_cancel, history);
+ evas_object_smart_callback_add(genlist_all, "drag,start,up",
+ _on_list_slide_cancel, history);
+
genlist_missed = elm_genlist_add(obj);
EINA_SAFETY_ON_NULL_GOTO(genlist_missed, err_object_new);
elm_object_style_set(genlist_missed, "history");
+ evas_object_smart_callback_add(genlist_missed, "drag,start,right",
+ _on_list_slide_enter, history);
+ evas_object_smart_callback_add(genlist_missed, "drag,start,left",
+ _on_list_slide_cancel, history);
+ evas_object_smart_callback_add(genlist_missed, "drag,start,down",
+ _on_list_slide_cancel, history);
+ evas_object_smart_callback_add(genlist_missed, "drag,start,up",
+ _on_list_slide_cancel, history);
+
itc = elm_genlist_item_class_new();
EINA_SAFETY_ON_NULL_GOTO(itc, err_object_new);
itc->item_style = "history";
itc->func.content_get = _item_content_get;
itc->func.state_get = _item_state_get;
itc->func.del = NULL;
+ itc->decorate_all_item_style = "history-delete";
+ itc->decorate_item_style = "history-delete";
history->genlist_all = genlist_all;
history->genlist_missed = genlist_missed;
history->itc = itc;
elm_object_part_content_set(obj, "elm.swallow.missed", genlist_missed);
elm_object_signal_emit(obj, "show,all", "gui");
elm_object_signal_callback_add(obj, "clicked,*", "gui",
- _on_clicked, NULL);
+ _on_clicked, history);
config_path = efreet_config_home_get();
snprintf(base_dir, sizeof(base_dir), "%s/%s", config_path,