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)
This commit is contained in:
Soeren Sandmann 2003-08-04 22:09:02 +00:00 committed by Søren Sandmann Pedersen
parent 6f6d3a2202
commit 094657e85b
6 changed files with 137 additions and 2 deletions

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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;