[epiphany/wip/exalm/tabs: 3/7] Bring back popover




commit 6f05f5f505c86164c93c085f9668d99f8463507f
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Wed Jan 27 22:15:41 2021 +0500

    Bring back popover
    
    (tmp, if we want this it should be in the tabs commit)

 src/ephy-page-row.c                |  34 ++++++
 src/ephy-page-row.h                |   4 +
 src/ephy-pages-popover.c           | 221 +++++++++++++++++++++++++++++++++++++
 src/ephy-pages-popover.h           |  40 +++++++
 src/ephy-pages-view.c              |   2 +
 src/ephy-pages-view.h              |   5 +-
 src/ephy-window.c                  |  34 ++++++
 src/meson.build                    |   1 +
 src/resources/gtk/page-row.ui      |   6 -
 src/resources/gtk/pages-popover.ui |   2 +-
 10 files changed, 339 insertions(+), 10 deletions(-)
---
diff --git a/src/ephy-page-row.c b/src/ephy-page-row.c
index ccb239a68..f42b37c0b 100644
--- a/src/ephy-page-row.c
+++ b/src/ephy-page-row.c
@@ -29,6 +29,7 @@
 struct _EphyPageRow {
   GtkPopover parent_instance;
 
+  GtkBox *box;
   GtkImage *icon;
   GtkStack *icon_stack;
   GtkImage *speaker_icon;
@@ -70,6 +71,7 @@ ephy_page_row_class_init (EphyPageRowClass *klass)
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/epiphany/gtk/page-row.ui");
+  gtk_widget_class_bind_template_child (widget_class, EphyPageRow, box);
   gtk_widget_class_bind_template_child (widget_class, EphyPageRow, icon);
   gtk_widget_class_bind_template_child (widget_class, EphyPageRow, icon_stack);
   gtk_widget_class_bind_template_child (widget_class, EphyPageRow, speaker_icon);
@@ -176,6 +178,38 @@ ephy_page_row_new (EphyTabView *tab_view,
   return self;
 }
 
+void
+ephy_page_row_set_adaptive_mode (EphyPageRow      *self,
+                                 EphyAdaptiveMode  adaptive_mode)
+{
+  GtkStyleContext *context;
+
+  g_assert (EPHY_IS_PAGE_ROW (self));
+
+  context = gtk_widget_get_style_context (GTK_WIDGET (self));
+
+  switch (adaptive_mode) {
+    case EPHY_ADAPTIVE_MODE_NORMAL:
+      gtk_widget_set_size_request (GTK_WIDGET (self->box), -1, -1);
+      gtk_widget_set_margin_end (GTK_WIDGET (self->box), 0);
+      gtk_widget_set_margin_start (GTK_WIDGET (self->box), 4);
+      gtk_box_set_spacing (self->box, 0);
+
+      gtk_style_context_remove_class (context, "narrow");
+
+      break;
+    case EPHY_ADAPTIVE_MODE_NARROW:
+      gtk_widget_set_size_request (GTK_WIDGET (self->box), -1, 50);
+      gtk_widget_set_margin_end (GTK_WIDGET (self->box), 4);
+      gtk_widget_set_margin_start (GTK_WIDGET (self->box), 8);
+      gtk_box_set_spacing (self->box, 4);
+
+      gtk_style_context_add_class (context, "narrow");
+
+      break;
+  }
+}
+
 HdyTabPage *
 ephy_page_row_get_page (EphyPageRow *self)
 {
diff --git a/src/ephy-page-row.h b/src/ephy-page-row.h
index 6369359d7..bff823af3 100644
--- a/src/ephy-page-row.h
+++ b/src/ephy-page-row.h
@@ -22,6 +22,7 @@
 #pragma once
 
 #include <handy.h>
+#include "ephy-adaptive-mode.h"
 #include "ephy-tab-view.h"
 
 G_BEGIN_DECLS
@@ -33,6 +34,9 @@ G_DECLARE_FINAL_TYPE (EphyPageRow, ephy_page_row, EPHY, PAGE_ROW, GtkListBoxRow)
 EphyPageRow *ephy_page_row_new (EphyTabView *view,
                                 HdyTabPage  *page);
 
+void ephy_page_row_set_adaptive_mode (EphyPageRow      *self,
+                                      EphyAdaptiveMode  adaptive_mode);
+
 HdyTabPage *ephy_page_row_get_page (EphyPageRow *self);
 
 G_END_DECLS
diff --git a/src/ephy-pages-popover.c b/src/ephy-pages-popover.c
new file mode 100644
index 000000000..045e7cf09
--- /dev/null
+++ b/src/ephy-pages-popover.c
@@ -0,0 +1,221 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2019 Purism SPC
+ *  Copyright © 2019 Adrien Plazas <kekun plazas laposte net>
+ *
+ *  This file is part of Epiphany.
+ *
+ *  Epiphany is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Epiphany is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Epiphany.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "ephy-pages-popover.h"
+
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+
+#include "ephy-page-row.h"
+#include "ephy-window.h"
+
+struct _EphyPagesPopover {
+  GtkPopover parent_instance;
+
+  GtkListBox *list_box;
+  GtkScrolledWindow *scrolled_window;
+
+  GListModel *model;
+  EphyTabView *tab_view;
+};
+
+G_DEFINE_TYPE (EphyPagesPopover, ephy_pages_popover, GTK_TYPE_POPOVER)
+
+static void
+drop_tab_view (EphyPagesPopover *self)
+{
+  self->tab_view = NULL;
+}
+
+static void
+release_tab_view (EphyPagesPopover *self)
+{
+  if (self->tab_view) {
+    g_object_weak_unref (G_OBJECT (self->tab_view), (GWeakNotify)drop_tab_view, self);
+    drop_tab_view (self);
+  }
+}
+
+static void
+row_activated_cb (EphyPagesPopover *self,
+                  EphyPageRow      *row)
+{
+  EphyWindow *window;
+  GApplication *application;
+  HdyTabPage *page;
+
+  g_assert (EPHY_IS_PAGES_POPOVER (self));
+  g_assert (EPHY_IS_PAGE_ROW (row));
+
+  application = g_application_get_default ();
+  window = EPHY_WINDOW (gtk_application_get_active_window (GTK_APPLICATION (application)));
+  page = ephy_page_row_get_page (EPHY_PAGE_ROW (row));
+
+  hdy_tab_view_set_selected_page (ephy_tab_view_get_tab_view (self->tab_view), page);
+  ephy_window_close_pages_view (window);
+
+  gtk_popover_popdown (GTK_POPOVER (self));
+}
+
+static GtkWidget *
+create_row (HdyTabPage    *page,
+            EphyPagesPopover *self)
+{
+  EphyPageRow *row = ephy_page_row_new (self->tab_view, page);
+
+  ephy_page_row_set_adaptive_mode (row, EPHY_ADAPTIVE_MODE_NORMAL);
+
+  gtk_widget_show (GTK_WIDGET (row));
+
+  return GTK_WIDGET (row);
+}
+
+static void
+selected_page_changed_cb (HdyTabView       *tab_view,
+                          GParamSpec       *pspec,
+                          EphyPagesPopover *self)
+{
+  HdyTabPage *page = hdy_tab_view_get_selected_page (tab_view);
+  gint position;
+  GtkListBoxRow *row;
+
+  if (!page) {
+    gtk_list_box_unselect_all (self->list_box);
+
+    return;
+  }
+
+  position = hdy_tab_view_get_page_position (tab_view, page);
+  row = gtk_list_box_get_row_at_index (self->list_box, position);
+  gtk_list_box_select_row (self->list_box, row);
+}
+
+static void
+ephy_pages_popover_dispose (GObject *object)
+{
+  EphyPagesPopover *self = EPHY_PAGES_POPOVER (object);
+
+  release_tab_view (self);
+
+  G_OBJECT_CLASS (ephy_pages_popover_parent_class)->dispose (object);
+}
+
+#ifdef GDK_WINDOWING_X11
+static void
+ephy_pages_popover_get_preferred_height (GtkWidget *widget,
+                                         gint      *minimum_height,
+                                         gint      *natural_height)
+{
+  EphyPagesPopover *self = EPHY_PAGES_POPOVER (widget);
+  int height;
+
+  GTK_WIDGET_CLASS (ephy_pages_popover_parent_class)->get_preferred_height (widget,
+                                                                            minimum_height,
+                                                                            natural_height);
+  /* Ensure that popover won't leave current window */
+  height = gtk_widget_get_allocated_height (GTK_WIDGET (self->tab_view));
+  gtk_scrolled_window_set_max_content_height (self->scrolled_window, height);
+}
+
+static GtkSizeRequestMode
+ephy_pages_popover_get_request_mode (GtkWidget *widget)
+{
+  return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
+}
+#endif
+
+static void
+ephy_pages_popover_class_init (EphyPagesPopoverClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->dispose = ephy_pages_popover_dispose;
+
+#ifdef GDK_WINDOWING_X11
+  if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) {
+    widget_class->get_request_mode = ephy_pages_popover_get_request_mode;
+    widget_class->get_preferred_height = ephy_pages_popover_get_preferred_height;
+  }
+#endif
+
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/epiphany/gtk/pages-popover.ui");
+  gtk_widget_class_bind_template_child (widget_class, EphyPagesPopover, list_box);
+  gtk_widget_class_bind_template_child (widget_class, EphyPagesPopover, scrolled_window);
+  gtk_widget_class_bind_template_callback (widget_class, row_activated_cb);
+}
+
+static void
+ephy_pages_popover_init (EphyPagesPopover *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+EphyPagesPopover *
+ephy_pages_popover_new (GtkWidget *relative_to)
+{
+  g_assert (!relative_to || GTK_IS_WIDGET (relative_to));
+
+  return g_object_new (EPHY_TYPE_PAGES_POPOVER,
+                       "relative-to", relative_to,
+                       NULL);
+}
+
+EphyTabView *
+ephy_pages_popover_get_tab_view (EphyPagesPopover *self)
+{
+  g_assert (EPHY_IS_PAGES_POPOVER (self));
+
+  return self->tab_view;
+}
+
+void
+ephy_pages_popover_set_tab_view (EphyPagesPopover *self,
+                                 EphyTabView      *tab_view)
+{
+  g_assert (EPHY_IS_PAGES_POPOVER (self));
+
+  if (self->tab_view)
+    release_tab_view (self);
+
+  if (!tab_view)
+    return;
+
+  g_object_weak_ref (G_OBJECT (tab_view), (GWeakNotify)drop_tab_view, self);
+  self->tab_view = tab_view;
+
+  self->model = hdy_tab_view_get_pages (ephy_tab_view_get_tab_view (tab_view));
+
+  gtk_list_box_bind_model (self->list_box,
+                           self->model,
+                           (GtkListBoxCreateWidgetFunc)create_row,
+                           self,
+                           NULL);
+
+  g_signal_connect_object (ephy_tab_view_get_tab_view (tab_view),
+                           "notify::selected-page",
+                           G_CALLBACK (selected_page_changed_cb),
+                           self,
+                           0);
+}
diff --git a/src/ephy-pages-popover.h b/src/ephy-pages-popover.h
new file mode 100644
index 000000000..1c148d403
--- /dev/null
+++ b/src/ephy-pages-popover.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2019 Purism SPC
+ *  Copyright © 2019 Adrien Plazas <kekun plazas laposte net>
+ *
+ *  This file is part of Epiphany.
+ *
+ *  Epiphany is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Epiphany is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Epiphany.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+#include "ephy-tab-view.h"
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_PAGES_POPOVER (ephy_pages_popover_get_type())
+
+G_DECLARE_FINAL_TYPE (EphyPagesPopover, ephy_pages_popover, EPHY, PAGES_POPOVER, GtkPopover)
+
+EphyPagesPopover *ephy_pages_popover_new (GtkWidget *relative_to);
+
+EphyTabView *ephy_pages_popover_get_tab_view (EphyPagesPopover *self);
+void         ephy_pages_popover_set_tab_view (EphyPagesPopover *self,
+                                              EphyTabView      *tab_view);
+
+G_END_DECLS
diff --git a/src/ephy-pages-view.c b/src/ephy-pages-view.c
index 87a334b84..c0d1936f8 100644
--- a/src/ephy-pages-view.c
+++ b/src/ephy-pages-view.c
@@ -78,6 +78,8 @@ create_row (HdyTabPage    *page,
 {
   EphyPageRow *row = ephy_page_row_new (self->tab_view, page);
 
+  ephy_page_row_set_adaptive_mode (row, EPHY_ADAPTIVE_MODE_NARROW);
+
   gtk_widget_show (GTK_WIDGET (row));
 
   return GTK_WIDGET (row);
diff --git a/src/ephy-pages-view.h b/src/ephy-pages-view.h
index 6c05b0a7a..0ad828b35 100644
--- a/src/ephy-pages-view.h
+++ b/src/ephy-pages-view.h
@@ -22,7 +22,6 @@
 
 #include <gtk/gtk.h>
 
-#include "ephy-adaptive-mode.h"
 #include "ephy-tab-view.h"
 
 G_BEGIN_DECLS
@@ -33,8 +32,8 @@ G_DECLARE_FINAL_TYPE (EphyPagesView, ephy_pages_view, EPHY, PAGES_VIEW, GtkBox)
 
 EphyPagesView *ephy_pages_view_new               (void);
 
-EphyTabView   *ephy_pages_view_get_tab_view      (EphyPagesView *view);
-void           ephy_pages_view_set_tab_view      (EphyPagesView *view,
+EphyTabView   *ephy_pages_view_get_tab_view      (EphyPagesView *self);
+void           ephy_pages_view_set_tab_view      (EphyPagesView *self,
                                                   EphyTabView   *tab_view);
 
 G_END_DECLS
diff --git a/src/ephy-window.c b/src/ephy-window.c
index eb0bbcd94..daf8f246e 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -45,6 +45,7 @@
 #include "ephy-link.h"
 #include "ephy-location-entry.h"
 #include "ephy-mouse-gesture-controller.h"
+#include "ephy-pages-popover.h"
 #include "ephy-pages-view.h"
 #include "ephy-permissions-manager.h"
 #include "ephy-prefs.h"
@@ -3411,6 +3412,37 @@ setup_header_bar (EphyWindow *window)
   return header_bar;
 }
 
+static void
+setup_tabs_menu (EphyWindow *window)
+{
+  GtkWidget *revealer;
+  GtkWidget *menu_button;
+  EphyPagesPopover *popover;
+
+  revealer = gtk_revealer_new ();
+  gtk_revealer_set_transition_type (GTK_REVEALER (revealer),
+                                    GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT);
+  hdy_tab_bar_set_end_action_widget (window->tab_bar, revealer);
+
+  menu_button = gtk_menu_button_new ();
+  gtk_button_set_relief (GTK_BUTTON (menu_button), GTK_RELIEF_NONE);
+  /* Translators: tooltip for the tab switcher menu button */
+  gtk_widget_set_tooltip_text (menu_button, _("View open tabs"));
+  gtk_widget_set_margin_start (menu_button, 1);
+  gtk_container_add (GTK_CONTAINER (revealer), menu_button);
+
+  popover = ephy_pages_popover_new (menu_button);
+  ephy_pages_popover_set_tab_view (popover, window->tab_view);
+  gtk_menu_button_set_popover (GTK_MENU_BUTTON (menu_button),
+                               GTK_WIDGET (popover));
+
+  g_object_bind_property (window->tab_bar, "is-overflowing",
+                          revealer, "reveal-child",
+                          G_BINDING_SYNC_CREATE);
+
+  gtk_widget_show_all (revealer);
+}
+
 static EphyLocationController *
 setup_location_controller (EphyWindow    *window,
                            EphyHeaderBar *header_bar)
@@ -3683,6 +3715,8 @@ ephy_window_constructed (GObject *object)
   hdy_tab_bar_set_view (window->tab_bar, ephy_tab_view_get_tab_view (window->tab_view));
   ephy_pages_view_set_tab_view (window->pages_view, window->tab_view);
 
+  setup_tabs_menu (window);
+
   shell = ephy_shell_get_default ();
   mode = ephy_embed_shell_get_mode (EPHY_EMBED_SHELL (shell));
 
diff --git a/src/meson.build b/src/meson.build
index f3d82d88b..fa2318567 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -38,6 +38,7 @@ libephymain_sources = [
   'ephy-mouse-gesture-controller.c',
   'ephy-page-row.c',
   'ephy-pages-button.c',
+  'ephy-pages-popover.c',
   'ephy-pages-view.c',
   'ephy-session.c',
   'ephy-shell.c',
diff --git a/src/resources/gtk/page-row.ui b/src/resources/gtk/page-row.ui
index 8e95a71a7..cf458bf1f 100644
--- a/src/resources/gtk/page-row.ui
+++ b/src/resources/gtk/page-row.ui
@@ -4,9 +4,6 @@
   <requires lib="gtk+" version="3.16"/>
   <template class="EphyPageRow" parent="GtkListBoxRow">
     <property name="can_focus">True</property>
-    <style>
-      <class name="narrow"/>
-    </style>
     <child>
       <object class="GtkEventBox">
         <property name="visible">True</property>
@@ -16,9 +13,6 @@
           <object class="GtkBox" id="box">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="height-request">50</property>
-            <property name="margin-start">8</property>
-            <property name="margin-end">4</property>
             <child>
               <object class="GtkStack" id="icon_stack">
                 <property name="visible">True</property>
diff --git a/src/resources/gtk/pages-popover.ui b/src/resources/gtk/pages-popover.ui
index 219ec5dcd..4a052da20 100644
--- a/src/resources/gtk/pages-popover.ui
+++ b/src/resources/gtk/pages-popover.ui
@@ -17,7 +17,7 @@
             <property name="selection_mode">single</property>
             <property name="visible">True</property>
             <property name="width_request">300</property>
-            <signal name="row-selected" handler="row_selected_cb" swapped="true"/>
+            <signal name="row-activated" handler="row_activated_cb" swapped="true"/>
             <style>
               <class name="transparent"/>
             </style>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]