mainview: Add support for split-panes.

This adds the ability to edit multiple regions of the same
file at the same time. The views are synchronised. This
also adds a complementary function allowing us to get panel
from path name. We use this for focus sanity with our
additional split views.
This commit is contained in:
Al Poole 2017-10-10 23:29:17 +01:00
parent 3908d27b67
commit 7a5083c790
6 changed files with 133 additions and 1 deletions

View File

@ -953,6 +953,13 @@ _edi_menu_view_open_window_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUS
edi_mainview_new_window();
}
static void
_edi_menu_view_split_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
edi_mainview_split_current();
}
static void
_edi_menu_view_new_panel_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
@ -1165,6 +1172,7 @@ _edi_menu_setup(Evas_Object *win)
menu_it = elm_menu_item_add(menu, NULL, NULL, _("View"), NULL, NULL);
elm_menu_item_add(menu, menu_it, "window-new", _("New Window"), _edi_menu_view_open_window_cb, NULL);
elm_menu_item_add(menu, menu_it, "object-flip-horizontal", _("New Panel"), _edi_menu_view_new_panel_cb, NULL);
elm_menu_item_add(menu, menu_it, "object-flip-vertical", _("Split View"), _edi_menu_view_split_cb, NULL);
elm_menu_item_separator_add(menu, menu_it);
elm_menu_item_add(menu, menu_it, "edit-find", _("Open Tasks"), _edi_menu_view_tasks_cb, NULL);

View File

@ -1317,6 +1317,12 @@ _edi_editor_config_changed(void *data, int type EINA_UNUSED, void *event EINA_UN
return ECORE_CALLBACK_RENEW;
}
void
edi_editor_widget_config_get(Elm_Code_Widget *widget)
{
_edi_editor_config_changed(widget, 0, NULL);
}
static void
_editor_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *o, void *event_info EINA_UNUSED)
{

View File

@ -144,6 +144,17 @@ void edi_editor_save(Edi_Editor *editor);
*/
void edi_editor_doc_open(Edi_Editor *editor);
/**
* Get global configuration values for code editor and
* apply them to an Elm_Code_Widget instance.
*
* @param widget The Elm_Code_Widget obj to update.
*
* @ingroup Widgets
*/
void edi_editor_widget_config_get(Elm_Code_Widget *widget);
/**
* @}
*/

View File

@ -100,6 +100,27 @@ edi_mainview_panel_for_item_get(Edi_Mainview_Item *item)
return NULL;
}
Edi_Mainview_Panel *
edi_mainview_panel_for_path_get(const char *path)
{
Eina_List *item;
Edi_Mainview_Panel *panel;
Edi_Mainview_Item *it;
int i;
for (i = 0; i < edi_mainview_panel_count(); i++)
{
panel = edi_mainview_panel_by_index(i);
EINA_LIST_FOREACH(panel->items, item, it)
{
if (it && !strcmp(it->path, path))
return panel;
}
}
return NULL;
}
unsigned int
edi_mainview_panel_index_get(Edi_Mainview_Panel *panel)
{
@ -259,6 +280,62 @@ edi_mainview_open_path(const char *path)
edi_mainview_panel_open_path(_current_panel, path);
}
static void
_focused_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Elm_Code *code;
const char *path;
Edi_Mainview_Panel *panel;
Edi_Editor *editor = data;
code = elm_code_widget_code_get(editor->entry);
path = elm_code_file_path_get(code->file);
panel = edi_mainview_panel_for_path_get(path);
edi_mainview_panel_focus(panel);
}
static void
_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Edi_Editor *editor = data;
editor->modified = EINA_TRUE;
ecore_event_add(EDI_EVENT_FILE_CHANGED, NULL, NULL, NULL);
}
void edi_mainview_split_current(void)
{
Elm_Code *code;
Elm_Code_Widget *widget;
Edi_Editor *editor;
Edi_Mainview_Panel *panel;
if (edi_mainview_is_empty())
return;
panel = edi_mainview_panel_current_get();
edi_mainview_panel_focus(panel);
editor = evas_object_data_get(panel->current->view, "editor");
if (!editor)
return;
code = elm_code_widget_code_get(editor->entry);
widget = elm_code_widget_add(panel->content, code);
elm_code_widget_editable_set(widget, EINA_TRUE);
elm_code_widget_line_numbers_set(widget, EINA_TRUE);
evas_object_smart_callback_add(widget, "changed,user", _changed_cb, editor);
evas_object_smart_callback_add(widget, "focused", _focused_cb, editor);
edi_editor_widget_config_get(widget);
evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(widget);
elm_box_pack_start(panel->current->container, widget);
}
void
edi_mainview_open(Edi_Path_Options *options)
{

View File

@ -104,6 +104,14 @@ void edi_mainview_open(Edi_Path_Options *options);
*/
void edi_mainview_open_window_path(const char *path);
/**
* Open editable split view with the currently selected item.
*
* @ingroup Content
*/
void edi_mainview_split_current(void);
/**
* Open the file described in the provided options in a new window - path and location etc.
*
@ -334,6 +342,16 @@ Edi_Mainview_Panel *edi_mainview_panel_append();
*/
Edi_Mainview_Panel *edi_mainview_panel_for_item_get(Edi_Mainview_Item *item);
/*
* Return panel object from path.
*
* @param path the item path related to the returned panel.
* @return the mainview panel object associated with the path.
*
* @ingroup Panels
*/
Edi_Mainview_Panel *edi_mainview_panel_for_path_get(const char *path);
/*
* Return panel object from it's numeric index.
*

View File

@ -667,8 +667,20 @@ void
edi_mainview_panel_goto_popup_show(Edi_Mainview_Panel *panel)
{
Evas_Object *popup, *box, *input, *sep, *button;
Edi_Editor *editor;
if (edi_mainview_is_empty())
return;
if (!edi_mainview_panel_item_count(edi_mainview_panel_current_get()))
return;
editor = evas_object_data_get(panel->current->view, "editor");
if (!editor)
return;
popup = elm_popup_add(editor->entry);
popup = elm_popup_add(_main_win);
_edi_mainview_goto_popup = popup;
elm_object_part_text_set(popup, "title,text",
_("Enter line number"));