colorclass: add subsystem for remotely editing colorclasses over dbus

the winid should match the e_pixmap id

also various theme improvements
This commit is contained in:
Mike Blumenkrantz 2015-04-05 16:02:05 -04:00
parent 0e754183ac
commit 84b68085c3
8 changed files with 624 additions and 51 deletions

View File

@ -1,6 +1,34 @@
group { "elm/layout/colorclass/base"; program_source: "elm"; nobroadcast;
parts {
swallow { "elm.swallow.list"; }
rect { "clip"; }
rect { "remote_fader";
desc { hid;
color: 0 0 0 0;
}
desc { "vis";
color: 0 0 0 192;
link.base: "elm,state,remote";
}
program { signal: "mouse,down,1"; source: "remote_fader";
action: SIGNAL_EMIT "elm,colorclass,dismiss" "elm";
}
}
rect { "list_bg";
desc {
color: 64 64 64 255;
color_class: "dialog_base";
rel1.to: "elm.swallow.list";
rel2.to: "elm.swallow.list";
}
}
swallow { "elm.swallow.list";
desc {}
desc { "remote";
rel1.relative: 0.1 0.1;
rel2.relative: 0.9 0.9;
link.base: "elm,state,remote";
}
}
rect { "fader";
desc { hid;
color: 0 0 0 0;
@ -20,24 +48,26 @@ group { "elm/layout/colorclass/base"; program_source: "elm"; nobroadcast;
}
desc { "vis";
rel1.to: "colors";
rel2.to: "colors";
rel2.to_x: "colors";
color: 0 0 0 225;
}
}
alias: "elm.swallow.colors" "colors:colors";
group { "colors"; source: "colorclass/colors";
group { "colors"; source: "colorclass/colors"; clip: "clip";
desc { hid; align: 0 0;
rel1.relative: 1.1 0.1;
rel2.relative: 1.9 0;
rel2.to_y: "elm.swallow.reset";
fixed: 1 1;
}
desc { "vis"; align: 0 0;
rel1.relative: 0.1 0.1;
rel2.relative: 0.9 0;
rel2.to_y: "elm.swallow.reset";
fixed: 1 1;
}
}
swallow { "elm.swallow.reset";
swallow { "elm.swallow.reset"; clip: "clip";
desc { hid; min: 40 24; max: 40 24;
align: 0.5 1;
rel1.relative: 1.0 0.0;
@ -49,10 +79,48 @@ group { "elm/layout/colorclass/base"; program_source: "elm"; nobroadcast;
rel2.relative: 1.0 1.0;
}
}
rect { "text_bg";
desc { hid;
color: 64 64 64 255;
color_class: "dialog_base";
rel1.relative: 0.5 0.5;
rel2.relative: 0.5 0.5;
}
desc { "vis";
color: 64 64 64 255;
color_class: "dialog_base";
rel1.to: "elm.swallow.list";
rel2.to: "elm.swallow.list";
}
}
text { "elm.text";
scale;
desc { hid;
color: FN_COL_DEFAULT_BASIC;
rel1.relative: 0.1 0.1;
rel2.relative: 0.9 0.9;
text { font: FN; size: 10;
min: 1 1;
ellipsis: -1;
fit: 1 0;
}
}
desc { "vis"; inherit: "default"; vis; }
}
program { signal: "elm,state,info";
action: STATE_SET "vis";
transition: LINEAR 0.2;
targets: "text_bg" "elm.text";
}
program { signal: "elm,state,loaded";
action: STATE_SET "default";
transition: LINEAR 0.2;
targets: "text_bg" "elm.text";
}
program { signal: "elm,colors,hide";
action: STATE_SET "default";
transition: LINEAR 0.2;
targets: "fader" "colors" "elm.swallow.reset" "bg";
action: STATE_SET "default";
transition: LINEAR 0.2;
targets: "fader" "colors" "elm.swallow.reset" "bg";
}
program { signal: "elm,colors,show";
transition: LINEAR 0.2;
@ -216,7 +284,7 @@ group { "colorclass/color1"; nomouse; nobroadcast;
rel1.relative: 1.0 0.0;
rel2.offset: -3 -1;
rel2.relative: 0 1;
color: 255 255 255 255;
color: FN_COL_DEFAULT_BASIC;
text { font: FN; size: 10;
min: 1 1;
ellipsis: -1;

View File

@ -17,7 +17,8 @@ test_colorclass()
win = elm_win_util_standard_add("colorclass", "Color Classes");
elm_win_autodel_set(win, EINA_TRUE);
cc = elm_color_class_editor_add(win, tl_cb);
elm_color_class_translate_cb_set(tl_cb);
cc = elm_color_class_editor_add(win, 0);
elm_win_resize_object_add(win, cc);
evas_object_size_hint_weight_set(cc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(cc, EVAS_HINT_FILL, EVAS_HINT_FILL);

View File

@ -388,6 +388,11 @@ elm_win_legacy.h \
elm_helper.h
includesubdir = $(includedir)/elementary-@VMAJ@/
COLORCLASS_GEN = \
eldbus_elementary_colorclass.c \
eldbus_elementary_colorclass.h \
eldbus_utils.h
libelementary_la_SOURCES = \
elm_priv.h \
els_box.h \
@ -502,7 +507,8 @@ elm_helper.c \
els_box.c \
els_cursor.c \
els_tooltip.c \
elu_ews_wm.c
elu_ews_wm.c \
$(COLORCLASS_GEN)
libelementary_la_CFLAGS = @ELEMENTARY_CFLAGS@
libelementary_la_LIBADD = \
@ -512,10 +518,17 @@ libelementary_la_LIBADD = \
libelementary_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
EXTRA_DIST = \
elm_color_class.xml \
elm_factory.h \
elm_factory.c \
elm_intro.h.in
$(COLORCLASS_GEN): elm_color_class.xml
@cd $(top_builddir)/src/lib && \
eldbus-codegen $(abs_top_srcdir)/src/lib/elm_color_class.xml
elm_color_class.c: $(COLORCLASS_GEN)
elm_eolian_files = \
elm_access.eo \
elm_actionslider.eo \
@ -772,3 +785,4 @@ endif
MAINTAINERCLEANFILES += $(COLORCLASS_GEN)

View File

@ -3,10 +3,13 @@
#endif
#include <Elementary.h>
#include "elm_priv.h"
#include "elm_color_class.h"
#include "eldbus_elementary_colorclass.h"
static Eldbus_Proxy *cc_proxy;
static Ecore_Event_Handler *h1;
static Ecore_Event_Handler *h2;
typedef struct Colorclass
{
@ -19,11 +22,14 @@ typedef struct Colorclass
typedef struct Colorclass_UI
{
EINA_INLIST;
Evas_Object *ly;
Evas_Object *gl;
Evas_Object *reset;
Evas_Object *cs;
Elm_Color_Class_Name_Cb cb;
uint64_t winid;
Ecore_Timer *timer;
Colorclass *current; //actually Elm_Color_Overlay
unsigned int num; //color[num]
@ -32,6 +38,24 @@ typedef struct Colorclass_UI
Eina_Bool exist : 1;
} Colorclass_UI;
typedef enum
{
COLORCLASS_SIGNAL_EDIT,
COLORCLASS_SIGNAL_CHANGED,
} Colorclass_Signals;
static const Eldbus_Signal colorclass_editor_signals[] =
{
[COLORCLASS_SIGNAL_EDIT] = {"Edit", ELDBUS_ARGS({"t", "Window ID"}), 0},
[COLORCLASS_SIGNAL_CHANGED] = {"Changed", ELDBUS_ARGS({"t", "Window ID"}, {"s", "Color class name"}, {"a(iiii)", "Colors"}), 0},
{NULL, NULL, 0}
};
static Eina_Inlist *remote_ccuis;
static Eldbus_Service_Interface *remote_iface;
static Elm_Color_Class_Name_Cb tl_cb;
static Elm_Color_Class_List_Cb list_cb;
static void
_colorclass_cc_update(Colorclass_UI *cc, int num)
{
@ -44,6 +68,29 @@ _colorclass_cc_update(Colorclass_UI *cc, int num)
0, 0, 0, 0);
}
static void
_dbus_signal_changed(Colorclass_UI *cc)
{
Eldbus_Message *msg;
Eldbus_Message_Iter *iter, *array, *struc;
int x;
msg = eldbus_service_signal_new(remote_iface, COLORCLASS_SIGNAL_CHANGED);
eldbus_message_arguments_append(msg, "t", cc->winid);
eldbus_message_arguments_append(msg, "s", cc->current->name);
iter = eldbus_message_iter_get(msg);
array = eldbus_message_iter_container_new(iter, 'a', "(iiii)");
for (x = 0; x < 3; x++)
{
eldbus_message_iter_arguments_append(array, "(iiii)", &struc);
eldbus_message_iter_arguments_append(struc, "iiii",
cc->current->color[x].r, cc->current->color[x].g, cc->current->color[x].b, cc->current->color[x].a);
eldbus_message_iter_container_close(array, struc);
}
eldbus_message_iter_container_close(iter, array);
eldbus_service_signal_send(remote_iface, msg);
}
static void
_colorclass_select(void *data, Evas_Object *obj EINA_UNUSED, const char *sig, const char *src EINA_UNUSED)
{
@ -74,10 +121,13 @@ _colorclass_changed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info E
elm_colorselector_color_get(cc->cs, (int*)&cc->current->color[cc->num].r, (int*)&cc->current->color[cc->num].g,
(int*)&cc->current->color[cc->num].b, (int*)&cc->current->color[cc->num].a);
edje_color_class_set(cc->current->name,
cc->current->color[0].r, cc->current->color[0].g, cc->current->color[0].b, cc->current->color[0].a,
cc->current->color[1].r, cc->current->color[1].g, cc->current->color[1].b, cc->current->color[1].a,
cc->current->color[2].r, cc->current->color[2].g, cc->current->color[2].b, cc->current->color[2].a);
if (remote_iface)
_dbus_signal_changed(cc);
else
edje_color_class_set(cc->current->name,
cc->current->color[0].r, cc->current->color[0].g, cc->current->color[0].b, cc->current->color[0].a,
cc->current->color[1].r, cc->current->color[1].g, cc->current->color[1].b, cc->current->color[1].a,
cc->current->color[2].r, cc->current->color[2].g, cc->current->color[2].b, cc->current->color[2].a);
edje_color_class_set("elm_colorclass_text",
cc->current->color[0].r, cc->current->color[0].g, cc->current->color[0].b, cc->current->color[0].a,
cc->current->color[1].r, cc->current->color[1].g, cc->current->color[1].b, cc->current->color[1].a,
@ -111,6 +161,8 @@ _colorclass_reset(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EIN
_colorclass_cc_update(cc, 0);
_colorclass_cc_update(cc, 1);
_colorclass_cc_update(cc, 2);
if (remote_iface)
_dbus_signal_changed(cc);
}
static void
@ -188,19 +240,38 @@ _colorclass_deactivate(void *data, Evas_Object *obj EINA_UNUSED, const char *sig
elm_genlist_item_selected_set(elm_genlist_selected_item_get(cc->gl), 0);
}
static void
_colorclass_dismiss(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
{
Colorclass_UI *cc = data;
evas_object_smart_callback_call(cc->ly, "dismissed", NULL);
}
static void
_colorclass_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Colorclass_UI *cc = data;
_colorclass_save(cc);
if (cc->winid)
remote_ccuis = eina_inlist_remove(remote_ccuis, EINA_INLIST_GET(cc));
if (remote_iface && (!remote_ccuis))
{
Eldbus_Connection *conn;
conn = eldbus_service_connection_get(remote_iface);
eldbus_name_release(conn, ELM_COLOR_CLASS_METHOD_BASE, NULL, NULL);
ELM_SAFE_FREE(remote_iface, eldbus_service_interface_unregister);
eldbus_connection_unref(conn);
}
free(cc);
}
static char *
_colorclass_text_get(Edje_Color_Class *ecc, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
{
if (ecc->desc) return strdup(ecc->desc);
if (ecc->desc && ecc->desc[0]) return strdup(ecc->desc);
return strdup(ecc->name ?: "");
}
@ -212,50 +283,366 @@ _colorclass_item_del(Edje_Color_Class *ecc, Evas_Object *obj EINA_UNUSED)
free(ecc);
}
static void
_dbus_request_name_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
{
unsigned int flag;
Colorclass_UI *cc = data;
if (eldbus_message_error_get(msg, NULL, NULL) ||
(!eldbus_message_arguments_get(msg, "u", &flag)) ||
(!(flag & ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER)))
{
/* FIXME: translate */
elm_object_text_set(cc->ly, "The color editor could not assume ownership of the DBus interface.");
elm_object_signal_emit(cc->ly, "elm,state,info", "elm");
return;
}
if (remote_ccuis)
eldbus_service_signal_emit(remote_iface, COLORCLASS_SIGNAL_EDIT, cc->winid);
}
static Evas_Object *
_colorclass_find_win(uint64_t winid)
{
Evas_Object *win;
Eina_List *l;
pid_t pid = getpid();
EINA_LIST_FOREACH(_elm_win_list, l, win)
{
Ecore_Evas *ee;
const char *engine_name;
uint64_t id = elm_win_window_id_get(win);
ee = ecore_evas_ecore_evas_get(evas_object_evas_get(win));
engine_name = ecore_evas_engine_name_get(ee);
if (!strncmp(engine_name, "wayland", sizeof("wayland") - 1))
id = ((uint64_t)id << 32) + pid;
if (id == winid) return win;
}
return NULL;
}
static void
_dbus_edit_helper(Eldbus_Message_Iter *array, Colorclass *lcc)
{
Eldbus_Message_Iter *struc, *array2, *struc2;
int x;
char *desc = "";
eldbus_message_iter_arguments_append(array, "(ssa(iiii))", &struc);
if (lcc)
{
if (lcc->desc && lcc->desc[0])
desc = tl_cb ? tl_cb((char*)lcc->desc) : (char*)lcc->desc;
eldbus_message_iter_arguments_append(struc, "ss", lcc->name, desc);
}
else
eldbus_message_iter_arguments_append(struc, "ss", "", desc);
array2 = eldbus_message_iter_container_new(struc, 'a', "(iiii)");
for (x = 0; x < 3; x++)
{
eldbus_message_iter_arguments_append(array2, "(iiii)", &struc2);
if (lcc)
eldbus_message_iter_arguments_append(struc2, "iiii",
lcc->color[x].r, lcc->color[x].g, lcc->color[x].b, lcc->color[x].a);
else
eldbus_message_iter_arguments_append(struc2, "iiii", 0, 0, 0, 0);
eldbus_message_iter_container_close(array2, struc2);
}
eldbus_message_iter_container_close(struc, array2);
eldbus_message_iter_container_close(array, struc);
}
static Eina_Bool
_dbus_edit(void *d EINA_UNUSED, int t EINA_UNUSED, Elementary_Colorclass_Edit_Data *ev)
{
Evas_Object *win;
Eldbus_Message *msg;
Eldbus_Message_Iter *iter, *array;
Eina_Iterator *it;
Eina_List *eccs = NULL;
win = _colorclass_find_win(ev->winid);
if (!win) return ECORE_CALLBACK_RENEW;
msg = eldbus_proxy_method_call_new(cc_proxy, "SendCC");
iter = eldbus_message_iter_get(msg);
eldbus_message_arguments_append(msg, "t", ev->winid);
iter = eldbus_message_iter_get(msg);
array = eldbus_message_iter_container_new(iter, 'a', "(ssa(iiii))");
if (list_cb)
eccs = list_cb();
it = edje_color_class_active_iterator_new();
if (it || eccs)
{
Edje_Color_Class *ecc;
Eina_Hash *test = NULL;
if (it && eccs)
test = eina_hash_string_superfast_new(NULL);
if (it)
{
EINA_ITERATOR_FOREACH(it, ecc)
{
if (test)
eina_hash_add(test, ecc->name, ecc);
_dbus_edit_helper(array, (Colorclass*)ecc);
}
}
EINA_LIST_FREE(eccs, ecc)
{
if (test && (!eina_hash_find(test, ecc->name)))
{
eina_hash_add(test, ecc->name, ecc);
_dbus_edit_helper(array, (Colorclass*)ecc);
}
}
eina_hash_free(test);
}
else
_dbus_edit_helper(array, NULL);
eldbus_message_iter_container_close(iter, array);
eina_iterator_free(it);
eldbus_proxy_send(cc_proxy, msg, NULL, NULL, -1);
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
_dbus_changed(void *d EINA_UNUSED, int t EINA_UNUSED, Elementary_Colorclass_Changed_Data *ev)
{
Eina_Value idv, array;
uint64_t id;
char *name;
Evas_Object *win;
unsigned int i;
int color[3][4];
eina_value_struct_value_get(ev->value, "arg0", &idv);
eina_value_get(&idv, &id);
win = _colorclass_find_win(id);
eina_value_flush(&idv);
if (!win) return ECORE_CALLBACK_RENEW;
eina_value_struct_value_get(ev->value, "arg1", &idv);
eina_value_get(&idv, &name);
eina_value_struct_value_get(ev->value, "arg2", &array);
if (eina_value_array_count(&array) != 3)
{
ERR("Someone is failing at sending color class data over dbus!");
goto out;
}
for (i = 0; i < eina_value_array_count(&array); i++)
{
Eina_Value struc2, c;
eina_value_array_value_get(&array, i, &struc2);
eina_value_struct_value_get(&struc2, "arg0", &c);
eina_value_get(&c, &color[i][0]);
eina_value_struct_value_get(&struc2, "arg1", &c);
eina_value_get(&c, &color[i][1]);
eina_value_struct_value_get(&struc2, "arg2", &c);
eina_value_get(&c, &color[i][2]);
eina_value_struct_value_get(&struc2, "arg3", &c);
eina_value_get(&c, &color[i][3]);
eina_value_flush(&c);
eina_value_flush(&struc2);
}
edje_color_class_set(name, color[0][0], color[0][1], color[0][2], color[0][3],
color[1][0], color[1][1], color[1][2], color[1][3],
color[2][0], color[2][1], color[2][2], color[2][3]);
out:
eina_value_flush(&idv);
eina_value_flush(&array);
return ECORE_CALLBACK_RENEW;
}
static Elm_Genlist_Item_Class itc =
{
.item_style = "default",
.func = {
.text_get = (Elm_Genlist_Item_Text_Get_Cb)_colorclass_text_get,
.del = (Elm_Genlist_Item_Del_Cb)_colorclass_item_del
},
.version = ELM_GENLIST_ITEM_CLASS_VERSION
};
static Colorclass_UI *
_dbus_ccui_find(uint64_t winid)
{
Colorclass_UI *cc;
EINA_INLIST_FOREACH(remote_ccuis, cc)
if (cc->winid == winid)
return cc;
return NULL;
}
static Eldbus_Message *
_dbus_close(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
{
Colorclass_UI *cc;
uint64_t winid;
if (!eldbus_message_arguments_get(msg, "t", &winid))
return eldbus_message_method_return_new(msg);
cc = _dbus_ccui_find(winid);
if (cc)
{
evas_object_smart_callback_call(cc->ly, "application_closed", NULL);
ELM_SAFE_FREE(cc->timer, ecore_timer_del);
}
return eldbus_message_method_return_new(msg);
}
static Eldbus_Message *
_dbus_send_cc(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
{
Colorclass_UI *cc;
Eldbus_Message_Iter *array, *struc;
uint64_t winid;
if (!eldbus_message_arguments_get(msg, "ta(ssa(iiii))", &winid, &array))
return eldbus_message_method_return_new(msg);
cc = _dbus_ccui_find(winid);
if (!cc)
return eldbus_message_method_return_new(msg);
ELM_SAFE_FREE(cc->timer, ecore_timer_del);
while (eldbus_message_iter_get_and_next(array, 'r', &struc))
{
Colorclass *ecc;
const char *name, *desc;
Eldbus_Message_Iter *array2, *struc2;
int i = 0;
eldbus_message_iter_arguments_get(struc, "ssa(iiii)", &name, &desc, &array2);
if ((!name[0]) && (!desc[0]) && (!elm_genlist_items_count(cc->gl)))
break;
ecc = malloc(sizeof(Colorclass));
ecc->name = eina_stringshare_add(name);
ecc->desc = eina_stringshare_add(desc);
while (eldbus_message_iter_get_and_next(array2, 'r', &struc2))
{
if (i > 2)
{
ERR("Someone failed at trying to send color class data!");
break;
}
eldbus_message_iter_arguments_get(struc2, "iiii",
&ecc->color[i].r, &ecc->color[i].g, &ecc->color[i].b, &ecc->color[i].a);
i++;
}
elm_genlist_item_append(cc->gl, &itc, ecc, NULL, 0, NULL, NULL);
}
if (elm_genlist_items_count(cc->gl))
elm_object_signal_emit(cc->ly, "elm,state,loaded", "elm");
else
elm_object_text_set(cc->ly, "No color scheme available!");
return eldbus_message_method_return_new(msg);
}
static Eina_Bool
_dbus_timeout(Colorclass_UI *cc)
{
ELM_SAFE_FREE(cc->timer, ecore_timer_del);
evas_object_smart_callback_call(cc->ly, "timeout", NULL);
/* FIXME: translate */
elm_object_text_set(cc->ly, "Application was unable to provide color scheme info");
return EINA_FALSE;
}
/* internal */ void
elm_color_class_init(void)
{
cc_proxy = elementary_colorclass_proxy_get(eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION), ELM_COLOR_CLASS_METHOD_BASE, NULL);
h1 = ecore_event_handler_add(ELEMENTARY_COLORCLASS_EDIT_EVENT, (Ecore_Event_Handler_Cb)_dbus_edit, NULL);
h2 = ecore_event_handler_add(ELEMENTARY_COLORCLASS_CHANGED_EVENT, (Ecore_Event_Handler_Cb)_dbus_changed, NULL);
}
void
elm_color_class_shutdown(void)
{
Eldbus_Connection *conn = eldbus_object_connection_get(eldbus_proxy_object_get(cc_proxy));
ELM_SAFE_FREE(cc_proxy, eldbus_proxy_unref);
eldbus_connection_unref(conn);
ecore_event_handler_del(h1);
ecore_event_handler_del(h2);
h1 = h2 = NULL;
}
static const Eldbus_Method colorclass_editor_methods[] =
{
{ "SendCC", ELDBUS_ARGS({"t", "Window ID"}, {"a(ssa(iiii))", "Array of color classes"}), NULL, _dbus_send_cc, 0},
{ "Close", ELDBUS_ARGS({"t", "Window ID"}), NULL, _dbus_close, 0},
{NULL, NULL, NULL, NULL, 0}
};
static const Eldbus_Service_Interface_Desc base_desc =
{
ELM_COLOR_CLASS_METHOD_BASE, colorclass_editor_methods, colorclass_editor_signals, NULL, NULL, NULL
};
EAPI Evas_Object *
elm_color_class_editor_add(Evas_Object *obj, Elm_Color_Class_Name_Cb cb)
elm_color_class_editor_add(Evas_Object *obj, uint64_t winid)
{
Evas_Object *ly, *bt, *gl, *cs;
Colorclass_UI *cc;
Edje_Color_Class *ecc, *ecc2;
Eina_Iterator *it;
Eina_Hash *test = NULL;
Eina_List *ccs = NULL;
static Elm_Genlist_Item_Class itc =
{
.item_style = "default",
.func = {
.text_get = (Elm_Genlist_Item_Text_Get_Cb)_colorclass_text_get,
.del = (Elm_Genlist_Item_Del_Cb)_colorclass_item_del
},
.version = ELM_GENLIST_ITEM_CLASS_VERSION
};
cc = calloc(1, sizeof(Colorclass_UI));
if (!cc) return NULL;
it = edje_color_class_active_iterator_new();
EINA_ITERATOR_FOREACH(it, ecc)
if (!winid)
{
Colorclass *lcc;
it = edje_color_class_active_iterator_new();
EINA_ITERATOR_FOREACH(it, ecc)
{
Colorclass *lcc;
ecc2 = malloc(sizeof(Edje_Color_Class));
memcpy(ecc2, ecc, sizeof(Edje_Color_Class));
ecc2->name = eina_stringshare_add(ecc->name);
if (cb)
ecc2->desc = eina_stringshare_add(cb((char*)ecc->desc));
else
ecc2->desc = eina_stringshare_add(ecc->desc);
lcc = (Colorclass*)ecc;
edje_color_class_set(lcc->name,
lcc->color[0].r, lcc->color[0].g, lcc->color[0].b, lcc->color[0].a,
lcc->color[1].r, lcc->color[1].g, lcc->color[1].b, lcc->color[1].a,
lcc->color[2].r, lcc->color[2].g, lcc->color[2].b, lcc->color[2].a);
ccs = eina_list_append(ccs, ecc2);
ecc2 = malloc(sizeof(Edje_Color_Class));
memcpy(ecc2, ecc, sizeof(Edje_Color_Class));
ecc2->name = eina_stringshare_add(ecc->name);
if (tl_cb)
ecc2->desc = eina_stringshare_add(tl_cb((char*)ecc->desc));
else
ecc2->desc = eina_stringshare_add(ecc->desc);
if (list_cb && (!test))
test = eina_hash_string_superfast_new(NULL);
if (test)
eina_hash_add(test, ecc->name, ecc2);
lcc = (Colorclass*)ecc;
edje_color_class_set(lcc->name,
lcc->color[0].r, lcc->color[0].g, lcc->color[0].b, lcc->color[0].a,
lcc->color[1].r, lcc->color[1].g, lcc->color[1].b, lcc->color[1].a,
lcc->color[2].r, lcc->color[2].g, lcc->color[2].b, lcc->color[2].a);
ccs = eina_list_append(ccs, ecc2);
}
eina_iterator_free(it);
}
eina_iterator_free(it);
else
{
if (!remote_iface)
{
Eldbus_Connection *dbus_conn;
dbus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
eldbus_name_request(dbus_conn, ELM_COLOR_CLASS_METHOD_BASE, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
_dbus_request_name_cb, cc);
remote_iface = eldbus_service_interface_register(dbus_conn, "/", &base_desc);
}
cc->timer = ecore_timer_add(1.5, (Ecore_Task_Cb)_dbus_timeout, cc);
remote_ccuis = eina_inlist_append(remote_ccuis, EINA_INLIST_GET(cc));
}
cc->winid = winid;
cc->ly = ly = elm_layout_add(obj);
elm_layout_theme_set(ly, "layout", "colorclass", "base");
elm_layout_signal_callback_add(ly, "elm,colorclass,select,*", "elm", _colorclass_select, cc);
elm_layout_signal_callback_add(ly, "elm,colorclass,deactivate", "elm", _colorclass_deactivate, cc);
elm_layout_signal_callback_add(ly, "elm,colorclass,dismiss", "elm", _colorclass_dismiss, cc);
evas_object_event_callback_add(ly, EVAS_CALLBACK_DEL, _colorclass_del, cc);
cc->gl = gl = elm_genlist_add(ly);
@ -268,6 +655,7 @@ elm_color_class_editor_add(Evas_Object *obj, Elm_Color_Class_Name_Cb cb)
cc->reset = bt = elm_button_add(ly);
elm_object_style_set(bt, "colorclass");
/* FIXME: translate */
elm_object_text_set(bt, "Reset");
elm_object_part_content_set(ly, "elm.swallow.reset", bt);
evas_object_smart_callback_add(bt, "clicked", _colorclass_reset, cc);
@ -280,5 +668,38 @@ elm_color_class_editor_add(Evas_Object *obj, Elm_Color_Class_Name_Cb cb)
EINA_LIST_FREE(ccs, ecc)
elm_genlist_item_append(gl, &itc, ecc, NULL, 0, NULL, NULL);
if (winid)
{
/* FIXME: translate */
elm_object_text_set(ly, "Loading color scheme...");
elm_object_signal_emit(ly, "elm,state,info", "elm");
elm_object_signal_emit(ly, "elm,state,remote", "elm");
}
else if (list_cb)
{
ccs = list_cb();
EINA_LIST_FREE(ccs, ecc)
{
if (test)
{
if (eina_hash_find(test, ecc->name)) continue;
eina_hash_add(test, ecc->name, ecc2);
}
elm_genlist_item_append(gl, &itc, ecc, NULL, 0, NULL, NULL);
}
}
return ly;
}
EAPI void
elm_color_class_translate_cb_set(Elm_Color_Class_Name_Cb cb)
{
tl_cb = cb;
}
EAPI void
elm_color_class_list_cb_set(Elm_Color_Class_List_Cb cb)
{
list_cb = cb;
}

View File

@ -1,3 +1,6 @@
#ifndef ELM_COLOR_CLASS_H
# define ELM_COLOR_CLASS_H
/**
* @defgroup Elm_Color_Class_Group Color Class Editor
* @ingroup Elm_Color_Class_Group
@ -6,25 +9,65 @@
* @{
*/
#define ELM_COLOR_CLASS_METHOD_BASE "org.elementary.colorclass"
/**
* @typedef Elm_Color_Class_Name_Cb
* @brief A callback used to translate color class descriptions
* @since 1.14
*/
typedef char *(*Elm_Color_Class_Name_Cb)(char *);
/**
* @typedef Elm_Color_Class_List_Cb
* @brief A callback used to provide a list of allocated Edje_Color_Class structs used by an application
* @since 1.14
*
* The list and its members will be freed internally.
*/
typedef Eina_List *(*Elm_Color_Class_List_Cb)(void);
/**
* @brief Create a new color class editor
* @param obj The parent object
* @param cb The translation callback to use
* @param winid The remote window id to edit
*
* A color class editor is a visual representation of the color schemes in an application.
* Values changed in the editor are stored in Elementary's config and will remain until they
* are reset or the config is cleared.
* are reset or the config is cleared. By default, the editor will load only the currently active
* color classes in an application.
*
* If @p winid is provided the editor will run in remote mode, managing color classes over DBus
* for applications which provide the required interfaces.
*
* Passing a @c NULL param for @p cb will cause the editor to work in remote mode, using dbus
* signals to message between the target application.
* @since 1.14
*/
EAPI Evas_Object *elm_color_class_editor_add(Evas_Object *obj, Elm_Color_Class_Name_Cb cb);
EAPI Evas_Object *elm_color_class_editor_add(Evas_Object *obj, uint64_t winid);
/**
* @brief Set a callback to provide translations for color class descriptions
* @param cb The callback to use
*
* This callback will be called globally by the application to translate any available color class
* description strings from the theme's color classes.
*
* @since 1.14
**/
EAPI void elm_color_class_translate_cb_set(Elm_Color_Class_Name_Cb cb);
/**
* @brief Set a callback to provide a list of supplementary color classes
* @param cb The callback to use
*
* This callback will be called globally by the application to provide extra color classes
* that an application may use but which may not be currently loaded.
*
* @see Elm_Color_Class_List_Cb
*
* @since 1.14
**/
EAPI void elm_color_class_list_cb_set(Elm_Color_Class_List_Cb cb);
/** }@ */
#endif

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<node name="/">
<interface name="org.elementary.colorclass">
<method name="SendCC">
<arg type="t" name="winid" direction="in" />
<arg type="a(ssa(iiii))" name="Array of color classes" direction="in" />
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true" />
</method>
<method name="Close">
<arg type="t" name="winid" direction="in" />
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true" />
</method>
<signal name="Edit">
<arg type="t" name="winid" direction="out" />
</signal>
<signal name="Changed">
<arg type="t" name="winid" direction="out" />
<arg type="s" name="Color class name" direction="out" />
<arg type="a(iiii)" name="Colors" direction="out" />
</signal>
</interface>
</node>

View File

@ -696,6 +696,7 @@ elm_quicklaunch_sub_init(int argc,
ecore_con_url_init();
_elm_prefs_init();
_elm_ews_wm_init();
elm_color_class_init();
}
return _elm_sub_init_count;
}
@ -744,6 +745,7 @@ elm_quicklaunch_shutdown(void)
ELM_SAFE_FREE(_elm_appname, free);
_elm_config_shutdown();
elm_color_class_shutdown();
ELM_SAFE_FREE(_elm_exit_handler, ecore_event_handler_del);

View File

@ -417,7 +417,8 @@ void _elm_config_reload(void);
size_t _elm_config_user_dir_snprintf(char *dst, size_t size,
const char *fmt, ...)
EINA_PRINTF(3, 4);
void elm_color_class_init(void);
void elm_color_class_shutdown(void);
void _elm_recache(void);
const char *_elm_config_current_profile_get(void);