elm_code: selection highlighting

Adding initial support for displaying selection within the widget
This commit is contained in:
Andy Williams 2015-03-17 22:42:03 +00:00
parent 433bac2c1b
commit e4cf9ed41a
7 changed files with 195 additions and 10 deletions

View File

@ -85,6 +85,9 @@ _elm_code_test_welcome_setup(Evas_Object *parent)
evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(widget);
elm_code_widget_selection_start(widget, 1, 3);
elm_code_widget_selection_end(widget, 1, 13);
return widget;
}

View File

@ -40,6 +40,7 @@
#include "elm_code_parse.h"
#include "elm_code_widget.eo.h"
#include "elm_code_widget_text.h"
#include "elm_code_widget_selection.h"
#include "elm_code_diff_widget.h"
#ifdef __cplusplus

View File

@ -25,6 +25,7 @@ elm_code_file.h \
elm_code_parse.h \
elm_code_widget.eo.h \
elm_code_widget_text.h \
elm_code_widget_selection.h \
elm_code_diff_widget.h \
Elm_Code.h
includesdir = $(includedir)/edi-@VMAJ@
@ -35,6 +36,7 @@ elm_code_text.c \
elm_code_file.c \
elm_code_parse.c \
elm_code_widget_text.c \
elm_code_widget_selection.c \
elm_code_widget.c \
elm_code_diff_widget.c \
elm_code.c \

View File

@ -26,6 +26,15 @@ extern int _elm_code_lib_log_dom;
#endif
/**
* Structure holding the info about a selected region.
*/
typedef struct
{
unsigned int start_line, end_line;
unsigned int start_col, end_col;
} Elm_Code_Widget_Selection_Data;
typedef struct
{
Elm_Code *code;
@ -39,6 +48,8 @@ typedef struct
Eina_Bool show_line_numbers;
unsigned int line_width_marker;
Eina_Bool show_whitespace;
Elm_Code_Widget_Selection_Data *selection;
} Elm_Code_Widget_Data;
/* Private parser callbacks */

View File

@ -10,6 +10,7 @@ typedef enum {
ELM_CODE_WIDGET_COLOR_GUTTER_FG,
ELM_CODE_WIDGET_COLOR_WHITESPACE,
ELM_CODE_WIDGET_COLOR_CURSOR,
ELM_CODE_WIDGET_COLOR_SELECTION,
ELM_CODE_WIDGET_COLOR_COUNT
} Elm_Code_Widget_Colors;
@ -226,8 +227,14 @@ _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, Eina_Unicode character, Evas_Textgrid_Cell *cell)
_elm_code_widget_fill_whitespace(Elm_Code_Widget *widget, Eina_Unicode character, Evas_Textgrid_Cell *cell)
{
Elm_Code_Widget_Data *pd;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
if (!pd->show_whitespace)
return;
switch (character)
{
case ' ':
@ -246,6 +253,47 @@ _elm_code_widget_fill_whitespace(Elm_Code_Widget *widget EINA_UNUSED, Eina_Unico
cell->fg = ELM_CODE_WIDGET_COLOR_WHITESPACE;
}
static void
_elm_code_widget_fill_cursor(Elm_Code_Widget *widget, Elm_Code_Line *line, Evas_Textgrid_Cell *cells,
int gutter, int w)
{
Elm_Code_Widget_Data *pd;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
if (pd->editable && pd->focussed && pd->cursor_line == line->number)
{
if (pd->cursor_col + gutter - 1 < (unsigned int) w)
cells[pd->cursor_col + gutter - 1].bg = ELM_CODE_WIDGET_COLOR_CURSOR;
}
}
static void
_elm_code_widget_fill_selection(Elm_Code_Widget *widget, Elm_Code_Line *line, Evas_Textgrid_Cell *cells,
int gutter, int w)
{
Elm_Code_Widget_Data *pd;
unsigned int x, start, end;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
if (!pd->selection)
return;
if (pd->selection->start_line > line->number || pd->selection->end_line < line->number)
return;
start = pd->selection->start_col;
if (pd->selection->start_line < line->number)
start = 1;
end = pd->selection->end_col;
if (pd->selection->end_line > line->number)
end = w;
for (x = gutter + start - 1; x < gutter + end && x < (unsigned int) w; x++)
cells[x].bg = ELM_CODE_WIDGET_COLOR_SELECTION;
}
static void
_elm_code_widget_fill_line(Elm_Code_Widget *widget, Elm_Code_Line *line)
{
@ -276,8 +324,7 @@ _elm_code_widget_fill_line(Elm_Code_Widget *widget, Elm_Code_Line *line)
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, unichr, &cells[x]);
_elm_code_widget_fill_whitespace(widget, unichr, &cells[x]);
}
for (; x < (unsigned int) w; x++)
{
@ -285,13 +332,9 @@ _elm_code_widget_fill_line(Elm_Code_Widget *widget, Elm_Code_Line *line)
cells[x].bg = _elm_code_widget_status_type_get(widget, line->status, x - gutter + 1);
}
if (pd->editable && pd->focussed && pd->cursor_line == line->number)
{
if (pd->cursor_col + gutter - 1 < (unsigned int) w)
cells[pd->cursor_col + gutter - 1].bg = ELM_CODE_WIDGET_COLOR_CURSOR;
}
if (pd->show_whitespace)
_elm_code_widget_fill_whitespace(widget, '\n', &cells[length + gutter]);
_elm_code_widget_fill_cursor(widget, line, cells, gutter, w);
_elm_code_widget_fill_selection(widget, line, cells, gutter, w);
_elm_code_widget_fill_whitespace(widget, '\n', &cells[length + gutter]);
evas_object_textgrid_update_add(pd->grid, 0, line->number - 1, w, 1);
}
@ -1042,6 +1085,8 @@ _elm_code_widget_setup_palette(Evas_Object *o)
// other styles that the widget uses
evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_WIDGET_COLOR_CURSOR,
205, 205, 54, 255);
evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_WIDGET_COLOR_SELECTION,
51, 153, 255, 255);
evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_WIDGET_COLOR_GUTTER_BG,
75, 75, 75, 255);
evas_object_textgrid_palette_set(o, EVAS_TEXTGRID_PALETTE_STANDARD, ELM_CODE_WIDGET_COLOR_GUTTER_FG,

View File

@ -0,0 +1,89 @@
#ifdef HAVE_CONFIG
# include "config.h"
#endif
#include "Elm_Code.h"
#include "elm_code_private.h"
static Elm_Code_Widget_Selection_Data *
_elm_code_widget_selection_new()
{
Elm_Code_Widget_Selection_Data *data;
data = calloc(1, sizeof(Elm_Code_Widget_Selection_Data));
return data;
}
EAPI void
elm_code_widget_selection_start(Evas_Object *widget,
unsigned int line, unsigned int col)
{
Elm_Code_Widget_Data *pd;
Elm_Code_Widget_Selection_Data *selection;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
if (!pd->selection)
{
selection = _elm_code_widget_selection_new();
selection->end_line = line;
selection->end_col = col;
pd->selection = selection;
}
pd->selection->start_line = line;
pd->selection->start_col = col;
}
EAPI void
elm_code_widget_selection_end(Evas_Object *widget,
unsigned int line, unsigned int col)
{
Elm_Code_Widget_Data *pd;
Elm_Code_Widget_Selection_Data *selection;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
if (!pd->selection)
{
selection = _elm_code_widget_selection_new();
selection->start_line = line;
selection->start_col = col;
pd->selection = selection;
}
pd->selection->end_line = line;
pd->selection->end_col = col;
}
EAPI void
elm_code_widget_selection_clear(Evas_Object *widget)
{
Elm_Code_Widget_Data *pd;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
if (pd->selection)
free(pd->selection);
pd->selection = NULL;
}
EAPI const char *
elm_code_widget_selection_text_get(Evas_Object *widget)
{
Elm_Code_Widget_Data *pd;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
if (!pd->selection)
return "";
return "TODO";
}

View File

@ -0,0 +1,34 @@
#ifndef ELM_CODE_WIDGET_SELECTION_H_
# define ELM_CODE_WIDGET_SELECTION_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Selection handling functions.
* @defgroup Managing the complexities of selecting text across seperate lines.
*
* @{
*
* Functions for selection handling
*
*/
EAPI void elm_code_widget_selection_start(Evas_Object *widget, unsigned int line, unsigned int col);
EAPI void elm_code_widget_selection_end(Evas_Object *widget, unsigned int line, unsigned int col);
EAPI void elm_code_widget_selection_clear(Evas_Object *widget);
EAPI const char *elm_code_widget_selection_text_get(Evas_Object *widget);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ELM_CODE_WIDGET_SELECTION_H_ */