express/src/bin/channel.c

1333 lines
36 KiB
C

#include "private.h"
#include "channel.h"
#include "config.h"
#include "theme.h"
#include "window.h"
#include "grid.h"
#include "utils.h"
#include "commands.h"
struct _Channel
{
const char *name;
const char *server;
Evas *evas;
Evas_Object *o_win;
Evas_Object *o_base;
Evas_Object *o_bg;
Evas_Object *o_grid;
Evas_Object *o_spacer;
Evas_Object *o_tab_spacer;
Evas_Object *o_tabregion_bg;
Evas_Object *o_tabregion_base;
Evas_Object *o_img;
Evas_Object *o_entry;
struct
{
Evas_Object *o_frame;
Evas_Object *o_spacer;
Evas_Object *o_box;
Evas_Object *o_label;
Evas_Object *o_list;
Evas_Object *o_dismiss;
Eina_Bool visible : 1;
Eina_List *users;
int opcount;
} userlist;
struct
{
Evas_Object *o_frame;
Evas_Object *o_box;
Evas_Object *o_list;
Elm_Object_Item *group;
Elm_Genlist_Item_Class *itc, *gitc;
} treeview;
struct
{
struct
{
Evas_Object *o_box;
Eina_List *tabs;
} l, r;
} tabbar;
int step_x, step_y;
int min_w, min_h;
int req_w, req_h;
Eina_Bool active : 1;
Eina_Bool size_done : 1;
Eina_Bool translucent : 1;
Eina_Bool focused : 1;
Eina_Bool unswallowed : 1;
Eina_Bool missed : 1;
Express_Network *net;
};
static void
_cb_theme_reload(Channel *chl)
{
Edje_Message_Int msg;
chl->translucent = _ex_cfg->gui.translucent;
if (chl->translucent)
msg.val = _ex_cfg->gui.opacity;
else
msg.val = 100;
edje_object_message_send(chl->o_bg, EDJE_MESSAGE_INT, 1, &msg);
edje_object_message_send(chl->o_base, EDJE_MESSAGE_INT, 1, &msg);
}
static void
_cb_size_hint(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
{
Channel *chl;
Evas_Coord mw, mh, rw, rh, w = 0, h = 0;
chl = data;
evas_object_size_hint_min_get(obj, &mw, &mh);
evas_object_size_hint_request_get(obj, &rw, &rh);
edje_object_size_min_calc(chl->o_base, &w, &h);
evas_object_size_hint_min_set(chl->o_base, w, h);
edje_object_size_min_calc(chl->o_bg, &w, &h);
evas_object_size_hint_min_set(chl->o_bg, w, h);
chl->step_x = mw;
chl->step_y = mh;
chl->min_w = (w - mw);
chl->min_h = (h - mh);
chl->req_w = (w - mw + rw);
chl->req_h = (h - mh + rh);
if (chl->active) _window_size_update();
}
static void
_cb_prev(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Channel *chl, *pchl = NULL;
chl = data;
if (chl->active)
{
if ((pchl = _window_channel_previous_get(chl)))
_window_channel_switch(chl, pchl);
}
}
static void
_cb_next(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Channel *chl, *nchl = NULL;
chl = data;
if (chl->active)
{
if ((nchl = _window_channel_next_get(chl)))
_window_channel_switch(chl, nchl);
}
}
static void
_cb_count_go(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *source EINA_UNUSED)
{
Channel *chl;
chl = data;
_window_channel_switch(chl, chl);
}
static void
_cb_count_prev(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *source EINA_UNUSED)
{
_cb_prev(data, NULL, NULL);
}
static void
_cb_count_next(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *source EINA_UNUSED)
{
_cb_next(data, NULL, NULL);
}
static void
_cb_userlist_go(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *source EINA_UNUSED)
{
Channel *chl;
chl = data;
if (!chl->userlist.visible)
{
edje_object_signal_emit(chl->o_base, "userlist,show", PACKAGE_NAME);
chl->userlist.visible = EINA_TRUE;
}
else
{
edje_object_signal_emit(chl->o_base, "userlist,hide", PACKAGE_NAME);
chl->userlist.visible = EINA_FALSE;
}
}
static int
_cb_userlist_compare(const void *data1, const void *data2)
{
const char *label1, *label2;
const Elm_Object_Item *item1, *item2;
char *item_data1, *item_data2;
item1 = data1;
item2 = data2;
label1 = elm_object_item_text_get(item1);
label2 = elm_object_item_text_get(item2);
item_data1 = elm_object_item_data_get(item1);
item_data2 = elm_object_item_data_get(item2);
if ((item_data1) && (item_data2))
return strcasecmp(label1, label2);
else if ((item_data1) && (!item_data2))
return -1;
else if ((!item_data1) && (item_data2))
return 1;
return strcasecmp(label1, label2);
}
static void
_cb_userlist_dismiss_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
_cb_userlist_go(data, NULL, NULL, NULL);
}
static void
_cb_userlist_done(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *source EINA_UNUSED)
{
Channel *chl;
chl = data;
chl->userlist.o_dismiss = NULL;
}
static void
_cb_options_done(void *data)
{
Channel *chl;
chl = data;
if (chl->active) elm_object_focus_set(chl->o_entry, EINA_TRUE);
}
static void
_cb_options(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Channel *chl;
chl = data;
_window_options_toggle(chl->o_grid, _cb_options_done, chl);
}
static void
_cb_entry_go(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Channel *chl;
char *txt;
chl = data;
if (!chl->net) return;
if ((txt = (char *)elm_entry_entry_get(chl->o_entry)))
{
if (strlen(txt) < 1) return;
if ((txt = elm_entry_markup_to_utf8(txt)))
{
char buff[PATH_MAX];
if (_cmd_txt_handle(chl->net, chl->name, txt, buff))
{
const char *nick;
nick = express_network_nickname_get(chl->net);
_channel_text_append(chl, nick, buff,
_row_color_simple_create(0));
}
elm_entry_entry_set(chl->o_entry, "");
}
}
}
static void
_cb_entry_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
{
Evas_Event_Key_Down *ev;
ev = event;
if (!strcmp(ev->key, "Tab"))
{
Channel *chl;
const char *usr, *str;
Eina_List *l, *m = NULL;
chl = data;
str = elm_entry_entry_get(chl->o_entry);
if ((!str) || (strlen(str) < 1)) return;
EINA_LIST_FOREACH(chl->userlist.users, l, usr)
{
if (_util_str_has_prefix(usr, str))
m = eina_list_append(m, usr);
}
if (eina_list_count(m) > 1)
{
Eina_Strbuf *sb;
char *s;
sb = eina_strbuf_new();
EINA_LIST_FOREACH(m, l, usr)
{
eina_strbuf_append_length(sb, usr, strlen(usr));
eina_strbuf_append_char(sb, ' ');
}
if (eina_strbuf_length_get(sb) < 1)
{
eina_strbuf_free(sb);
return;
}
eina_strbuf_append_char(sb, '\r');
eina_strbuf_append_char(sb, '\n');
s = eina_strbuf_string_steal(sb);
eina_strbuf_free(sb);
_channel_text_append(chl, "*", s, _row_color_simple_create(0));
}
else
{
elm_entry_entry_set(chl->o_entry, eina_list_data_get(m));
elm_entry_entry_append(chl->o_entry, ": ");
elm_entry_cursor_end_set(chl->o_entry);
}
}
}
static void
_cb_tabregion_change(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
{
Channel *chl;
Evas_Coord w = 0, h = 0;
chl = data;
evas_object_geometry_get(obj, NULL, NULL, &w, &h);
evas_object_size_hint_min_set(chl->o_tabregion_base, w, h);
edje_object_part_swallow(chl->o_bg, "channel.tabregion",
chl->o_tabregion_bg);
edje_object_part_swallow(chl->o_base, "channel.tabregion",
chl->o_tabregion_base);
}
static void
_channel_userlist_create(Channel *chl)
{
if (!chl->userlist.o_frame)
{
Evas_Object *o;
o = elm_frame_add(chl->o_win);
WEIGHT_SET(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
ALIGN_SET(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(o, "Users");
elm_object_focus_allow_set(o, EINA_FALSE);
chl->userlist.o_frame = o;
edje_object_part_swallow(chl->o_base, "userlist.content", o);
}
if (!chl->userlist.o_box)
{
Evas_Object *o;
o = elm_box_add(chl->o_win);
WEIGHT_SET(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
ALIGN_SET(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_align_set(o, 0.5, 0.0);
elm_box_padding_set(o, 2, 2);
evas_object_show(o);
chl->userlist.o_box = o;
elm_object_content_set(chl->userlist.o_frame, o);
}
if (!chl->userlist.o_label)
{
Evas_Object *o;
o = elm_label_add(chl->o_win);
elm_label_line_wrap_set(o, ELM_WRAP_NONE);
evas_object_show(o);
chl->userlist.o_label = o;
elm_box_pack_end(chl->userlist.o_box, o);
}
if (!chl->userlist.o_list)
{
Evas_Object *o;
o = elm_list_add(chl->o_win);
WEIGHT_SET(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
ALIGN_SET(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_focus_allow_set(o, EINA_FALSE);
elm_scroller_content_min_limit(o, EINA_TRUE, EINA_FALSE);
elm_scroller_bounce_set(o, EINA_FALSE, EINA_TRUE);
elm_scroller_policy_set(o, ELM_SCROLLER_POLICY_OFF,
ELM_SCROLLER_POLICY_AUTO);
evas_object_show(o);
chl->userlist.o_list = o;
elm_box_pack_end(chl->userlist.o_box, o);
}
if (!chl->userlist.o_spacer)
{
Evas_Object *o;
Evas_Coord w = 0, h = 0;
o = elm_icon_add(chl->o_win);
elm_icon_standard_set(o, "user-idle");
elm_coords_finger_size_adjust(1, &w, 1, &h);
evas_object_size_hint_min_set(o, w, h);
elm_object_focus_allow_set(o, EINA_FALSE);
chl->userlist.o_spacer = o;
edje_object_part_swallow(chl->o_bg, "userlist.control", o);
}
if (!chl->userlist.o_dismiss)
{
chl->userlist.o_dismiss = evas_object_rectangle_add(chl->evas);
evas_object_color_set(chl->userlist.o_dismiss, 0, 0, 0, 0);
evas_object_event_callback_add(chl->userlist.o_dismiss,
EVAS_CALLBACK_MOUSE_DOWN,
_cb_userlist_dismiss_mouse_down, chl);
edje_object_signal_callback_add(chl->o_base, "userlist,hide,done",
PACKAGE_NAME, _cb_userlist_done, chl);
edje_object_part_swallow(chl->o_base, "userlist.dismiss",
chl->userlist.o_dismiss);
}
}
static char *
_channel_treeview_group_name_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
{
/* char buff[256]; */
const char *group;
if (!(group = data)) return NULL;
return strdup(group);
/* snprintf(buff, sizeof(buff), "%s", express_network_name_get(net)); */
/* return strdup(buff); */
}
static char *
_channel_treeview_item_name_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
{
Channel *chl;
if (!(chl = data)) return NULL;
return strdup(chl->name);
}
static void
_channel_treeview_create(Channel *chl)
{
if (!chl->treeview.o_frame)
{
Evas_Object *o;
o = elm_frame_add(chl->o_win);
WEIGHT_SET(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
FILL_SET(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(o, "Channels");
elm_object_focus_allow_set(o, EINA_FALSE);
evas_object_show(o);
chl->treeview.o_frame = o;
edje_object_part_swallow(chl->o_base, "treeview.content", o);
}
if (!chl->treeview.o_box)
{
Evas_Object *o;
o = elm_box_add(chl->o_win);
WEIGHT_SET(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
FILL_SET(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_align_set(o, 0.5, 0.0);
elm_box_padding_set(o, 2, 2);
evas_object_show(o);
chl->treeview.o_box = o;
elm_object_content_set(chl->treeview.o_frame, o);
}
if (!chl->treeview.o_list)
{
Evas_Object *o;
chl->treeview.gitc = elm_genlist_item_class_new();
chl->treeview.gitc->item_style = "group_index";
chl->treeview.gitc->func.text_get = _channel_treeview_group_name_get;
chl->treeview.itc = elm_genlist_item_class_new();
chl->treeview.itc->item_style = "default";
chl->treeview.itc->func.text_get = _channel_treeview_item_name_get;
o = elm_genlist_add(chl->o_win);
WEIGHT_SET(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
FILL_SET(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_genlist_focus_on_selection_set(o, EINA_FALSE);
elm_scroller_content_min_limit(o, EINA_TRUE, EINA_FALSE);
elm_scroller_bounce_set(o, EINA_FALSE, EINA_TRUE);
elm_scroller_policy_set(o, ELM_SCROLLER_POLICY_OFF,
ELM_SCROLLER_POLICY_AUTO);
evas_object_show(o);
chl->treeview.o_list = o;
elm_box_pack_end(chl->treeview.o_box, o);
}
edje_object_signal_emit(chl->o_base, "treeview,on", PACKAGE_NAME);
}
static void
_channel_treeview_destroy(Channel *chl)
{
edje_object_signal_emit(chl->o_base, "treeview,off", PACKAGE_NAME);
if (chl->treeview.gitc) elm_genlist_item_class_free(chl->treeview.gitc);
chl->treeview.gitc = NULL;
if (chl->treeview.itc) elm_genlist_item_class_free(chl->treeview.itc);
chl->treeview.itc = NULL;
if (chl->treeview.o_list) evas_object_del(chl->treeview.o_list);
chl->treeview.o_list = NULL;
if (chl->treeview.o_box) evas_object_del(chl->treeview.o_box);
chl->treeview.o_box = NULL;
if (chl->treeview.o_frame) evas_object_del(chl->treeview.o_frame);
chl->treeview.o_frame = NULL;
}
static void
_cb_treeview_selected(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
{
Elm_Object_Item *item;
Channel *chl, *pchl;
if (!(item = event)) return;
if (!(chl = elm_object_item_data_get(item))) return;
if ((pchl = _window_channel_active_get()))
{
if (pchl != chl)
_window_channel_unswallow(pchl);
}
_window_channel_activate(chl);
_window_channel_swallow(chl);
/* elm_genlist_item_selected_set(item, EINA_TRUE); */
}
static void
_channel_tabbar_create(Channel *chl)
{
if (!chl->o_tabregion_bg)
{
chl->o_tabregion_bg = evas_object_rectangle_add(chl->evas);
evas_object_color_set(chl->o_tabregion_bg, 0, 0, 0, 0);
evas_object_event_callback_add(chl->o_tabregion_bg,
EVAS_CALLBACK_MOVE,
_cb_tabregion_change, chl);
evas_object_event_callback_add(chl->o_tabregion_bg,
EVAS_CALLBACK_RESIZE,
_cb_tabregion_change, chl);
edje_object_part_swallow(chl->o_bg, "channel.tabregion",
chl->o_tabregion_bg);
}
if (!chl->o_tabregion_base)
{
chl->o_tabregion_base = evas_object_rectangle_add(chl->evas);
evas_object_color_set(chl->o_tabregion_base, 0, 0, 0, 0);
edje_object_part_swallow(chl->o_base, "channel.tabregion",
chl->o_tabregion_base);
}
_window_tabcount_update();
}
static void
_channel_tabbar_destroy(Channel *chl EINA_UNUSED)
{
/* NB: This function will already destroy tabbar */
_window_tabcount_update();
}
/* external functions */
Channel *
_channel_create(Evas *evas, Evas_Object *win, const char *name, const char *server)
{
Channel *chl;
/* try to allocate space for channel structure */
if (!(chl = calloc(1, sizeof(Channel)))) return NULL;
/* set channel to the opposite of config translucent
* NB: This is done so that first time through the signals get sent */
chl->translucent = !_ex_cfg->gui.translucent;
chl->evas = evas;
chl->o_win = win;
/* store channel name */
if (name) chl->name = eina_stringshare_add(name);
/* store channel server */
if (server) chl->server = eina_stringshare_add(server);
/* add base object */
chl->o_base = edje_object_add(evas);
_theme_apply(chl->o_base, "express/channel");
_theme_reload_enable(chl->o_base);
evas_object_data_set(chl->o_base, "theme_reload_func", _cb_theme_reload);
evas_object_data_set(chl->o_base, "theme_reload_func_data", chl);
/* add bg object */
chl->o_bg = edje_object_add(evas);
WEIGHT_SET(chl->o_bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
FILL_SET(chl->o_bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
_theme_apply(chl->o_bg, "express/background");
_theme_reload_enable(chl->o_bg);
evas_object_data_set(chl->o_bg, "theme_reload_func", _cb_theme_reload);
evas_object_data_set(chl->o_bg, "theme_reload_func_data", chl);
/* add tabregion */
if (_ex_cfg->gui.tabs)
_channel_tabbar_create(chl);
else
_channel_treeview_create(chl);
/* add grid */
chl->o_grid = _grid_add(evas);
WEIGHT_SET(chl->o_grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
FILL_SET(chl->o_grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
/* add userlist */
_channel_userlist_create(chl);
evas_object_event_callback_add(chl->o_grid,
EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_cb_size_hint, chl);
evas_object_smart_callback_add(chl->o_grid, "options", _cb_options, chl);
evas_object_smart_callback_add(chl->o_grid, "prev", _cb_prev, chl);
evas_object_smart_callback_add(chl->o_grid, "next", _cb_next, chl);
/* swallow parts */
edje_object_part_swallow(chl->o_base, "channel.content", chl->o_grid);
edje_object_part_swallow(chl->o_bg, "background.content", chl->o_base);
/* add handlers for chlcount signals */
edje_object_signal_callback_add(chl->o_bg, "chlcount,go", PACKAGE_NAME,
_cb_count_go, chl);
edje_object_signal_callback_add(chl->o_bg, "chlcount,prev", PACKAGE_NAME,
_cb_count_prev, chl);
edje_object_signal_callback_add(chl->o_bg, "chlcount,next", PACKAGE_NAME,
_cb_count_next, chl);
/* add handlers for userlist signals */
edje_object_signal_callback_add(chl->o_bg, "userlist,go", PACKAGE_NAME,
_cb_userlist_go, chl);
return chl;
}
void
_channel_destroy(Channel *chl)
{
const char *usr;
/* delete tabregion stuff */
_channel_tabbar_destroy(chl);
_channel_treeview_destroy(chl);
/* delete channel userlist objects */
EINA_LIST_FREE(chl->userlist.users, usr)
eina_stringshare_del(usr);
if (chl->userlist.o_dismiss) evas_object_del(chl->userlist.o_dismiss);
if (chl->userlist.o_list) evas_object_del(chl->userlist.o_list);
if (chl->userlist.o_label) evas_object_del(chl->userlist.o_label);
if (chl->userlist.o_box) evas_object_del(chl->userlist.o_box);
if (chl->userlist.o_spacer) evas_object_del(chl->userlist.o_spacer);
if (chl->userlist.o_frame) evas_object_del(chl->userlist.o_frame);
/* delete channel objects */
if (chl->o_img) evas_object_del(chl->o_img);
if (chl->o_spacer) evas_object_del(chl->o_spacer);
if (chl->o_entry) evas_object_del(chl->o_entry);
if (chl->o_grid) evas_object_del(chl->o_grid);
if (chl->o_bg) evas_object_del(chl->o_bg);
if (chl->o_base) evas_object_del(chl->o_base);
/* delete channel name */
if (chl->name) eina_stringshare_del(chl->name);
/* delete channel server name */
if (chl->server) eina_stringshare_del(chl->server);
/* free allocated channel structure */
free(chl);
}
void
_channel_update(Channel *chl)
{
chl->size_done = EINA_FALSE;
/* update channel transparency */
_cb_theme_reload(chl);
if (_ex_cfg->gui.tabs)
{
_channel_treeview_destroy(chl);
_window_tabcount_update();
}
else
{
_channel_tabbar_destroy(chl);
_channel_treeview_create(chl);
_window_treeview_update();
}
/* update grid config */
_grid_update(chl->o_grid);
edje_object_part_swallow(chl->o_base, "channel.content", chl->o_grid);
edje_object_part_swallow(chl->o_bg, "background.content", chl->o_base);
}
void
_channel_focused_set(Channel *chl, Eina_Bool focus)
{
chl->focused = focus;
}
Eina_Bool
_channel_focused_get(Channel *chl)
{
return chl->focused;
}
void
_channel_focus(Channel *chl)
{
if (chl->focused) return;
edje_object_signal_emit(chl->o_bg, "focus,in", PACKAGE_NAME);
edje_object_signal_emit(chl->o_base, "focus,in", PACKAGE_NAME);
chl->focused = EINA_TRUE;
}
void
_channel_unfocus(Channel *chl)
{
if (!chl->focused) return;
edje_object_signal_emit(chl->o_bg, "focus,out", PACKAGE_NAME);
edje_object_signal_emit(chl->o_base, "focus,out", PACKAGE_NAME);
chl->focused = EINA_FALSE;
}
void
_channel_active_set(Channel *chl, Eina_Bool active)
{
chl->active = active;
elm_object_focus_allow_set(chl->o_entry, active);
elm_object_focus_set(chl->o_entry, active);
}
Eina_Bool
_channel_active_get(Channel *chl)
{
return chl->active;
}
const char *
_channel_name_get(Channel *chl)
{
return chl->name;
}
const char *
_channel_server_name_get(Channel *chl)
{
return chl->server;
}
void
_channel_size_update(Channel *chl)
{
_cb_size_hint(chl, NULL, chl->o_grid, NULL);
}
void
_channel_size_min_get(Channel *chl, int *w, int *h)
{
evas_object_size_hint_min_get(chl->o_bg, w, h);
}
void
_channel_size_step_get(Channel *chl, int *w, int *h)
{
if (w) *w = chl->step_x;
if (h) *h = chl->step_y;
}
void
_channel_size_request_get(Channel *chl, int *w, int *h)
{
if (w) *w = chl->req_w;
if (h) *h = chl->req_h;
}
void
_channel_size_done_set(Channel *chl, Eina_Bool done)
{
chl->size_done = done;
}
Eina_Bool
_channel_size_done_get(Channel *chl)
{
return chl->size_done;
}
Evas_Object *
_channel_background_get(Channel *chl)
{
return chl->o_bg;
}
void
_channel_background_hide(Channel *chl)
{
evas_object_hide(chl->o_bg);
}
void
_channel_background_show(Channel *chl)
{
evas_object_show(chl->o_bg);
}
Evas_Object *
_channel_base_get(Channel *chl)
{
return chl->o_base;
}
void
_channel_base_unswallow(Channel *chl)
{
edje_object_part_unswallow(chl->o_bg, chl->o_base);
evas_object_lower(chl->o_base);
evas_object_move(chl->o_base, -9999, -9999);
evas_object_show(chl->o_base);
evas_object_clip_unset(chl->o_base);
#if (EVAS_VERSION_MAJOR > 1) || (EVAS_VERSION_MINOR >= 8)
evas_object_image_source_visible_set(chl->o_img, EINA_FALSE);
#endif
chl->unswallowed = EINA_TRUE;
}
Evas_Object *
_channel_image_get(Channel *chl)
{
return chl->o_img;
}
void
_channel_image_unset(Channel *chl)
{
#if (EVAS_VERSION_MAJOR > 1) || (EVAS_VERSION_MINOR >= 8)
evas_object_image_source_visible_set(chl->o_img, EINA_TRUE);
#endif
chl->o_img = NULL;
}
void
_channel_image_create(Channel *chl)
{
Evas_Coord w = 0, h = 0;
chl->o_img = evas_object_image_filled_add(chl->evas);
evas_object_image_source_set(chl->o_img, chl->o_base);
evas_object_geometry_get(chl->o_base, NULL, NULL, &w, &h);
evas_object_resize(chl->o_img, w, h);
evas_object_data_set(chl->o_img, "grid", chl->o_grid);
}
Eina_Bool
_channel_missed_get(Channel *chl)
{
return chl->missed;
}
void
_channel_missed_set(Channel *chl, Eina_Bool missed)
{
chl->missed = missed;
}
void
_channel_missed_count_set(Channel *chl, int count)
{
if (count > 0)
{
char buff[32];
snprintf(buff, sizeof(buff), "%i", count);
edje_object_part_text_set(chl->o_bg, "chlmissed.label", buff);
}
else
edje_object_part_text_set(chl->o_bg, "chlmissed.label", NULL);
if (count > 0)
edje_object_signal_emit(chl->o_bg, "chlmissed,on", PACKAGE_NAME);
else
edje_object_signal_emit(chl->o_bg, "chlmissed,off", PACKAGE_NAME);
}
void
_channel_count_set(Channel *chl, int count, int total)
{
if (total > 1)
{
char buff[32];
snprintf(buff, sizeof(buff), "%i/%i", count, total);
edje_object_part_text_set(chl->o_bg, "chlcount.label", buff);
edje_object_signal_emit(chl->o_bg, "chlcount,on", PACKAGE_NAME);
}
else
edje_object_signal_emit(chl->o_bg, "chlcount,off", PACKAGE_NAME);
}
void
_channel_userlist_show(Channel *chl)
{
edje_object_signal_emit(chl->o_bg, "userlist,on", PACKAGE_NAME);
}
void
_channel_userlist_hide(Channel *chl)
{
edje_object_signal_emit(chl->o_bg, "userlist,off", PACKAGE_NAME);
}
Eina_Bool
_channel_unswallowed_get(Channel *chl)
{
return chl->unswallowed;
}
void
_channel_unswallowed_set(Channel *chl, Eina_Bool swallowed)
{
chl->unswallowed = swallowed;
if (!swallowed)
{
edje_object_part_swallow(chl->o_base, "channel.content", chl->o_grid);
edje_object_part_swallow(chl->o_bg, "background.content", chl->o_base);
}
}
void
_channel_spacer_create(Channel *chl)
{
if (!chl->o_spacer)
{
Evas_Coord w = 0, h = 0;
chl->o_spacer = evas_object_rectangle_add(chl->evas);
evas_object_color_set(chl->o_spacer, 0, 0, 0, 0);
elm_coords_finger_size_adjust(1, &w, 1, &h);
evas_object_size_hint_min_set(chl->o_spacer, w, h);
edje_object_part_swallow(chl->o_bg, "chlcount.control", chl->o_spacer);
}
}
void
_channel_text_append(Channel *chl, const char *user, const char *txt, Row_Color *color)
{
/* fprintf(stderr, "Channel %s Append: %s", chl->name, txt); */
/* write buff to grid */
if (user)
{
/* If user is * ie for messages use a different color */
Row_Color *ucolor;
if (!strncmp(user, "*", strlen(user)))
ucolor = _row_color_simple_create(78);
else
ucolor = _row_color_simple_create(31);
_grid_text_append(chl->o_grid, user, strlen(user), ucolor);
_grid_text_append(chl->o_grid, "\t", strlen("\t"), ucolor);
if (ucolor) free(ucolor);
}
_grid_text_append(chl->o_grid, txt, strlen(txt), color);
if (color) free(color);
if (!chl->active) chl->missed = EINA_TRUE;
else chl->missed = EINA_FALSE;
_window_channel_count_update();
if (chl->missed) _window_tabbar_update(chl);
}
void
_channel_window_set(Channel *chl, Evas_Object *win)
{
_grid_window_set(chl->o_grid, win);
_grid_theme_set(chl->o_grid, chl->o_bg);
if (chl->o_entry) return;
chl->o_entry = elm_entry_add(win);
WEIGHT_SET(chl->o_entry, EVAS_HINT_EXPAND, 0.0);
ALIGN_SET(chl->o_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_entry_single_line_set(chl->o_entry, EINA_TRUE);
elm_entry_scrollable_set(chl->o_entry, EINA_TRUE);
elm_entry_line_wrap_set(chl->o_entry, ELM_WRAP_NONE);
elm_scroller_policy_set(chl->o_entry, ELM_SCROLLER_POLICY_OFF,
ELM_SCROLLER_POLICY_OFF);
elm_entry_input_panel_layout_set(chl->o_entry,
ELM_INPUT_PANEL_LAYOUT_TERMINAL);
elm_entry_autocapital_type_set(chl->o_entry, ELM_AUTOCAPITAL_TYPE_NONE);
elm_entry_input_panel_enabled_set(chl->o_entry, EINA_TRUE);
elm_entry_input_panel_language_set(chl->o_entry,
ELM_INPUT_PANEL_LANG_ALPHABET);
elm_entry_input_panel_return_key_type_set(chl->o_entry,
ELM_INPUT_PANEL_RETURN_KEY_TYPE_GO);
elm_entry_prediction_allow_set(chl->o_entry, EINA_TRUE);
elm_entry_cnp_mode_set(chl->o_entry, ELM_CNP_MODE_PLAINTEXT);
evas_object_smart_callback_add(chl->o_entry, "activated",
_cb_entry_go, chl);
/* NB: This is messed up. Elm_Entry in single-line mode does not
* generate a changed event when pressing the Tab key */
evas_object_event_callback_add(chl->o_entry, EVAS_CALLBACK_KEY_DOWN,
_cb_entry_key_down, chl);
edje_object_part_swallow(chl->o_base, "channel.entry", chl->o_entry);
elm_entry_entry_set(chl->o_entry, "");
elm_object_focus_allow_set(chl->o_entry, EINA_FALSE);
}
void
_channel_network_set(Channel *chl, Express_Network *net)
{
chl->net = net;
_grid_nicklen_set(chl->o_grid, express_network_nickname_length_get(net));
}
Express_Network *
_channel_network_get(Channel *chl)
{
return chl->net;
}
void
_channel_userlist_user_append(Channel *chl, const char *user, Eina_Bool op)
{
char users[PATH_MAX];
if ((!user) || (strlen(user) < 1)) return;
/* append to list of users for autocomplete */
chl->userlist.users =
eina_list_append(chl->userlist.users, eina_stringshare_add(user));
if (!op)
elm_list_item_sorted_insert(chl->userlist.o_list, user, NULL, NULL,
NULL, NULL, _cb_userlist_compare);
else
{
Evas_Object *icon;
char buff[PATH_MAX];
static char data[] = "1";
icon = elm_icon_add(chl->o_bg);
elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
WEIGHT_SET(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
ALIGN_SET(icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_focus_allow_set(icon, EINA_FALSE);
snprintf(buff, sizeof(buff), "%s/images/operator.png",
elm_app_data_dir_get());
elm_image_file_set(icon, buff, NULL);
evas_object_show(icon);
elm_list_item_sorted_insert(chl->userlist.o_list, user, icon, NULL,
NULL, &data, _cb_userlist_compare);
chl->userlist.opcount++;
}
snprintf(users, sizeof(users), "(%d ops, %d total)",
chl->userlist.opcount, eina_list_count(chl->userlist.users));
elm_object_text_set(chl->userlist.o_label, users);
}
void
_channel_userlist_go(Channel *chl)
{
elm_list_go(chl->userlist.o_list);
}
void
_channel_tabbar_lbox_create(Channel *chl, Evas_Object *win)
{
if (!chl->tabbar.l.o_box)
{
chl->tabbar.l.o_box = elm_box_add(win);
elm_box_horizontal_set(chl->tabbar.l.o_box, EINA_TRUE);
elm_box_homogeneous_set(chl->tabbar.l.o_box, EINA_TRUE);
WEIGHT_SET(chl->tabbar.l.o_box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
FILL_SET(chl->tabbar.l.o_box, EVAS_HINT_FILL, EVAS_HINT_FILL);
edje_object_part_swallow(chl->o_bg, "tabl.content",
chl->tabbar.l.o_box);
elm_object_focus_allow_set(chl->tabbar.l.o_box, EINA_FALSE);
evas_object_show(chl->tabbar.l.o_box);
}
}
void
_channel_tabbar_rbox_create(Channel *chl, Evas_Object *win)
{
if (!chl->tabbar.r.o_box)
{
chl->tabbar.r.o_box = elm_box_add(win);
elm_box_horizontal_set(chl->tabbar.r.o_box, EINA_TRUE);
elm_box_homogeneous_set(chl->tabbar.r.o_box, EINA_TRUE);
WEIGHT_SET(chl->tabbar.r.o_box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
FILL_SET(chl->tabbar.r.o_box, EVAS_HINT_FILL, EVAS_HINT_FILL);
edje_object_part_swallow(chl->o_bg, "tabr.content",
chl->tabbar.r.o_box);
elm_object_focus_allow_set(chl->tabbar.r.o_box, EINA_FALSE);
evas_object_show(chl->tabbar.r.o_box);
}
}
void
_channel_tabbar_lbox_append(Channel *chl, Evas_Object *o)
{
chl->tabbar.l.tabs = eina_list_append(chl->tabbar.l.tabs, o);
elm_box_pack_end(chl->tabbar.l.o_box, o);
}
void
_channel_tabbar_rbox_append(Channel *chl, Evas_Object *o)
{
chl->tabbar.r.tabs = eina_list_append(chl->tabbar.r.tabs, o);
elm_box_pack_end(chl->tabbar.r.o_box, o);
}
void
_channel_tabbar_clear(Channel *chl)
{
Evas_Object *o;
if (chl->tabbar.l.o_box)
{
EINA_LIST_FREE(chl->tabbar.l.tabs, o)
evas_object_del(o);
evas_object_del(chl->tabbar.l.o_box);
chl->tabbar.l.o_box = NULL;
}
if (chl->tabbar.r.o_box)
{
EINA_LIST_FREE(chl->tabbar.r.tabs, o)
evas_object_del(o);
evas_object_del(chl->tabbar.r.o_box);
chl->tabbar.r.o_box = NULL;
}
}
void
_channel_tabbar_update(Channel *chl)
{
Eina_List *l;
Evas_Object *o;
Channel *pchl;
EINA_LIST_FOREACH(chl->tabbar.l.tabs, l, o)
{
pchl = evas_object_data_get(o, "channel");
if ((pchl) && (pchl != chl))
{
if (pchl->missed)
edje_object_signal_emit(o, "tabmissed,on", PACKAGE_NAME);
else
edje_object_signal_emit(o, "tabmissed,off", PACKAGE_NAME);
}
}
EINA_LIST_FOREACH(chl->tabbar.r.tabs, l, o)
{
pchl = evas_object_data_get(o, "channel");
if ((pchl) && (pchl != chl))
{
if (pchl->missed)
edje_object_signal_emit(o, "tabmissed,on", PACKAGE_NAME);
else
edje_object_signal_emit(o, "tabmissed,off", PACKAGE_NAME);
}
}
}
void
_channel_tabspacer_create(Channel *chl, double v1, double v2)
{
if (!chl->o_tab_spacer)
{
Evas_Coord w = 0, h = 0;
chl->o_tab_spacer = evas_object_rectangle_add(chl->evas);
evas_object_color_set(chl->o_tab_spacer, 0, 0, 0, 0);
elm_coords_finger_size_adjust(1, &w, 1, &h);
evas_object_size_hint_min_set(chl->o_tab_spacer, w, h);
edje_object_part_swallow(chl->o_bg, "tab", chl->o_tab_spacer);
edje_object_part_drag_value_set(chl->o_bg, "tabl", v1, 0.0);
edje_object_part_drag_value_set(chl->o_bg, "tabr", v2, 0.0);
edje_object_part_text_set(chl->o_bg, "tab.title", chl->name);
edje_object_signal_emit(chl->o_bg, "tabbar,on", PACKAGE_NAME);
edje_object_signal_emit(chl->o_base, "tabbar,on", PACKAGE_NAME);
edje_object_message_signal_process(chl->o_bg);
}
else
{
edje_object_part_drag_value_set(chl->o_bg, "tabl", v1, 0.0);
edje_object_part_drag_value_set(chl->o_bg, "tabr", v2, 0.0);
edje_object_message_signal_process(chl->o_bg);
}
}
void
_channel_tabspacer_destroy(Channel *chl)
{
if (chl->o_tab_spacer)
{
edje_object_signal_emit(chl->o_bg, "tabbar,off", PACKAGE_NAME);
edje_object_signal_emit(chl->o_base, "tabbar,off", PACKAGE_NAME);
evas_object_del(chl->o_tab_spacer);
chl->o_tab_spacer = NULL;
edje_object_message_signal_process(chl->o_bg);
}
}
Eina_Bool
_channel_user_find(Channel *chl, const char *user)
{
if ((!chl) || (!user)) return EINA_FALSE;
if (eina_list_data_find(chl->userlist.users, user) == user)
return EINA_TRUE;
return EINA_FALSE;
}
void
_channel_treeview_clear(Channel *chl)
{
elm_genlist_clear(chl->treeview.o_list);
}
void
_channel_treeview_group_add(Channel *chl, const char *group)
{
Elm_Object_Item *it;
it = elm_genlist_item_append(chl->treeview.o_list, chl->treeview.gitc,
group, NULL, ELM_GENLIST_ITEM_GROUP,
NULL, NULL);
elm_genlist_item_expanded_set(it, EINA_FALSE);
elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
if (chl->net)
{
const char *netname;
if ((netname = express_network_name_get(chl->net)))
{
if (!strcmp(netname, group))
chl->treeview.group = it;
}
}
}
void
_channel_treeview_group_item_add(Channel *pchl, Channel *chl)
{
Elm_Object_Item *it;
it =
elm_genlist_item_append(pchl->treeview.o_list, pchl->treeview.itc,
chl, pchl->treeview.group, ELM_GENLIST_ITEM_NONE,
_cb_treeview_selected, NULL);
if (chl->active)
elm_genlist_item_selected_set(it, EINA_TRUE);
}
void
_channel_treeview_item_add(Channel *pchl, Channel *chl)
{
Elm_Object_Item *it;
it =
elm_genlist_item_append(pchl->treeview.o_list, pchl->treeview.itc,
chl, NULL, ELM_GENLIST_ITEM_NONE,
_cb_treeview_selected, NULL);
if (chl->active)
elm_genlist_item_selected_set(it, EINA_TRUE);
}