forked from enlightenment/edi
elm_code: initial work on line numbers
This commit is contained in:
parent
3cd5ec7003
commit
f6b7a380df
|
@ -53,9 +53,10 @@ _elm_code_test_welcome_setup(Evas_Object *parent)
|
|||
code = elm_code_create();
|
||||
widget = eo_add(ELM_CODE_WIDGET_CLASS, parent);
|
||||
eo_do(widget,
|
||||
elm_code_widget_code_set(code);
|
||||
elm_code_widget_font_size_set(14);
|
||||
elm_code_widget_editable_set(EINA_TRUE);
|
||||
elm_code_widget_code_set(code),
|
||||
elm_code_widget_font_size_set(14),
|
||||
elm_code_widget_editable_set(EINA_TRUE),
|
||||
elm_code_widget_line_numbers_set(EINA_TRUE),
|
||||
eo_event_callback_add(ELM_CODE_WIDGET_EVENT_LINE_CLICKED, _elm_code_test_line_cb, code));
|
||||
|
||||
_append_line(code->file, "Hello World, Elm Code!");
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "elm_code_file.h"
|
||||
#include "elm_code_parse.h"
|
||||
#include "elm_code_widget.eo.h"
|
||||
#include "elm_code_widget_text.h"
|
||||
#include "elm_code_diff_widget.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -20,6 +20,7 @@ includesdir = $(includedir)/edi-@VMAJ@
|
|||
libelm_code_la_SOURCES = \
|
||||
elm_code_file.c \
|
||||
elm_code_parse.c \
|
||||
elm_code_widget_text.c \
|
||||
elm_code_widget.c \
|
||||
elm_code_diff_widget.c \
|
||||
elm_code.c \
|
||||
|
|
|
@ -25,3 +25,17 @@ extern int _elm_code_lib_log_dom;
|
|||
#define DBG(...) EINA_LOG_DOM_DBG(_elm_code_lib_log_dom, __VA_ARGS__)
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elm_Code *code;
|
||||
Evas_Object *grid, *scroller;
|
||||
|
||||
Evas_Font_Size font_size;
|
||||
double gravity_x, gravity_y;
|
||||
|
||||
unsigned int cursor_line, cursor_col;
|
||||
Eina_Bool cursor_move_vetoed;
|
||||
Eina_Bool editable, focussed;
|
||||
Eina_Bool show_line_numbers;
|
||||
} Elm_Code_Widget_Data;
|
||||
|
|
|
@ -5,19 +5,6 @@
|
|||
#include <Elm_Code.h>
|
||||
#include "elm_code_private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elm_Code *code;
|
||||
Evas_Object *grid, *scroller;
|
||||
|
||||
Evas_Font_Size font_size;
|
||||
double gravity_x, gravity_y;
|
||||
|
||||
unsigned int cursor_line, cursor_col;
|
||||
Eina_Bool cursor_move_vetoed;
|
||||
Eina_Bool editable, focussed;
|
||||
} Elm_Code_Widget_Data;
|
||||
|
||||
Eina_Unicode status_icons[] = {
|
||||
' ',
|
||||
'!',
|
||||
|
@ -69,10 +56,11 @@ _elm_code_widget_resize(Elm_Code_Widget *widget)
|
|||
Elm_Code_Line *line;
|
||||
Eina_List *item;
|
||||
Evas_Coord ww, wh, old_width, old_height;
|
||||
int w, h, cw, ch;
|
||||
int w, h, cw, ch, gutter;
|
||||
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);
|
||||
|
||||
if (!pd->code)
|
||||
return EINA_FALSE;
|
||||
|
@ -85,8 +73,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 + 2 > w)
|
||||
w = line->length + 2;
|
||||
if (line->length + gutter + 1 > w)
|
||||
w = line->length + gutter + 1;
|
||||
|
||||
if (w*cw > ww)
|
||||
ww = w*cw;
|
||||
|
@ -116,24 +104,26 @@ _elm_code_widget_fill_line_token(Evas_Textgrid_Cell *cells, int count, int start
|
|||
}
|
||||
|
||||
static void
|
||||
_elm_code_widget_fill_line_tokens(Evas_Textgrid_Cell *cells, unsigned int count, Elm_Code_Line *line)
|
||||
_elm_code_widget_fill_line_tokens(Elm_Code_Widget *widget, Evas_Textgrid_Cell *cells,
|
||||
unsigned int count, Elm_Code_Line *line)
|
||||
{
|
||||
Eina_List *item;
|
||||
Elm_Code_Token *token;
|
||||
int start, length;
|
||||
int start, length, offset;
|
||||
|
||||
start = 1;
|
||||
length = line->length;
|
||||
offset = elm_code_widget_text_left_gutter_width_get(widget) - 1;
|
||||
start = offset + 1;
|
||||
length = line->length + offset;
|
||||
|
||||
EINA_LIST_FOREACH(line->tokens, item, token)
|
||||
{
|
||||
|
||||
_elm_code_widget_fill_line_token(cells, count, start, token->start, ELM_CODE_TOKEN_TYPE_DEFAULT);
|
||||
_elm_code_widget_fill_line_token(cells, count, start, token->start + offset, 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);
|
||||
_elm_code_widget_fill_line_token(cells, count, token->start + offset, token->end + offset, token->type);
|
||||
|
||||
start = token->end + 1;
|
||||
start = token->end + offset + 1;
|
||||
}
|
||||
|
||||
_elm_code_widget_fill_line_token(cells, count, start, length, ELM_CODE_TOKEN_TYPE_DEFAULT);
|
||||
|
@ -144,10 +134,11 @@ _elm_code_widget_fill_line(Elm_Code_Widget *widget, Evas_Textgrid_Cell *cells, E
|
|||
{
|
||||
char *chr;
|
||||
unsigned int length, x;
|
||||
int w;
|
||||
int w, gutter, g;
|
||||
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);
|
||||
|
||||
if (!_elm_code_widget_resize(widget))
|
||||
return;
|
||||
|
@ -160,11 +151,19 @@ _elm_code_widget_fill_line(Elm_Code_Widget *widget, Evas_Textgrid_Cell *cells, E
|
|||
cells[0].fg = ELM_CODE_TOKEN_TYPE_DEFAULT;
|
||||
cells[0].bg = line->status;
|
||||
|
||||
for (g = 1; g < gutter; g++)
|
||||
{
|
||||
// TODO figure what our actual line number is as a string! (of length g)
|
||||
cells[g].codepoint = (g == gutter - 1) ? '|' : '_';
|
||||
cells[g].fg = ELM_CODE_TOKEN_TYPE_DEFAULT;
|
||||
cells[g].bg = ELM_CODE_STATUS_TYPE_DEFAULT;
|
||||
}
|
||||
|
||||
if (line->modified)
|
||||
chr = line->modified;
|
||||
else
|
||||
chr = (char *)line->content;
|
||||
for (x = 1; x < (unsigned int) w && x <= length; x++)
|
||||
for (x = gutter; x < (unsigned int) w && x < length + gutter; x++)
|
||||
{
|
||||
cells[x].codepoint = *chr;
|
||||
cells[x].bg = line->status;
|
||||
|
@ -177,11 +176,11 @@ _elm_code_widget_fill_line(Elm_Code_Widget *widget, Evas_Textgrid_Cell *cells, E
|
|||
cells[x].bg = line->status;
|
||||
}
|
||||
|
||||
_elm_code_widget_fill_line_tokens(cells, w, line);
|
||||
_elm_code_widget_fill_line_tokens(widget, cells, w, line);
|
||||
if (pd->editable && pd->focussed && pd->cursor_line == line->number)
|
||||
{
|
||||
if (pd->cursor_col < (unsigned int) w)
|
||||
cells[pd->cursor_col].bg = ELM_CODE_TOKEN_TYPE_CURSOR;
|
||||
if (pd->cursor_col + gutter - 1 < (unsigned int) w)
|
||||
cells[pd->cursor_col + gutter - 1].bg = ELM_CODE_TOKEN_TYPE_CURSOR;
|
||||
}
|
||||
|
||||
evas_object_textgrid_update_add(pd->grid, 0, line->number - 1, w, 1);
|
||||
|
@ -269,7 +268,7 @@ _elm_code_widget_clicked_editable_cb(Elm_Code_Widget *widget, Evas_Coord x, Evas
|
|||
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
|
||||
|
||||
evas_object_textgrid_cell_size_get(pd->grid, &cw, &ch);
|
||||
col = ((double) x / cw) + 2;
|
||||
col = ((double) x / cw) - elm_code_widget_text_left_gutter_width_get(widget) + 1;
|
||||
row = ((double) y / ch) + 1;
|
||||
|
||||
line = elm_code_file_line_get(pd->code->file, row);
|
||||
|
@ -277,8 +276,8 @@ _elm_code_widget_clicked_editable_cb(Elm_Code_Widget *widget, Evas_Coord x, Evas
|
|||
{
|
||||
pd->cursor_line = row;
|
||||
|
||||
if (col <= (unsigned int) line->length + 2)
|
||||
pd->cursor_col = col - 2;
|
||||
if (col <= (unsigned int) line->length + 1)
|
||||
pd->cursor_col = col;
|
||||
else
|
||||
pd->cursor_col = line->length + 1;
|
||||
}
|
||||
|
@ -571,6 +570,18 @@ _elm_code_widget_editable_get(Eo *obj EINA_UNUSED, Elm_Code_Widget_Data *pd)
|
|||
return pd->editable;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_elm_code_widget_line_numbers_set(Eo *obj EINA_UNUSED, Elm_Code_Widget_Data *pd, Eina_Bool line_numbers)
|
||||
{
|
||||
pd->show_line_numbers = line_numbers;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_elm_code_widget_line_numbers_get(Eo *obj EINA_UNUSED, Elm_Code_Widget_Data *pd)
|
||||
{
|
||||
return pd->show_line_numbers;
|
||||
}
|
||||
|
||||
static void
|
||||
_elm_code_widget_setup_palette(Evas_Object *o)
|
||||
{
|
||||
|
|
|
@ -84,6 +84,26 @@ class Elm_Code_Widget (Elm_Box, Elm_Interface_Scrollable,
|
|||
Eina_Bool editable; /*@ The editable state of the widget */
|
||||
}
|
||||
}
|
||||
line_numbers {
|
||||
set {
|
||||
/*@
|
||||
Set whether line numbers should be displayed in the left gutter.
|
||||
|
||||
Passing EINA_TRUE will reserve a space for showing line numbers,
|
||||
EINA_FALSE will turn this off.
|
||||
|
||||
@ingroup Features */
|
||||
}
|
||||
get {
|
||||
/*@
|
||||
Get the status of line number display for this widget.
|
||||
|
||||
@ingroup Features */
|
||||
}
|
||||
values {
|
||||
Eina_Bool line_numbers; /*@ Whether or not line numbers (or their placeholder) should be shown */
|
||||
}
|
||||
}
|
||||
}
|
||||
methods {
|
||||
}
|
||||
|
|
|
@ -33,6 +33,14 @@ Eina_Bool _elm_code_widget_editable_get(Eo *obj, Elm_Code_Widget_Data *pd);
|
|||
|
||||
EOAPI EO_FUNC_BODY(elm_code_widget_editable_get, Eina_Bool, 0);
|
||||
|
||||
void _elm_code_widget_line_numbers_set(Eo *obj, Elm_Code_Widget_Data *pd, Eina_Bool line_numbers);
|
||||
|
||||
EOAPI EO_VOID_FUNC_BODYV(elm_code_widget_line_numbers_set, EO_FUNC_CALL(line_numbers), Eina_Bool line_numbers);
|
||||
|
||||
Eina_Bool _elm_code_widget_line_numbers_get(Eo *obj, Elm_Code_Widget_Data *pd);
|
||||
|
||||
EOAPI EO_FUNC_BODY(elm_code_widget_line_numbers_get, Eina_Bool, 0);
|
||||
|
||||
void _elm_code_widget_eo_base_constructor(Eo *obj, Elm_Code_Widget_Data *pd);
|
||||
|
||||
|
||||
|
@ -58,6 +66,8 @@ static Eo_Op_Description _elm_code_widget_op_desc[] = {
|
|||
EO_OP_FUNC(elm_code_widget_gravity_get, _elm_code_widget_gravity_get, "Get the current x and y gravity of the widget's scroller"),
|
||||
EO_OP_FUNC(elm_code_widget_editable_set, _elm_code_widget_editable_set, "Set whether this widget allows editing"),
|
||||
EO_OP_FUNC(elm_code_widget_editable_get, _elm_code_widget_editable_get, "Get the current editable state of this widget"),
|
||||
EO_OP_FUNC(elm_code_widget_line_numbers_set, _elm_code_widget_line_numbers_set, "Set whether line numbers should be displayed in the left gutter."),
|
||||
EO_OP_FUNC(elm_code_widget_line_numbers_get, _elm_code_widget_line_numbers_get, "Get the status of line number display for this widget."),
|
||||
EO_OP_SENTINEL
|
||||
};
|
||||
|
||||
|
|
|
@ -63,8 +63,7 @@ EOAPI Evas_Font_Size elm_code_widget_font_size_get(void);
|
|||
*
|
||||
* Set how this widget's scroller should respond to new lines being added.
|
||||
*
|
||||
* An x value of 0.0 will maintain the distance from the left edge, 1.0
|
||||
will ensure the rightmost edge (of the longest line) is respected
|
||||
* An x value of 0.0 will maintain the distance from the left edge, 1.0 will ensure the rightmost edge (of the longest line) is respected
|
||||
* With 0.0 for y the view will keep it's position relative to the top whereas 1.0 will scroll downward as lines are added.
|
||||
*
|
||||
* @ingroup Layout
|
||||
|
@ -81,7 +80,7 @@ EOAPI void elm_code_widget_gravity_set(double x, double y);
|
|||
*
|
||||
* @ingroup Layout
|
||||
*
|
||||
* @param[out] x The horizontal value of the scroller gravity, currently ignored
|
||||
* @param[out] x The horizontal value of the scroller gravity - valid values are 0.0 and 1.0
|
||||
* @param[out] y The vertical gravity of the widget's scroller - valid values are 0.0 and 1.0
|
||||
*
|
||||
*/
|
||||
|
@ -117,6 +116,30 @@ EOAPI void elm_code_widget_editable_set(Eina_Bool editable);
|
|||
*/
|
||||
EOAPI Eina_Bool elm_code_widget_editable_get(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* Set whether line numbers should be displayed in the left gutter.
|
||||
*
|
||||
* Passing EINA_TRUE will reserve a space for showing line numbers,
|
||||
* EINA_FALSE will turn this off.
|
||||
*
|
||||
* @ingroup Features
|
||||
*
|
||||
* @param[in] line_numbers Whether or not line numbers (or their placeholder) should be shown
|
||||
*
|
||||
*/
|
||||
EOAPI void elm_code_widget_line_numbers_set(Eina_Bool line_numbers);
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the status of line number display for this widget.
|
||||
*
|
||||
* @ingroup Features
|
||||
*
|
||||
*
|
||||
*/
|
||||
EOAPI Eina_Bool elm_code_widget_line_numbers_get(void);
|
||||
|
||||
EOAPI extern const Eo_Event_Description _ELM_CODE_WIDGET_EVENT_LINE_CLICKED;
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
#ifdef HAVE_CONFIG
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "Elm_Code.h"
|
||||
|
||||
#include "elm_code_private.h"
|
||||
|
||||
EAPI int
|
||||
elm_code_widget_text_line_number_width_get(Elm_Code_Widget *widget)
|
||||
{
|
||||
Elm_Code_Widget_Data *pd;
|
||||
int max;
|
||||
|
||||
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
|
||||
max = elm_code_file_lines_get(pd->code->file);
|
||||
if (max < 1)
|
||||
max = 1;
|
||||
|
||||
return ceil(log10(max));
|
||||
}
|
||||
|
||||
EAPI int
|
||||
elm_code_widget_text_left_gutter_width_get(Elm_Code_Widget *widget)
|
||||
{
|
||||
Elm_Code_Widget_Data *pd;
|
||||
int width = 1; // the status icon, for now
|
||||
|
||||
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
|
||||
|
||||
if (pd->show_line_numbers)
|
||||
width += elm_code_widget_text_line_number_width_get(widget) + 1;
|
||||
|
||||
return width;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef ELM_CODE_WIDGET_TEXT_H_
|
||||
# define ELM_CODE_WIDGET_TEXT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Text layout handling functions.
|
||||
* @defgroup Managing the complexities of layout out text in an Elm_Code_Widget
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* Functions for text layout handling
|
||||
*
|
||||
*/
|
||||
|
||||
EAPI int elm_code_widget_text_left_gutter_width_get(Elm_Code_Widget *widget);
|
||||
|
||||
EAPI int elm_code_widget_text_line_number_width_get(Elm_Code_Widget *widget);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ELM_CODE_WIDGET_TEXT_H_ */
|
Loading…
Reference in New Issue