forked from enlightenment/edi
Added basic undo support - thanks to ecrire (Tasn) for the undo_redo_do function
This commit is contained in:
parent
d2117bac25
commit
a3a4f5fce6
|
@ -1,3 +1,7 @@
|
||||||
|
2014-05-15 ajwillia.ms (Andy Williams)
|
||||||
|
|
||||||
|
* Add basic undo support
|
||||||
|
|
||||||
2014-04-27 ajwillia.ms (Andy Williams)
|
2014-04-27 ajwillia.ms (Andy Williams)
|
||||||
|
|
||||||
* Add simple build functions
|
* Add simple build functions
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
|
||||||
#include <Eina.h>
|
#include <Eina.h>
|
||||||
#include <Eio.h>
|
#include <Elementary.h>
|
||||||
|
|
||||||
#include "edi_editor.h"
|
#include "edi_editor.h"
|
||||||
|
|
||||||
|
@ -14,6 +14,86 @@
|
||||||
#include "edi_private.h"
|
#include "edi_private.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_undo_do(Edi_Editor *editor, Elm_Entry_Change_Info *inf)
|
||||||
|
{
|
||||||
|
if (inf->insert)
|
||||||
|
{
|
||||||
|
const Evas_Object *tb = elm_entry_textblock_get(editor->entry);
|
||||||
|
Evas_Textblock_Cursor *mcur, *end;
|
||||||
|
mcur = (Evas_Textblock_Cursor *) evas_object_textblock_cursor_get(tb);
|
||||||
|
end = evas_object_textblock_cursor_new(tb);
|
||||||
|
|
||||||
|
if (inf->insert)
|
||||||
|
{
|
||||||
|
elm_entry_cursor_pos_set(editor->entry, inf->change.insert.pos);
|
||||||
|
evas_textblock_cursor_pos_set(end, inf->change.insert.pos +
|
||||||
|
inf->change.insert.plain_length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elm_entry_cursor_pos_set(editor->entry, inf->change.del.start);
|
||||||
|
evas_textblock_cursor_pos_set(end, inf->change.del.end);
|
||||||
|
}
|
||||||
|
|
||||||
|
evas_textblock_cursor_range_delete(mcur, end);
|
||||||
|
evas_textblock_cursor_free(end);
|
||||||
|
elm_entry_calc_force(editor->entry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (inf->insert)
|
||||||
|
{
|
||||||
|
elm_entry_cursor_pos_set(editor->entry, inf->change.insert.pos);
|
||||||
|
elm_entry_entry_insert(editor->entry, inf->change.insert.content);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t start;
|
||||||
|
start = (inf->change.del.start < inf->change.del.end) ?
|
||||||
|
inf->change.del.start : inf->change.del.end;
|
||||||
|
|
||||||
|
elm_entry_cursor_pos_set(editor->entry, start);
|
||||||
|
elm_entry_entry_insert(editor->entry, inf->change.insert.content);
|
||||||
|
elm_entry_cursor_pos_set(editor->entry, inf->change.del.end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_undo_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||||
|
{
|
||||||
|
Elm_Entry_Change_Info *change;
|
||||||
|
Edi_Editor *editor = data;
|
||||||
|
|
||||||
|
if (!eina_list_next(editor->undo_stack))
|
||||||
|
return;
|
||||||
|
|
||||||
|
change = eina_list_data_get(editor->undo_stack);
|
||||||
|
_undo_do(editor, change);
|
||||||
|
editor->undo_stack = eina_list_next(editor->undo_stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
|
||||||
|
{
|
||||||
|
Elm_Entry_Change_Info *change;
|
||||||
|
Edi_Editor *editor = data;
|
||||||
|
|
||||||
|
change = calloc(1, sizeof(*change));
|
||||||
|
memcpy(change, event_info, sizeof(*change));
|
||||||
|
if (change->insert)
|
||||||
|
{
|
||||||
|
eina_stringshare_ref(change->change.insert.content);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eina_stringshare_ref(change->change.del.content);
|
||||||
|
}
|
||||||
|
|
||||||
|
editor->undo_stack = eina_list_prepend(editor->undo_stack, change);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_smart_cb_key_down(void *data, Evas *e EINA_UNUSED,
|
_smart_cb_key_down(void *data, Evas *e EINA_UNUSED,
|
||||||
Evas_Object *obj EINA_UNUSED, void *event)
|
Evas_Object *obj EINA_UNUSED, void *event)
|
||||||
|
@ -43,6 +123,10 @@ _smart_cb_key_down(void *data, Evas *e EINA_UNUSED,
|
||||||
{
|
{
|
||||||
edi_mainview_search();
|
edi_mainview_search();
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(ev->key, "z"))
|
||||||
|
{
|
||||||
|
_undo_cb(data, obj, event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +135,7 @@ EAPI Evas_Object *edi_editor_add(Evas_Object *parent, const char *path)
|
||||||
Evas_Object *txt;
|
Evas_Object *txt;
|
||||||
Evas_Modifier_Mask ctrl, shift, alt;
|
Evas_Modifier_Mask ctrl, shift, alt;
|
||||||
Evas *e;
|
Evas *e;
|
||||||
|
Edi_Editor *editor;
|
||||||
|
|
||||||
txt = elm_entry_add(parent);
|
txt = elm_entry_add(parent);
|
||||||
elm_entry_editable_set(txt, EINA_TRUE);
|
elm_entry_editable_set(txt, EINA_TRUE);
|
||||||
|
@ -63,8 +148,12 @@ EAPI Evas_Object *edi_editor_add(Evas_Object *parent, const char *path)
|
||||||
evas_object_size_hint_align_set(txt, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
evas_object_size_hint_align_set(txt, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||||
evas_object_show(txt);
|
evas_object_show(txt);
|
||||||
|
|
||||||
|
editor = calloc(1, sizeof(*editor));
|
||||||
|
editor->entry = txt;
|
||||||
evas_object_event_callback_add(txt, EVAS_CALLBACK_KEY_DOWN,
|
evas_object_event_callback_add(txt, EVAS_CALLBACK_KEY_DOWN,
|
||||||
_smart_cb_key_down, txt);
|
_smart_cb_key_down, editor);
|
||||||
|
evas_object_smart_callback_add(txt, "changed,user", _changed_cb, editor);
|
||||||
|
evas_object_smart_callback_add(txt, "undo,request", _undo_cb, editor);
|
||||||
|
|
||||||
e = evas_object_evas_get(txt);
|
e = evas_object_evas_get(txt);
|
||||||
ctrl = evas_key_modifier_mask_get(e, "Control");
|
ctrl = evas_key_modifier_mask_get(e, "Control");
|
||||||
|
@ -75,6 +164,7 @@ EAPI Evas_Object *edi_editor_add(Evas_Object *parent, const char *path)
|
||||||
evas_object_key_grab(txt, "Next", ctrl, shift | alt, 1);
|
evas_object_key_grab(txt, "Next", ctrl, shift | alt, 1);
|
||||||
evas_object_key_grab(txt, "s", ctrl, shift | alt, 1);
|
evas_object_key_grab(txt, "s", ctrl, shift | alt, 1);
|
||||||
evas_object_key_grab(txt, "f", ctrl, shift | alt, 1);
|
evas_object_key_grab(txt, "f", ctrl, shift | alt, 1);
|
||||||
|
evas_object_key_grab(txt, "z", ctrl, shift | alt, 1);
|
||||||
|
|
||||||
return txt;
|
return txt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,26 @@ extern "C" {
|
||||||
* @brief These routines are used for interacting with the main Edi editor view.
|
* @brief These routines are used for interacting with the main Edi editor view.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef Edi_Editor
|
||||||
|
* An instance of an editor view.
|
||||||
|
*/
|
||||||
|
typedef struct _Edi_Editor Edi_Editor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct _Edi_Editor
|
||||||
|
* An instance of an editor view.
|
||||||
|
*/
|
||||||
|
struct _Edi_Editor
|
||||||
|
{
|
||||||
|
Evas_Object *entry; /**< The main text entry widget for the editor */
|
||||||
|
Eina_List *undo_stack; /**< The list of operations that can be undone */
|
||||||
|
|
||||||
|
/* Private */
|
||||||
|
|
||||||
|
/* Add new members here. */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Editor.
|
* @brief Editor.
|
||||||
* @defgroup Editor The main text editor functions
|
* @defgroup Editor The main text editor functions
|
||||||
|
|
Loading…
Reference in New Issue