summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/notebook.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/notebook.c b/src/notebook.c
index 48957c9..01f7923 100644
--- a/src/notebook.c
+++ b/src/notebook.c
@@ -44,6 +44,7 @@ struct _MqNotebook {
MqTabPage *find_page;
MqTabTree *found_node;
MqTabPage *current_page;
+ GtkWidget *tab_tree_popover;
};
enum {
@@ -132,6 +133,105 @@ new_tab_clicked_cb(GtkWidget G_GNUC_UNUSED *button, MqNotebook *notebook)
}
static void
+create_tab_tree_model_recurse(MqTabTree *node, GtkTreeStore *tree_store,
+ GtkTreeIter *parent_tree_iter)
+{
+ GtkTreeIter tree_iter;
+
+ for (; node; node = MQ_TAB_TREE(mq_tree_next(node))) {
+ gtk_tree_store_append(tree_store, &tree_iter, parent_tree_iter);
+ gtk_tree_store_set(tree_store, &tree_iter, 0,
+ mq_tab_page_get_title(node->page), -1);
+ create_tab_tree_model_recurse(
+ MQ_TAB_TREE(mq_tree_first_child(node)),
+ tree_store, &tree_iter);
+ }
+}
+
+static GtkTreeModel *
+create_tab_tree_model(MqNotebook *notebook)
+{
+ GtkTreeStore *tree_store;
+
+ tree_store = gtk_tree_store_new(1, G_TYPE_STRING);
+
+ create_tab_tree_model_recurse(
+ MQ_TAB_TREE(mq_tree_first_child(notebook->tree)),
+ tree_store, NULL);
+
+ return GTK_TREE_MODEL(tree_store);
+}
+
+static void
+tab_tree_row_activated_cb(GtkTreeView G_GNUC_UNUSED *tree_view,
+ GtkTreePath *tree_path,
+ GtkTreeViewColumn G_GNUC_UNUSED *tree_view_column, MqNotebook *notebook)
+{
+ gint *indices;
+ gint depth;
+
+ indices = gtk_tree_path_get_indices_with_depth(tree_path, &depth);
+ g_assert(depth == 1);
+ mq_notebook_set_current_page(notebook, indices[0]);
+ gtk_widget_hide(notebook->tab_tree_popover);
+}
+
+static GtkWidget *
+create_tab_tree_view(MqNotebook *notebook)
+{
+ GtkTreeModel *tree_model;
+ GtkWidget *tree_view;
+ GtkTreeSelection *tree_selection;
+ GtkCellRenderer *cell_renderer;
+
+ tree_model = create_tab_tree_model(notebook);
+ tree_view = gtk_tree_view_new_with_model(tree_model);
+ tree_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
+ gtk_tree_selection_set_mode(tree_selection, GTK_SELECTION_BROWSE);
+ gtk_tree_selection_select_path(tree_selection,
+ gtk_tree_path_new_from_indices(
+ gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)),
+ -1));
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), FALSE);
+ gtk_tree_view_set_activate_on_single_click(GTK_TREE_VIEW(tree_view),
+ TRUE);
+ gtk_tree_view_expand_all(GTK_TREE_VIEW(tree_view));
+ gtk_tree_view_set_reorderable(GTK_TREE_VIEW(tree_view), TRUE);
+ gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW(tree_view), TRUE);
+ g_signal_connect(tree_view, "row-activated",
+ G_CALLBACK(tab_tree_row_activated_cb), notebook);
+
+ cell_renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree_view),
+ -1, NULL, cell_renderer, "text", 0, NULL);
+
+ return tree_view;
+}
+
+static void
+tab_list_clicked_cb(GtkWidget *button, MqNotebook *notebook)
+{
+ GtkWidget *tab_tree_view;
+ GtkWidget *scrolled_window;
+
+ tab_tree_view = create_tab_tree_view(notebook);
+
+ scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_min_content_width(
+ GTK_SCROLLED_WINDOW(scrolled_window), 400);
+ gtk_scrolled_window_set_min_content_height(
+ GTK_SCROLLED_WINDOW(scrolled_window), 200);
+ gtk_container_add(GTK_CONTAINER(scrolled_window), tab_tree_view);
+
+ notebook->tab_tree_popover = gtk_popover_new(button);
+ gtk_container_add(GTK_CONTAINER(notebook->tab_tree_popover),
+ scrolled_window);
+
+ /* NB: gtk_popover_popup() is new in GTK+ 3.22. */
+ gtk_widget_show_all(notebook->tab_tree_popover);
+}
+
+static void
mq_notebook_init(MqNotebook *notebook)
{
GtkWidget *new_tab_button;
@@ -162,6 +262,8 @@ mq_notebook_init(MqNotebook *notebook)
gtk_notebook_set_action_widget(GTK_NOTEBOOK(notebook), tab_list_button,
GTK_PACK_END);
gtk_widget_show_all(tab_list_button);
+ g_signal_connect(tab_list_button, "clicked",
+ G_CALLBACK(tab_list_clicked_cb), notebook);
g_signal_connect(notebook, "switch-page",
G_CALLBACK(switch_page_cb), NULL);