Text settings: Add analysis typed text for redoundo feature.

Added cases:
    Analyse auto indention for new lines. It mean, that redo/undo
            line creation will finished by one step.
    Analyse input symbols speed. In case when user writes somethenigi
            and takes a short delay (by default 0.8sec)
            between written symbols - redo/undo action will use this delay
            as point to create new node in redo/undo queue.
    Analyse input symbols on a "words". Ongoing alphabetic symbols
            between nonalphabetic symbols known as
            "word". Redo/undo action will use for a step a whole "word".

In text setting added addition toggle named "Smart undo/redo".
By default this feature is disabled.

Todo: make this feature work with auto intendation.

Prortotype here: https://phab.enlightenment.org/D1288
This commit is contained in:
Mykyta Biliavskyi 2015-12-10 10:53:12 +09:00
parent 2e541e722a
commit 6aea530622
10 changed files with 151 additions and 2 deletions

View File

@ -38,6 +38,7 @@ typedef struct config_s
Eina_Bool console;
Eina_Bool auto_complete;
Eina_Bool view_size_configurable;
Eina_Bool smart_undo_redo;
} config_data;
static config_data *g_cd = NULL;
@ -178,6 +179,7 @@ config_load(void)
cd->auto_complete = EINA_TRUE;
cd->view_size_configurable = EINA_FALSE;
cd->version = ENVENTOR_CONFIG_VERSION;
cd->smart_undo_redo = EINA_FALSE;
}
g_cd = cd;
@ -282,6 +284,8 @@ eddc_init(void)
EET_DATA_DESCRIPTOR_ADD_BASIC(edd_base, config_data,
"view_size_configurable",
view_size_configurable, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(edd_base, config_data, "smart_undo_redo",
smart_undo_redo, EET_T_UCHAR);
}
void
@ -732,6 +736,20 @@ config_font_scale_get(void)
return cd->font_scale;
}
Eina_Bool
config_smart_undo_redo_get(void)
{
config_data *cd = g_cd;
return cd->smart_undo_redo;
}
void
config_smart_undo_redo_set(Eina_Bool smart_undo_redo)
{
config_data *cd = g_cd;
cd->smart_undo_redo = smart_undo_redo;
}
void
config_auto_complete_set(Eina_Bool auto_complete)
{

View File

@ -56,6 +56,7 @@ enventor_common_setup(Evas_Object *enventor)
enventor_object_live_view_scale_set(enventor, config_view_scale_get());
enventor_object_auto_indent_set(enventor, config_auto_indent_get());
enventor_object_auto_complete_set(enventor, config_auto_complete_get());
enventor_object_smart_undo_redo_set(enventor, config_smart_undo_redo_get());
Eina_List *list = eina_list_append(NULL, config_output_path_get());
enventor_object_path_set(enventor, ENVENTOR_PATH_TYPE_EDJ, list);

View File

@ -864,6 +864,11 @@ text_setting_layout_create(Evas_Object *parent)
config_auto_complete_get());
elm_box_pack_end(box, toggle_autocomp);
//Toggle (Smart Undo/Redo)
Evas_Object *toggle_smart_undo_redo = toggle_create(box, _("Smart Undo/Redo"),
config_smart_undo_redo_get());
elm_box_pack_end(box, toggle_smart_undo_redo);
//Font Name and Style (Box)
box = elm_box_add(layout);
elm_box_horizontal_set(box, EINA_TRUE);
@ -953,7 +958,7 @@ text_setting_layout_create(Evas_Object *parent)
tsd->toggle_linenum = toggle_linenum;
tsd->toggle_indent = toggle_indent;
tsd->toggle_autocomp = toggle_autocomp;
tsd->toggle_smart_undo_redo = toggle_smart_undo_redo;
return layout;
}
@ -999,6 +1004,7 @@ text_setting_config_set(void)
config_linenumber_set(elm_check_state_get(tsd->toggle_linenum));
config_auto_indent_set(elm_check_state_get(tsd->toggle_indent));
config_auto_complete_set(elm_check_state_get(tsd->toggle_autocomp));
config_smart_undo_redo_set(elm_check_state_get(tsd->toggle_smart_undo_redo));
}
static void
@ -1058,6 +1064,13 @@ text_setting_auto_complete_set(Eina_Bool enabled)
elm_check_state_set(tsd->toggle_autocomp, enabled);
}
void
text_setting_smart_undo_redo_set(Eina_Bool enabled)
{
text_setting_data *tsd = g_tsd;
elm_check_state_set(tsd->toggle_smart_undo_redo, enabled);
}
void
text_setting_init(void)
{

View File

@ -58,3 +58,5 @@ double config_editor_size_get(void);
void config_console_set(Eina_Bool enabled);
void config_win_size_get(Evas_Coord *w, Evas_Coord *h);
void config_win_size_set(Evas_Coord w, Evas_Coord h);
void config_smart_undo_redo_set(Eina_Bool smart_undo_redo);
Eina_Bool config_smart_undo_redo_get(void);

View File

@ -15,6 +15,7 @@ struct text_setting_s
Evas_Object *toggle_linenum;
Evas_Object *toggle_indent;
Evas_Object *toggle_autocomp;
Evas_Object *toggle_smart_undo_redo;
color_keyword *color_keyword_list;
char *syntax_template_format;
@ -37,5 +38,6 @@ void text_setting_font_scale_set(double font_scale);
void text_setting_linenumber_set(Eina_Bool enabled);
void text_setting_auto_indent_set(Eina_Bool enabled);
void text_setting_auto_complete_set(Eina_Bool enabled);
void text_setting_smart_undo_redo_set(Eina_Bool enabled);
void text_setting_term(void);
void text_setting_init(void);

View File

@ -60,6 +60,7 @@ struct editor_s
Eina_Bool part_highlight : 1;
Eina_Bool ctxpopup_enabled : 1;
Eina_Bool on_save : 1;
Eina_Bool smart_undo_redo : 1;
};
/*****************************************************************************/
@ -1184,6 +1185,7 @@ edit_init(Evas_Object *enventor)
ed->auto_indent = EINA_TRUE;
ed->part_highlight = EINA_TRUE;
ed->ctxpopup_enabled = EINA_TRUE;
ed->smart_undo_redo = EINA_FALSE;
ed->cur_line = -1;
ed->select_pos = -1;
ed->font_scale = 1;
@ -1432,6 +1434,20 @@ edit_disabled_set(edit_data *ed, Eina_Bool disabled)
else if (ed->part_highlight) edit_view_sync(ed);
}
void
edit_smart_undo_redo_set(edit_data *ed, Eina_Bool smart_undo_redo)
{
smart_undo_redo = !!smart_undo_redo;
ed->smart_undo_redo = smart_undo_redo;
redoundo_smart_set(ed->rd, smart_undo_redo);
}
Eina_Bool
edit_smart_undo_redo_get(edit_data *ed)
{
return ed->smart_undo_redo;
}
void
edit_auto_indent_set(edit_data *ed, Eina_Bool auto_indent)
{

View File

@ -91,6 +91,15 @@ class Enventor.Object (Elm.Widget, Efl.File) {
linenumber: bool;
}
}
@property smart_undo_redo {
set {
}
get {
}
values {
smart_undo_redo: bool;
}
}
path_set {
return: Eina_Bool;
params {

View File

@ -195,6 +195,7 @@ void redoundo_entry_region_push(redoundo_data *rd, int cursor_pos, int cursor_po
int redoundo_undo(redoundo_data *rd, Eina_Bool *changed);
int redoundo_redo(redoundo_data *rd, Eina_Bool *changed);
void redoundo_n_diff_cancel(redoundo_data *rd, unsigned int n);
void redoundo_smart_set(redoundo_data *rd, Eina_Bool status);
/* edj_viewer */
@ -271,6 +272,8 @@ Eina_Bool edit_part_highlight_get(edit_data *ed);
void edit_ctxpopup_enabled_set(edit_data *ed, Eina_Bool enabled);
Eina_Bool edit_ctxpopup_enabled_get(edit_data *ed);
Eina_Bool edit_ctxpopup_visible_get(edit_data *ed);
void edit_smart_undo_redo_set(edit_data *ed, Eina_Bool smart_undo_redo);
Eina_Bool edit_smart_undo_redo_get(edit_data *ed);
void edit_ctxpopup_dismiss(edit_data *ed);
Eina_Bool edit_load(edit_data *ed, const char *edc_path);
void edit_selection_clear(edit_data *ed);

View File

@ -309,6 +309,19 @@ _enventor_object_linenumber_get(Eo *obj EINA_UNUSED, Enventor_Object_Data *pd)
return edit_linenumber_get(pd->ed);
}
EOLIAN static void
_enventor_object_smart_undo_redo_set(Eo *obj EINA_UNUSED, Enventor_Object_Data *pd,
Eina_Bool smart_undo_redo)
{
edit_smart_undo_redo_set(pd->ed, smart_undo_redo);
}
EOLIAN static Eina_Bool
_enventor_object_smart_undo_redo_get(Eo *obj EINA_UNUSED, Enventor_Object_Data *pd)
{
return edit_smart_undo_redo_get(pd->ed);
}
EOLIAN static void
_enventor_object_auto_indent_set(Eo *obj EINA_UNUSED, Enventor_Object_Data *pd,
Eina_Bool auto_indent)

View File

@ -6,6 +6,7 @@
#include "enventor_private.h"
#define DEFAULT_QUEUE_SIZE 200
#define INPUT_SPEED 0.8 //how much time need to input one symbol with speed 75sym/min
typedef struct diff_s
{
@ -26,11 +27,72 @@ struct redoundo_s
diff_data *last_diff;
unsigned int queue_max; //Maximum queuing data count 0: unlimited
Eina_Bool internal_change : 1; //Entry change by redoundo
struct {
Eina_Bool enable;
Ecore_Timer *timer;
Eina_Bool continues_input;
double input_delay;
} smart;
};
/*****************************************************************************/
/* Internal method implementation */
/*****************************************************************************/
Eina_Bool
_input_timer_cb(void *data)
{
redoundo_data *rd = (redoundo_data *)data;
if (!rd->smart.continues_input) return ECORE_CALLBACK_CANCEL;
rd->smart.continues_input = EINA_FALSE;
ecore_timer_del(rd->smart.timer);
rd->smart.timer = NULL;
return ECORE_CALLBACK_CANCEL;
}
static diff_data *
smart_analyser(redoundo_data *rd, diff_data *diff)
{
if (!rd->smart.enable) return diff;
if (rd->smart.timer)
{
ecore_timer_del(rd->smart.timer);
rd->smart.timer = NULL;
}
if ((!diff) || (diff->length > 1) || (!rd->last_diff)) return diff;
/* Autoindent. Here need edit_data pointer,
* for check status of autoindent feature.
*
* if (edit_auto_indent_get(edit_obj_get))
* {
* if (strstr(diff->text, "<br/>")) diff->relative = EINA_TRUE;
* else diff->relative = EINA_FALSE;
* }
*/
// Analyse speed of text input and words separates
if ((rd->smart.continues_input) && (!diff->relative) &&
(isalpha(diff->text[0])) && (isalpha(rd->last_diff->text[0])))
{
diff_data *tmp = diff;
const char *text;
diff = rd->last_diff;
diff->length += tmp->length;
text = eina_stringshare_printf("%s%s", diff->text, tmp->text);
eina_stringshare_replace(&diff->text, text);
eina_stringshare_del(text);
rd->last_diff = eina_list_data_get(eina_list_prev(rd->current_node));
rd->queue = eina_list_remove_list(rd->queue, rd->current_node);
eina_stringshare_del(tmp->text);
free(tmp);
}
rd->smart.continues_input = EINA_TRUE;
rd->smart.timer = ecore_timer_add(rd->smart.input_delay, _input_timer_cb, rd);
return diff;
}
static void
untracked_diff_free(redoundo_data *rd)
@ -104,7 +166,7 @@ entry_changed_user_cb(void *data, Evas_Object *obj EINA_UNUSED,
diff->length = abs(length);
diff->action = EINA_FALSE;
}
diff->relative = EINA_FALSE;
diff = smart_analyser(rd, diff);
untracked_diff_free(rd);
rd->queue = eina_list_append(rd->queue, diff);
@ -319,6 +381,8 @@ redoundo_init(Evas_Object *entry)
rd->textblock = elm_entry_textblock_get(entry);
rd->cursor = evas_object_textblock_cursor_new(rd->textblock);
rd->queue_max = DEFAULT_QUEUE_SIZE;
rd->smart.enable = EINA_FALSE;
rd->smart.input_delay = INPUT_SPEED;
//FIXME: Why signal callback? not smart callback?
elm_object_signal_callback_add(entry, "entry,changed,user", "*",
@ -337,6 +401,7 @@ redoundo_clear(redoundo_data *rd)
free(data);
}
rd->internal_change = EINA_FALSE;
ecore_timer_del(rd->smart.timer);
}
void
@ -395,3 +460,10 @@ redoundo_n_diff_cancel(redoundo_data *rd, unsigned int n)
rd->last_diff = (diff_data *)eina_list_data_get(rd->current_node);
untracked_diff_free(rd);
}
void
redoundo_smart_set(redoundo_data *rd, Eina_Bool status)
{
if (!rd) return;
rd->smart.enable = status;
}