diff -urN aa/gnome-panel-2.6.0/gnome-panel/Makefile.am gnome-panel-2.6.0/gnome-panel/Makefile.am --- aa/gnome-panel-2.6.0/gnome-panel/Makefile.am 2004-02-06 17:04:50.000000000 +0100 +++ gnome-panel-2.6.0/gnome-panel/Makefile.am 2004-03-27 00:29:00.520061944 +0100 @@ -80,6 +80,8 @@ panel-typebuiltins.h \ panel-marshal.c \ panel-marshal.h \ + panel-menu.c \ + panel-menu.h \ main.c \ panel-widget.c \ button-widget.c \ diff -urN aa/gnome-panel-2.6.0/gnome-panel/menu.c gnome-panel-2.6.0/gnome-panel/menu.c --- aa/gnome-panel-2.6.0/gnome-panel/menu.c 2004-03-09 11:08:47.000000000 +0100 +++ gnome-panel-2.6.0/gnome-panel/menu.c 2004-03-27 00:29:00.522061640 +0100 @@ -44,6 +44,7 @@ #include "menu-fentry.h" #include "menu-util.h" #include "menu-ditem.h" +#include "panel-menu.h" #include "panel-util.h" #include "panel-gconf.h" #include "panel.h" @@ -67,6 +68,7 @@ #include "panel-lockdown.h" #undef MENU_DEBUG +#define MENU_SNAP_LENGTH 10 static char *gnome_folder = NULL; @@ -614,6 +616,9 @@ if (repo->orig_func != NULL) { repo->orig_func (menu, x, y, push_in, repo->orig_data); + if (*x < MENU_SNAP_LENGTH) + *x = 0; + if (menu->parent_menu_item != NULL) { /* This is a submenu so behave submenuish */ if (*x < monitor_basex || @@ -709,8 +714,8 @@ reload_image_menu_items (); } -GtkWidget * -panel_create_menu (void) +static GtkWidget * +panel_create_menu_of_type (GType menu_type) { GtkWidget *retval; static gboolean registered_icon_theme_changer = FALSE; @@ -722,8 +727,7 @@ G_CALLBACK (icon_theme_changed), NULL); } - retval = gtk_menu_new (); - + retval = g_object_new (menu_type, NULL); panel_gconf_notify_add_while_alive ("/desktop/gnome/interface/menus_have_icons", (GConfClientNotifyFunc) menus_have_icons_changed, G_OBJECT (retval)); @@ -739,12 +743,18 @@ return retval; } +GtkWidget * +panel_create_menu (void) +{ + return panel_create_menu_of_type (gtk_menu_get_type()); +} + static GtkWidget * -menu_new (void) +menu_new_of_type (GType menu_type) { GtkWidget *retval; - retval = panel_create_menu (); + retval = panel_create_menu_of_type (menu_type); g_signal_connect ( retval, "show", G_CALLBACK (setup_menu_panel), NULL); @@ -752,6 +762,13 @@ return retval; } +static GtkWidget * +menu_new (void) +{ + return menu_new_of_type (gtk_menu_get_type ()); +} + + static void icon_to_load_free (IconToLoad *icon) { @@ -3314,7 +3331,7 @@ } if (!root_menu) - root_menu = menu_new (); + root_menu = menu_new_of_type (panel_menu_get_type ()); g_object_set_data (G_OBJECT (root_menu), "menu_panel", panel); diff -urN aa/gnome-panel-2.6.0/gnome-panel/panel-config-global.c gnome-panel-2.6.0/gnome-panel/panel-config-global.c --- aa/gnome-panel-2.6.0/gnome-panel/panel-config-global.c 2004-01-18 15:35:47.000000000 +0100 +++ gnome-panel-2.6.0/gnome-panel/panel-config-global.c 2004-03-27 00:29:00.523061488 +0100 @@ -45,6 +45,7 @@ guint drawer_auto_close : 1; guint confirm_panel_remove : 1; guint highlight_when_over : 1; + guint menu_stripe : 1; } GlobalConfig; static GlobalConfig global_config = { 0, }; @@ -94,6 +95,13 @@ return global_config.confirm_panel_remove; } +gboolean +panel_global_config_get_menu_stripe (void) +{ + g_assert (global_config_initialised == TRUE); + + return global_config.menu_stripe; +} static void panel_global_config_set_entry (GConfEntry *entry) @@ -151,6 +159,11 @@ else if (strcmp (key, "highlight_launchers_on_mouseover") == 0) global_config.highlight_when_over = gconf_value_get_bool (value); + + else if (strcmp (key, "show_menu_stripe") == 0) + global_config.menu_stripe = + gconf_value_get_bool (value); + } static void diff -urN aa/gnome-panel-2.6.0/gnome-panel/panel-config-global.h gnome-panel-2.6.0/gnome-panel/panel-config-global.h --- aa/gnome-panel-2.6.0/gnome-panel/panel-config-global.h 2004-01-18 15:32:28.000000000 +0100 +++ gnome-panel-2.6.0/gnome-panel/panel-config-global.h 2004-03-27 00:29:00.523061488 +0100 @@ -37,6 +37,7 @@ gboolean panel_global_config_get_drawer_auto_close (void); gboolean panel_global_config_get_tooltips_enabled (void); gboolean panel_global_config_get_confirm_panel_remove (void); +gboolean panel_global_config_get_menu_stripe (void); G_END_DECLS diff -urN aa/gnome-panel-2.6.0/gnome-panel/panel-global.schemas.in gnome-panel-2.6.0/gnome-panel/panel-global.schemas.in --- aa/gnome-panel-2.6.0/gnome-panel/panel-global.schemas.in 2004-01-18 16:10:23.000000000 +0100 +++ gnome-panel-2.6.0/gnome-panel/panel-global.schemas.in 2004-03-27 00:29:00.588051608 +0100 @@ -93,6 +93,18 @@ + /schemas/apps/panel/global/show_menu_stripe + /apps/panel/global/show_menu_stripe + panel + bool + true + + + + + + + /schemas/apps/panel/global/enable_key_bindings /apps/panel/global/enable_key_bindings panel diff -urN aa/gnome-panel-2.6.0/gnome-panel/panel-menu.c gnome-panel-2.6.0/gnome-panel/panel-menu.c --- aa/gnome-panel-2.6.0/gnome-panel/panel-menu.c 1970-01-01 01:00:00.000000000 +0100 +++ gnome-panel-2.6.0/gnome-panel/panel-menu.c 2004-03-27 00:49:47.929426896 +0100 @@ -0,0 +1,1082 @@ +/* + * To set this up insert something like this in your ~/.gtkrc-2.0 + * + * Copyright (C) 2002 Ximian, Inc. + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima + * Copyright (C) 2003 Marcin Krzyżanowski + * + * style "default" + * { + * PanelMenu::default_side_image = "/tmp/stripelogo.png" + * PanelMenu::gradient_bg = true + * } + * class "PanelMenu" style "default" + * + * Authors: + * Thomas, Michael Meeks + * GtkMenu code by the GTK+ team + * Gradient code from WindowMaker by Dan Pascu and Alfredo Kojima, + * by way of metacity by Havoc Pennington. + * Marcin Krzyżanowski + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "panel-config-global.h" + +#define dprintf(a) g_warning a +/*#define dprintf(a) G_STMT_START { (void) 0; } G_STMT_END*/ + +GNOME_CLASS_BOILERPLATE (PanelMenu, panel_menu, + GtkMenu, GTK_TYPE_MENU) + + + +static void +panel_menu_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + PanelMenu *pm = PANEL_MENU (widget); + + GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition); + + if (panel_global_config_get_menu_stripe () && pm->side_image != NULL) + requisition->width += gdk_pixbuf_get_width (pm->side_image) + + gtk_widget_get_style (widget)->xthickness; +} + +static GdkColor * +get_light_stripe_color (PanelMenu *pm) +{ + GdkColor *color; + + gtk_widget_style_get (GTK_WIDGET (pm), + "stripe-color-light", &color, + NULL); + + if (!color) { + color = gdk_color_copy (>K_WIDGET (pm)->style->bg[GTK_STATE_NORMAL]); + } + + return color; +} + +static GdkColor * +get_stripe_color (PanelMenu *pm) +{ + GdkColor *color; + + gtk_widget_style_get (GTK_WIDGET (pm), + "stripe-color", &color, + NULL); + + if (!color) { + color = gdk_color_copy (>K_WIDGET (pm)->style->bg[GTK_STATE_SELECTED]); + } + + return color; +} + +static GdkGC * +get_stripe_gc (PanelMenu *pm) +{ + GdkGCValues gc_values; + GdkGCValuesMask gc_values_mask; + GdkColor *color; + + color = get_stripe_color (pm); + gc_values.foreground = *color; + gdk_color_free (color); + gc_values_mask = GDK_GC_FOREGROUND; + + gdk_rgb_find_color (GTK_WIDGET (pm)->style->colormap, &gc_values.foreground); + + return gtk_gc_get (GTK_WIDGET (pm)->style->depth, + GTK_WIDGET (pm)->style->colormap, + &gc_values, gc_values_mask); +} + +static gboolean +panel_menu_expose_event (GtkWidget *widget, + GdkEventExpose *event) +{ + GdkRectangle exposed; + GdkRectangle position; + GdkWindow *window; + int bin_height; + GdkGC *stripe_gc; + PanelMenu *pm = PANEL_MENU (widget); + + GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); + + if (!panel_global_config_get_menu_stripe () || !pm->side_image) { + return TRUE; + } + window = GTK_MENU (widget)->bin_window; + + stripe_gc = get_stripe_gc (pm); + + gdk_gc_set_clip_rectangle (stripe_gc, &event->area); + gdk_draw_rectangle (window, + stripe_gc, + TRUE, + widget->allocation.x, + widget->allocation.y, + gdk_pixbuf_get_width (pm->side_image), + widget->allocation.height); + gdk_gc_set_clip_rectangle (stripe_gc, NULL); + + bin_height = widget->allocation.height - 2 * (GTK_CONTAINER (widget)->border_width + widget->style->ythickness); + + position = widget->allocation; + position.y += bin_height - gdk_pixbuf_get_height (pm->side_image); + position.width = gdk_pixbuf_get_width (pm->side_image); + position.height = gdk_pixbuf_get_height (pm->side_image); + + if (widget->allocation.height >= gdk_pixbuf_get_height (pm->side_image)) { + if (gdk_rectangle_intersect (&event->area, + &position, + &exposed)) { + gdk_pixbuf_render_to_drawable ( + pm->side_image, window, + widget->style->black_gc, + exposed.x - position.x, + exposed.y - position.y, + exposed.x, exposed.y, + exposed.width, exposed.height, + GDK_RGB_DITHER_NORMAL, + exposed.x, exposed.y); + } + } + + position = widget->allocation; + if (position.height != gdk_pixbuf_get_height (pm->side_image)) { + position.width = gdk_pixbuf_get_width (pm->side_image); + if (position.height > gdk_pixbuf_get_height (pm->side_image)) { + position.height = bin_height - gdk_pixbuf_get_height (pm->side_image); + } else { + position.height = bin_height; + } + + if (pm->scaled_image && gdk_rectangle_intersect (&event->area, + &position, + &exposed)) { + + gdk_pixbuf_render_to_drawable ( + pm->scaled_image, window, + widget->style->black_gc, + exposed.x - position.x, + exposed.y - position.y, + exposed.x, exposed.y, + exposed.width, exposed.height, + GDK_RGB_DITHER_NORMAL, + exposed.x, exposed.y); + } + } + + return TRUE; +} + +/* begin metacity cut and paste */ +static void +free_buffer (guchar *pixels, gpointer data) +{ + g_free (pixels); +} + +static GdkPixbuf* +blank_pixbuf (int width, int height, gboolean no_padding) +{ + guchar *buf; + int rowstride; + + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + + if (no_padding) + rowstride = width * 3; + else + /* Always align rows to 32-bit boundaries */ + rowstride = 4 * ((3 * width + 3) / 4); + + buf = g_try_malloc (height * rowstride); + if (!buf) + return NULL; + + return gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB, + FALSE, 8, + width, height, rowstride, + free_buffer, NULL); +} + +static GdkPixbuf* +meta_gradient_create_vertical (int width, int height, + const GdkColor *from, + const GdkColor *to) +{ + int i, j; + long r, g, b, dr, dg, db; + GdkPixbuf *pixbuf; + unsigned char *ptr; + unsigned char rr, gg, bb; + int r0, g0, b0; + int rf, gf, bf; + int rowstride; + unsigned char *pixels; + + pixbuf = blank_pixbuf (width, height, FALSE); + if (pixbuf == NULL) + return NULL; + + pixels = gdk_pixbuf_get_pixels (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + + r0 = (guchar) (from->red / 256.0); + g0 = (guchar) (from->green / 256.0); + b0 = (guchar) (from->blue / 256.0); + rf = (guchar) (to->red / 256.0); + gf = (guchar) (to->green / 256.0); + bf = (guchar) (to->blue / 256.0); + + r = r0<<16; + g = g0<<16; + b = b0<<16; + + dr = ((rf-r0)<<16)/(int)height; + dg = ((gf-g0)<<16)/(int)height; + db = ((bf-b0)<<16)/(int)height; + + for (i=0; i>16; + gg = g>>16; + bb = b>>16; + for (j=0; jheights); + + g_free (priv); +} + +static GtkMenuPrivate * +gtk_menu_get_private (GtkMenu *menu) +{ + GtkMenuPrivate *private; + static GQuark private_quark = 0; + + if (!private_quark) + private_quark = g_quark_from_static_string ("gtk-menu-private"); + + private = g_object_get_qdata (G_OBJECT (menu), private_quark); + + if (!private) + { + private = g_new0 (GtkMenuPrivate, 1); + private->have_position = FALSE; + + g_object_set_qdata_full (G_OBJECT (menu), private_quark, + private, gtk_menu_free_private); + } + + return private; +} + +static void +gtk_menu_remove_scroll_timeout (GtkMenu *menu) +{ + if (menu->timeout_id) + { + g_source_remove (menu->timeout_id); + menu->timeout_id = 0; + } +} + +static void +gtk_menu_stop_scrolling (GtkMenu *menu) +{ + gtk_menu_remove_scroll_timeout (menu); + + menu->upper_arrow_prelight = FALSE; + menu->lower_arrow_prelight = FALSE; +} + +static void +gtk_menu_scroll_to (GtkMenu *menu, + gint offset) +{ + GtkWidget *widget; + gint x, y; + gint view_width, view_height; + gint border_width; + gboolean last_visible; + gint menu_height; + guint vertical_padding; + + widget = GTK_WIDGET (menu); + + if (menu->tearoff_active && + menu->tearoff_adjustment && + (menu->tearoff_adjustment->value != offset)) + { + menu->tearoff_adjustment->value = + CLAMP (offset, + 0, menu->tearoff_adjustment->upper - menu->tearoff_adjustment->page_size); + gtk_adjustment_value_changed (menu->tearoff_adjustment); + } + + /* Move/resize the viewport according to arrows: */ + view_width = widget->allocation.width; + view_height = widget->allocation.height; + + gtk_widget_style_get (GTK_WIDGET (menu), + "vertical-padding", &vertical_padding, + NULL); + + border_width = GTK_CONTAINER (menu)->border_width; + view_width -= (border_width + widget->style->xthickness) * 2; + view_height -= (border_width + widget->style->ythickness + vertical_padding) * 2; + menu_height = widget->requisition.height - + (border_width + widget->style->ythickness + vertical_padding) * 2; + + x = border_width + widget->style->xthickness; + y = border_width + widget->style->ythickness + vertical_padding; + + if (!menu->tearoff_active) + { + last_visible = menu->upper_arrow_visible; + menu->upper_arrow_visible = offset > 0; + + if (menu->upper_arrow_visible) + view_height -= MENU_SCROLL_ARROW_HEIGHT; + + if ( (last_visible != menu->upper_arrow_visible) && + !menu->upper_arrow_visible) + { + menu->upper_arrow_prelight = FALSE; + + /* If we hid the upper arrow, possibly remove timeout */ + if (menu->scroll_step < 0) + { + gtk_menu_stop_scrolling (menu); + gtk_widget_queue_draw (GTK_WIDGET (menu)); + } + } + + last_visible = menu->lower_arrow_visible; + menu->lower_arrow_visible = offset < menu_height - view_height; + + if (menu->lower_arrow_visible) + view_height -= MENU_SCROLL_ARROW_HEIGHT; + + if ( (last_visible != menu->lower_arrow_visible) && + !menu->lower_arrow_visible) + { + menu->lower_arrow_prelight = FALSE; + + /* If we hid the lower arrow, possibly remove timeout */ + if (menu->scroll_step > 0) + { + gtk_menu_stop_scrolling (menu); + gtk_widget_queue_draw (GTK_WIDGET (menu)); + } + } + + if (menu->upper_arrow_visible) + y += MENU_SCROLL_ARROW_HEIGHT; + } + + /* Scroll the menu: */ + if (GTK_WIDGET_REALIZED (menu)) + gdk_window_move (menu->bin_window, 0, -offset); + + if (GTK_WIDGET_REALIZED (menu)) + gdk_window_move_resize (menu->view_window, + x, + y, + view_width, + view_height); + + menu->scroll_offset = offset; +} + +static AttachInfo * +get_attach_info (GtkWidget *child) +{ + GObject *object = G_OBJECT (child); + AttachInfo *ai = g_object_get_data (object, ATTACH_INFO_KEY); + + if (!ai) + { + ai = g_new0 (AttachInfo, 1); + g_object_set_data_full (object, ATTACH_INFO_KEY, ai, g_free); + } + + return ai; +} + +static gboolean +is_grid_attached (AttachInfo *ai) +{ + return (ai->left_attach >= 0 && + ai->right_attach >= 0 && + ai->top_attach >= 0 && + ai->bottom_attach >= 0); +} + +static void +menu_ensure_layout (GtkMenu *menu) +{ + GtkMenuPrivate *priv = gtk_menu_get_private (menu); + + if (!priv->have_layout) + { + GtkMenuShell *menu_shell = GTK_MENU_SHELL (menu); + GList *l; + gchar *row_occupied; + gint current_row; + gint max_right_attach; + gint max_bottom_attach; + + /* Find extents of gridded portion */ + max_right_attach = 1; + max_bottom_attach = 0; + + for (l = menu_shell->children; l; l = l->next) + { + GtkWidget *child = l->data; + AttachInfo *ai = get_attach_info (child); + + if (is_grid_attached (ai)) + { + max_bottom_attach = MAX (max_bottom_attach, ai->bottom_attach); + max_right_attach = MAX (max_right_attach, ai->right_attach); + } + } + + /* Find empty rows */ + row_occupied = g_malloc0 (max_bottom_attach); + + for (l = menu_shell->children; l; l = l->next) + { + GtkWidget *child = l->data; + AttachInfo *ai = get_attach_info (child); + + if (is_grid_attached (ai)) + { + gint i; + + for (i = ai->top_attach; i < ai->bottom_attach; i++) + row_occupied[i] = TRUE; + } + } + + /* Lay non-grid-items out in those rows */ + current_row = 0; + for (l = menu_shell->children; l; l = l->next) + { + GtkWidget *child = l->data; + AttachInfo *ai = get_attach_info (child); + + if (!is_grid_attached (ai)) + { + while (current_row < max_bottom_attach && row_occupied[current_row]) + current_row++; + + ai->effective_left_attach = 0; + ai->effective_right_attach = max_right_attach; + ai->effective_top_attach = current_row; + ai->effective_bottom_attach = current_row + 1; + + current_row++; + } + else + { + ai->effective_left_attach = ai->left_attach; + ai->effective_right_attach = ai->right_attach; + ai->effective_top_attach = ai->top_attach; + ai->effective_bottom_attach = ai->bottom_attach; + } + } + + g_free (row_occupied); + + priv->n_rows = MAX (current_row, max_bottom_attach); + priv->n_columns = max_right_attach; + priv->have_layout = TRUE; + } +} + + +static gint +gtk_menu_get_n_columns (GtkMenu *menu) +{ + GtkMenuPrivate *priv = gtk_menu_get_private (menu); + + menu_ensure_layout (menu); + + return priv->n_columns; +} + +static gint +gtk_menu_get_n_rows (GtkMenu *menu) +{ + GtkMenuPrivate *priv = gtk_menu_get_private (menu); + + menu_ensure_layout (menu); + + return priv->n_rows; +} + +static void +get_effective_child_attach (GtkWidget *child, + int *l, + int *r, + int *t, + int *b) +{ + GtkMenu *menu = GTK_MENU (child->parent); + AttachInfo *ai; + + menu_ensure_layout (menu); + + ai = get_attach_info (child); + + if (l) + *l = ai->effective_left_attach; + if (r) + *r = ai->effective_right_attach; + if (t) + *t = ai->effective_top_attach; + if (b) + *b = ai->effective_bottom_attach; + +} + +static void +gtk_menu_set_tearoff_hints (GtkMenu *menu, + gint width) +{ + GdkGeometry geometry_hints; + + if (!menu->tearoff_window) + return; + + if (GTK_WIDGET_VISIBLE (menu->tearoff_scrollbar)) + { + gtk_widget_size_request (menu->tearoff_scrollbar, NULL); + width += menu->tearoff_scrollbar->requisition.width; + } + + geometry_hints.min_width = width; + geometry_hints.max_width = width; + + geometry_hints.min_height = 0; + geometry_hints.max_height = GTK_WIDGET (menu)->requisition.height; + + gtk_window_set_geometry_hints (GTK_WINDOW (menu->tearoff_window), + NULL, + &geometry_hints, + GDK_HINT_MAX_SIZE|GDK_HINT_MIN_SIZE); +} + +static void +gtk_menu_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkMenu *menu; + GtkMenuShell *menu_shell; + GtkWidget *child; + GtkAllocation child_allocation; + GtkRequisition child_requisition; + GtkMenuPrivate *priv; + GList *children; + gint x, y; + gint width, height; + guint vertical_padding; + guint menu_stripe_width; + + g_return_if_fail (GTK_IS_MENU (widget)); + g_return_if_fail (allocation != NULL); + + menu = GTK_MENU (widget); + menu_shell = GTK_MENU_SHELL (widget); + priv = gtk_menu_get_private (menu); + + widget->allocation = *allocation; + gtk_widget_get_child_requisition (GTK_WIDGET (menu), &child_requisition); + + gtk_widget_style_get (GTK_WIDGET (menu), + "vertical-padding", &vertical_padding, + NULL); + + x = GTK_CONTAINER (menu)->border_width + widget->style->xthickness; + y = GTK_CONTAINER (menu)->border_width + widget->style->ythickness + vertical_padding; + + width = MAX (1, allocation->width - x * 2); + height = MAX (1, allocation->height - y * 2); + + child_requisition.width -= x * 2; + child_requisition.height -= y * 2; + + if (menu_shell->active) + gtk_menu_scroll_to (menu, menu->scroll_offset); + + if (menu->upper_arrow_visible && !menu->tearoff_active) + { + y += MENU_SCROLL_ARROW_HEIGHT; + height -= MENU_SCROLL_ARROW_HEIGHT; + } + + if (menu->lower_arrow_visible && !menu->tearoff_active) + height -= MENU_SCROLL_ARROW_HEIGHT; + + if (GTK_WIDGET_REALIZED (widget)) + { + gdk_window_move_resize (widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height); + + gdk_window_move_resize (menu->view_window, + x, + y, + width, + height); + } + +/* inserted for panel-menu.c */ + if (panel_global_config_get_menu_stripe () && PANEL_MENU (widget)->side_image) { + menu_stripe_width = gdk_pixbuf_get_width (PANEL_MENU (widget)->side_image) + gtk_widget_get_style (widget)->xthickness; + } else { + menu_stripe_width = 0; + } +/* end panel-menu.c */ + + if (menu_shell->children) + { +/* inserted for panel-menu.c */ +#if 0 + gint base_width = width / gtk_menu_get_n_columns (menu); +#else + gint base_width = (width - menu_stripe_width) / gtk_menu_get_n_columns (menu); +#endif +/* end panel-menu.c */ + + children = menu_shell->children; + while (children) + { + child = children->data; + children = children->next; + + if (GTK_WIDGET_VISIBLE (child)) + { + gint i; + guint l, r, t, b; + + get_effective_child_attach (child, &l, &r, &t, &b); + + if (gtk_widget_get_direction (GTK_WIDGET (menu)) == GTK_TEXT_DIR_RTL) + { + guint tmp; + tmp = gtk_menu_get_n_columns (menu) - l; + l = gtk_menu_get_n_columns (menu) - r; + r = tmp; + } + + child_allocation.width = (r - l) * base_width; + child_allocation.height = 0; +/* inserted for panel-menu.c */ +#if 0 + child_allocation.x = l * base_width; +#else + child_allocation.x = l * base_width + menu_stripe_width; +#endif + child_allocation.y = 0; + + for (i = 0; i < b; i++) + { + if (i < t) + child_allocation.y += priv->heights[i]; + else + child_allocation.height += priv->heights[i]; + } + + + gtk_menu_item_toggle_size_allocate (GTK_MENU_ITEM (child), + menu->toggle_size); + + gtk_widget_size_allocate (child, &child_allocation); + +#if 0 + +/* inserted for panel-menu.c */ + if (use_menu_stripe && g_type_is_a (G_OBJECT_TYPE (child), GTK_TYPE_SEPARATOR_MENU_ITEM)) + { + /* this is dumb, gtkmenuitem.c uses allocation.width as an absolute point */ + child_allocation.width += gdk_pixbuf_get_width (PANEL_MENU (widget)->side_image); + } + + gtk_widget_size_allocate (child, &child_allocation); + + if (use_menu_stripe && g_type_is_a (G_OBJECT_TYPE (child), GTK_TYPE_SEPARATOR_MENU_ITEM)) + { + child_allocation.width -= gdk_pixbuf_get_width (PANEL_MENU (widget)->side_image); + } +#endif + + /* Hack to handle events on the stripe area */ + if (GTK_WIDGET_REALIZED (child) && l == 0) + { + gdk_window_move_resize (GTK_MENU_ITEM (child)->event_window, + 0, child_allocation.y, + child_allocation.width + child_allocation.x, + child_allocation.height); + } +/* end panel-menu.c */ + + gtk_widget_queue_draw (child); + } + } + + /* Resize the item window */ + if (GTK_WIDGET_REALIZED (widget)) + { + gint i; + gint width, height; + + height = 0; + for (i = 0; i < gtk_menu_get_n_rows (menu); i++) + height += priv->heights[i]; + +/* inserted for panel-menu.c */ +#if 0 + width = gtk_menu_get_n_columns (menu) * base_width; +#else + width = gtk_menu_get_n_columns (menu) * base_width + menu_stripe_width; +#endif +/* end panel-menu.c */ + + gdk_window_resize (menu->bin_window, width, height); + } + + if (menu->tearoff_active) + { + if (allocation->height >= widget->requisition.height) + { + if (GTK_WIDGET_VISIBLE (menu->tearoff_scrollbar)) + { + gtk_widget_hide (menu->tearoff_scrollbar); + gtk_menu_set_tearoff_hints (menu, allocation->width); + + gtk_menu_scroll_to (menu, 0); + } + } + else + { + menu->tearoff_adjustment->upper = widget->requisition.height; + menu->tearoff_adjustment->page_size = allocation->height; + + if (menu->tearoff_adjustment->value + menu->tearoff_adjustment->page_size > + menu->tearoff_adjustment->upper) + { + gint value; + value = menu->tearoff_adjustment->upper - menu->tearoff_adjustment->page_size; + if (value < 0) + value = 0; + gtk_menu_scroll_to (menu, value); + } + + gtk_adjustment_changed (menu->tearoff_adjustment); + + if (!GTK_WIDGET_VISIBLE (menu->tearoff_scrollbar)) + { + gtk_widget_show (menu->tearoff_scrollbar); + gtk_menu_set_tearoff_hints (menu, allocation->width); + } + } + } + } +/* inserted for panel-menu.c */ + + { + PanelMenu *pm = PANEL_MENU (widget); + + gint scaled_height = height; + + if (pm->side_image && widget->allocation.height > gdk_pixbuf_get_height (pm->side_image)) + { + scaled_height -= gdk_pixbuf_get_height (pm->side_image); + } + + if (pm->side_image && widget->allocation.height < gdk_pixbuf_get_height (pm->side_image)) + { + gint scaled_width = ((scaled_height * gdk_pixbuf_get_width (pm->side_image)) / gdk_pixbuf_get_height (pm->side_image)); + + if (pm->scaled_image) + gdk_pixbuf_unref(pm->scaled_image); + + pm->scaled_image = gdk_pixbuf_scale_simple (pm->side_image, + scaled_width, + scaled_height, + GDK_INTERP_BILINEAR); /* maybe HYPER ? */ + gdk_pixbuf_unref(pm->side_image); + pm->side_image = pm->scaled_image; + } + else + { + gboolean draw_gradient; + gtk_widget_style_get (GTK_WIDGET (pm), + "gradient_bg", &draw_gradient, + NULL); + + if (pm->side_image && draw_gradient) + { + GdkColor *stripe_color; + GdkColor *light_color; + + stripe_color = get_stripe_color (pm); + light_color = get_light_stripe_color (pm); + pm->scaled_image = meta_gradient_create_vertical + (gdk_pixbuf_get_width (pm->side_image), + scaled_height, + light_color, + stripe_color); + gdk_color_free (light_color); + gdk_color_free (stripe_color); + } + } + } +/* end panel-menu.c */ +} + +/* end gtkmenu cut and paste */ + +static void +unload_images (PanelMenu *pm) +{ + if (pm->side_image) { + g_object_unref (pm->side_image); + pm->side_image = NULL; + } + + if (pm->scaled_image) { + g_object_unref (pm->scaled_image); + pm->scaled_image = NULL; + } +} + +static GdkPixbuf * +get_stripe_image (PanelMenu *pm, + const char *name, + const char *default_filename) +{ + GdkPixbuf *image = NULL; + char *file_src; + + gtk_widget_style_get (GTK_WIDGET (pm), name, &file_src, NULL); + + if (!file_src) { + file_src = gnome_program_locate_file (NULL, + GNOME_FILE_DOMAIN_PIXMAP, + default_filename, + TRUE, + NULL); + } + + if (file_src) + image = gdk_pixbuf_new_from_file (file_src, NULL); + + g_free (file_src); + + return image; +} + +static void +load_images (PanelMenu *pm) +{ + GdkPixbuf *image; + + unload_images (pm); + + pm->side_image = get_stripe_image (pm, "default_side_image", + "pld-desktop-stripe.png"); +} + +static void +panel_menu_style_set (GtkWidget *widget, + GtkStyle *old_style) +{ + load_images (PANEL_MENU (widget)); + GNOME_CALL_PARENT (GTK_WIDGET_CLASS, style_set, (widget, old_style)); +} + +static void +panel_menu_destroy (GtkObject *object) +{ + PanelMenu *pm = PANEL_MENU (object); + + unload_images (pm); + + GNOME_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); +} + +static void +panel_menu_finalize (GObject *object) +{ + GNOME_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); +} + +static void +panel_menu_class_init (PanelMenuClass *klass) +{ + GtkWidgetClass *widget_class = (GtkWidgetClass *) klass; + GtkObjectClass *gtk_object_class = (GtkObjectClass *)klass; + GObjectClass *object_class = (GObjectClass *) klass; + + gtk_widget_class_install_style_property ( + widget_class, + g_param_spec_string ("default_side_image", + _("Default Side Image"), + _("Filename of logo down the side of applications menu"), + NULL, + G_PARAM_READWRITE)); + + gtk_widget_class_install_style_property ( + widget_class, + g_param_spec_boolean ("gradient_bg", + _("Gradient Background"), + _("Draw a gradient in the menu stripe"), + FALSE, + G_PARAM_READWRITE)); + gtk_widget_class_install_style_property ( + widget_class, + g_param_spec_boxed ("stripe_color", + _("Stripe Color"), + _("Color of the panel menu stripe"), + GDK_TYPE_COLOR, + G_PARAM_READABLE)); + + gtk_widget_class_install_style_property ( + widget_class, + g_param_spec_boxed ("stripe_color_light", + _("Light Stripe Color"), + _("Light color of the panel menu stripe, for gradients"), + GDK_TYPE_COLOR, + G_PARAM_READABLE)); + + object_class->finalize = panel_menu_finalize; + gtk_object_class->destroy = panel_menu_destroy; + widget_class->size_request = panel_menu_size_request; + widget_class->size_allocate = gtk_menu_size_allocate; + widget_class->expose_event = panel_menu_expose_event; + widget_class->style_set = panel_menu_style_set; +} + +static void +panel_menu_instance_init (PanelMenu *pm) +{ + gtk_widget_ensure_style (GTK_WIDGET (pm)); + + load_images (pm); + + gtk_widget_add_events ( + GTK_WIDGET (pm), + GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK); +} diff -urN aa/gnome-panel-2.6.0/gnome-panel/panel-menu.h gnome-panel-2.6.0/gnome-panel/panel-menu.h --- aa/gnome-panel-2.6.0/gnome-panel/panel-menu.h 1970-01-01 01:00:00.000000000 +0100 +++ gnome-panel-2.6.0/gnome-panel/panel-menu.h 2004-03-27 00:29:00.640043704 +0100 @@ -0,0 +1,31 @@ +#include +#include + +typedef struct _PanelMenu PanelMenu; +typedef struct _PanelMenuClass PanelMenuClass; + +#define PANEL_MENU(obj) \ + GTK_CHECK_CAST (obj, panel_menu_get_type (), PanelMenu) +#define PANEL_MENU_CLASS(k) \ + GTK_CHECK_CLASS_CAST (k, panel_menu_get_type (), PanelMenuClass) +#define PANEL_IS_MENU(obj) \ + GTK_CHECK_TYPE (obj, panel_menu_get_type ()) + + +struct _PanelMenu +{ + GtkMenu parent; + + GdkPixbuf *side_image; + GdkPixbuf *scaled_image; + + GdkRegion *navigation_region; +}; + +struct _PanelMenuClass +{ + GtkMenuClass parent_class; +}; + +GType panel_menu_get_type (void); +GtkWidget *panel_menu_evolve (void);