From 29f683d08419e4e9c19594654cd2a86c00b1ec7e Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sat, 24 Jan 2015 22:07:00 +0000 Subject: [PATCH] Complete port of elm_code widget to eo as widget2 --- elm_code/bin/elm_code_test_main.c | 22 +- elm_code/lib/elm_code.c | 2 +- elm_code/lib/elm_code_widget2.c | 339 ++++++++++++++++++++++++++--- elm_code/lib/elm_code_widget2.eo | 21 +- elm_code/lib/elm_code_widget2.eo.c | 29 ++- elm_code/lib/elm_code_widget2.eo.h | 44 +++- 6 files changed, 392 insertions(+), 65 deletions(-) diff --git a/elm_code/bin/elm_code_test_main.c b/elm_code/bin/elm_code_test_main.c index 7180eb7..755c532 100644 --- a/elm_code/bin/elm_code_test_main.c +++ b/elm_code/bin/elm_code_test_main.c @@ -48,23 +48,15 @@ static Evas_Object * _elm_code_test_welcome_setup(Evas_Object *parent) { Elm_Code *code; - Evas_Object *widget; + Elm_Code_Widget2 *widget; code = elm_code_create(); - - Elm_Code_Widget2 *obj = eo_add(ELM_CODE_WIDGET2_CLASS, parent); - eo_do(obj, - elm_code_widget2_font_size_set(14)); - - evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_show(obj); -return obj; -// TODO - add all this good stuff into the eo api - widget = elm_code_widget_add(parent, code); - elm_code_widget_font_size_set(widget, 14); - elm_code_widget_editable_set(widget, EINA_TRUE); - eo_do(widget,eo_event_callback_add(&ELM_CODE_WIDGET_EVENT_LINE_CLICKED, _elm_code_test_line_cb, code)); + widget = eo_add(ELM_CODE_WIDGET2_CLASS, parent); + eo_do(widget, + elm_code_widget2_code_set(code); + elm_code_widget2_font_size_set(14); + elm_code_widget2_editable_set(EINA_TRUE); + eo_event_callback_add(ELM_CODE_WIDGET2_EVENT_LINE_CLICKED, _elm_code_test_line_cb, code)); _append_line(code->file, "Hello World, Elm Code!"); elm_code_file_line_token_add(code->file, 1, 14, 21, ELM_CODE_TOKEN_TYPE_COMMENT); diff --git a/elm_code/lib/elm_code.c b/elm_code/lib/elm_code.c index d1e3282..1f96512 100644 --- a/elm_code/lib/elm_code.c +++ b/elm_code/lib/elm_code.c @@ -105,7 +105,7 @@ EAPI void elm_code_callback_fire(Elm_Code *code, const Eo_Event_Description *signal, void *data) { Eina_List *item; - Evas_Object *widget; + Eo *widget; EINA_LIST_FOREACH(code->widgets, item, widget) { diff --git a/elm_code/lib/elm_code_widget2.c b/elm_code/lib/elm_code_widget2.c index b9ba337..fa16532 100644 --- a/elm_code/lib/elm_code_widget2.c +++ b/elm_code/lib/elm_code_widget2.c @@ -11,69 +11,342 @@ typedef struct { Elm_Code *code; + Evas_Object *grid; Evas_Font_Size font_size; unsigned int cursor_line, cursor_col; Eina_Bool editable; - } Elm_Code_Widget2_Data; +Eina_Unicode status_icons2[] = { + ' ', + '!', + + '+', + '-', + ' ', + + 0x2713, + 0x2717, + + 0 +}; + + EOLIAN static void -_elm_code_widget2_eo_base_constructor(Eo *obj, Elm_Code_Widget2_Data *pd) +_elm_code_widget2_eo_base_constructor(Eo *obj, Elm_Code_Widget2_Data *pd EINA_UNUSED) { eo_do_super(obj, ELM_CODE_WIDGET2_CLASS, eo_constructor()); -printf("constr\n"); + + pd->cursor_line = 1; + pd->cursor_col = 1; } EOLIAN static void -_elm_code_widget2_evas_object_smart_resize(Eo *obj, Elm_Code_Widget2_Data *pd, Evas_Coord w, Evas_Coord h) -{ -printf("size %d, %d\n", w, h); -} - -EOLIAN static void -_elm_code_widget2_class_constructor(Eo_Class *klass) +_elm_code_widget2_class_constructor(Eo_Class *klass EINA_UNUSED) { } -EOLIAN static void -_elm_code_widget2_elm_interface_scrollable_content_pos_set(Eo *obj, Elm_Code_Widget2_Data *pd, Evas_Coord x, Evas_Coord y, Eina_Bool sig) +static Eina_Bool +_elm_code_widget_resize(Evas_Object *o) { + int w, h, cw, ch; + evas_object_geometry_get(o, NULL, NULL, &w, &h); + evas_object_textgrid_cell_size_get(o, &cw, &ch); + + evas_object_textgrid_size_set(o, ceil(((double) w) / cw), + ceil(((double) h) / ch)); + + return h > 0 && w > 0; +} + +static void +_elm_code_widget_fill_line_token(Evas_Textgrid_Cell *cells, int count, int start, int end, Elm_Code_Token_Type type) +{ + int x; + + for (x = start; x <= end && x < count; x++) + { + cells[x].fg = type; + } +} + +static void +_elm_code_widget_fill_line_tokens(Evas_Textgrid_Cell *cells, unsigned int count, Elm_Code_Line *line) +{ + Eina_List *item; + Elm_Code_Token *token; + int start, length; + + start = 1; + length = line->length; + + EINA_LIST_FOREACH(line->tokens, item, token) + { + + _elm_code_widget_fill_line_token(cells, count, start, token->start, ELM_CODE_TOKEN_TYPE_DEFAULT); + + // TODO handle a token starting before the previous finishes + _elm_code_widget_fill_line_token(cells, count, token->start, token->end, token->type); + + start = token->end + 1; + } + + _elm_code_widget_fill_line_token(cells, count, start, length, ELM_CODE_TOKEN_TYPE_DEFAULT); +} + +static void +_elm_code_widget_fill_line(Elm_Code_Widget2_Data *pd, Evas_Textgrid_Cell *cells, Elm_Code_Line *line) +{ + char *chr; + unsigned int length, x; + int w; + + if (!_elm_code_widget_resize(pd->grid)) + return; + + length = line->length; + evas_object_textgrid_size_get(pd->grid, &w, NULL); + + cells[0].codepoint = status_icons2[line->status]; + cells[0].bold = 1; + cells[0].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; + cells[0].bg = line->status; + + if (line->modified) + chr = line->modified; + else + chr = (char *)line->content; + for (x = 1; x < (unsigned int) w && x <= length; x++) + { + cells[x].codepoint = *chr; + cells[x].bg = line->status; + + chr++; + } + for (; x < (unsigned int) w; x++) + { + cells[x].codepoint = 0; + cells[x].bg = line->status; + } + + _elm_code_widget_fill_line_tokens(cells, w, line); + if (pd->editable && pd->cursor_line == line->number) + { + if (pd->cursor_col < (unsigned int) w) + cells[pd->cursor_col].bg = ELM_CODE_TOKEN_TYPE_CURSOR; + } + + evas_object_textgrid_update_add(pd->grid, 0, line->number - 1, w, 1); +} + +static void +_elm_code_widget_fill(Elm_Code_Widget2_Data *pd) +{ + Elm_Code_Line *line; + Evas_Textgrid_Cell *cells; + int w, h; + unsigned int y; + + if (!_elm_code_widget_resize(pd->grid)) + return; + evas_object_textgrid_size_get(pd->grid, &w, &h); + + for (y = 1; y <= (unsigned int) h && y <= elm_code_file_lines_get(pd->code->file); y++) + { + line = elm_code_file_line_get(pd->code->file, y); + + cells = evas_object_textgrid_cellrow_get(pd->grid, y - 1); + _elm_code_widget_fill_line(pd, cells, line); + } +} + +static Eina_Bool +_elm_code_widget2_line_cb(void *data, Eo *obj EINA_UNUSED, + const Eo_Event_Description *desc EINA_UNUSED, void *event_info) +{ + Elm_Code_Widget2_Data *widget; + Elm_Code_Line *line; + int h; + + Evas_Textgrid_Cell *cells; + + widget = (Elm_Code_Widget2_Data *)data; + line = (Elm_Code_Line *)event_info; + + evas_object_textgrid_size_get(widget->grid, NULL, &h); + + if (line->number > (unsigned int) h) + return EINA_TRUE; + + cells = evas_object_textgrid_cellrow_get(widget->grid, line->number - 1); + _elm_code_widget_fill_line(widget, cells, line); + + return EINA_TRUE; +} + + +static Eina_Bool +_elm_code_widget2_file_cb(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Elm_Code_Widget2_Data *widget; + + widget = (Elm_Code_Widget2_Data *)data; + + _elm_code_widget_fill(widget); + return EINA_TRUE; +} + +static void +_elm_code_widget2_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Elm_Code_Widget2_Data *widget; + + widget = (Elm_Code_Widget2_Data *)data; + + _elm_code_widget_fill(widget); +} + +static void +_elm_code_widget2_clicked_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info) +{ + Elm_Code_Widget2 *widget; + Elm_Code_Widget2_Data *pd; + Elm_Code_Line *line; + Evas_Event_Mouse_Up *event; + Evas_Coord y; + int ch; + unsigned int row; + + widget = (Elm_Code_Widget2 *)data; + pd = eo_data_scope_get(widget, ELM_CODE_WIDGET2_CLASS); + event = (Evas_Event_Mouse_Up *)event_info; + y = event->canvas.y; + + evas_object_textgrid_cell_size_get(pd->grid, NULL, &ch); + row = ((double) y / ch) + 1; + + line = elm_code_file_line_get(pd->code->file, row); + if (line) + eo_do(widget, eo_event_callback_call(ELM_CODE_WIDGET2_EVENT_LINE_CLICKED, line)); +} + +EOLIAN static void +_elm_code_widget2_elm_interface_scrollable_content_pos_set(Eo *obj EINA_UNUSED, + Elm_Code_Widget2_Data *pd EINA_UNUSED, + Evas_Coord x, Evas_Coord y, + Eina_Bool sig EINA_UNUSED) +{ + printf("scroll to %d, %d\n", x, y); +} + +EOLIAN static void +_elm_code_widget2_font_size_set(Eo *obj EINA_UNUSED, Elm_Code_Widget2_Data *pd, Evas_Font_Size font_size) +{ + evas_object_textgrid_font_set(pd->grid, "Mono", font_size * elm_config_scale_get()); + pd->font_size = font_size; +} + +EOLIAN static Evas_Font_Size +_elm_code_widget2_font_size_get(Eo *obj EINA_UNUSED, Elm_Code_Widget2_Data *pd) +{ + return pd->font_size; +} + +EOLIAN static void +_elm_code_widget2_code_set(Eo *obj EINA_UNUSED, Elm_Code_Widget2_Data *pd, Elm_Code *code) +{ + pd->code = code; + + code->widgets = eina_list_append(code->widgets, pd); +} + +EOLIAN static Elm_Code * +_elm_code_widget2_code_get(Eo *obj EINA_UNUSED, Elm_Code_Widget2_Data *pd) +{ + return pd->code; +} + +EOLIAN static void +_elm_code_widget2_editable_set(Eo *obj EINA_UNUSED, Elm_Code_Widget2_Data *pd, Eina_Bool editable) +{ + pd->editable = editable; +} + +EOLIAN static Eina_Bool +_elm_code_widget2_editable_get(Eo *obj EINA_UNUSED, Elm_Code_Widget2_Data *pd) +{ + return pd->editable; +} + +static void +_elm_code_widget2_setup_palette(Evas_Object *o) +{ + // setup status colors + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_DEFAULT, + 36, 36, 36, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_ERROR, + 205, 54, 54, 255); + + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_ADDED, + 36, 96, 36, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_REMOVED, + 96, 36, 36, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_CHANGED, + 36, 36, 96, 255); + + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_PASSED, + 54, 96, 54, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_STATUS_TYPE_FAILED, + 96, 54, 54, 255); + + // setup token colors + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_DEFAULT, + 205, 205, 205, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_COMMENT, + 54, 205, 255, 255); + + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_ADDED, + 54, 255, 54, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_REMOVED, + 255, 54, 54, 255); + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_CHANGED, + 54, 54, 255, 255); + + // the style for a cursor - this is a special token and will be applied to the background + evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_TOKEN_TYPE_CURSOR, + 205, 205, 54, 255); } EOLIAN static void _elm_code_widget2_evas_object_smart_add(Eo *obj, Elm_Code_Widget2_Data *pd) { - Evas_Object *text; + Evas_Object *grid; -printf("add\n"); eo_do_super(obj, ELM_CODE_WIDGET2_CLASS, evas_obj_smart_add()); - elm_widget_sub_object_parent_add(obj); // elm_widget_can_focus_set(obj, EINA_TRUE); - text = elm_label_add(obj); - elm_object_text_set(text, "HELLO"); - evas_object_size_hint_weight_set(text, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(text, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_show(text); - elm_box_pack_end(obj, text); + grid = evas_object_textgrid_add(obj); + evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(grid, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(grid); + elm_box_pack_end(obj, grid); + pd->grid = grid; + _elm_code_widget2_setup_palette(grid); - eo_do(obj, elm_obj_widget_theme_apply()); -} + evas_object_event_callback_add(grid, EVAS_CALLBACK_RESIZE, _elm_code_widget2_resize_cb, pd); + evas_object_event_callback_add(grid, EVAS_CALLBACK_MOUSE_UP, _elm_code_widget2_clicked_cb, obj); -EOLIAN static void -_elm_code_widget2_font_size_set(Eo *obj, Elm_Code_Widget2_Data *pd, Evas_Font_Size font_size) -{ - printf("set\n"); - pd->font_size = font_size; -} + eo_do(obj, + eo_event_callback_add(&ELM_CODE_EVENT_LINE_SET_DONE, _elm_code_widget2_line_cb, pd); + eo_event_callback_add(&ELM_CODE_EVENT_FILE_LOAD_DONE, _elm_code_widget2_file_cb, pd)); -EOLIAN static Evas_Font_Size -_elm_code_widget2_font_size_get(Eo *obj, Elm_Code_Widget2_Data *pd) -{ - return pd->font_size; + _elm_code_widget2_font_size_set(obj, pd, 10); } #include "elm_code_widget2.eo.c" diff --git a/elm_code/lib/elm_code_widget2.eo b/elm_code/lib/elm_code_widget2.eo index 63bc5d2..d71f78f 100644 --- a/elm_code/lib/elm_code_widget2.eo +++ b/elm_code/lib/elm_code_widget2.eo @@ -3,6 +3,15 @@ class Elm_Code_Widget2 (Elm_Box, Elm_Interface_Scrollable, { eo_prefix: elm_code_widget2; properties { + code { + set { + } + get { + } + values { + Elm_Code *code; + } + } font_size { set { } @@ -12,6 +21,15 @@ class Elm_Code_Widget2 (Elm_Box, Elm_Interface_Scrollable, Evas_Font_Size font_size; } } + editable { + set { + } + get { + } + values { + Eina_Bool editable; + } + } } methods { } @@ -22,8 +40,7 @@ class Elm_Code_Widget2 (Elm_Box, Elm_Interface_Scrollable, Elm_Interface_Scrollable.content_pos_set; } events { - focused; - unfocused; + line,clicked; } } diff --git a/elm_code/lib/elm_code_widget2.eo.c b/elm_code/lib/elm_code_widget2.eo.c index b689d76..bf34af5 100644 --- a/elm_code/lib/elm_code_widget2.eo.c +++ b/elm_code/lib/elm_code_widget2.eo.c @@ -1,7 +1,13 @@ -EOAPI const Eo_Event_Description _ELM_CODE_WIDGET2_EVENT_FOCUSED = - EO_EVENT_DESCRIPTION("focused", ""); -EOAPI const Eo_Event_Description _ELM_CODE_WIDGET2_EVENT_UNFOCUSED = - EO_EVENT_DESCRIPTION("unfocused", ""); +EOAPI const Eo_Event_Description _ELM_CODE_WIDGET2_EVENT_LINE_CLICKED = + EO_EVENT_DESCRIPTION("line,clicked", ""); + +void _elm_code_widget2_code_set(Eo *obj, Elm_Code_Widget2_Data *pd, Elm_Code *code); + +EOAPI EO_VOID_FUNC_BODYV(elm_code_widget2_code_set, EO_FUNC_CALL(code), Elm_Code *code); + +Elm_Code * _elm_code_widget2_code_get(Eo *obj, Elm_Code_Widget2_Data *pd); + +EOAPI EO_FUNC_BODY(elm_code_widget2_code_get, Elm_Code *, 0); void _elm_code_widget2_font_size_set(Eo *obj, Elm_Code_Widget2_Data *pd, Evas_Font_Size font_size); @@ -11,6 +17,14 @@ Evas_Font_Size _elm_code_widget2_font_size_get(Eo *obj, Elm_Code_Widget2_Data *p EOAPI EO_FUNC_BODY(elm_code_widget2_font_size_get, Evas_Font_Size, 0); +void _elm_code_widget2_editable_set(Eo *obj, Elm_Code_Widget2_Data *pd, Eina_Bool editable); + +EOAPI EO_VOID_FUNC_BODYV(elm_code_widget2_editable_set, EO_FUNC_CALL(editable), Eina_Bool editable); + +Eina_Bool _elm_code_widget2_editable_get(Eo *obj, Elm_Code_Widget2_Data *pd); + +EOAPI EO_FUNC_BODY(elm_code_widget2_editable_get, Eina_Bool, 0); + void _elm_code_widget2_eo_base_constructor(Eo *obj, Elm_Code_Widget2_Data *pd); @@ -24,14 +38,17 @@ static Eo_Op_Description _elm_code_widget2_op_desc[] = { EO_OP_FUNC_OVERRIDE(eo_constructor, _elm_code_widget2_eo_base_constructor), EO_OP_FUNC_OVERRIDE(evas_obj_smart_add, _elm_code_widget2_evas_object_smart_add), EO_OP_FUNC_OVERRIDE(elm_interface_scrollable_content_pos_set, _elm_code_widget2_elm_interface_scrollable_content_pos_set), + EO_OP_FUNC(elm_code_widget2_code_set, _elm_code_widget2_code_set, ""), + EO_OP_FUNC(elm_code_widget2_code_get, _elm_code_widget2_code_get, ""), EO_OP_FUNC(elm_code_widget2_font_size_set, _elm_code_widget2_font_size_set, ""), EO_OP_FUNC(elm_code_widget2_font_size_get, _elm_code_widget2_font_size_get, ""), + EO_OP_FUNC(elm_code_widget2_editable_set, _elm_code_widget2_editable_set, ""), + EO_OP_FUNC(elm_code_widget2_editable_get, _elm_code_widget2_editable_get, ""), EO_OP_SENTINEL }; static const Eo_Event_Description *_elm_code_widget2_event_desc[] = { - ELM_CODE_WIDGET2_EVENT_FOCUSED, - ELM_CODE_WIDGET2_EVENT_UNFOCUSED, + ELM_CODE_WIDGET2_EVENT_LINE_CLICKED, NULL }; diff --git a/elm_code/lib/elm_code_widget2.eo.h b/elm_code/lib/elm_code_widget2.eo.h index 75d1b4d..cbad231 100644 --- a/elm_code/lib/elm_code_widget2.eo.h +++ b/elm_code/lib/elm_code_widget2.eo.h @@ -17,6 +17,23 @@ typedef Eo Elm_Code_Widget2; const Eo_Class *elm_code_widget2_class_get(void) EINA_CONST; +/** + * + * No description supplied. + * + * @param[in] code No description supplied. + * + */ +EOAPI void elm_code_widget2_code_set(Elm_Code *code); + +/** + * + * No description supplied. + * + * + */ +EOAPI Elm_Code * elm_code_widget2_code_get(void); + /** * * No description supplied. @@ -34,17 +51,28 @@ EOAPI void elm_code_widget2_font_size_set(Evas_Font_Size font_size); */ EOAPI Evas_Font_Size elm_code_widget2_font_size_get(void); -EOAPI extern const Eo_Event_Description _ELM_CODE_WIDGET2_EVENT_FOCUSED; -EOAPI extern const Eo_Event_Description _ELM_CODE_WIDGET2_EVENT_UNFOCUSED; +/** + * + * No description supplied. + * + * @param[in] editable No description supplied. + * + */ +EOAPI void elm_code_widget2_editable_set(Eina_Bool editable); + +/** + * + * No description supplied. + * + * + */ +EOAPI Eina_Bool elm_code_widget2_editable_get(void); + +EOAPI extern const Eo_Event_Description _ELM_CODE_WIDGET2_EVENT_LINE_CLICKED; /** * No description */ -#define ELM_CODE_WIDGET2_EVENT_FOCUSED (&(_ELM_CODE_WIDGET2_EVENT_FOCUSED)) - -/** - * No description - */ -#define ELM_CODE_WIDGET2_EVENT_UNFOCUSED (&(_ELM_CODE_WIDGET2_EVENT_UNFOCUSED)) +#define ELM_CODE_WIDGET2_EVENT_LINE_CLICKED (&(_ELM_CODE_WIDGET2_EVENT_LINE_CLICKED)) #endif