enlightenment/src/modules/time/config.c

635 lines
19 KiB
C

#include "clock.h"
#include <time.h>
static const char *datecfg[] =
{
N_("None"),
N_("Full"),
N_("Numeric"),
N_("Date-only"),
N_("ISO 8601"),
N_("Custom"),
};
static void
_config_rect_click(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Evas_Event_Mouse_Up *ev = event_info;
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
evas_object_del(data);
}
static Evas_Object *
_config_autoclose_rect_add(Evas_Object *obj)
{
Evas_Object *rect;
rect = evas_object_rectangle_add(e_comp->evas);
e_comp_object_util_fullscreen(rect);
evas_object_color_set(rect, 0, 0, 0, 0);
evas_object_layer_set(rect, E_LAYER_MENU - 1);
evas_object_show(rect);
evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_UP, _config_rect_click, obj);
return rect;
}
static void
_config_close(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
time_config->config_dialog = NULL;
}
static void
_config_changed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
time_config_update(data);
}
static void
_clock_color_dismissed(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
evas_object_del(obj);
}
static void
_config_color_reset(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Config_Item *ci = data;
Evas_Object *cs;
int num;
num = !evas_object_data_get(obj, "bg_color");
if (ci->colorclass[num])
{
elm_config_color_overlay_unset(ci->colorclass[num]);
edje_color_class_del(ci->colorclass[num]);
}
eina_stringshare_replace(&ci->colorclass[num], NULL);
cs = evas_object_data_get(obj, "colorselector");
elm_colorselector_color_set(cs, 0, 0, 0, 0);
elm_colorselector_palette_item_color_set(evas_object_data_get(cs, "colorselector_it"),
0, 0, 0, 0);
time_config_update(data);
}
static void
_config_color_change(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Config_Item *ci = data;
int r, g, b, a;
int num;
char buf[1024];
num = !evas_object_data_get(obj, "bg_color");
elm_colorselector_color_get(obj, &r, &g, &b, &a);
if (!ci->colorclass[num])
{
snprintf(buf, sizeof(buf), "e.clock_color_%s.%d", num ? "fg" : "bg", ci->id);
eina_stringshare_replace(&ci->colorclass[num], buf);
}
elm_config_color_overlay_set(ci->colorclass[num], r, g, b, a, 0, 0, 0, 0, 0, 0, 0, 0);
edje_color_class_set(ci->colorclass[num], r, g, b, a, 0, 0, 0, 0, 0, 0, 0, 0);
elm_colorselector_palette_item_color_set(evas_object_data_get(obj, "colorselector_it"), r, g, b, a);
time_config_update(data);
}
static void
_config_color_setup(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Config_Item *ci = data;
Evas_Object *cs, *ctx, *bx, *bt, *rect;
int r, g, b, a, x, y;
Eina_Bool bg;
const char *ccname, *ccnames[] =
{
"e.clock_color_bg",
"e.clock_color_fg",
};
bg = !!evas_object_data_get(obj, "bg_color");
ccname = ci->colorclass[!bg];
if (!ccname) ccname = ccnames[!bg];
edje_color_class_get(ccname, &r, &g, &b, &a,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
bx = elm_box_add(obj);
E_FILL(bx);
evas_object_show(bx);
cs = elm_colorselector_add(obj);
evas_object_data_set(cs, "colorselector_bt", evas_object_data_get(obj, "colorselector_tt"));
evas_object_data_set(cs, "bg_color", (void*)(long)bg);
evas_object_smart_callback_add(cs, "changed,user", _config_color_change, ci);
elm_colorselector_mode_set(cs, ELM_COLORSELECTOR_COMPONENTS);
elm_colorselector_color_set(cs, r, g, b, a);
E_FILL(cs);
elm_box_pack_end(bx, cs);
evas_object_show(cs);
bt = elm_button_add(bx);
evas_object_data_set(bt, "colorselector", cs);
evas_object_data_set(bt, "bg_color", (void*)(long)bg);
elm_object_text_set(bt, _("Reset"));
evas_object_smart_callback_add(bt, "clicked", _config_color_reset, ci);
evas_object_show(bt);
elm_box_pack_end(bx, bt);
/* size hints: the final frontier */
rect = evas_object_rectangle_add(e_comp->elm);
evas_object_geometry_get(time_config->config_dialog, NULL, NULL, &x, &y);
evas_object_size_hint_min_set(rect, x - 10, 1);
e_comp_object_util_del_list_append(bx, rect);
elm_box_pack_end(bx, rect);
ctx = elm_ctxpopup_add(obj);
elm_ctxpopup_hover_parent_set(ctx, e_comp->elm);
evas_object_layer_set(ctx, E_LAYER_MENU);
elm_object_style_set(ctx, "noblock");
rect = _config_autoclose_rect_add(ctx);
evas_object_smart_callback_call(ci->inst->o_clock, "gadget_popup", rect);
e_comp_object_util_del_list_append(ctx, rect);
evas_object_smart_callback_add(ctx, "dismissed", _clock_color_dismissed, NULL);
elm_object_content_set(ctx, bx);
evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
evas_object_move(ctx, x, y);
evas_object_show(ctx);
}
static void
_config_digital_timestr_update(Config_Item *ci, Evas_Object *obj, int idx)
{
const char *str, *p;
char seconds[] =
{
'S',
's',
'r',
'T',
};
unsigned int i;
str = elm_entry_entry_get(obj);
eina_stringshare_replace(&ci->time_str[idx], str);
ci->show_seconds = 0;
for (p = strchr(str, '%'); p; p = strchr(p + 1, '%'))
{
for (i = 0; i < EINA_C_ARRAY_LENGTH(seconds); i++)
if (p[1] == seconds[i])
{
ci->show_seconds = 1;
time_config_update(ci);
return;
}
}
time_config_update(ci);
}
static void
_config_digital_datestr_changed(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
_config_digital_timestr_update(data, obj, 1);
}
static Evas_Object *
_config_date_custom(Config_Item *ci, Evas_Object *bx)
{
Evas_Object *o;
o = elm_entry_add(bx);
elm_entry_single_line_set(o, 1);
elm_object_tooltip_text_set(o, _("strftime() format string"));
elm_entry_entry_set(o, ci->time_str[1]);
evas_object_smart_callback_add(o, "changed,user", _config_digital_datestr_changed, ci);
E_FILL(o);
E_EXPAND(o);
evas_object_show(o);
elm_box_pack_end(bx, o);
return o;
}
static void
_config_date_changed(void *data, Evas_Object *obj, void *event_info)
{
Config_Item *ci = data;
Evas_Object *bx = elm_object_parent_widget_get(obj);
Eina_Bool custom;
custom = ci->show_date == CLOCK_DATE_DISPLAY_CUSTOM;
ci->show_date = (intptr_t)elm_object_item_data_get(event_info);
if (custom)
{
elm_box_unpack(bx, obj);
elm_box_clear(bx);
E_FILL(obj);
E_EXPAND(obj);
elm_box_pack_end(bx, obj);
}
else if (ci->show_date == CLOCK_DATE_DISPLAY_CUSTOM)
{
E_WEIGHT(obj, 0, 0);
E_ALIGN(obj, 0, 0.5);
elm_object_focus_set(_config_date_custom(ci, bx), 1);
}
time_config_update(ci);
}
static void
_config_weekend_changed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Config_Item *ci = data;
ci->weekend.start = (intptr_t)elm_object_item_data_get(event_info);
time_config_update(ci);
}
static void
_config_weekend_end_changed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Config_Item *ci = data;
int end;
end = (intptr_t)elm_object_item_data_get(event_info);
if (end < ci->weekend.start) end += 7;
ci->weekend.len = end - ci->weekend.start + 1;
time_config_update(ci);
}
static void
_config_date_populate(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Config_Item *ci = data;
unsigned int i;
elm_hoversel_clear(obj);
for (i = 0; i <= 5; i++)
if (ci->show_date != i)
elm_hoversel_item_add(obj, datecfg[i], NULL, ELM_ICON_NONE, NULL, (uintptr_t*)(unsigned long)i);
}
static void
_config_weekend_populate(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Config_Item *ci = data;
char daynames[7][64];
struct tm tm;
int i;
memset(&tm, 0, sizeof(struct tm));
for (i = 0; i < 7; i++)
{
tm.tm_wday = i;
strftime(daynames[i], sizeof(daynames[i]), "%A", &tm);
}
elm_hoversel_clear(obj);
for (i = ci->weekend.start + 1; i <= 6; i++)
if (ci->weekend.start != i)
elm_hoversel_item_add(obj, daynames[i], NULL, ELM_ICON_NONE, NULL, (intptr_t*)(long)i);
for (i = 0; i < ci->weekend.start; i++)
elm_hoversel_item_add(obj, daynames[i], NULL, ELM_ICON_NONE, NULL, (intptr_t*)(long)i);
}
static void
_config_weekend_end_populate(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Config_Item *ci = data;
char daynames[7][64];
struct tm tm;
int i, end;
memset(&tm, 0, sizeof(struct tm));
for (i = 0; i < 7; i++)
{
tm.tm_wday = i;
strftime(daynames[i], sizeof(daynames[i]), "%A", &tm);
}
elm_hoversel_clear(obj);
end = (ci->weekend.start + ci->weekend.len - 1) % 7;
for (i = end + 1; i <= 6; i++)
if (end != i)
elm_hoversel_item_add(obj, daynames[i], NULL, ELM_ICON_NONE, NULL, (intptr_t*)(long)i);
for (i = 0; i < end; i++)
elm_hoversel_item_add(obj, daynames[i], NULL, ELM_ICON_NONE, NULL, (intptr_t*)(long)i);
}
static void
_config_timezone_setup(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Evas_Object *hover, *gl, *r;
Config_Item *ci = data;
hover = elm_hover_add(e_comp->elm);
evas_object_layer_set(hover, E_LAYER_MENU);
elm_hover_parent_set(hover, elm_object_parent_widget_get(obj));
elm_hover_target_set(hover, elm_object_parent_widget_get(obj));
gl = elm_genlist_add(hover);
evas_object_layer_set(gl, E_LAYER_MENU);
evas_object_data_set(gl, "config_item", data);
evas_object_data_set(gl, "button", obj);
elm_genlist_mode_set(gl, ELM_LIST_COMPRESS);
elm_genlist_homogeneous_set(gl, 1);
elm_scroller_bounce_set(gl, 0, 0);
evas_object_show(gl);
elm_object_part_content_set(hover, "middle", gl);
time_zoneinfo_scan(gl);
e_comp_object_util_del_list_append(gl, hover);
r = _config_autoclose_rect_add(gl);
evas_object_smart_callback_call(ci->inst->o_clock, "gadget_popup", r);
e_comp_object_util_del_list_append(gl, r);
evas_object_show(hover);
}
static void
_config_digital_timestr_changed(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
_config_digital_timestr_update(data, obj, 0);
}
static void
_config_label_add(Evas_Object *tb, const char *txt, int row)
{
Evas_Object *o;
o = elm_label_add(tb);
E_ALIGN(o, 0, 0.5);
elm_object_text_set(o, txt);
evas_object_show(o);
elm_table_pack(tb, o, 0, row, 1, 1);
}
static void
_config_digital_rows_setup(Config_Item *ci, Evas_Object *tb)
{
int row = 1;
Evas_Object *o;
evas_object_del(elm_table_child_get(tb, 0, 1));
evas_object_del(elm_table_child_get(tb, 1, 1));
evas_object_del(elm_table_child_get(tb, 0, 2));
evas_object_del(elm_table_child_get(tb, 1, 2));
if (ci->advanced)
{
_config_label_add(tb, _("Time string:"), row);
o = elm_entry_add(tb);
E_FILL(o);
evas_object_show(o);
elm_entry_single_line_set(o, 1);
elm_entry_entry_set(o, ci->time_str[0]);
elm_object_focus_set(o, 1);
evas_object_smart_callback_add(o, "changed,user", _config_digital_timestr_changed, ci);
elm_table_pack(tb, o, 1, row++, 1, 1);
o = elm_separator_add(tb);
E_EXPAND(o);
E_FILL(o);
elm_separator_horizontal_set(o, 1);
evas_object_show(o);
elm_table_pack(tb, o, 0, row++, 2, 1);
return;
}
if (ci->digital_clock)
{
_config_label_add(tb, _("24-hour Display:"), row);
o = elm_check_add(tb);
E_FILL(o);
evas_object_show(o);
elm_object_style_set(o, "toggle");
elm_object_part_text_set(o, "on", "On");
elm_object_part_text_set(o, "off", "Off");
elm_check_state_pointer_set(o, &ci->digital_24h);
evas_object_smart_callback_add(o, "changed", _config_changed, ci);
elm_table_pack(tb, o, 1, row++, 1, 1);
}
_config_label_add(tb, _("Show Seconds:"), row);
o = elm_check_add(tb);
E_FILL(o);
evas_object_show(o);
elm_object_style_set(o, "toggle");
elm_object_part_text_set(o, "on", _("On"));
elm_object_part_text_set(o, "off", _("Off"));
elm_check_state_pointer_set(o, &ci->show_seconds);
evas_object_smart_callback_add(o, "changed", _config_changed, ci);
elm_table_pack(tb, o, 1, row++, 1, 1);
}
static void
_config_advanced_changed(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Config_Item *ci = data;
_config_digital_rows_setup(data, evas_object_data_get(obj, "table"));
time_config_update(ci);
}
EINTERN Evas_Object *
config_clock(Config_Item *ci, E_Zone *zone)
{
Evas_Object *popup, *tb, *o, *bx;
int i, row = 0;
char daynames[7][64];
struct tm tm;
if (!zone) zone = e_zone_current_get();
memset(&tm, 0, sizeof(struct tm));
for (i = 0; i < 7; i++)
{
tm.tm_wday = i;
strftime(daynames[i], sizeof(daynames[i]), "%A", &tm);
}
popup = elm_popup_add(e_comp->elm);
E_EXPAND(popup);
evas_object_layer_set(popup, E_LAYER_POPUP);
elm_popup_allow_events_set(popup, 1);
elm_popup_scrollable_set(popup, 1);
tb = elm_table_add(popup);
E_EXPAND(tb);
evas_object_show(tb);
elm_object_content_set(popup, tb);
if (ci->digital_clock)
{
_config_label_add(tb, _("Mode"), row);
o = elm_check_add(tb);
E_FILL(o);
evas_object_show(o);
elm_object_style_set(o, "toggle");
elm_object_part_text_set(o, "on", _("Advanced"));
elm_object_part_text_set(o, "off", _("Simple"));
elm_check_state_pointer_set(o, &ci->advanced);
evas_object_smart_callback_add(o, "changed", _config_advanced_changed, ci);
evas_object_data_set(o, "table", tb);
elm_table_pack(tb, o, 1, row++, 1, 1);
}
_config_digital_rows_setup(ci, tb);
row = 3;
_config_label_add(tb, _("Date Display:"), row);
bx = elm_box_add(tb);
elm_box_horizontal_set(bx, 1);
evas_object_show(bx);
elm_table_pack(tb, bx, 1, row++, 1, 1);
E_FILL(bx);
E_EXPAND(bx);
o = elm_hoversel_add(tb);
elm_box_pack_end(bx, o);
elm_hoversel_hover_parent_set(o, popup);
elm_hoversel_auto_update_set(o, 1);
evas_object_show(o);
evas_object_smart_callback_add(o, "clicked", _config_date_populate, ci);
evas_object_smart_callback_add(o, "selected", _config_date_changed, ci);
elm_object_text_set(o, datecfg[ci->show_date]);
if (ci->show_date == CLOCK_DATE_DISPLAY_CUSTOM)
{
E_ALIGN(o, 0, 0.5);
E_WEIGHT(o, 0, 0);
_config_date_custom(ci, bx);
}
else
{
E_FILL(o);
E_EXPAND(o);
}
_config_label_add(tb, _("Weekend Start:"), row);
o = elm_hoversel_add(tb);
E_FILL(o);
elm_hoversel_hover_parent_set(o, popup);
elm_hoversel_auto_update_set(o, 1);
evas_object_show(o);
elm_table_pack(tb, o, 1, row++, 1, 1);
elm_object_text_set(o, daynames[ci->weekend.start]);
evas_object_smart_callback_add(o, "clicked", _config_weekend_populate, ci);
evas_object_smart_callback_add(o, "selected", _config_weekend_changed, ci);
_config_label_add(tb, _("Weekend End:"), row);
o = elm_hoversel_add(tb);
E_FILL(o);
elm_hoversel_hover_parent_set(o, popup);
elm_hoversel_auto_update_set(o, 1);
evas_object_show(o);
elm_table_pack(tb, o, 1, row++, 1, 1);
elm_object_text_set(o, daynames[(ci->weekend.start + ci->weekend.len - 1) % 7]);
evas_object_smart_callback_add(o, "clicked", _config_weekend_end_populate, ci);
evas_object_smart_callback_add(o, "selected", _config_weekend_end_changed, ci);
_config_label_add(tb, _("Timezone:"), row);
o = elm_button_add(tb);
E_FILL(o);
elm_object_text_set(o, ci->timezone ?: _("System"));
evas_object_show(o);
evas_object_smart_callback_add(o, "clicked", _config_timezone_setup, ci);
elm_table_pack(tb, o, 1, row++, 1, 1);
for (i = 0; i <= 1; i++)
{
const char *ccname, *names[] =
{
N_("Background"),
N_("Foreground"),
};
const char *ccnames[] =
{
"e.clock_color_bg",
"e.clock_color_fg",
};
Evas_Object *cs;
Elm_Object_Item *it;
int r, g, b, a;
cs = elm_colorselector_add(tb);
elm_colorselector_mode_set(cs, ELM_COLORSELECTOR_PALETTE);
ccname = ci->colorclass[i];
if (!ccname) ccname = ccnames[i];
edje_color_class_get(ccname, &r, &g, &b, &a,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
it = elm_colorselector_palette_color_add(cs, r, g, b, a);
o = elm_button_add(tb);
elm_object_text_set(o, names[i]);
elm_object_content_set(o, cs);
E_FILL(o);
if (!i)
evas_object_data_set(o, "bg_color", (void*)1L);
evas_object_data_set(o, "colorselector_it", it);
evas_object_smart_callback_add(o, "clicked", _config_color_setup, ci);
evas_object_show(o);
elm_table_pack(tb, o, i, row, 1, 1);
}
popup = e_comp_object_util_add(popup, E_COMP_OBJECT_TYPE_NONE);
evas_object_layer_set(popup, E_LAYER_POPUP);
evas_object_move(popup, zone->x, zone->y);
evas_object_resize(popup, zone->w / 4, zone->h / 3);
e_comp_object_util_center(popup);
evas_object_show(popup);
e_comp_object_util_autoclose(popup, NULL, e_comp_object_util_autoclose_on_escape, NULL);
evas_object_event_callback_add(popup, EVAS_CALLBACK_DEL, _config_close, NULL);
return time_config->config_dialog = popup;
}
static char *
_config_timezone_text_get(const char *str, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
{
return strdup(str);
}
static void
_config_timezone_text_del(void *d, Evas_Object *obj EINA_UNUSED)
{
free(d);
}
static int
_config_timezone_sort(void *ita, void *itb)
{
const char *a, *b;
a = elm_object_item_data_get(ita);
b = elm_object_item_data_get(itb);
return strcmp(a, b);
}
static void
_config_timezone_set(void *data EINA_UNUSED, Evas_Object *obj, void *event_info)
{
char *tz = elm_object_item_data_get(event_info);
Config_Item *ci;
Evas_Object *bt;
ci = evas_object_data_get(obj, "config_item");
bt = evas_object_data_get(obj, "button");
eina_stringshare_replace(&ci->timezone, tz);
elm_object_text_set(bt, tz);
time_config_update(ci);
evas_object_del(obj);
}
EINTERN void
config_timezone_populate(Evas_Object *obj, const char *name)
{
static const Elm_Genlist_Item_Class itc =
{
.item_style = "default",
.func = {
.text_get = (Elm_Genlist_Item_Text_Get_Cb)_config_timezone_text_get,
.del = _config_timezone_text_del,
},
.version = ELM_GENLIST_ITEM_CLASS_VERSION
};
Config_Item *ci;
Elm_Object_Item *it;
it = elm_genlist_item_sorted_insert(obj, &itc, strdup(name), NULL, 0, (Eina_Compare_Cb)_config_timezone_sort, _config_timezone_set, NULL);
ci = evas_object_data_get(obj, "config_item");
if (eina_streq(name, ci->timezone))
elm_genlist_item_bring_in(it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
}