Re: GTK menu fixing...



Thus spake Nils Barth:
> Okay, here's my start at improving (sub)menus in GTK:
<snip>
...and a false start.

The previous patch was in error (it didn't work until you had already
traversed the menu, thus allocating size for the submenus).
It works now; see attached.
Previous notes still hold.

-- 
  -nils
Public key: http://www.fas.harvard.edu/~nbarth/pub-key.txt
Index: gtkmenu.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenu.c,v
retrieving revision 1.43
diff -u -r1.43 gtkmenu.c
--- gtkmenu.c	1999/11/22 21:52:47	1.43
+++ gtkmenu.c	2000/05/19 06:50:54
@@ -686,7 +686,6 @@
     gtk_menu_position (menu);
 }
 
-
 void       
 gtk_menu_set_tearoff_state (GtkMenu  *menu,
 			    gboolean  torn_off)
@@ -1165,7 +1164,7 @@
 
   /* We need the requisition to figure out the right place to
    * popup the menu. In fact, we always need to ask here, since
-   * if one a size_request was queued while we weren't popped up,
+   * if a size_request was queued while we weren't popped up,
    * the requisition won't have been recomputed yet.
    */
   gtk_widget_size_request (widget, &requisition);
Index: gtkmenu.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenu.h,v
retrieving revision 1.17
diff -u -r1.17 gtkmenu.h
--- gtkmenu.h	2000/03/14 19:57:24	1.17
+++ gtkmenu.h	2000/05/19 06:50:54
@@ -118,7 +118,7 @@
 void	   gtk_menu_set_active		  (GtkMenu	       *menu,
 					   guint		index);
 
-/* set/get the acclerator group that holds global accelerators (should
+/* set/get the accelerator group that holds global accelerators (should
  * be added to the corresponding toplevel with gtk_window_add_accel_group().
  */
 void	       gtk_menu_set_accel_group	  (GtkMenu	       *menu,
Index: gtkmenuitem.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenuitem.c,v
retrieving revision 1.38
diff -u -r1.38 gtkmenuitem.c
--- gtkmenuitem.c	2000/04/07 21:36:13	1.38
+++ gtkmenuitem.c	2000/05/19 06:50:54
@@ -35,6 +35,7 @@
 
 #define BORDER_SPACING  3
 #define SELECT_TIMEOUT  75
+#define GTK_DIRECTION_DEFAULT  GTK_DIRECTION_RIGHT;
 
 #define MENU_ITEM_CLASS(w)  GTK_MENU_ITEM_CLASS (GTK_OBJECT (w)->klass)
 
@@ -171,8 +172,8 @@
   menu_item->accelerator_width = 0;
   menu_item->show_toggle_indicator = FALSE;
   menu_item->show_submenu_indicator = FALSE;
-  menu_item->submenu_direction = GTK_DIRECTION_RIGHT;
-  menu_item->submenu_placement = GTK_TOP_BOTTOM;
+  menu_item->submenu_direction = GTK_DIRECTION_DEFAULT;
+  menu_item->submenu_placement = GTK_LEFT_RIGHT;
   menu_item->right_justify = FALSE;
 
   menu_item->timer = 0;
@@ -423,8 +424,12 @@
   GtkMenuItem *menu_item;
   GtkStateType state_type;
   GtkShadowType shadow_type;
+  GtkArrowType arrow_direction;
   gint width, height;
   gint x, y;
+  gint dummy_a=0;
+  gint dummy_b=0;
+  GtkRequisition requisition;
 
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_MENU_ITEM (widget));
@@ -459,11 +464,35 @@
 	  shadow_type = GTK_SHADOW_OUT;
 	  if (state_type == GTK_STATE_PRELIGHT)
 	    shadow_type = GTK_SHADOW_IN;
+	  
+          /* Similarly to in gtk_menu_position(), we need to figure out
+	   * where the menu will pop up to figure out the arrow direction
+	   */
+	  gtk_widget_size_request (GTK_WIDGET(menu_item->submenu),
+	                          &requisition);
+	  /* The temporary requisition is so that gtk_widget_size_request
+	   * doesn't whine.
+	   */
+	  GTK_WIDGET(menu_item->submenu)->requisition.width  = requisition.width;
+	  GTK_WIDGET(menu_item->submenu)->requisition.height = requisition.height;
+	  gtk_menu_item_position_menu(GTK_MENU(menu_item->submenu),
+	                              &dummy_a, &dummy_b, menu_item);
 
+	  switch (menu_item->submenu_direction)
+	    {
+	      case GTK_DIRECTION_LEFT:
+		arrow_direction=GTK_ARROW_LEFT;
+		break;
+	      
+	      case GTK_DIRECTION_RIGHT:
+		arrow_direction=GTK_ARROW_RIGHT;
+		break;
+	    }
+	  
 	  gtk_paint_arrow (widget->style, widget->window,
 			   state_type, shadow_type, 
 			   area, widget, "menuitem", 
-			   GTK_ARROW_RIGHT, TRUE,
+			   arrow_direction, TRUE,
 			   x + width - 15, y + height / 2 - 5, 10, 10);
 	}
       else if (!GTK_BIN (menu_item)->child)
@@ -676,7 +705,7 @@
   gint screen_height;
   gint twidth, theight;
   gint tx, ty;
-
+  
   g_return_if_fail (menu != NULL);
   g_return_if_fail (x != NULL);
   g_return_if_fail (y != NULL);
@@ -708,10 +737,10 @@
       break;
 
     case GTK_LEFT_RIGHT:
-      menu_item->submenu_direction = GTK_DIRECTION_RIGHT;
       parent_menu_item = GTK_MENU (GTK_WIDGET (menu_item)->parent)->parent_menu_item;
       if (parent_menu_item)
 	menu_item->submenu_direction = GTK_MENU_ITEM (parent_menu_item)->submenu_direction;
+      else menu_item->submenu_direction = GTK_DIRECTION_DEFAULT;
 
       switch (menu_item->submenu_direction)
 	{
Index: gtktypeutils.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktypeutils.h,v
retrieving revision 1.47
diff -u -r1.47 gtktypeutils.h
--- gtktypeutils.h	2000/02/13 08:16:47	1.47
+++ gtktypeutils.h	2000/05/19 06:50:54
@@ -279,7 +279,7 @@
 #define GTK_VALUE_C_CALLBACK(a) ((a).d.c_callback_data)
 #define GTK_VALUE_FOREIGN(a)	((a).d.foreign_data)
 
-/* return location macros, these all narow down to
+/* return location macros, these all narrow down to
  * pointer types, because return values need to be
  * passed by reference
  */


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