From 8c3d69509ecdae0b62f895cf99fb04259a407625 Mon Sep 17 00:00:00 2001 From: Patrick McDermott Date: Mon, 23 Oct 2017 16:05:27 -0400 Subject: MqNotebook: Add tab tree popover --- 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); -- cgit v0.9.1