diff options
author | Soeren Sandmann <sandmann@daimi.au.dk> | 2003-08-04 22:09:02 +0000 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@src.gnome.org> | 2003-08-04 22:09:02 +0000 |
commit | 094657e85bdc916860948c31cd99a9e0b15bf6d9 (patch) | |
tree | 2f9fe49b3e4ec48b75c2ed3c8cc2e2ce549e2bf0 | |
parent | 6f6d3a2202194c441dfa4745caa1ab83db38789c (diff) | |
download | gtk+-094657e85bdc916860948c31cd99a9e0b15bf6d9.tar.gz |
New positioning algorithm.(#116649)
Tue Aug 5 00:24:13 2003 Soeren Sandmann <sandmann@daimi.au.dk>
* gtk/gtkmenu.c (gtk_menu_position): New positioning
algorithm.(#116649)
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 5 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 5 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 5 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 5 | ||||
-rw-r--r-- | gtk/gtkmenu.c | 114 |
6 files changed, 137 insertions, 2 deletions
@@ -1,3 +1,8 @@ +Tue Aug 5 00:24:13 2003 Soeren Sandmann <sandmann@daimi.au.dk> + + * gtk/gtkmenu.c (gtk_menu_position): New positioning + algorithm.(#116649) + Fri Aug 1 15:26:46 2003 Soeren Sandmann <sandmann@daimi.au.dk> * gtk/gtktoolbar.c, gtk/toolitem.c: add new "is_important" diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 8c5919c934..4b34764d8f 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,8 @@ +Tue Aug 5 00:24:13 2003 Soeren Sandmann <sandmann@daimi.au.dk> + + * gtk/gtkmenu.c (gtk_menu_position): New positioning + algorithm.(#116649) + Fri Aug 1 15:26:46 2003 Soeren Sandmann <sandmann@daimi.au.dk> * gtk/gtktoolbar.c, gtk/toolitem.c: add new "is_important" diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 8c5919c934..4b34764d8f 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,8 @@ +Tue Aug 5 00:24:13 2003 Soeren Sandmann <sandmann@daimi.au.dk> + + * gtk/gtkmenu.c (gtk_menu_position): New positioning + algorithm.(#116649) + Fri Aug 1 15:26:46 2003 Soeren Sandmann <sandmann@daimi.au.dk> * gtk/gtktoolbar.c, gtk/toolitem.c: add new "is_important" diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 8c5919c934..4b34764d8f 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,8 @@ +Tue Aug 5 00:24:13 2003 Soeren Sandmann <sandmann@daimi.au.dk> + + * gtk/gtkmenu.c (gtk_menu_position): New positioning + algorithm.(#116649) + Fri Aug 1 15:26:46 2003 Soeren Sandmann <sandmann@daimi.au.dk> * gtk/gtktoolbar.c, gtk/toolitem.c: add new "is_important" diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 8c5919c934..4b34764d8f 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,8 @@ +Tue Aug 5 00:24:13 2003 Soeren Sandmann <sandmann@daimi.au.dk> + + * gtk/gtkmenu.c (gtk_menu_position): New positioning + algorithm.(#116649) + Fri Aug 1 15:26:46 2003 Soeren Sandmann <sandmann@daimi.au.dk> * gtk/gtktoolbar.c, gtk/toolitem.c: add new "is_important" diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c index 81907cfd06..81c518ea59 100644 --- a/gtk/gtkmenu.c +++ b/gtk/gtkmenu.c @@ -2750,8 +2750,118 @@ gtk_menu_position (GtkMenu *menu) (* menu->position_func) (menu, &x, &y, &push_in, menu->position_func_data); else { - x = CLAMP (x - 2, monitor.x, MAX (monitor.x, monitor.x + monitor.width - requisition.width)); - y = CLAMP (y - 2, monitor.y, MAX (monitor.y, monitor.y + monitor.height - requisition.height)); + gint space_left, space_right, space_above, space_below; + gint needed_width; + gint needed_height; + gint xthickness = widget->style->xthickness; + gint ythickness = widget->style->ythickness; + gboolean rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL); + + /* The placement of popup menus horizontally works like this (with + * RTL in parentheses) + * + * - If there is enough room to the right (left) of the mouse cursor, + * position the menu there. + * + * - Otherwise, if if there is enough room to the left (right) of the + * mouse cursor, position the menu there. + * + * - Otherwise if the menu is smaller than the monitor, position it + * on the side of the mouse cursor that has the most space available + * + * - Otherwise (if there is simply not enough room for the menu on the + * monitor), position it as far left (right) as possible. + * + * Positioning in the vertical direction is similar: first try below + * mouse cursor, then above. + */ + space_left = x - monitor.x; + space_right = monitor.x + monitor.width - x - 1; + space_above = y - monitor.y; + space_below = monitor.y + monitor.height - y - 1; + + /* position horizontally */ + + /* the amount of space we need to position the menu. Note the + * menu is offset "xthickness" pixels + */ + needed_width = requisition.width - xthickness; + + if (needed_width <= space_left || + needed_width <= space_right) + { + if ((rtl && needed_width <= space_left) || + (!rtl && needed_width > space_right)) + { + /* position left */ + x = x + xthickness - requisition.width + 1; + } + else + { + /* position right */ + x = x - xthickness; + } + + /* x is clamped on-screen further down */ + } + else if (requisition.width <= monitor.width) + { + /* the menu is too big to fit on either side of the mouse + * cursor, but smaller than the monitor. Position it on + * the side that has the most space + */ + if (space_left > space_right) + { + /* left justify */ + x = monitor.x; + } + else + { + /* right justify */ + x = monitor.x + monitor.width - requisition.width; + } + } + else /* menu is simply too big for the monitor */ + { + if (rtl) + { + /* right justify */ + x = monitor.x + monitor.width - requisition.width; + } + else + { + /* left justify */ + x = monitor.x; + } + } + + /* Position vertically. The algorithm is the same as above, but + * simpler because we don't have to take RTL into account. + */ + needed_height = requisition.height - ythickness; + + if (needed_height <= space_above || + needed_height <= space_below) + { + if (needed_height <= space_below) + y = y - ythickness; + else + y = y + ythickness - requisition.height + 1; + + y = CLAMP (y, monitor.y, + monitor.y + monitor.height - requisition.height); + } + else if (needed_height > space_below && needed_height > space_above) + { + if (space_below >= space_above) + y = monitor.y + monitor.height - requisition.height; + else + y = monitor.y; + } + else + { + y = monitor.y; + } } scroll_offset = 0; |