diff --git a/README b/README index 92dc983..bda17e8 100644 --- a/README +++ b/README @@ -68,6 +68,7 @@ Ctrl+V = Paste Copied Text Ctrl+X = Cut Selected Text Ctrl+D = Delete a Current line Ctrl+F = Find/Replace +Ctrl+L = Go to line Ctrl+Home = Go to the Top line Ctrl+End = Go to the Bottom line diff --git a/data/themes/default/layout.edc b/data/themes/default/layout.edc index f2b8694..2e46cde 100644 --- a/data/themes/default/layout.edc +++ b/data/themes/default/layout.edc @@ -3,7 +3,97 @@ styles { base: "font="FN" font_size=11 text_class=entry color=#ffffff style=shadow,bottom shadow_color=#00000080 glow_color=#3399ff18 valign=1 ellipsis=1.0 wrap=none"; } } - +group { name: "goto"; + parts { + part { name: "base"; + type: SPACER; + description { state: "default" 0.0; + min: 300 67; + } + } + part { name: "left_top_padding"; + type: SPACER; + scale: 1; + description { state: "default" 0.0; + rel1.relative: 0 0; + rel2.relative: 0 0; + fixed: 1 1; + align: 0 0; + min: 5 5; + } + } + part { name: "elm.text.goto"; + type: TEXT; + scale: 1; + effect: SHADOW BOTTOM; + description { state: "default" 0.0; + align: 0 0; + rel1.to: "left_top_padding"; + rel2.to: "left_top_padding"; + rel1.relative: 1 1; + rel2.relative: 1 1; + text { + font: FN; + size: 11; + align: 0 0; + } + color: 255 255 255 255; + color3: 0 0 0 128; + min: 180 20; + fixed: 1 1; + } + } + part { name: "elm.swallow.entry"; + type: SWALLOW; + scale: 1; + description { state: "default" 0.0; + rel1.relative: 1 0; + rel2.relative: 1 1; + rel1.to: "elm.text.goto"; + rel2.to_y: "elm.text.goto"; + rel2.offset: -5 -1; + fixed: 1 1; + } + } + part { name: "elm.text.msg"; + type: TEXT; + scale: 1; + effect: GLOW; + description { state: "default" 0.0; + align: 0 0; + rel1.to: "elm.text.goto"; + rel2.to: "elm.text.goto"; + rel1.relative: 0 1; + rel2.relative: 0 1; + rel1.offset: 0 10; + text { + font: FN; + size: 10; + align: 0 0.5; + } + color: 51 153 255 255; + color2: 51 153 255 16; + color3: 51 153 255 8; + min: 180 30; + fixed: 1 1; + } + } + part { name: "elm.swallow.btn"; + type: SWALLOW; + scale: 1; + description { state: "default" 0.0; + rel1.relative: 1 0; + rel2.relative: 1 1; + rel1.to_y: "elm.text.msg"; + rel1.offset: 5 0; + rel2.offset: -3 -3; + min: 75 0; + align: 1 0; + fixed: 1 1; + } + } + } +} group { name: "search"; parts { part { name: "base"; diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index e614c7b..059e52c 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -28,6 +28,7 @@ enventor_SOURCES = \ build.c \ tools.c \ search.c \ + goto.c \ newfile.c \ globals.c diff --git a/src/bin/base_gui.c b/src/bin/base_gui.c index 704522c..df25b9e 100644 --- a/src/bin/base_gui.c +++ b/src/bin/base_gui.c @@ -16,6 +16,13 @@ win_delete_request_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, menu_exit(); } +static void +win_focused_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + goto_close(); +} + void base_title_set(const char *path) { @@ -129,6 +136,7 @@ base_gui_init() elm_win_focus_highlight_enabled_set(win, EINA_TRUE); evas_object_smart_callback_add(win, "delete,request", win_delete_request_cb, NULL); + evas_object_smart_callback_add(win, "focused", win_focused_cb, NULL); //Window icon Evas_Object *icon = evas_object_image_add(evas_object_evas_get(win)); diff --git a/src/bin/edc_editor.c b/src/bin/edc_editor.c index bb8ff50..80b6048 100644 --- a/src/bin/edc_editor.c +++ b/src/bin/edc_editor.c @@ -1171,3 +1171,19 @@ edit_cur_part_name_get(edit_data *ed) { return parser_cur_name_fast_get(ed->en_edit, "part"); } + +int +edit_max_line_get(edit_data *ed) +{ + return ed->line_max; +} + +void +edit_goto(edit_data *ed, int line) +{ + Evas_Object *tb = elm_entry_textblock_get(ed->en_edit); + Evas_Textblock_Cursor *cur = evas_object_textblock_cursor_get(tb); + evas_textblock_cursor_line_set(cur, (line - 1)); + elm_entry_calc_force(ed->en_edit); + elm_object_focus_set(ed->en_edit, EINA_TRUE); +} diff --git a/src/bin/goto.c b/src/bin/goto.c new file mode 100644 index 0000000..78f9429 --- /dev/null +++ b/src/bin/goto.c @@ -0,0 +1,162 @@ +#include +#include "common.h" + +typedef struct goto_s +{ + Evas_Object *win; + Evas_Object *layout; + Evas_Object *btn; + edit_data *ed; +} goto_data; + +static goto_data *g_gd = NULL; +static Evas_Coord win_x = -1; +static Evas_Coord win_y = -1; +static Evas_Coord win_w = DEFAULT_GOTO_WIN_W; +static Evas_Coord win_h = DEFAULT_GOTO_WIN_H; + +static void +win_delete_request_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + goto_close(); +} + +static void +win_moved_cb(void *data EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + /* Move the window with the previous remembered position when the window is + moved by window manager first time. */ + if ((win_x != -1) || (win_y != -1)) evas_object_move(obj, win_x, win_y); + evas_object_smart_callback_del(obj, "moved", win_moved_cb); +} + +static void +entry_activated_cb(void *data, Evas_Object *obj, void* event_info EINA_UNUSED) +{ + goto_data *gd = data; + + if (elm_object_disabled_get(gd->btn)) return; + + const char *txt = elm_entry_entry_get(obj); + int line = atoi(txt); + edit_goto(gd->ed, line); + goto_close(); +} + +static void +entry_changed_cb(void *data, Evas_Object *obj, void* event_info EINA_UNUSED) +{ + goto_data *gd = data; + const char *txt = elm_entry_entry_get(obj); + if (txt[0] == 0) return; + + int line = atoi(txt); + + if ((line < 1) || (line > edit_max_line_get(gd->ed))) + { + elm_object_part_text_set(gd->layout, "elm.text.msg", + "Invalid line number."); + elm_object_disabled_set(gd->btn, EINA_TRUE); + } + else + { + elm_object_part_text_set(gd->layout, "elm.text.msg", ""); + elm_object_disabled_set(gd->btn, EINA_FALSE); + } +} + +void +goto_open(edit_data *ed) +{ + goto_data *gd = g_gd; + + if (gd) + { + elm_win_activate(gd->win); + return; + } + + search_close(); + + gd = calloc(1, sizeof(goto_data)); + g_gd = gd; + + //Win + Evas_Object *win = elm_win_add(base_win_get(), "Enventor Goto Line", + ELM_WIN_DIALOG_BASIC); + elm_win_focus_highlight_enabled_set(win, EINA_TRUE); + + elm_win_title_set(win, "Go to Line"); + evas_object_resize(win, win_w, win_h); + evas_object_smart_callback_add(win, "delete,request", win_delete_request_cb, + gd); + evas_object_smart_callback_add(win, "moved", win_moved_cb, gd); + + //Bg + Evas_Object *bg = elm_bg_add(win); + evas_object_show(bg); + elm_win_resize_object_add(win, bg); + + //Layout + Evas_Object *layout = elm_layout_add(win); + elm_layout_file_set(layout, EDJE_PATH, "goto"); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(layout); + elm_win_resize_object_add(win, layout); + + char buf[256]; + snprintf(buf, sizeof(buf), "Enter line number [1..%d]:", + edit_max_line_get(ed)); + elm_object_part_text_set(layout, "elm.text.goto", buf); + + //Entry (line) + Evas_Object *entry = elm_entry_add(layout); + elm_entry_single_line_set(entry, EINA_TRUE); + elm_entry_scrollable_set(entry, EINA_TRUE); + evas_object_smart_callback_add(entry, "activated", entry_activated_cb, + gd); + evas_object_smart_callback_add(entry, "changed,user", entry_changed_cb, gd); + evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, 0); + evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, 0); + evas_object_show(entry); + elm_object_focus_set(entry, EINA_TRUE); + elm_object_part_content_set(layout, "elm.swallow.entry", entry); + + //Button (ok) + Evas_Object *btn = elm_button_add(layout); + elm_object_text_set(btn, "Ok"); + //evas_object_smart_callback_add(btn_backward, "clicked", + // backward_clicked_cb, sd); + elm_object_part_content_set(layout, "elm.swallow.btn", + btn); + + evas_object_show(win); + + gd->win = win; + gd->layout = layout; + gd->btn = btn; + gd->ed = ed; +} + +Eina_Bool +goto_is_opened() +{ + goto_data *gd = g_gd; + return (gd ? EINA_TRUE : EINA_FALSE); +} + +void +goto_close() +{ + goto_data *gd = g_gd; + if (!gd) return; + + //Save last state + evas_object_geometry_get(gd->win, NULL, NULL, &win_w, &win_h); + elm_win_screen_position_get(gd->win, &win_x, &win_y); + evas_object_del(gd->win); + free(gd); + g_gd = NULL; +} diff --git a/src/bin/main.c b/src/bin/main.c index 3d83559..01634cc 100644 --- a/src/bin/main.c +++ b/src/bin/main.c @@ -126,6 +126,12 @@ ctrl_func(app_data *ad, const char *key) search_open(); return ECORE_CALLBACK_DONE; } + //Goto Line + if (!strcmp(key, "l") || !strcmp(key, "L")) + { + goto_open(ad->ed); + return ECORE_CALLBACK_DONE; + } //Part Highlight if (!strcmp(key, "h") || !strcmp(key, "h")) { @@ -189,8 +195,9 @@ main_key_down_cb(void *data, int type EINA_UNUSED, void *ev) //Main Menu if (!strcmp(event->key, "Escape")) { - if (search_is_opened()) + if (search_is_opened() || goto_is_opened()) { + goto_close(); search_close(); edit_focus_set(ad->ed); return ECORE_CALLBACK_DONE; diff --git a/src/bin/search.c b/src/bin/search.c index 8f9edc0..973e701 100644 --- a/src/bin/search.c +++ b/src/bin/search.c @@ -275,6 +275,8 @@ search_open() return; } + goto_close(); + sd = calloc(1, sizeof(search_data)); g_sd = sd; @@ -287,7 +289,6 @@ search_open() evas_object_smart_callback_add(win, "delete,request", win_delete_request_cb, sd); evas_object_smart_callback_add(win, "moved", win_moved_cb, sd); - evas_object_show(win); //Bg Evas_Object *bg = elm_bg_add(win); @@ -352,6 +353,8 @@ search_open() replace_all_clicked_cb, sd); elm_object_part_content_set(layout, "elm.swallow.replace_all", btn_replace_all); + evas_object_show(win); + sd->win = win; sd->layout = layout; sd->en_find = entry_find; diff --git a/src/include/common.h b/src/include/common.h index edf3a4a..8a6b6e0 100644 --- a/src/include/common.h +++ b/src/include/common.h @@ -27,6 +27,7 @@ typedef struct indent_s indent_data; #include "tools.h" #include "base_gui.h" #include "search.h" +#include "goto.h" #include "newfile.h" #endif diff --git a/src/include/edc_editor.h b/src/include/edc_editor.h index 314b7f8..db67aa5 100644 --- a/src/include/edc_editor.h +++ b/src/include/edc_editor.h @@ -19,3 +19,5 @@ void edit_line_delete(edit_data *ed); void edit_edc_reload(edit_data *ed, const char *edc_path); Eina_Stringshare *edit_cur_prog_name_get(edit_data *ed); Eina_Stringshare *edit_cur_part_name_get(edit_data *ed); +int edit_max_line_get(edit_data *ed); +void edit_goto(edit_data *ed, int line); diff --git a/src/include/goto.h b/src/include/goto.h new file mode 100644 index 0000000..7098263 --- /dev/null +++ b/src/include/goto.h @@ -0,0 +1,5 @@ +#define DEFAULT_GOTO_WIN_W 330 +#define DEFAULT_GOTO_WIN_H 77 +void goto_open(edit_data *ed); +void goto_close(); +Eina_Bool goto_is_opened();