Enlightenment CVS committal Author : moom Project : e17 Module : apps/e
Dir : e17/apps/e/src/bin Modified Files: e_entry.c Log Message: * [Entry] The entry now supports the keybindings of Emacs. It's disabled by default. Since I'm not an Emacs/Jed user, I may have forgotten or miscoded some important keybindings. I'd be glad if some Emacs/Jed users could tell me what is wrong. For this, you need to enable the keybindings by changing the line 47 of e_entry.c: "static int _e_entry_emacs_keybindings = 0;" --> "static int _e_entry_emacs_keybindings = 1;" =================================================================== RCS file: /cvs/e/e17/apps/e/src/bin/e_entry.c,v retrieving revision 1.30 retrieving revision 1.31 diff -u -3 -r1.30 -r1.31 --- e_entry.c 23 Aug 2006 10:14:17 -0000 1.30 +++ e_entry.c 23 Aug 2006 13:39:46 -0000 1.31 @@ -14,6 +14,7 @@ int enabled; int focused; int selection_dragging; + int selection_mode; float valign; int min_width; int height; @@ -25,7 +26,10 @@ static void _e_entry_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); static void _e_entry_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); static int _e_entry_x_selection_notify_handler(void *data, int type, void *event); + static void _e_entry_x_selection_update(Evas_Object *entry); +static void _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event); +static void _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event); static void _e_entry_smart_add(Evas_Object *object); static void _e_entry_smart_del(Evas_Object *object); @@ -40,6 +44,7 @@ /* local subsystem globals */ static Evas_Smart *_e_entry_smart = NULL; static int _e_entry_smart_use = 0; +static int _e_entry_emacs_keybindings = 0; /* externally accessible functions */ @@ -195,6 +200,11 @@ evas_object_focus_set(entry, 1); edje_object_signal_emit(sd->entry_object, "e,state,focused", "e"); + if (!sd->selection_dragging) + { + e_editable_cursor_move_to_end(sd->editable_object); + e_editable_selection_move_to_end(sd->editable_object); + } if (sd->enabled) e_editable_cursor_show(sd->editable_object); e_editable_selection_show(sd->editable_object); @@ -220,8 +230,6 @@ evas_object_focus_set(entry, 0); edje_object_signal_emit(sd->entry_object, "e,state,unfocused", "e"); - e_editable_cursor_move_to_end(sd->editable_object); - e_editable_selection_move_to_end(sd->editable_object); e_editable_cursor_hide(sd->editable_object); e_editable_selection_hide(sd->editable_object); sd->focused = 0; @@ -277,9 +285,181 @@ static void _e_entry_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) { + if (_e_entry_emacs_keybindings) + _e_entry_key_down_emacs(obj, event_info); + else + _e_entry_key_down_windows(obj, event_info); +} + +/* Called when the entry object is pressed by the mouse */ +static void +_e_entry_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + E_Entry_Smart_Data *sd; + Evas_Event_Mouse_Down *event; + Evas_Coord ox, oy; + int pos; + + if ((!obj) || (!(sd = evas_object_smart_data_get(obj)))) + return; + if (!(event = event_info)) + return; + + evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL); + pos = e_editable_pos_get_from_coords(sd->editable_object, + event->canvas.x - ox, + event->canvas.y - oy); + + if (event->button == 1) + { + if (event->flags & EVAS_BUTTON_DOUBLE_CLICK) + e_editable_select_all(sd->editable_object); + else + { + e_editable_cursor_pos_set(sd->editable_object, pos); + if (!evas_key_modifier_is_set(event->modifiers, "Shift")) + e_editable_selection_pos_set(sd->editable_object, pos); + + sd->selection_dragging = 1; + } + } + else if (event->button == 2) + { + E_Win *win; + + e_editable_cursor_pos_set(sd->editable_object, pos); + e_editable_selection_pos_set(sd->editable_object, pos); + + if ((win = e_win_evas_object_win_get(obj))) + ecore_x_selection_primary_request(win->evas_win, + ECORE_X_SELECTION_TARGET_UTF8_STRING); + } +} + +/* Called when the entry object is released by the mouse */ +static void +_e_entry_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + E_Entry_Smart_Data *sd; + + if ((!obj) || (!(sd = evas_object_smart_data_get(obj)))) + return; + + if (sd->selection_dragging) + { + sd->selection_dragging = 0; + _e_entry_x_selection_update(obj); + } +} + +/* Called when the mouse moves over the entry object */ +static void +_e_entry_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + E_Entry_Smart_Data *sd; + Evas_Event_Mouse_Move *event; + Evas_Coord ox, oy; + int pos; + + if ((!obj) || (!(sd = evas_object_smart_data_get(obj)))) + return; + if (!(event = event_info)) + return; + + if (sd->selection_dragging) + { + evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL); + pos = e_editable_pos_get_from_coords(sd->editable_object, + event->cur.canvas.x - ox, + event->cur.canvas.y - oy); + e_editable_cursor_pos_set(sd->editable_object, pos); + } +} + +/* Called when the the "selection_notify" event is emitted */ +static int +_e_entry_x_selection_notify_handler(void *data, int type, void *event) +{ + Evas_Object *entry; + E_Entry_Smart_Data *sd; + Ecore_X_Event_Selection_Notify *ev; + Ecore_X_Selection_Data *selection_data; + Evas_Object *editable; + int cursor_pos, selection_pos; + int start_pos, end_pos; + int selecting; + int changed = 0; + + if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry)))) + return 1; + if (!sd->focused) + return 1; + + editable = sd->editable_object; + cursor_pos = e_editable_cursor_pos_get(editable); + selection_pos = e_editable_selection_pos_get(editable); + start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos; + end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos; + selecting = (start_pos != end_pos); + + ev = event; + if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) || + (ev->selection == ECORE_X_SELECTION_PRIMARY)) + { + if (strcmp(ev->target, ECORE_X_SELECTION_TARGET_UTF8_STRING) == 0) + { + Ecore_X_Selection_Data_Text *text_data; + + text_data = ev->data; + if (selecting && !_e_entry_emacs_keybindings) + changed |= e_editable_delete(editable, start_pos, end_pos); + changed |= e_editable_insert(editable, start_pos, text_data->text); + } + } + + if (changed) + evas_object_smart_callback_call(entry, "changed", NULL); + + return 1; +} + +/* Updates the X selection with the selected text of the entry */ +static void +_e_entry_x_selection_update(Evas_Object *entry) +{ + E_Entry_Smart_Data *sd; + Evas_Object *editable; + E_Win *win; + int cursor_pos, selection_pos; + int start_pos, end_pos; + int selecting; + char *text; + + if ((!entry) || (!(sd = evas_object_smart_data_get(entry)))) + return; + if (!(win = e_win_evas_object_win_get(entry))) + return; + + editable = sd->editable_object; + cursor_pos = e_editable_cursor_pos_get(editable); + selection_pos = e_editable_selection_pos_get(editable); + start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos; + end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos; + selecting = (start_pos != end_pos); + + if ((!selecting) || + (!(text = e_editable_text_range_get(editable, start_pos, end_pos)))) + return; + + ecore_x_selection_primary_set(win->evas_win, text, strlen(text) + 1); + free(text); +} + +/* Treats the "key down" event to mimick the behavior of Windows/Gtk2/Qt */ +static void _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event) +{ E_Entry_Smart_Data *sd; Evas_Object *editable; - Evas_Event_Key_Down *event; int cursor_pos, selection_pos; int start_pos, end_pos; int selecting; @@ -288,9 +468,9 @@ char *range; E_Win *win; - if ((!obj) || (!(sd = evas_object_smart_data_get(obj)))) + if ((!entry) || (!(sd = evas_object_smart_data_get(entry)))) return; - if (!(event = event_info) || !(event->keyname)) + if ((!event) || (!event->keyname)) return; editable = sd->editable_object; @@ -300,6 +480,7 @@ end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos; selecting = (start_pos != end_pos); + /* Move the cursor/selection to the left */ if (strcmp(event->key, "Left") == 0) { @@ -364,7 +545,7 @@ else selection_changed = 1; } - /* Remove the previous character */ + /* Delete the previous character */ else if ((sd->enabled) && (strcmp(event->keyname, "BackSpace") == 0)) { if (selecting) @@ -372,7 +553,7 @@ else changed = e_editable_delete(editable, cursor_pos - 1, cursor_pos); } - /* Remove the next character */ + /* Delete the next character */ else if ((sd->enabled) && (strcmp(event->keyname, "Delete") == 0)) { if (selecting) @@ -396,7 +577,7 @@ range = e_editable_text_range_get(editable, start_pos, end_pos); if (range) { - if ((win = e_win_evas_object_win_get(obj))) + if ((win = e_win_evas_object_win_get(entry))) ecore_x_selection_clipboard_set(win->evas_win, range, strlen(range) + 1); @@ -408,7 +589,7 @@ } else if ((sd->enabled) && (strcmp(event->keyname, "v") == 0)) { - if ((win = e_win_evas_object_win_get(obj))) + if ((win = e_win_evas_object_win_get(entry))) ecore_x_selection_clipboard_request(win->evas_win, ECORE_X_SELECTION_TARGET_UTF8_STRING); } @@ -418,120 +599,35 @@ ((strlen(event->string) != 1) || (event->string[0] >= 0x20))) { if (selecting) - changed = e_editable_delete(editable, start_pos, end_pos); + changed |= e_editable_delete(editable, start_pos, end_pos); changed |= e_editable_insert(editable, start_pos, event->string); } + if (changed) - evas_object_smart_callback_call(obj, "changed", NULL); + evas_object_smart_callback_call(entry, "changed", NULL); if (selection_changed) - _e_entry_x_selection_update(obj); + _e_entry_x_selection_update(entry); } -/* Called when the entry object is pressed by the mouse */ -static void -_e_entry_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +/* Treats the "key down" event to mimick the behavior of Emacs */ +static void _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event) { E_Entry_Smart_Data *sd; - Evas_Event_Mouse_Down *event; - Evas_Coord ox, oy; - int pos; - - if ((!obj) || (!(sd = evas_object_smart_data_get(obj)))) - return; - if (!(event = event_info)) - return; - - evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL); - pos = e_editable_pos_get_from_coords(sd->editable_object, - event->canvas.x - ox, - event->canvas.y - oy); - - if (event->button == 1) - { - if (event->flags & EVAS_BUTTON_DOUBLE_CLICK) - e_editable_select_all(sd->editable_object); - else - { - e_editable_cursor_pos_set(sd->editable_object, pos); - if (!evas_key_modifier_is_set(event->modifiers, "Shift")) - e_editable_selection_pos_set(sd->editable_object, pos); - - sd->selection_dragging = 1; - } - } - else if (event->button == 2) - { - E_Win *win; - - e_editable_cursor_pos_set(sd->editable_object, pos); - e_editable_selection_pos_set(sd->editable_object, pos); - - if ((win = e_win_evas_object_win_get(obj))) - ecore_x_selection_primary_request(win->evas_win, - ECORE_X_SELECTION_TARGET_UTF8_STRING); - } -} - -/* Called when the entry object is released by the mouse */ -static void -_e_entry_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - E_Entry_Smart_Data *sd; - - if ((!obj) || (!(sd = evas_object_smart_data_get(obj)))) - return; - - if (sd->selection_dragging) - { - sd->selection_dragging = 0; - _e_entry_x_selection_update(obj); - } -} - -/* Called when the mouse moves over the entry object */ -static void -_e_entry_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - E_Entry_Smart_Data *sd; - Evas_Event_Mouse_Move *event; - Evas_Coord ox, oy; - int pos; - - if ((!obj) || (!(sd = evas_object_smart_data_get(obj)))) - return; - if (!(event = event_info)) - return; - - if (sd->selection_dragging) - { - evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL); - pos = e_editable_pos_get_from_coords(sd->editable_object, - event->cur.canvas.x - ox, - event->cur.canvas.y - oy); - e_editable_cursor_pos_set(sd->editable_object, pos); - } -} - -/* Called when the the "selection_notify" event is emitted */ -static int -_e_entry_x_selection_notify_handler(void *data, int type, void *event) -{ - Evas_Object *entry; - E_Entry_Smart_Data *sd; - Ecore_X_Event_Selection_Notify *ev; - Ecore_X_Selection_Data *selection_data; Evas_Object *editable; int cursor_pos, selection_pos; int start_pos, end_pos; int selecting; int changed = 0; + int selection_changed = 0; + char *range; + E_Win *win; - if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry)))) - return 1; - if (!sd->focused) - return 1; - + if ((!entry) || (!(sd = evas_object_smart_data_get(entry)))) + return; + if ((!event) || (!event->keyname)) + return; + editable = sd->editable_object; cursor_pos = e_editable_cursor_pos_get(editable); selection_pos = e_editable_selection_pos_get(editable); @@ -539,57 +635,124 @@ end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos; selecting = (start_pos != end_pos); - ev = event; - if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) || - (ev->selection == ECORE_X_SELECTION_PRIMARY)) + + /* Move the cursor/selection to the left */ + if ((strcmp(event->key, "Left") == 0) || + ((evas_key_modifier_is_set(event->modifiers, "Control")) && + (strcmp(event->key, "b") == 0))) { - if (strcmp(ev->target, ECORE_X_SELECTION_TARGET_UTF8_STRING) == 0) + e_editable_cursor_move_left(editable); + if (sd->selection_mode) + selection_changed = 1; + else + e_editable_selection_pos_set(editable, + e_editable_cursor_pos_get(editable)); + } + /* Move the cursor/selection to the right */ + else if ((strcmp(event->key, "Right") == 0) || + ((evas_key_modifier_is_set(event->modifiers, "Control")) && + (strcmp(event->key, "f") == 0))) + { + e_editable_cursor_move_right(editable); + if (sd->selection_mode) + selection_changed = 1; + else + e_editable_selection_pos_set(editable, + e_editable_cursor_pos_get(editable)); + } + /* Move the cursor/selection to the start of the entry */ + else if ((strcmp(event->keyname, "Home") == 0) || + ((evas_key_modifier_is_set(event->modifiers, "Control")) && + (strcmp(event->key, "a") == 0))) + { + e_editable_cursor_move_to_start(editable); + if (sd->selection_mode) + selection_changed = 1; + else + e_editable_selection_pos_set(editable, + e_editable_cursor_pos_get(editable)); + } + /* Move the cursor/selection to the end of the entry */ + else if ((strcmp(event->keyname, "End") == 0) || + ((evas_key_modifier_is_set(event->modifiers, "Control")) && + (strcmp(event->key, "e") == 0))) + { + e_editable_cursor_move_to_end(editable); + if (sd->selection_mode) + selection_changed = 1; + else + e_editable_selection_pos_set(editable, + e_editable_cursor_pos_get(editable)); + } + /* Delete the previous character */ + else if ((sd->enabled) && (strcmp(event->keyname, "BackSpace") == 0)) + changed = e_editable_delete(editable, cursor_pos - 1, cursor_pos); + /* Delete the next character */ + else if ((sd->enabled) && + ((evas_key_modifier_is_set(event->modifiers, "Control")) && + (strcmp(event->key, "d") == 0))) + changed = e_editable_delete(editable, cursor_pos, cursor_pos + 1); + /* Delete until end of line */ + else if ((sd->enabled) && + ((evas_key_modifier_is_set(event->modifiers, "Control")) && + (strcmp(event->key, "k") == 0))) + changed = e_editable_delete(editable, cursor_pos, + e_editable_text_length_get(editable)); + /* Toggle the selection mode */ + else if ((evas_key_modifier_is_set(event->modifiers, "Control")) && + (strcmp(event->key, "space") == 0)) + { + if (sd->selection_mode) { - Ecore_X_Selection_Data_Text *text_data; - - text_data = ev->data; - if (selecting) - changed = e_editable_delete(editable, start_pos, end_pos); - changed |= e_editable_insert(editable, start_pos, text_data->text); + e_editable_selection_pos_set(editable, cursor_pos); + sd->selection_mode = 0; } + else + sd->selection_mode = 1; } + /* Cut/Copy */ + else if ((evas_key_modifier_is_set(event->modifiers, "Control") || + evas_key_modifier_is_set(event->modifiers, "Shift")) && + (strcmp(event->key, "w") == 0)) + { + if (selecting) + { + range = e_editable_text_range_get(editable, start_pos, end_pos); + if (range) + { + if ((win = e_win_evas_object_win_get(entry))) + ecore_x_selection_clipboard_set(win->evas_win, + range, + strlen(range) + 1); + free(range); + } + if ((sd->enabled) && (evas_key_modifier_is_set(event->modifiers, "Control"))) + { + changed = e_editable_delete(editable, start_pos, end_pos); + sd->selection_mode = 0; + } + } + } + /* Paste */ + else if ((sd->enabled) && + ((evas_key_modifier_is_set(event->modifiers, "Control")) && + (strcmp(event->key, "y") == 0))) + { + if ((win = e_win_evas_object_win_get(entry))) + ecore_x_selection_clipboard_request(win->evas_win, + ECORE_X_SELECTION_TARGET_UTF8_STRING); + } + /* Otherwise, we insert the corresponding character */ + else if ((event->string) && + ((strlen(event->string) != 1) || + (event->string[0] >= 0x20 && event->string[0] != 0x7f))) + changed = e_editable_insert(editable, cursor_pos, event->string); + if (changed) evas_object_smart_callback_call(entry, "changed", NULL); - - return 1; -} - -/* Updates the X selection with the selected text of the entry */ -static void -_e_entry_x_selection_update(Evas_Object *entry) -{ - E_Entry_Smart_Data *sd; - Evas_Object *editable; - E_Win *win; - int cursor_pos, selection_pos; - int start_pos, end_pos; - int selecting; - char *text; - - if ((!entry) || (!(sd = evas_object_smart_data_get(entry)))) - return; - if (!(win = e_win_evas_object_win_get(entry))) - return; - - editable = sd->editable_object; - cursor_pos = e_editable_cursor_pos_get(editable); - selection_pos = e_editable_selection_pos_get(editable); - start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos; - end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos; - selecting = (start_pos != end_pos); - - if ((!selecting) || - (!(text = e_editable_text_range_get(editable, start_pos, end_pos)))) - return; - - ecore_x_selection_primary_set(win->evas_win, text, strlen(text) + 1); - free(text); + if (selection_changed) + _e_entry_x_selection_update(entry); } /* Editable object's smart methods */ @@ -613,6 +776,7 @@ sd->enabled = 1; sd->focused = 0; sd->selection_dragging = 0; + sd->selection_mode = 0; sd->valign = 0.5; o = edje_object_add(evas); ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs