From a25b043761d0ccb8803dd940105c5aa3b97d77f8 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 12 Jul 2030 21:12:05 +0100 Subject: [PATCH] Move search UI into a panel at the top of the editor. Correct search to work across multiple tabs within one Edi instance. Fix various issues around searc. --- src/bin/edi_mainview.c | 2 +- src/bin/editor/edi_editor.c | 11 ++- src/bin/editor/edi_editor.h | 29 ++++-- src/bin/editor/edi_editor_search.c | 153 +++++++++++++++-------------- 4 files changed, 111 insertions(+), 84 deletions(-) diff --git a/src/bin/edi_mainview.c b/src/bin/edi_mainview.c index 2c5555b..122aec7 100644 --- a/src/bin/edi_mainview.c +++ b/src/bin/edi_mainview.c @@ -520,7 +520,7 @@ edi_mainview_search() editor = (Edi_Editor *)evas_object_data_get(content, "editor"); if (editor) - edi_editor_search(editor->entry); + edi_editor_search(editor); } EAPI void diff --git a/src/bin/editor/edi_editor.c b/src/bin/editor/edi_editor.c index c22f3bd..f10eb0f 100644 --- a/src/bin/editor/edi_editor.c +++ b/src/bin/editor/edi_editor.c @@ -18,7 +18,6 @@ static void _update_lines(Edi_Editor *editor); - static void _undo_do(Edi_Editor *editor, Elm_Entry_Change_Info *inf) { @@ -222,7 +221,7 @@ _edi_editor_statusbar_add(Evas_Object *panel, Edi_Editor *editor) EAPI Evas_Object *edi_editor_add(Evas_Object *parent, const char *path) { - Evas_Object *txt, *lines, *vbox, *box, *statusbar; + Evas_Object *txt, *lines, *vbox, *box, *searchbar, *statusbar; Evas_Modifier_Mask ctrl, shift, alt; Evas *e; Edi_Editor *editor; @@ -230,6 +229,11 @@ EAPI Evas_Object *edi_editor_add(Evas_Object *parent, const char *path) vbox = elm_box_add(parent); evas_object_show(vbox); + searchbar = elm_box_add(vbox); + evas_object_size_hint_weight_set(searchbar, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(searchbar, EVAS_HINT_FILL, 0.0); + elm_box_pack_end(vbox, searchbar); + box = elm_box_add(vbox); elm_box_horizontal_set(box, EINA_TRUE); evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); @@ -277,6 +281,7 @@ EAPI Evas_Object *edi_editor_add(Evas_Object *parent, const char *path) evas_object_smart_callback_add(txt, "scroll", _scroll_cb, editor); evas_object_smart_callback_add(txt, "undo,request", _undo_cb, editor); + edi_editor_search_add(searchbar, editor); _edi_editor_statusbar_add(statusbar, editor); e = evas_object_evas_get(txt); @@ -290,7 +295,7 @@ EAPI Evas_Object *edi_editor_add(Evas_Object *parent, const char *path) (void)!evas_object_key_grab(txt, "f", ctrl, shift | alt, 1); (void)!evas_object_key_grab(txt, "z", ctrl, shift | alt, 1); - evas_object_data_set(box, "editor", editor); + evas_object_data_set(vbox, "editor", editor); _update_lines(editor); return vbox; } diff --git a/src/bin/editor/edi_editor.h b/src/bin/editor/edi_editor.h index 1cdcad0..8d5d110 100644 --- a/src/bin/editor/edi_editor.h +++ b/src/bin/editor/edi_editor.h @@ -12,6 +12,12 @@ extern "C" { * @brief These routines are used for interacting with the main Edi editor view. */ +/** + * @typedef Edi_Editor_Search + * An instance of an editor search session. + */ +typedef struct _Edi_Editor_Search Edi_Editor_Search; + /** * @typedef Edi_Editor * An instance of an editor view. @@ -25,10 +31,11 @@ typedef struct _Edi_Editor Edi_Editor; struct _Edi_Editor { Evas_Object *entry; /**< The main text entry widget for the editor */ - Evas_Object *lines; Eina_List *undo_stack; /**< The list of operations that can be undone */ /* Private */ + Evas_Object *lines; + Edi_Editor_Search *search; /* Add new members here. */ }; @@ -55,21 +62,31 @@ EAPI Evas_Object *edi_editor_add(Evas_Object *parent, const char *path); /** * @} * - * @brief Dialogs. - * @defgroup Dialogs Functions that open other dialogs + * @brief Widgets. + * @defgroup Widget Functions that open or manipulate feature panels * * @{ * */ +/** + * Add a search widget to the specified editor. + * + * @param parent The panel that the UI should be added to, + * @param editor The Edi_Editor instance that we are searching for text within. + * + * @ingroup Widgets + */ +EAPI void edi_editor_search_add(Evas_Object *parent, Edi_Editor *editor); + /** * Start a search in the specified editor. * - * @param entry The elm_entry that we are searching for text within. + * @param editor the text editor instance to search within. * - * @ingroup Dialogs + * @ingroup Widgets */ -EAPI void edi_editor_search(Evas_Object *entry); +EAPI void edi_editor_search(Edi_Editor *editor); /** * @} diff --git a/src/bin/editor/edi_editor_search.c b/src/bin/editor/edi_editor_search.c index 616b039..5fd8cef 100644 --- a/src/bin/editor/edi_editor_search.c +++ b/src/bin/editor/edi_editor_search.c @@ -14,36 +14,47 @@ #include "edi_editor.h" #include "edi_private.h" -static Evas_Object *_search_win, *_search_entry, *_target_entry; -static Evas_Textblock_Cursor *_current_search; +/** + * @struct _Edi_Editor_Search + * An instance of an editor view search session. + */ +struct _Edi_Editor_Search +{ + Evas_Object *entry; /**< The search text widget */ + Evas_Object *widget; /**< The search UI panel we wish to show and hide */ + Evas_Textblock_Cursor *current_search; /**< The current search cursor for this session */ + + /* Add new members here. */ +}; static Eina_Bool -_search_in_entry(Evas_Object *entry, const char *text) +_search_in_entry(Evas_Object *entry, Edi_Editor_Search *search) { Eina_Bool try_next = EINA_FALSE; - const char *found; + const char *found, *text; char *utf8; const Evas_Object *tb = elm_entry_textblock_get(entry); Evas_Textblock_Cursor *end, *start, *mcur; size_t initial_pos; Evas_Coord x, y, w, h; + text = elm_object_text_get(search->entry); if (!text || !*text) return EINA_FALSE; mcur = (Evas_Textblock_Cursor *) evas_object_textblock_cursor_get(tb); - if (!_current_search) + if (!search->current_search) { - _current_search = evas_object_textblock_cursor_new(tb); + search->current_search = evas_object_textblock_cursor_new(tb); } - else if (!evas_textblock_cursor_compare(_current_search, mcur)) + else if (!evas_textblock_cursor_compare(search->current_search, mcur)) { try_next = EINA_TRUE; } - evas_textblock_cursor_paragraph_last(_current_search); + evas_textblock_cursor_paragraph_last(search->current_search); start = mcur; - end = _current_search; + end = search->current_search; initial_pos = evas_textblock_cursor_pos_get(start); @@ -87,7 +98,7 @@ _search_in_entry(Evas_Object *entry, const char *text) w -= x; h -= y; elm_scroller_region_show(entry, x, y, w, h); - evas_textblock_cursor_copy(mcur, _current_search); + evas_textblock_cursor_copy(mcur, search->current_search); } free(utf8); @@ -96,92 +107,86 @@ _search_in_entry(Evas_Object *entry, const char *text) } static void -_search_clicked(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +_edi_editor_search_hide(Edi_Editor *editor) { - _search_in_entry(_target_entry, elm_object_text_get(_search_entry)); -} + Edi_Editor_Search *search; -static void -_search_win_del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - if (_current_search) - { - evas_textblock_cursor_free(_current_search); - _current_search = NULL; - } - - _search_win = NULL; + search = editor->search; + if (search) + evas_object_hide(search->widget); } EAPI void -edi_editor_search(Evas_Object *entry) +edi_editor_search(Edi_Editor *editor) { - Evas_Object *bg, *bx, *lbl, *hbx, *btn; + Edi_Editor_Search *search; - _target_entry = entry; - if (_search_win) - { - evas_object_show(_search_win); - return; - } + search = editor->search; + if (search) + evas_object_show(search->widget); +} - _search_win = elm_win_add(entry, "search", ELM_WIN_TOOLBAR); - elm_win_autodel_set(_search_win, EINA_TRUE); - elm_win_title_set(_search_win, "Search"); - evas_object_smart_callback_add(_search_win, "delete,request", _search_win_del, entry); +static void +_search_clicked(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Edi_Editor *editor; + Edi_Editor_Search *search; - bg = elm_bg_add(_search_win); - elm_win_resize_object_add(_search_win, bg); - evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_show(bg); + editor = (Edi_Editor *)data; + search = editor->search; - bx = elm_box_add(_search_win); - elm_win_resize_object_add(_search_win, bx); - evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_show(bx); + if (search) + _search_in_entry(editor->entry, search); +} - hbx = elm_box_add(_search_win); - elm_box_padding_set(hbx, 15, 0); - elm_box_horizontal_set(hbx, EINA_TRUE); - evas_object_size_hint_align_set(hbx, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_size_hint_weight_set(hbx, EVAS_HINT_EXPAND, 0.0); - evas_object_show(hbx); - elm_box_pack_end(bx, hbx); +static void +_cancel_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + _edi_editor_search_hide((Edi_Editor *)data); +} - lbl = elm_label_add(_search_win); +EAPI void +edi_editor_search_add(Evas_Object *parent, Edi_Editor *editor) +{ + Evas_Object *entry, *lbl, *btn; + Edi_Editor_Search *search; + + elm_box_padding_set(parent, 15, 0); + elm_box_horizontal_set(parent, EINA_TRUE); + + lbl = elm_label_add(parent); elm_object_text_set(lbl, "Search term:"); evas_object_size_hint_align_set(lbl, EVAS_HINT_FILL, 0.5); evas_object_size_hint_weight_set(lbl, 0.0, 0.0); - elm_box_pack_end(hbx, lbl); + elm_box_pack_end(parent, lbl); evas_object_show(lbl); - _search_entry = elm_entry_add(_search_win); - elm_entry_scrollable_set(_search_entry, EINA_TRUE); - elm_entry_single_line_set(_search_entry, EINA_TRUE); - evas_object_size_hint_align_set(_search_entry, EVAS_HINT_FILL, 0.0); - evas_object_size_hint_weight_set(_search_entry, EVAS_HINT_EXPAND, 0.0); - elm_box_pack_end(hbx, _search_entry); - evas_object_show(_search_entry); + entry = elm_entry_add(parent); + elm_entry_scrollable_set(entry, EINA_TRUE); + elm_entry_single_line_set(entry, EINA_TRUE); + evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, 0.0); + evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, 0.0); + elm_box_pack_end(parent, entry); + evas_object_show(entry); - hbx = elm_box_add(_search_win); - elm_box_homogeneous_set(hbx, EINA_FALSE); - elm_box_horizontal_set(hbx, EINA_TRUE); - evas_object_size_hint_align_set(hbx, 1.0, EVAS_HINT_FILL); - evas_object_size_hint_weight_set(hbx, 0.0, 0.0); - evas_object_show(hbx); - elm_box_pack_end(bx, hbx); - - btn = elm_button_add(_search_win); + btn = elm_button_add(parent); elm_object_text_set(btn, "Search"); evas_object_size_hint_align_set(btn, 1.0, 0.0); evas_object_size_hint_weight_set(btn, 0.0, 0.0); evas_object_show(btn); - elm_box_pack_end(hbx, btn); - evas_object_smart_callback_add(btn, "clicked", _search_clicked, entry); + elm_box_pack_end(parent, btn); + evas_object_smart_callback_add(btn, "clicked", _search_clicked, editor); - evas_object_resize(_search_win, 300 * elm_config_scale_get(), 50 * elm_config_scale_get()); - evas_object_show(_search_win); + btn = elm_button_add(parent); + elm_object_text_set(btn, "Cancel"); + evas_object_size_hint_align_set(btn, 1.0, 0.0); + evas_object_size_hint_weight_set(btn, 0.0, 0.0); + evas_object_show(btn); + elm_box_pack_end(parent, btn); + evas_object_smart_callback_add(btn, "clicked", _cancel_clicked, editor); - _current_search = NULL; + search = calloc(1, sizeof(*search)); + search->entry = entry; + search->widget = parent; + editor->search = search; } -