Add initial unicode support for elm_code

Note the number of utf8 characters when we load the data.
Make sure the widget is referencing unicode_length
for all our metrics.
This commit is contained in:
Andy Williams 2015-03-07 20:48:02 +01:00
parent 2e5d0e7e02
commit a2026576a2
8 changed files with 55 additions and 26 deletions

View File

@ -76,10 +76,10 @@ _elm_code_test_welcome_setup(Evas_Object *parent)
eo_event_callback_add(&ELM_CODE_EVENT_LINE_LOAD_DONE, _elm_code_test_line_done_cb, NULL);
eo_event_callback_add(ELM_CODE_WIDGET_EVENT_LINE_CLICKED, _elm_code_test_line_clicked_cb, code));
_append_line(code->file, "Hello World, Elm Code!");
_append_line(code->file, "Hello World, Elm Code!");
_append_line(code->file, "");
_append_line(code->file, "This is a demo of elm_code's capabilities.");
_append_line(code->file, "*** Currently experimental ***");
_append_line(code->file, "*** Currently experimental ***");
evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL);

View File

@ -21,7 +21,23 @@ static Elm_Code_Line *_elm_code_file_line_blank_create(Elm_Code_File *file, int
return ecl;
}
static void _elm_code_file_line_insert_data(Elm_Code_File *file, const char *content, int length,
static unsigned int
_elm_code_file_line_unicode_strlen(const char *chars, unsigned int length)
{
unsigned int count = 0;
int index = 0;
while ((unsigned int) index < length)
{
eina_unicode_utf8_next_get(chars, &index);
count++;
}
return count;
}
static void _elm_code_file_line_insert_data(Elm_Code_File *file, const char *content, unsigned int length,
unsigned int row, Eina_Bool mapped, void *data)
{
Elm_Code_Line *line, *after;
@ -41,6 +57,7 @@ static void _elm_code_file_line_insert_data(Elm_Code_File *file, const char *con
line->modified[length] = 0;
line->length = length;
}
line->unicode_length = _elm_code_file_line_unicode_strlen(content, length);
if (row == 1)
file->lines = eina_list_prepend(file->lines, line);

View File

@ -6,6 +6,12 @@
#include "elm_code_private.h"
EAPI unsigned int
elm_code_line_utf8_length_get(Elm_Code_Line *line)
{
return line->unicode_length;
}
EAPI void elm_code_line_status_set(Elm_Code_Line *line, Elm_Code_Status_Type status)
{
if (!line)

View File

@ -24,7 +24,7 @@ typedef struct _Elm_Code_Line
Elm_Code_File *file;
const char *content;
int length;
unsigned int length, unicode_length;
unsigned int number;
char *modified;
@ -34,6 +34,8 @@ typedef struct _Elm_Code_Line
void *data;
} Elm_Code_Line;
EAPI unsigned int elm_code_line_utf8_length_get(Elm_Code_Line *line);
/**
* @brief Line markup functions.
* @defgroup Line highlighting and status manipulation

View File

@ -106,6 +106,7 @@ _elm_code_parser_diff_trim_leading(Elm_Code_Line *line, unsigned int count)
}
line->length -= count;
line->unicode_length -= count;
}
static void

View File

@ -37,7 +37,7 @@ _elm_code_line_tokens_move_right(Elm_Code_Line *line, int position, int move)
}
EAPI void
elm_code_line_text_insert(Elm_Code_Line *line, int position, const char *string, int length)
elm_code_line_text_insert(Elm_Code_Line *line, unsigned int position, const char *string, int length)
{
Elm_Code_File *file;
char *inserted;
@ -46,11 +46,10 @@ elm_code_line_text_insert(Elm_Code_Line *line, int position, const char *string,
return;
inserted = malloc(sizeof(char) * line->length + length + 1);
position--;
if (position > 0)
position--;
if (position > line->length)
position = line->length;
if (position < 0)
position = 0;
_elm_code_line_tokens_move_right(line, position + 1, length);

View File

@ -22,7 +22,7 @@ extern "C" {
EAPI const char *elm_code_line_text_get(Elm_Code_Line *line, int *length);
EAPI void elm_code_line_text_insert(Elm_Code_Line *line, int position, const char *string, int length);
EAPI void elm_code_line_text_insert(Elm_Code_Line *line, unsigned int position, const char *string, int length);
/**
* @}

View File

@ -105,8 +105,8 @@ _elm_code_widget_resize(Elm_Code_Widget *widget)
w = 0;
h = elm_code_file_lines_get(pd->code->file);
EINA_LIST_FOREACH(pd->code->file->lines, item, line)
if (line->length + gutter + 1 > w)
w = line->length + gutter + 1;
if ((int) line->unicode_length + gutter + 1 > w)
w = (int) line->unicode_length + gutter + 1;
if (w*cw > ww)
ww = w*cw;
@ -159,7 +159,7 @@ _elm_code_widget_fill_line_tokens(Elm_Code_Widget *widget, Evas_Textgrid_Cell *c
offset = elm_code_widget_text_left_gutter_width_get(widget) - 1;
start = offset + 1;
length = line->length + offset;
length = line->unicode_length + offset;
EINA_LIST_FOREACH(line->tokens, item, token)
{
@ -220,7 +220,7 @@ _elm_code_widget_fill_gutter(Elm_Code_Widget *widget, Evas_Textgrid_Cell *cells,
}
static void
_elm_code_widget_fill_whitespace(Elm_Code_Widget *widget EINA_UNUSED, char character, Evas_Textgrid_Cell *cell)
_elm_code_widget_fill_whitespace(Elm_Code_Widget *widget EINA_UNUSED, Eina_Unicode character, Evas_Textgrid_Cell *cell)
{
switch (character)
{
@ -244,33 +244,37 @@ static void
_elm_code_widget_fill_line(Elm_Code_Widget *widget, Elm_Code_Line *line)
{
char *chr;
Eina_Unicode unichr;
unsigned int length, x;
int w, gutter;
int w, chrpos, gutter;
Evas_Textgrid_Cell *cells;
Elm_Code_Widget_Data *pd;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
gutter = elm_code_widget_text_left_gutter_width_get(widget);
length = line->length;
evas_object_textgrid_size_get(pd->grid, &w, NULL);
cells = evas_object_textgrid_cellrow_get(pd->grid, line->number - 1);
_elm_code_widget_fill_gutter(widget, cells, line->status, line->number);
_elm_code_widget_fill_line_tokens(widget, cells, w, line);
length = elm_code_line_utf8_length_get(line);
chrpos = 0;
if (line->modified)
chr = line->modified;
else
chr = (char *)line->content;
for (x = gutter; x < (unsigned int) w && x < length + gutter; x++)
{
cells[x].codepoint = *chr;
unichr = eina_unicode_utf8_next_get(chr, &chrpos);
cells[x].codepoint = unichr;
cells[x].bg = _elm_code_widget_status_type_get(widget, line->status, x - gutter + 1);
if (pd->show_whitespace)
_elm_code_widget_fill_whitespace(widget, *chr, &cells[x]);
chr++;
_elm_code_widget_fill_whitespace(widget, unichr, &cells[x]);
}
for (; x < (unsigned int) w; x++)
{
@ -395,7 +399,7 @@ _elm_code_widget_cursor_key_will_move(Elm_Code_Widget *widget, const char *key)
else if (!strcmp(key, "Left"))
return pd->cursor_col > 1;
else if (!strcmp(key, "Right"))
return pd->cursor_col < (unsigned int) line->length + 1;
return pd->cursor_col < (unsigned int) line->unicode_length + 1;
else
return EINA_FALSE;
}
@ -487,8 +491,8 @@ _elm_code_widget_clicked_editable_cb(Elm_Code_Widget *widget, Evas_Coord x, Evas
if (!line)
return;
if (col > (unsigned int) line->length + 1)
col = line->length + 1;
if (col > (unsigned int) line->unicode_length + 1)
col = line->unicode_length + 1;
else if (col == 0)
col = 1;
@ -553,8 +557,8 @@ _elm_code_widget_cursor_move_up(Elm_Code_Widget *widget)
row--;
line = elm_code_file_line_get(pd->code->file, row);
if (col > (unsigned int) line->length + 1)
col = line->length + 1;
if (col > (unsigned int) line->unicode_length + 1)
col = line->unicode_length + 1;
_elm_code_widget_cursor_move(widget, pd, col, row, EINA_TRUE);
}
@ -575,8 +579,8 @@ _elm_code_widget_cursor_move_down(Elm_Code_Widget *widget)
row++;
line = elm_code_file_line_get(pd->code->file, row);
if (col > (unsigned int) line->length + 1)
col = line->length + 1;
if (col > (unsigned int) line->unicode_length + 1)
col = line->unicode_length + 1;
_elm_code_widget_cursor_move(widget, pd, col, row, EINA_TRUE);
}
@ -603,7 +607,7 @@ _elm_code_widget_cursor_move_right(Elm_Code_Widget *widget)
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
line = elm_code_file_line_get(pd->code->file, pd->cursor_line);
if (pd->cursor_col > (unsigned int) line->length)
if (pd->cursor_col > (unsigned int) line->unicode_length)
return;
_elm_code_widget_cursor_move(widget, pd, pd->cursor_col+1, pd->cursor_line, EINA_TRUE);