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.
This commit is contained in:
Andy Williams 2030-07-12 21:12:05 +01:00
parent 21a5f2b1b4
commit a25b043761
4 changed files with 111 additions and 84 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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);
/**
* @}

View File

@ -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;
}