[gtk/global-coords: 22/24] menu: Keep selected item in view



commit e599336ad4551763699b0495758e600693ad3c58
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri May 31 20:29:30 2019 +0000

    menu: Keep selected item in view
    
    This gets us most of the way to working scrolling.

 gtk/gtkmenu.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
---
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index fe69fc88cf..2f240edbf5 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -172,6 +172,7 @@ static void     gtk_menu_get_property      (GObject          *object,
                                             GParamSpec       *pspec);
 static void     gtk_menu_finalize          (GObject          *object);
 static void     gtk_menu_destroy           (GtkWidget        *widget);
+static void     gtk_menu_realize           (GtkWidget        *widget);
 static void     gtk_menu_unrealize         (GtkWidget        *widget);
 static void     gtk_menu_size_allocate     (GtkWidget        *widget,
                                             int               widget_width,
@@ -184,6 +185,10 @@ static void     gtk_menu_motion            (GtkEventController *controller,
                                             gpointer            user_data);
 static void     gtk_menu_grab_notify       (GtkWidget        *widget,
                                             gboolean          was_grabbed);
+static void     gtk_menu_scroll_item_visible (GtkMenuShell    *menu_shell,
+                                              GtkWidget       *menu_item);
+static void     gtk_menu_select_item       (GtkMenuShell     *menu_shell,
+                                            GtkWidget        *menu_item);
 static void     gtk_menu_real_insert       (GtkMenuShell     *menu_shell,
                                             GtkWidget        *child,
                                             gint              position);
@@ -263,6 +268,7 @@ gtk_menu_class_init (GtkMenuClass *class)
   gobject_class->finalize = gtk_menu_finalize;
 
   widget_class->destroy = gtk_menu_destroy;
+  widget_class->realize = gtk_menu_realize;
   widget_class->unrealize = gtk_menu_unrealize;
   widget_class->size_allocate = gtk_menu_size_allocate;
   widget_class->show = gtk_menu_show;
@@ -276,6 +282,7 @@ gtk_menu_class_init (GtkMenuClass *class)
 
   menu_shell_class->submenu_placement = GTK_LEFT_RIGHT;
   menu_shell_class->deactivate = gtk_menu_deactivate;
+  menu_shell_class->select_item = gtk_menu_select_item;
   menu_shell_class->insert = gtk_menu_real_insert;
   menu_shell_class->get_popup_delay = gtk_menu_get_popup_delay;
   menu_shell_class->move_current = gtk_menu_move_current;
@@ -1932,6 +1939,16 @@ gtk_menu_reorder_child (GtkMenu   *menu,
   gtk_box_reorder_child_after (GTK_BOX (menu->priv->box), child, sibling);
 }
 
+static void
+gtk_menu_realize (GtkWidget *widget)
+{
+  GTK_WIDGET_CLASS (gtk_menu_parent_class)->realize (widget);
+
+  if (GTK_MENU_SHELL (widget)->priv->active_menu_item)
+    gtk_menu_scroll_item_visible (GTK_MENU_SHELL (widget),
+                                  GTK_MENU_SHELL (widget)->priv->active_menu_item);
+}
+
 static gboolean
 gtk_menu_focus (GtkWidget       *widget,
                 GtkDirectionType direction)
@@ -2353,6 +2370,40 @@ gtk_menu_position (GtkMenu *menu)
                            rect_anchor_dy);
 }
 
+static void
+gtk_menu_scroll_item_visible (GtkMenuShell *menu_shell,
+                              GtkWidget    *menu_item)
+{
+  GtkMenu *menu = GTK_MENU (menu_shell);
+  GtkMenuPrivate *priv = menu->priv;
+  graphene_rect_t rect;
+  GtkAdjustment *adj;
+  double value, page;
+
+  gtk_widget_compute_bounds (menu_item, priv->box, &rect);
+
+  adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->swin));
+
+  page = gtk_adjustment_get_page_size (adj);
+  value = gtk_adjustment_get_value (adj);
+
+  if (rect.origin.y + rect.size.height > value + page)
+    gtk_adjustment_set_value (adj, rect.origin.y + rect.size.height - page);
+  else if (rect.origin.y < value)
+    gtk_adjustment_set_value (adj, rect.origin.y);
+}
+
+static void
+gtk_menu_select_item (GtkMenuShell *menu_shell,
+                      GtkWidget    *menu_item)
+{
+  GtkMenu *menu = GTK_MENU (menu_shell);
+
+  if (gtk_widget_get_realized (GTK_WIDGET (menu)))
+    gtk_menu_scroll_item_visible (menu_shell, menu_item);
+
+  GTK_MENU_SHELL_CLASS (gtk_menu_parent_class)->select_item (menu_shell, menu_item);
+}
 
 static gint
 gtk_menu_get_popup_delay (GtkMenuShell *menu_shell)


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