]> git.sur5r.net Git - glabels/commitdiff
Improved menu positioning functions
authorJim Evins <evins@snaught.com>
Tue, 27 Oct 2009 00:12:06 +0000 (20:12 -0400)
committerJim Evins <evins@snaught.com>
Tue, 27 Oct 2009 00:12:06 +0000 (20:12 -0400)
Use requisition instead of allocation for menu size (the allocation does not
exist for a newly realized menu, so the position is not always right the
first time it is popped up, causing a mangled menu position with ugly
scroll buttons.)

Query for the actual screen of "this" instead of blindly using the default
screen.

src/color-combo-button.c
src/color-combo.c
src/field-button.c
src/font-combo.c

index 1c83ac8248dacb54d14606053c2a9d87e3cb69be..3593275a186147e9e5f81dbe937fd103c9137689 100644 (file)
@@ -296,41 +296,77 @@ button_clicked_cb( glColorComboButton *this )
 /* Menu positioning function.                                                */
 /*****************************************************************************/
 static void
-menu_position_function (GtkMenu  *menu,
-                        gint     *x,
-                        gint     *y,
-                        gboolean *push_in,
-                        gpointer  user_data)
+menu_position_function (GtkMenu            *menu,
+                        gint               *x,
+                        gint               *y,
+                        gboolean           *push_in,
+                        glColorComboButton *this)
 {
-        glColorComboButton *this = GL_COLOR_COMBO_BUTTON (user_data);
+        GdkScreen          *screen;
+        gint                w_screen, h_screen;
         GdkWindow          *window;
-        gint                x1, y1;
-        gint                menu_h, menu_w;
-
+        gint                x_window, y_window;
+        GtkAllocation      *allocation;
+        gint                x_this, y_this, h_this;
+        GtkRequisition      menu_requisition;
+        gint                h_menu, w_menu;
+
+        /*
+         * Screen size
+         */
+        screen = gtk_widget_get_screen (GTK_WIDGET (this));
+        w_screen = gdk_screen_get_width (screen);
+        h_screen = gdk_screen_get_height (screen);
+
+        /*
+         * Absolute position of "this" window on screen.
+         */
         window = gtk_widget_get_window (GTK_WIDGET (this));
-
-        gdk_window_get_origin (window, &x1, &y1);
-        *x = x1 + GTK_WIDGET (this)->allocation.x;
-        *y = y1 + GTK_WIDGET (this)->allocation.y +
-                GTK_WIDGET (this)->allocation.height;
+        gdk_window_get_origin (window, &x_window, &y_window);
+
+        /*
+         *  Position and size of "this" inside window
+         */
+        allocation = &GTK_WIDGET (this)->allocation;
+        x_this = allocation->x;
+        y_this = allocation->y;
+        h_this = allocation->height;
+
+        /*
+         * Size of menu.
+         */
+        gtk_widget_size_request (this->priv->menu, &menu_requisition);
+        h_menu = menu_requisition.height;
+        w_menu = menu_requisition.width;
+
+        /*
+         * Default position anchored to lower left corner of "this".
+         */
+        *x = x_window + x_this;
+        *y = y_window + y_this + h_this;
                 
-        menu_h = this->priv->menu->allocation.height;
-        menu_w = this->priv->menu->allocation.width;
-
-        if ((*y + menu_h) > gdk_screen_height ())
+        /*
+         * Adjust vertical position if menu if extends past bottom of screen.
+         */
+        if ( (*y + h_menu) > h_screen )
         {
-                *y = y1 + GTK_WIDGET (this)->allocation.y - menu_h;
+                *y = y_window + y_this - h_menu;
+
                 if ( *y < 0 )
                 {
-                        *y = gdk_screen_height () - menu_h;
+                        *y = h_screen - h_menu;
                 }
         }
 
-        if ((*x + menu_w) > gdk_screen_width ())
+        /*
+         * Adjust horizontal position if menu if extends past edge of screen.
+         */
+        if ( (*x + w_menu) > w_screen )
         {
-                *x = gdk_screen_width () - menu_w;
+                *x = w_screen - w_menu;
         }
 
+
         *push_in = TRUE;
 }
 
@@ -358,7 +394,7 @@ dropdown_button_press_event_cb (GtkWidget          *widget,
 
                 gtk_menu_popup (GTK_MENU (this->priv->menu),
                                 NULL, NULL,
-                                menu_position_function, this,
+                                (GtkMenuPositionFunc)menu_position_function, this,
                                 event->button, event->time);
                 break;
 
index a5e99d2211198c20eec131e6fa9c451bbcb70b6c..0334efdc15083fb9e836086020e936bf385b682c 100644 (file)
@@ -238,41 +238,77 @@ gl_color_combo_get_color (glColorCombo  *this,
 /* Menu positioning function.                                                */
 /*****************************************************************************/
 static void
-menu_position_function (GtkMenu  *menu,
-                        gint     *x,
-                        gint     *y,
-                        gboolean *push_in,
-                        gpointer  user_data)
+menu_position_function (GtkMenu       *menu,
+                        gint          *x,
+                        gint          *y,
+                        gboolean      *push_in,
+                        glColorCombo  *this)
 {
-        glColorCombo *this = GL_COLOR_COMBO (user_data);
-        GdkWindow    *window;
-        gint          x1, y1;
-        gint          menu_h, menu_w;
-
+        GdkScreen          *screen;
+        gint                w_screen, h_screen;
+        GdkWindow          *window;
+        gint                x_window, y_window;
+        GtkAllocation      *allocation;
+        gint                x_this, y_this, h_this;
+        GtkRequisition      menu_requisition;
+        gint                h_menu, w_menu;
+
+        /*
+         * Screen size
+         */
+        screen = gtk_widget_get_screen (GTK_WIDGET (this));
+        w_screen = gdk_screen_get_width (screen);
+        h_screen = gdk_screen_get_height (screen);
+
+        /*
+         * Absolute position of "this" window on screen.
+         */
         window = gtk_widget_get_window (GTK_WIDGET (this));
-
-        gdk_window_get_origin (window, &x1, &y1);
-        *x = x1 + GTK_WIDGET (this)->allocation.x;
-        *y = y1 + GTK_WIDGET (this)->allocation.y +
-                GTK_WIDGET (this)->allocation.height;
+        gdk_window_get_origin (window, &x_window, &y_window);
+
+        /*
+         *  Position and size of "this" inside window
+         */
+        allocation = &GTK_WIDGET (this)->allocation;
+        x_this = allocation->x;
+        y_this = allocation->y;
+        h_this = allocation->height;
+
+        /*
+         * Size of menu.
+         */
+        gtk_widget_size_request (this->priv->menu, &menu_requisition);
+        h_menu = menu_requisition.height;
+        w_menu = menu_requisition.width;
+
+        /*
+         * Default position anchored to lower left corner of "this".
+         */
+        *x = x_window + x_this;
+        *y = y_window + y_this + h_this;
                 
-        menu_h = this->priv->menu->allocation.height;
-        menu_w = this->priv->menu->allocation.width;
-
-        if ((*y + menu_h) > gdk_screen_height ())
+        /*
+         * Adjust vertical position if menu if extends past bottom of screen.
+         */
+        if ( (*y + h_menu) > h_screen )
         {
-                *y = y1 + GTK_WIDGET (this)->allocation.y - menu_h;
+                *y = y_window + y_this - h_menu;
+
                 if ( *y < 0 )
                 {
-                        *y = gdk_screen_height () - menu_h;
+                        *y = h_screen - h_menu;
                 }
         }
 
-        if ((*x + menu_w) > gdk_screen_width ())
+        /*
+         * Adjust horizontal position if menu if extends past edge of screen.
+         */
+        if ( (*x + w_menu) > w_screen )
         {
-                *x = gdk_screen_width () - menu_w;
+                *x = w_screen - w_menu;
         }
 
+
         *push_in = TRUE;
 }
 
@@ -293,7 +329,7 @@ button_press_event_cb (GtkWidget      *widget,
 
                 gtk_menu_popup (GTK_MENU (this->priv->menu),
                                 NULL, NULL,
-                                menu_position_function, this,
+                                (GtkMenuPositionFunc)menu_position_function, this,
                                 event->button, event->time);
                 break;
 
index a2892728528f3fc6d158bbb7348d91c0576d87e3..4000d41beec0b281d57a5e9fdc9584b84017dd0b 100644 (file)
@@ -192,41 +192,77 @@ gl_field_button_set_keys (glFieldButton  *this,
 /* Menu positioning function.                                                */
 /*****************************************************************************/
 static void
-menu_position_function (GtkMenu  *menu,
-                        gint     *x,
-                        gint     *y,
-                        gboolean *push_in,
-                        gpointer  user_data)
+menu_position_function (GtkMenu       *menu,
+                        gint          *x,
+                        gint          *y,
+                        gboolean      *push_in,
+                        glFieldButton *this)
 {
-        glFieldButton  *this = GL_FIELD_BUTTON (user_data);
-        GdkWindow      *window;
-        gint            x1, y1;
-        gint            menu_h, menu_w;
-
+        GdkScreen          *screen;
+        gint                w_screen, h_screen;
+        GdkWindow          *window;
+        gint                x_window, y_window;
+        GtkAllocation      *allocation;
+        gint                x_this, y_this, h_this;
+        GtkRequisition      menu_requisition;
+        gint                h_menu, w_menu;
+
+        /*
+         * Screen size
+         */
+        screen = gtk_widget_get_screen (GTK_WIDGET (this));
+        w_screen = gdk_screen_get_width (screen);
+        h_screen = gdk_screen_get_height (screen);
+
+        /*
+         * Absolute position of "this" window on screen.
+         */
         window = gtk_widget_get_window (GTK_WIDGET (this));
-
-        gdk_window_get_origin (window, &x1, &y1);
-        *x = x1 + GTK_WIDGET (this)->allocation.x;
-        *y = y1 + GTK_WIDGET (this)->allocation.y +
-                GTK_WIDGET (this)->allocation.height;
+        gdk_window_get_origin (window, &x_window, &y_window);
+
+        /*
+         *  Position and size of "this" inside window
+         */
+        allocation = &GTK_WIDGET (this)->allocation;
+        x_this = allocation->x;
+        y_this = allocation->y;
+        h_this = allocation->height;
+
+        /*
+         * Size of menu.
+         */
+        gtk_widget_size_request (this->priv->menu, &menu_requisition);
+        h_menu = menu_requisition.height;
+        w_menu = menu_requisition.width;
+
+        /*
+         * Default position anchored to lower left corner of "this".
+         */
+        *x = x_window + x_this;
+        *y = y_window + y_this + h_this;
                 
-        menu_h = this->priv->menu->allocation.height;
-        menu_w = this->priv->menu->allocation.width;
-
-        if ((*y + menu_h) > gdk_screen_height ())
+        /*
+         * Adjust vertical position if menu if extends past bottom of screen.
+         */
+        if ( (*y + h_menu) > h_screen )
         {
-                *y = y1 + GTK_WIDGET (this)->allocation.y - menu_h;
+                *y = y_window + y_this - h_menu;
+
                 if ( *y < 0 )
                 {
-                        *y = gdk_screen_height () - menu_h;
+                        *y = h_screen - h_menu;
                 }
         }
 
-        if ((*x + menu_w) > gdk_screen_width ())
+        /*
+         * Adjust horizontal position if menu if extends past edge of screen.
+         */
+        if ( (*x + w_menu) > w_screen )
         {
-                *x = gdk_screen_width () - menu_w;
+                *x = w_screen - w_menu;
         }
 
+
         *push_in = TRUE;
 }
 
@@ -247,7 +283,7 @@ button_press_event_cb (GtkWidget      *widget,
 
                 gtk_menu_popup (GTK_MENU (this->priv->menu),
                                 NULL, NULL,
-                                menu_position_function, this,
+                                (GtkMenuPositionFunc)menu_position_function, this,
                                 event->button, event->time);
                 break;
 
index d094497d89dc06ea41fce89b79f1455c71ec0a7c..49b0d7ee36c11d18e18c5e31a507180b40f9315b 100644 (file)
@@ -219,41 +219,77 @@ gl_font_combo_get_family (glFontCombo  *this)
 /* Menu positioning function.                                                */
 /*****************************************************************************/
 static void
-menu_position_function (GtkMenu  *menu,
-                        gint     *x,
-                        gint     *y,
-                        gboolean *push_in,
-                        gpointer  user_data)
+menu_position_function (GtkMenu      *menu,
+                        gint         *x,
+                        gint         *y,
+                        gboolean     *push_in,
+                        glFontCombo  *this)
 {
-        glFontCombo  *this = GL_FONT_COMBO (user_data);
-        GdkWindow    *window;
-        gint          x1, y1;
-        gint          menu_h, menu_w;
-
+        GdkScreen          *screen;
+        gint                w_screen, h_screen;
+        GdkWindow          *window;
+        gint                x_window, y_window;
+        GtkAllocation      *allocation;
+        gint                x_this, y_this, h_this;
+        GtkRequisition      menu_requisition;
+        gint                h_menu, w_menu;
+
+        /*
+         * Screen size
+         */
+        screen = gtk_widget_get_screen (GTK_WIDGET (this));
+        w_screen = gdk_screen_get_width (screen);
+        h_screen = gdk_screen_get_height (screen);
+
+        /*
+         * Absolute position of "this" window on screen.
+         */
         window = gtk_widget_get_window (GTK_WIDGET (this));
-
-        gdk_window_get_origin (window, &x1, &y1);
-        *x = x1 + GTK_WIDGET (this)->allocation.x;
-        *y = y1 + GTK_WIDGET (this)->allocation.y +
-                GTK_WIDGET (this)->allocation.height;
+        gdk_window_get_origin (window, &x_window, &y_window);
+
+        /*
+         *  Position and size of "this" inside window
+         */
+        allocation = &GTK_WIDGET (this)->allocation;
+        x_this = allocation->x;
+        y_this = allocation->y;
+        h_this = allocation->height;
+
+        /*
+         * Size of menu.
+         */
+        gtk_widget_size_request (this->priv->menu, &menu_requisition);
+        h_menu = menu_requisition.height;
+        w_menu = menu_requisition.width;
+
+        /*
+         * Default position anchored to lower left corner of "this".
+         */
+        *x = x_window + x_this;
+        *y = y_window + y_this + h_this;
                 
-        menu_h = this->priv->menu->allocation.height;
-        menu_w = this->priv->menu->allocation.width;
-
-        if ((*y + menu_h) > gdk_screen_height ())
+        /*
+         * Adjust vertical position if menu if extends past bottom of screen.
+         */
+        if ( (*y + h_menu) > h_screen )
         {
-                *y = y1 + GTK_WIDGET (this)->allocation.y - menu_h;
+                *y = y_window + y_this - h_menu;
+
                 if ( *y < 0 )
                 {
-                        *y = gdk_screen_height () - menu_h;
+                        *y = h_screen - h_menu;
                 }
         }
 
-        if ((*x + menu_w) > gdk_screen_width ())
+        /*
+         * Adjust horizontal position if menu if extends past edge of screen.
+         */
+        if ( (*x + w_menu) > w_screen )
         {
-                *x = gdk_screen_width () - menu_w;
+                *x = w_screen - w_menu;
         }
 
+
         *push_in = TRUE;
 }
 
@@ -274,7 +310,7 @@ button_press_event_cb (GtkWidget      *widget,
 
                 gtk_menu_popup (GTK_MENU (this->priv->menu),
                                 NULL, NULL,
-                                menu_position_function, this,
+                                (GtkMenuPositionFunc)menu_position_function, this,
                                 event->button, event->time);
                 break;