diff --git a/elm_code/bin/elm_code_test_main.c b/elm_code/bin/elm_code_test_main.c index c88f985..40f73bf 100644 --- a/elm_code/bin/elm_code_test_main.c +++ b/elm_code/bin/elm_code_test_main.c @@ -32,6 +32,7 @@ _elm_code_test_welcome_setup(Evas_Object *parent) code = elm_code_create(elm_code_file_new()); widget = elm_code_widget_add(parent, code); elm_code_file_line_append(code->file, "Hello World, Elm Code!"); + elm_code_file_line_token_add(code->file, 1, 14, 21, ELM_CODE_TOKEN_TYPE_COMMENT); elm_code_file_line_append(code->file, ""); elm_code_file_line_append(code->file, "This is a demo of elm_code's capabilities."); diff --git a/elm_code/lib/elm_code_common.h b/elm_code/lib/elm_code_common.h index bae3599..e19a6b3 100644 --- a/elm_code/lib/elm_code_common.h +++ b/elm_code/lib/elm_code_common.h @@ -21,6 +21,7 @@ typedef enum { typedef enum { ELM_CODE_TOKEN_TYPE_DEFAULT = ELM_CODE_STATUS_TYPE_COUNT, + ELM_CODE_TOKEN_TYPE_COMMENT, ELM_CODE_TOKEN_TYPE_COUNT } Elm_Code_Token_Type; diff --git a/elm_code/lib/elm_code_file.c b/elm_code/lib/elm_code_file.c index 9650b33..e649b28 100644 --- a/elm_code/lib/elm_code_file.c +++ b/elm_code/lib/elm_code_file.c @@ -156,3 +156,23 @@ EAPI void elm_code_file_line_status_set(Elm_Code_File *file, unsigned int number if (file->parent) elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_SET_DONE, line); } + +EAPI void elm_code_file_line_token_add(Elm_Code_File *file, unsigned int number, int start, int end, + Elm_Code_Token_Type type) +{ + Elm_Code_Line *line; + Elm_Code_Token *tok; + + line = elm_code_file_line_get(file, number); + tok = calloc(1, sizeof(Elm_Code_Token)); + + tok->start = start; + tok->end = end; + tok->type = type; + + line->tokens = eina_list_append(line->tokens, tok); + + if (file->parent) + elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_SET_DONE, line); +} + diff --git a/elm_code/lib/elm_code_file.h b/elm_code/lib/elm_code_file.h index 3ea1e4b..0950ed9 100644 --- a/elm_code/lib/elm_code_file.h +++ b/elm_code/lib/elm_code_file.h @@ -14,12 +14,22 @@ extern "C" { * @brief These routines are used for interacting with files using Elm Code. */ +typedef struct _Elm_Code_Token +{ + int start, end; + + Elm_Code_Token_Type type; + +} Elm_Code_Token; + typedef struct _Elm_Code_Line { char *content; unsigned int number; Elm_Code_Status_Type status; + Eina_List *tokens; + } Elm_Code_Line; @@ -76,6 +86,9 @@ EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int line EAPI void elm_code_file_line_status_set(Elm_Code_File *file, unsigned int line, Elm_Code_Status_Type status); +EAPI void elm_code_file_line_token_add(Elm_Code_File *file, unsigned int number, int start, int end, + Elm_Code_Token_Type type); + /** * @} */ diff --git a/elm_code/lib/elm_code_widget.c b/elm_code/lib/elm_code_widget.c index 760334f..011afdb 100644 --- a/elm_code/lib/elm_code_widget.c +++ b/elm_code/lib/elm_code_widget.c @@ -9,48 +9,93 @@ #include "elm_code_private.h" -EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) +static Eina_Bool _elm_code_widget_resize(Evas_Object *o) { - Elm_Code_Line *line; - Evas_Textgrid_Cell *cells; - const char *content; - char *chr; - unsigned int length; int w, h, cw, ch; - unsigned int x, y; 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 - 1; x < end && x < count; x++) + { + cells[x].fg = type; + } +} + +static void _elm_code_widget_fill_line(Evas_Object *o, Evas_Textgrid_Cell *cells, Elm_Code_Line *line) +{ + Eina_List *item; + Elm_Code_Token *token; + + char *chr; + unsigned int length, x; + int w, start; + + if (!_elm_code_widget_resize(o)) + return; + + length = strlen(line->content); + evas_object_textgrid_size_get(o, &w, NULL); + + chr = (char *)line->content; + for (x = 0; 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; + } + + start = 1; + + EINA_LIST_FOREACH(line->tokens, item, token) + { + + _elm_code_widget_fill_line_token(cells, w, start, token->start, ELM_CODE_TOKEN_TYPE_DEFAULT); + + // TODO handle a token starting before the previous finishes + _elm_code_widget_fill_line_token(cells, w, token->start, token->end, token->type); + + start = token->end + 1; + } + + _elm_code_widget_fill_line_token(cells, w, start, length, ELM_CODE_TOKEN_TYPE_DEFAULT); + + evas_object_textgrid_update_add(o, 0, line->number - 1, w, 1); +} + +EAPI void elm_code_widget_fill(Evas_Object *o, Elm_Code *code) +{ + Elm_Code_Line *line; + Evas_Textgrid_Cell *cells; + int w, h; + unsigned int y; + + if (!_elm_code_widget_resize(o)) + return; evas_object_textgrid_size_get(o, &w, &h); for (y = 1; y <= (unsigned int) h && y <= elm_code_file_lines_get(code->file); y++) { line = elm_code_file_line_get(code->file, y); - content = elm_code_file_line_content_get(code->file, y); - chr = (char *)content; cells = evas_object_textgrid_cellrow_get(o, y - 1); - length = strlen(content); - - for (x = 0; x < (unsigned int) w && x < length; x++) - { - cells[x].codepoint = *chr; - cells[x].bg = line->status; - cells[x].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; - - chr++; - } - for (; x < (unsigned int) w; x++) - { - cells[x].codepoint = 0; - cells[x].bg = line->status; - cells[x].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; - } + _elm_code_widget_fill_line(o, cells, line); } - - evas_object_textgrid_update_add(o, 0, 0, w, h); } static Eina_Bool @@ -61,34 +106,13 @@ _elm_code_widget_line_cb(void *data EINA_UNUSED, Eo *obj, Evas_Object *o; Evas_Textgrid_Cell *cells; - char *chr; - unsigned int length, x; - int w; line = (Elm_Code_Line *)event_info; o = (Evas_Object *)obj; cells = evas_object_textgrid_cellrow_get(o, line->number - 1); - length = strlen(line->content); - evas_object_textgrid_size_get(o, &w, NULL); + _elm_code_widget_fill_line(o, cells, line); - chr = (char *)line->content; - for (x = 0; x < (unsigned int) w && x < length; x++) - { - cells[x].codepoint = *chr; - cells[x].bg = line->status; - cells[x].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; - - chr++; - } - for (; x < (unsigned int) w; x++) - { - cells[x].codepoint = 0; - cells[x].bg = line->status; - cells[x].fg = ELM_CODE_TOKEN_TYPE_DEFAULT; - } - - evas_object_textgrid_update_add(o, 0, line->number - 1, w, 1); return EINA_TRUE; } @@ -114,6 +138,7 @@ _elm_code_widget_resize_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, Elm_Code *code; code = (Elm_Code *)data; + elm_code_widget_fill(obj, code); } @@ -141,6 +166,8 @@ EAPI Evas_Object *elm_code_widget_add(Evas_Object *parent, Elm_Code *code) // 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_event_callback_add(o, EVAS_CALLBACK_RESIZE, _elm_code_widget_resize_cb, code); diff --git a/elm_code/tests/elm_code_file_test_memory.c b/elm_code/tests/elm_code_file_test_memory.c index aa31649..21d2ce5 100644 --- a/elm_code/tests/elm_code_file_test_memory.c +++ b/elm_code/tests/elm_code_file_test_memory.c @@ -18,8 +18,25 @@ START_TEST (elm_code_file_memory_lines) } END_TEST +START_TEST (elm_code_file_memory_tokens) +{ + Elm_Code_File *file; + Elm_Code_Line *line; + + file = elm_code_file_new(); + + elm_code_file_line_append(file, "a line"); + elm_code_file_line_token_add(file, 1, 2, 5, ELM_CODE_TOKEN_TYPE_COMMENT); + + line = elm_code_file_line_get(file, 1); + ck_assert_uint_eq(1, eina_list_count(line->tokens)); + elm_code_file_free(file); +} +END_TEST + void elm_code_file_test_memory(TCase *tc) { tcase_add_test(tc, elm_code_file_memory_lines); + tcase_add_test(tc, elm_code_file_memory_tokens); }