2013-12-27 10:35:33 -08:00
|
|
|
#include "private.h"
|
2014-01-19 03:11:32 -08:00
|
|
|
#include "grid.h"
|
|
|
|
#include "config.h"
|
2013-12-27 10:35:33 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
typedef struct _Grid_Att Grid_Att;
|
|
|
|
struct _Grid_Att
|
|
|
|
{
|
|
|
|
unsigned char fg, bg;
|
|
|
|
unsigned short bold : 1;
|
|
|
|
unsigned short faint : 1;
|
|
|
|
#if defined(SUPPORT_ITALIC)
|
|
|
|
unsigned short italic : 1;
|
|
|
|
#endif
|
|
|
|
#if defined(SUPPORT_DBLWIDTH)
|
|
|
|
unsigned short dblwidth : 1;
|
|
|
|
#endif
|
|
|
|
unsigned short underline : 1;
|
|
|
|
unsigned short blink : 1;
|
|
|
|
unsigned short blink2 : 1;
|
|
|
|
unsigned short inverse : 1;
|
|
|
|
unsigned short invisible : 1;
|
|
|
|
unsigned short strike : 1;
|
|
|
|
unsigned short fg256 : 1;
|
|
|
|
unsigned short bg256 : 1;
|
|
|
|
unsigned short fgintense : 1;
|
|
|
|
unsigned short bgintense : 1;
|
|
|
|
|
|
|
|
unsigned short autowrapped : 1;
|
|
|
|
unsigned short newline : 1;
|
|
|
|
unsigned short tab : 1;
|
|
|
|
#if defined(SUPPORT_80_132_COLUMNS)
|
|
|
|
unsigned short is_80_132_mode_allowed : 1;
|
|
|
|
#endif
|
|
|
|
};
|
2013-12-27 12:00:39 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
typedef struct _Grid_Cell Grid_Cell;
|
|
|
|
struct _Grid_Cell
|
2013-12-27 12:00:39 -08:00
|
|
|
{
|
2014-01-19 03:11:32 -08:00
|
|
|
int codepoint;
|
|
|
|
Grid_Att att;
|
2013-12-27 12:00:39 -08:00
|
|
|
};
|
|
|
|
|
2013-12-27 10:35:33 -08:00
|
|
|
typedef struct _Grid Grid;
|
|
|
|
struct _Grid
|
|
|
|
{
|
|
|
|
Evas_Object_Smart_Clipped_Data __clipped_data;
|
2014-01-19 03:11:32 -08:00
|
|
|
|
2013-12-27 10:35:33 -08:00
|
|
|
Evas *evas;
|
2014-12-02 10:31:41 -08:00
|
|
|
Evas_Object *win;
|
2014-12-02 12:10:54 -08:00
|
|
|
Evas_Object *o_event;
|
2014-01-19 03:11:32 -08:00
|
|
|
|
|
|
|
int w, h;
|
|
|
|
Grid_Cell *cells;
|
2013-12-27 10:35:33 -08:00
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
int size, chw, chh;
|
|
|
|
const char *name;
|
|
|
|
} font;
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
struct
|
2013-12-27 10:35:33 -08:00
|
|
|
{
|
|
|
|
int w, h;
|
|
|
|
Evas_Object *obj;
|
|
|
|
} grid;
|
|
|
|
|
2014-12-02 10:31:41 -08:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
Eina_Bool active : 1;
|
|
|
|
} selection;
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
Ecore_Timer *delayed_size_tmr;
|
2013-12-27 10:35:33 -08:00
|
|
|
};
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* local function prototypes */
|
|
|
|
static void _smart_size(Evas_Object *obj, int w, int h, Eina_Bool force);
|
|
|
|
|
2013-12-27 10:35:33 -08:00
|
|
|
/* local variables */
|
|
|
|
static Evas_Smart *_smart = NULL;
|
|
|
|
static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
|
|
|
|
|
|
|
|
/* local functions */
|
|
|
|
static Eina_Bool
|
2014-01-19 03:11:32 -08:00
|
|
|
_cb_delayed_size(void *data)
|
2013-12-27 10:35:33 -08:00
|
|
|
{
|
|
|
|
Grid *sd;
|
2014-01-19 03:11:32 -08:00
|
|
|
Evas_Object *obj;
|
|
|
|
Evas_Coord w = 0, h = 0;
|
2013-12-27 10:35:33 -08:00
|
|
|
|
|
|
|
obj = data;
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* try to get the objects smart data */
|
2013-12-27 10:35:33 -08:00
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return EINA_FALSE;
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
sd->delayed_size_tmr = NULL;
|
2013-12-27 10:35:33 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
evas_object_geometry_get(obj, NULL, NULL, &w, &h);
|
|
|
|
_smart_size(obj, (w / sd->font.chw), (h / sd->font.chh), EINA_FALSE);
|
2013-12-27 10:35:33 -08:00
|
|
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-01-19 03:11:32 -08:00
|
|
|
_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
2013-12-27 10:35:33 -08:00
|
|
|
{
|
2014-01-04 06:47:44 -08:00
|
|
|
Evas_Event_Mouse_Down *ev;
|
|
|
|
|
|
|
|
ev = event;
|
2014-01-19 03:11:32 -08:00
|
|
|
if (ev->button != 3) return;
|
|
|
|
evas_object_smart_callback_call(data, "options", NULL);
|
2014-01-04 06:47:44 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-01-19 03:11:32 -08:00
|
|
|
_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
2014-01-04 06:47:44 -08:00
|
|
|
{
|
|
|
|
Evas_Event_Key_Down *ev;
|
|
|
|
|
|
|
|
ev = event;
|
|
|
|
if ((!evas_key_modifier_is_set(ev->modifiers, "Alt")) &&
|
|
|
|
(evas_key_modifier_is_set(ev->modifiers, "Control")) &&
|
|
|
|
(!evas_key_modifier_is_set(ev->modifiers, "Shift")))
|
|
|
|
{
|
2014-01-19 03:11:32 -08:00
|
|
|
if ((!strcmp(ev->key, "Prior")) || (!strcmp(ev->key, "Up")))
|
|
|
|
evas_object_smart_callback_call(data, "prev", NULL);
|
|
|
|
else if ((!strcmp(ev->key, "Next")) || (!strcmp(ev->key, "Down")))
|
|
|
|
evas_object_smart_callback_call(data, "next", NULL);
|
2014-01-04 06:47:44 -08:00
|
|
|
}
|
2013-12-27 10:35:33 -08:00
|
|
|
}
|
|
|
|
|
2014-12-02 10:31:41 -08:00
|
|
|
static void
|
|
|
|
_selection_set(Evas_Object *obj, Eina_Bool enabled)
|
|
|
|
{
|
|
|
|
Grid *sd;
|
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
|
|
|
|
if (sd->selection.active == enabled) return;
|
|
|
|
sd->selection.active = enabled;
|
|
|
|
if (enabled)
|
|
|
|
evas_object_smart_callback_call(sd->win, "selection,on", NULL);
|
|
|
|
else
|
|
|
|
evas_object_smart_callback_call(sd->win, "selection,off", NULL);
|
|
|
|
}
|
|
|
|
|
2013-12-27 10:35:33 -08:00
|
|
|
static void
|
|
|
|
_smart_add(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Grid *sd;
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* try to allocate space for smart data */
|
2013-12-27 10:35:33 -08:00
|
|
|
if (!(sd = calloc(1, sizeof(Grid)))) return;
|
|
|
|
|
|
|
|
evas_object_smart_data_set(obj, sd);
|
|
|
|
_parent_sc.add(obj);
|
|
|
|
|
|
|
|
sd->evas = evas_object_evas_get(obj);
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* create textgrid */
|
2013-12-27 10:35:33 -08:00
|
|
|
sd->grid.obj = evas_object_textgrid_add(sd->evas);
|
2014-12-02 12:10:54 -08:00
|
|
|
evas_object_pass_events_set(sd->grid.obj, EINA_TRUE);
|
|
|
|
evas_object_propagate_events_set(sd->grid.obj, EINA_FALSE);
|
2013-12-27 10:35:33 -08:00
|
|
|
evas_object_smart_member_add(sd->grid.obj, obj);
|
|
|
|
evas_object_show(sd->grid.obj);
|
|
|
|
|
2014-12-02 12:10:54 -08:00
|
|
|
sd->o_event = evas_object_rectangle_add(sd->evas);
|
|
|
|
evas_object_repeat_events_set(sd->o_event, EINA_TRUE);
|
|
|
|
evas_object_color_set(sd->o_event, 0, 0, 0, 0);
|
|
|
|
evas_object_smart_member_add(sd->o_event, obj);
|
|
|
|
evas_object_show(sd->o_event);
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* TODO: finish callbacks */
|
2014-12-02 12:10:54 -08:00
|
|
|
evas_object_event_callback_add(sd->o_event, EVAS_CALLBACK_MOUSE_DOWN,
|
2014-01-19 03:11:32 -08:00
|
|
|
_cb_mouse_down, obj);
|
2014-12-02 12:10:54 -08:00
|
|
|
evas_object_event_callback_add(sd->o_event, EVAS_CALLBACK_KEY_DOWN,
|
2014-01-19 03:11:32 -08:00
|
|
|
_cb_key_down, obj);
|
2013-12-27 10:35:33 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_del(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Grid *sd;
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* try to get the objects smart data */
|
2013-12-27 10:35:33 -08:00
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* delete the size timer */
|
|
|
|
if (sd->delayed_size_tmr) ecore_timer_del(sd->delayed_size_tmr);
|
|
|
|
|
|
|
|
/* delete animator */
|
|
|
|
/* if (sd->anim) ecore_animator_del(sd->anim); */
|
|
|
|
|
|
|
|
/* delete objects */
|
2013-12-27 10:35:33 -08:00
|
|
|
if (sd->grid.obj) evas_object_del(sd->grid.obj);
|
2014-12-02 12:10:54 -08:00
|
|
|
if (sd->o_event) evas_object_del(sd->o_event);
|
2014-01-19 03:11:32 -08:00
|
|
|
|
2013-12-27 12:00:39 -08:00
|
|
|
if (sd->font.name) eina_stringshare_del(sd->font.name);
|
2014-01-04 06:47:44 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* free grid cells */
|
|
|
|
if (sd->cells) free(sd->cells);
|
2013-12-27 10:35:33 -08:00
|
|
|
|
|
|
|
_parent_sc.del(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
|
|
|
|
{
|
|
|
|
Grid *sd;
|
|
|
|
Evas_Coord ow, oh;
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* try to get the objects smart data */
|
2013-12-27 10:35:33 -08:00
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* get geometry of the object */
|
2013-12-27 10:35:33 -08:00
|
|
|
evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
|
|
|
|
if ((ow == w) && (oh == h)) return;
|
|
|
|
|
|
|
|
evas_object_smart_changed(obj);
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
if (!sd->delayed_size_tmr)
|
|
|
|
sd->delayed_size_tmr = ecore_timer_add(0.0, _cb_delayed_size, obj);
|
|
|
|
else
|
2014-12-02 10:31:41 -08:00
|
|
|
ecore_timer_reset(sd->delayed_size_tmr);
|
|
|
|
// ecore_timer_delay(sd->delayed_size_tmr, 0.0);
|
2014-12-02 12:10:54 -08:00
|
|
|
evas_object_resize(sd->o_event, ow, oh);
|
2013-12-27 10:35:33 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_smart_move(Evas_Object *obj, Evas_Coord x EINA_UNUSED, Evas_Coord y EINA_UNUSED)
|
|
|
|
{
|
|
|
|
evas_object_smart_changed(obj);
|
|
|
|
}
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
static void
|
|
|
|
_smart_calculate(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Grid *sd;
|
|
|
|
Evas_Coord ox, oy, ow, oh;
|
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
|
|
|
|
evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
|
|
|
|
|
|
|
|
evas_object_move(sd->grid.obj, ox, oy);
|
|
|
|
evas_object_resize(sd->grid.obj, sd->grid.w * sd->font.chw,
|
|
|
|
sd->grid.h * sd->font.chh);
|
|
|
|
|
2014-12-02 12:10:54 -08:00
|
|
|
evas_object_move(sd->o_event, ox, oy);
|
|
|
|
evas_object_resize(sd->o_event, ow, oh);
|
2014-01-19 03:11:32 -08:00
|
|
|
}
|
|
|
|
|
2013-12-27 10:35:33 -08:00
|
|
|
static void
|
|
|
|
_smart_init(void)
|
|
|
|
{
|
|
|
|
static Evas_Smart_Class sc;
|
|
|
|
|
|
|
|
evas_object_smart_clipped_smart_set(&_parent_sc);
|
|
|
|
|
|
|
|
sc = _parent_sc;
|
|
|
|
sc.name = "grid";
|
|
|
|
sc.version = EVAS_SMART_CLASS_VERSION;
|
|
|
|
sc.add = _smart_add;
|
|
|
|
sc.del = _smart_del;
|
|
|
|
sc.resize = _smart_resize;
|
|
|
|
sc.move = _smart_move;
|
|
|
|
sc.calculate = _smart_calculate;
|
|
|
|
|
|
|
|
_smart = evas_smart_class_new(&sc);
|
|
|
|
}
|
|
|
|
|
2013-12-27 12:00:39 -08:00
|
|
|
static void
|
2014-01-19 03:11:32 -08:00
|
|
|
_smart_size(Evas_Object *obj, int w, int h, Eina_Bool force)
|
2013-12-27 12:00:39 -08:00
|
|
|
{
|
2014-01-19 03:11:32 -08:00
|
|
|
Grid *sd;
|
2013-12-27 12:00:39 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
2014-01-04 03:30:28 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
if (w < 1) w = 1;
|
|
|
|
if (h < 1) h = 1;
|
|
|
|
if (!force)
|
2013-12-27 12:00:39 -08:00
|
|
|
{
|
2014-01-19 03:11:32 -08:00
|
|
|
if ((w == sd->grid.w) && (h == sd->grid.h)) return;
|
2013-12-27 12:00:39 -08:00
|
|
|
}
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
evas_event_freeze(sd->evas);
|
2013-12-27 12:00:39 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
sd->grid.w = w;
|
|
|
|
sd->grid.h = h;
|
|
|
|
evas_object_textgrid_size_set(sd->grid.obj, sd->grid.w, sd->grid.h);
|
2013-12-27 12:00:39 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
evas_object_size_hint_min_set(obj, sd->font.chw, sd->font.chh);
|
|
|
|
evas_object_size_hint_request_set(obj, sd->font.chw * sd->grid.w,
|
|
|
|
sd->font.chh * sd->grid.h);
|
2013-12-27 12:00:39 -08:00
|
|
|
|
2014-12-02 10:31:41 -08:00
|
|
|
_selection_set(obj, EINA_FALSE);
|
|
|
|
|
|
|
|
/* TODO: call grid resize function to allocate cells */
|
2014-01-19 03:11:32 -08:00
|
|
|
|
|
|
|
_smart_calculate(obj);
|
2013-12-27 12:00:39 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
evas_event_thaw(sd->evas);
|
2013-12-27 12:00:39 -08:00
|
|
|
}
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* external functions */
|
2013-12-27 10:35:33 -08:00
|
|
|
Evas_Object *
|
2014-01-19 03:11:32 -08:00
|
|
|
_grid_add(Evas *evas)
|
2013-12-27 10:35:33 -08:00
|
|
|
{
|
|
|
|
Evas_Object *obj;
|
|
|
|
Grid *sd;
|
|
|
|
|
|
|
|
if (!_smart) _smart_init();
|
|
|
|
|
|
|
|
obj = evas_object_smart_add(evas, _smart);
|
2014-01-19 03:11:32 -08:00
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
2013-12-27 10:35:33 -08:00
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return obj;
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
sd->w = 80;
|
2014-12-02 12:10:54 -08:00
|
|
|
sd->h = 24;
|
2014-01-19 03:11:32 -08:00
|
|
|
|
|
|
|
sd->cells = calloc(1, sizeof(Grid_Cell) * sd->w * sd->h);
|
|
|
|
if (!sd->cells) goto err;
|
2014-01-04 03:30:28 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
_grid_update(obj);
|
2013-12-27 12:00:39 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
_smart_size(obj, sd->w, sd->h, EINA_FALSE);
|
2013-12-27 10:35:33 -08:00
|
|
|
|
|
|
|
return obj;
|
2014-01-19 03:11:32 -08:00
|
|
|
|
|
|
|
err:
|
|
|
|
free(sd);
|
|
|
|
return obj;
|
2013-12-27 10:35:33 -08:00
|
|
|
}
|
2013-12-27 12:00:39 -08:00
|
|
|
|
|
|
|
void
|
2014-01-19 03:11:32 -08:00
|
|
|
_grid_update(Evas_Object *obj)
|
2013-12-27 12:00:39 -08:00
|
|
|
{
|
|
|
|
Grid *sd;
|
2014-12-02 12:10:54 -08:00
|
|
|
Evas_Coord w = 0, h = 0;
|
|
|
|
Evas_Coord ow = 0, oh = 0;
|
2013-12-27 12:00:39 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
/* try to get the objects smart data */
|
2013-12-27 12:00:39 -08:00
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
if (sd->font.name) eina_stringshare_del(sd->font.name);
|
|
|
|
sd->font.name = NULL;
|
2013-12-27 12:00:39 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
if (_ex_cfg->font.bitmap)
|
2013-12-27 12:00:39 -08:00
|
|
|
{
|
2014-01-19 03:11:32 -08:00
|
|
|
char buff[PATH_MAX];
|
|
|
|
|
|
|
|
snprintf(buff, sizeof(buff), "%s/fonts/%s",
|
|
|
|
elm_app_data_dir_get(), _ex_cfg->font.name);
|
|
|
|
sd->font.name = eina_stringshare_add(buff);
|
2013-12-27 12:00:39 -08:00
|
|
|
}
|
2014-01-19 03:11:32 -08:00
|
|
|
else
|
|
|
|
sd->font.name = eina_stringshare_add(_ex_cfg->font.name);
|
2014-01-04 03:30:28 -08:00
|
|
|
|
2014-01-19 03:11:32 -08:00
|
|
|
sd->font.size = _ex_cfg->font.size;
|
|
|
|
|
|
|
|
evas_object_scale_set(sd->grid.obj, elm_config_scale_get());
|
|
|
|
evas_object_textgrid_font_set(sd->grid.obj, sd->font.name, sd->font.size);
|
|
|
|
|
|
|
|
evas_object_textgrid_cell_size_get(sd->grid.obj, &w, &h);
|
|
|
|
if (w < 1) w = 1;
|
|
|
|
if (h < 1) h = 1;
|
|
|
|
sd->font.chw = w;
|
|
|
|
sd->font.chh = h;
|
2014-01-04 03:30:28 -08:00
|
|
|
|
2014-12-02 12:10:54 -08:00
|
|
|
evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
|
|
|
|
_smart_size(obj, ow / w, oh / h, EINA_TRUE);
|
2014-01-04 03:30:28 -08:00
|
|
|
}
|
2014-12-02 10:31:41 -08:00
|
|
|
|
|
|
|
void
|
|
|
|
_grid_window_set(Evas_Object *obj, Evas_Object *win)
|
|
|
|
{
|
|
|
|
Grid *sd;
|
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
sd->win = win;
|
|
|
|
}
|