[PATCH] New mode for backgrounds



  SUMMARY

Patches to add a new mode for backgrounds provisionally entitled "Zoom".
These are from an existing bug 105231. I've been using them for the last
year.

http://bugs.gnome.org/show_bug.cgi?id=105231

  DESCRIPTION

This mode enlarges the image so as to cover desktop while maintaining
the aspect ratio by chopping either the top and bottom or left and
right edges. I.e. you're zooming or cropping the image to fill the
screen.

I've primarily done this for my widescreen laptop where stretched mode
("Fill Screen") makes 4:3 images look bad, but it would be useful for
any images that don't match the aspect ratio of your monitor.

  PROBLEM

The patches have been available since last year but not applied due to a
naming issue. Rodney Dawes didn't like "Zoom" as being too generic (see
comment #14 in bug). Second best name so far IMHO is "Cropped".

Suggestions please as getting this into Gnome 2.14 would be nice.

  PATCHES

There are four attached patches for eel, control-center, nautilus and
gnome-user-docs plus a new stock image.  The patches are against CVS
HEAD as of today (22/11/2005).

  1) bgzoom-eel.patch

Required before other patches can be considered. Raised in bug 320830.

http://bugzilla.gnome.org/show_bug.cgi?id=320830

Adds an EEL_BACKGROUND_ZOOM background placement enum and the two
functions eel_gdk_scale_to_min_factor() and
eel_gdk_pixbuf_scale_to_min(). The functions are basically the opposite
of the existing eel_gdk_scale_to_fit_factor() and
eel_gdk_pixbuf_scale_to_fit() functions. Instead of scaling to fit
within a box these are used scale to fit outwith a box.

  2) bgzoom-controlcenter.patch

The control center patch.

  3) bgzoom-nautilus.patch

Apparently Nautilus pulls the latest libbackground from CVS when it is
checked out (according to an email from Rodney Dawes) so only the two
small hunks for
nautilus/libnautilus-private/nautilus-directory-background.c need
applied?

  4) bgzoom-gnome2userdocs.patch

Add help for Zoomed mode. Also corrects the (very wrong) Tiled mode and
(slightly imprecise) Fill Screen descriptions.

  5) stock_wallpaper-zoom.png

Basically I wanted to show that the image would extend beyond the
boundary of the window. Tricky in a 16x16 icon...

Needs to be added next to the gnome-icon-theme/16x16/stock/image/
directory and its name added to
gnome-icon-theme/16x16/stock/image/Makefile.am so it is installed.

-- 
Alan.

"One must never be purposelessnessnesslessness."
diff -ur gnome-control-center.orig/capplets/background/gnome-wp-capplet.c gnome-control-center/capplets/background/gnome-wp-capplet.c
--- gnome-control-center.orig/capplets/background/gnome-wp-capplet.c	2005-11-21 04:42:44.000000000 +0000
+++ gnome-control-center/capplets/background/gnome-wp-capplet.c	2005-11-22 00:21:34.000000000 +0000
@@ -259,6 +259,9 @@
     } else if (!strcmp (value, "scaled")) {
       gtk_option_menu_set_history (GTK_OPTION_MENU (capplet->wp_opts),
 				   GNOME_WP_SCALE_TYPE_SCALED);
+    } else if (!strcmp (value, "zoom")) {
+      gtk_option_menu_set_history (GTK_OPTION_MENU (capplet->wp_opts),
+				   GNOME_WP_SCALE_TYPE_ZOOM);
     } else if (strcmp (value, "none") != 0) {
       gtk_option_menu_set_history (GTK_OPTION_MENU (capplet->wp_opts),
 				   GNOME_WP_SCALE_TYPE_TILED);
@@ -423,6 +426,9 @@
   case GNOME_WP_SCALE_TYPE_SCALED:
     item->options = g_strdup ("scaled");
     break;
+  case GNOME_WP_SCALE_TYPE_ZOOM:
+    item->options = g_strdup ("zoom");
+    break;
   case GNOME_WP_SCALE_TYPE_TILED:
     item->options = g_strdup ("wallpaper");
     break;
@@ -1133,6 +1139,27 @@
   gtk_widget_show (mitem);
 
   mitem = gtk_menu_item_new ();
+  set_accessible_name (mitem, _("Zoom"));
+  icofile = gnome_icon_theme_lookup_icon (capplet->theme,
+                                 	"stock_wallpaper-zoom",
+                                          16, NULL, NULL);
+  mbox = gtk_hbox_new (FALSE, 6);
+  gtk_container_add (GTK_CONTAINER (mitem), mbox);
+  gtk_widget_show (mbox);
+
+  if (icofile != NULL) {
+	capplet->sitem = gtk_image_new_from_file (icofile);
+	gtk_box_pack_start (GTK_BOX (mbox), capplet->sitem, FALSE, FALSE, 0);
+    gtk_widget_show (capplet->sitem);
+  }
+  label = gtk_label_new (_("Zoom"));
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+  gtk_box_pack_start (GTK_BOX (mbox), label, TRUE, TRUE, 0);
+  gtk_widget_show (label);
+  gtk_menu_append (GTK_MENU (menu), mitem);
+  gtk_widget_show (mitem);
+
+  mitem = gtk_menu_item_new ();
   set_accessible_name (mitem, _("Tiled"));
   icon_info = gtk_icon_theme_lookup_icon (capplet->theme,
 					  "stock_wallpaper-tile",
diff -ur gnome-control-center.orig/capplets/background/gnome-wp-capplet.h gnome-control-center/capplets/background/gnome-wp-capplet.h
--- gnome-control-center.orig/capplets/background/gnome-wp-capplet.h	2005-07-10 21:45:00.000000000 +0100
+++ gnome-control-center/capplets/background/gnome-wp-capplet.h	2005-11-22 00:19:50.000000000 +0000
@@ -100,6 +100,7 @@
   GNOME_WP_SCALE_TYPE_CENTERED,
   GNOME_WP_SCALE_TYPE_STRETCHED,
   GNOME_WP_SCALE_TYPE_SCALED,
+  GNOME_WP_SCALE_TYPE_ZOOM,
   GNOME_WP_SCALE_TYPE_TILED
 } GnomeWPScaleType;
 
diff -ur gnome-control-center.orig/capplets/background/gnome-wp-item.c gnome-control-center/capplets/background/gnome-wp-item.c
--- gnome-control-center.orig/capplets/background/gnome-wp-item.c	2005-10-01 22:29:39.000000000 +0100
+++ gnome-control-center/capplets/background/gnome-wp-item.c	2005-11-22 00:19:50.000000000 +0000
@@ -274,6 +274,15 @@
 	tw = bw;
       }
       scaled = gnome_wp_pixbuf_center (pixbuf, bgpixbuf, tw, th);
+    } else if (!strcmp (item->options, "zoom")) {
+      if ((gdouble) ph * (gdouble) bw < (gdouble) pw * (gdouble) bh) {
+	tw = 0.5 + (gdouble) pw * (gdouble) bh / (gdouble) ph; 
+	th = bh;
+      } else {
+	th = 0.5 + (gdouble) ph * (gdouble) bw / (gdouble) pw;
+	tw = bw;
+      }
+      scaled = gnome_wp_pixbuf_center (pixbuf, bgpixbuf, tw, th);
     }
   }
 
diff -ur gnome-control-center.orig/libbackground/applier.c gnome-control-center/libbackground/applier.c
--- gnome-control-center.orig/libbackground/applier.c	2005-06-10 19:49:06.000000000 +0100
+++ gnome-control-center/libbackground/applier.c	2005-11-22 00:19:50.000000000 +0000
@@ -1091,6 +1091,27 @@
 
 		break;
 
+	case WPTYPE_ZOOM:
+		asp = (gdouble) pwidth / (gdouble) virtual_geom->width;
+
+		if (asp > (gdouble) pheight / virtual_geom->height) {
+			src_geom->width = pwidth * virtual_geom->height / pheight;
+			src_geom->height = pheight;
+			src_geom->x = (pwidth - src_geom->width) / 2;
+			src_geom->y = 0;
+		} else {
+			src_geom->width = pwidth;
+			src_geom->height = pheight * virtual_geom->width / pwidth;
+			src_geom->x = 0;
+			src_geom->y = (pheight - src_geom->height) / 2;
+		}
+
+		dest_geom->x = dest_geom->y = 0;
+		dest_geom->width = field_geom->width;
+		dest_geom->height = field_geom->height;
+
+		break;
+
 	case WPTYPE_STRETCHED:
 		dest_geom->width = field_geom->width;
 		dest_geom->height = field_geom->height;
diff -ur gnome-control-center.orig/libbackground/preferences.c gnome-control-center/libbackground/preferences.c
--- gnome-control-center.orig/libbackground/preferences.c	2005-11-07 17:56:46.000000000 +0000
+++ gnome-control-center/libbackground/preferences.c	2005-11-22 00:19:50.000000000 +0000
@@ -50,6 +50,7 @@
 	{ WPTYPE_CENTERED, "WPTYPE_CENTERED", "centered"},
 	{ WPTYPE_SCALED, "WPTYPE_SCALED", "scaled"},
 	{ WPTYPE_STRETCHED, "WPTYPE_STRETCHED", "stretched"},
+	{ WPTYPE_ZOOM, "WPTYPE_ZOOM", "zoom"},
 	{ WPTYPE_NONE, "WPTYPE_NONE", "none"},
 	{ 0, NULL, NULL }
 };
@@ -383,6 +384,8 @@
 			type =  WPTYPE_SCALED;
 		} else if (!strncmp (string, "stretched", sizeof ("stretched"))) {
 			type =  WPTYPE_STRETCHED;
+		} else if (!strncmp (string, "zoom", sizeof ("zoom"))) {
+			type =  WPTYPE_ZOOM;
 		}
 		g_free (string);
 	}
@@ -432,6 +435,8 @@
 			return "scaled";
 		case WPTYPE_STRETCHED:
 			return "stretched";
+		case WPTYPE_ZOOM:
+			return "zoom";
 		case WPTYPE_NONE:
 			return "none";
 	        case WPTYPE_UNSET:
diff -ur gnome-control-center.orig/libbackground/preferences.h gnome-control-center/libbackground/preferences.h
--- gnome-control-center.orig/libbackground/preferences.h	2002-03-20 03:30:11.000000000 +0000
+++ gnome-control-center/libbackground/preferences.h	2005-11-22 00:19:50.000000000 +0000
@@ -52,7 +52,7 @@
 
 typedef enum _wallpaper_type_t {
 	WPTYPE_TILED = 0, WPTYPE_CENTERED, WPTYPE_SCALED,
-	WPTYPE_STRETCHED, WPTYPE_NONE,
+	WPTYPE_STRETCHED, WPTYPE_ZOOM, WPTYPE_NONE,
 	WPTYPE_UNSET
 } wallpaper_type_t;
 
diff -ur eel.orig/eel/eel-background.c eel/eel/eel-background.c
--- eel.orig/eel/eel-background.c	2005-10-27 16:03:37.000000000 +0100
+++ eel/eel/eel-background.c	2005-11-22 00:17:03.000000000 +0000
@@ -551,6 +551,7 @@
 	switch (background->details->image_placement) {
 	case EEL_BACKGROUND_TILED:
 	case EEL_BACKGROUND_SCALED:
+	case EEL_BACKGROUND_ZOOM:
 		return TRUE;
 	default:
 		g_assert_not_reached ();
@@ -676,6 +677,24 @@
 				}
 			}
 			break;
+		case EEL_BACKGROUND_ZOOM:
+			eel_gdk_scale_to_min_factor (background->details->image_width_unscaled,
+						     background->details->image_height_unscaled,
+						     dest_width, dest_height,
+						     &fit_width, &fit_height);
+
+			if (image_width != fit_width || image_height != fit_height) {
+				if (cur_scaled) {
+					reload_image = TRUE;
+				} else {
+					scaled_pixbuf = eel_gdk_pixbuf_scale_to_min (background->details->image, dest_width, dest_height);
+					g_object_unref (background->details->image);
+					background->details->image = scaled_pixbuf;
+					image_width = gdk_pixbuf_get_width (scaled_pixbuf);
+					image_height = gdk_pixbuf_get_height (scaled_pixbuf);
+				}
+			}
+			break;
 		}
 
 		if (reload_image) {
@@ -757,6 +776,7 @@
 		case EEL_BACKGROUND_CENTERED:
 		case EEL_BACKGROUND_SCALED:
 		case EEL_BACKGROUND_SCALED_ASPECT:
+		case EEL_BACKGROUND_ZOOM:
 			*pixmap_width = entire_width;
 			*pixmap_height = entire_height;
 		}
@@ -1354,6 +1374,7 @@
 		case EEL_BACKGROUND_CENTERED:
 		case EEL_BACKGROUND_SCALED:
 		case EEL_BACKGROUND_SCALED_ASPECT:
+		case EEL_BACKGROUND_ZOOM:
 			/* Since the image has already been scaled, all these cases
 			 * can be treated identically.
 			 */
diff -ur eel.orig/eel/eel-background.h eel/eel/eel-background.h
--- eel.orig/eel/eel-background.h	2005-03-16 08:29:16.000000000 +0000
+++ eel/eel/eel-background.h	2005-11-22 00:17:03.000000000 +0000
@@ -63,7 +63,8 @@
 	EEL_BACKGROUND_TILED = 0, /* zero makes this the default placement */
 	EEL_BACKGROUND_CENTERED,
 	EEL_BACKGROUND_SCALED,
-	EEL_BACKGROUND_SCALED_ASPECT
+	EEL_BACKGROUND_SCALED_ASPECT,
+	EEL_BACKGROUND_ZOOM
 } EelBackgroundImagePlacement;
 
 GtkType                     eel_background_get_type                         (void);
diff -ur eel.orig/eel/eel-gdk-pixbuf-extensions.c eel/eel/eel-gdk-pixbuf-extensions.c
--- eel.orig/eel/eel-gdk-pixbuf-extensions.c	2005-10-27 16:03:37.000000000 +0100
+++ eel/eel/eel-gdk-pixbuf-extensions.c	2005-11-22 00:17:03.000000000 +0000
@@ -404,6 +404,37 @@
 	}
 }
 
+double
+eel_gdk_scale_to_min_factor (int width, int height,
+			     int min_width, int min_height,
+			     int *scaled_width, int *scaled_height)
+{
+	double scale_factor;
+
+	scale_factor = MAX (min_width / (double) width, min_height / (double) height);
+
+	*scaled_width  = floor (width * scale_factor + .5);
+	*scaled_height = floor (height * scale_factor + .5);
+
+	return scale_factor;
+}
+
+/* Returns a scaled copy of pixbuf, preserving aspect ratio. The copy will
+ * be scaled as small as possible without going under the specified width and height.
+ */
+GdkPixbuf *
+eel_gdk_pixbuf_scale_to_min (GdkPixbuf *pixbuf, int min_width, int min_height)
+{
+	int scaled_width;
+	int scaled_height;
+
+	eel_gdk_scale_to_min_factor (gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf),
+				     min_width, min_height,
+				     &scaled_width, &scaled_height);
+
+	return gdk_pixbuf_scale_simple (pixbuf, scaled_width, scaled_height, GDK_INTERP_BILINEAR);	
+}
+
 /**
  * eel_gdk_pixbuf_is_valid:
  * @pixbuf: A GdkPixbuf
diff -ur eel.orig/eel/eel-gdk-pixbuf-extensions.h eel/eel/eel-gdk-pixbuf-extensions.h
--- eel.orig/eel/eel-gdk-pixbuf-extensions.h	2002-07-10 09:20:11.000000000 +0100
+++ eel/eel/eel-gdk-pixbuf-extensions.h	2005-11-22 00:17:03.000000000 +0000
@@ -71,6 +71,15 @@
 							       int                    max_height,
 							       int                   *scaled_width,
 							       int                   *scaled_height);
+GdkPixbuf *          eel_gdk_pixbuf_scale_to_min              (GdkPixbuf             *pixbuf,
+							       int                    min_width,
+							       int                    min_height);
+double              eel_gdk_scale_to_min_factor               (int                   width,
+                                                               int                   height,
+							       int                   min_width,
+							       int                   min_height,
+							       int                   *scaled_width,
+							       int                   *scaled_height);
 
 /* return average color values for each component (argb) */
 guint32              eel_gdk_pixbuf_average_value             (GdkPixbuf             *pixbuf);
diff -ur nautilus.orig/libbackground/applier.c nautilus/libbackground/applier.c
--- nautilus.orig/libbackground/applier.c	2005-06-10 19:49:06.000000000 +0100
+++ nautilus/libbackground/applier.c	2005-11-22 00:25:13.000000000 +0000
@@ -1091,6 +1091,28 @@
 
 		break;
 
+	case WPTYPE_ZOOM:
+		asp = (gdouble) pwidth / (gdouble) virtual_geom->width;
+
+		if (asp > (gdouble) pheight / virtual_geom->height) {
+			src_geom->width = pwidth * virtual_geom->height / pheight;
+			src_geom->height = pheight;
+			src_geom->x = (pwidth - src_geom->width) / 2;
+			src_geom->y = 0;
+		} else {
+			src_geom->width = pwidth;
+			src_geom->height = pheight * virtual_geom->width / pwidth;
+			src_geom->x = 0;
+			src_geom->y = (pheight - src_geom->height) / 2;
+		}
+
+
+		dest_geom->x = dest_geom->y = 0;
+		dest_geom->width = field_geom->width;
+		dest_geom->height = field_geom->height;
+
+		break;
+
 	case WPTYPE_STRETCHED:
 		dest_geom->width = field_geom->width;
 		dest_geom->height = field_geom->height;
diff -ur nautilus.orig/libbackground/preferences.c nautilus/libbackground/preferences.c
--- nautilus.orig/libbackground/preferences.c	2005-11-07 17:56:46.000000000 +0000
+++ nautilus/libbackground/preferences.c	2005-11-22 00:25:13.000000000 +0000
@@ -50,6 +50,7 @@
 	{ WPTYPE_CENTERED, "WPTYPE_CENTERED", "centered"},
 	{ WPTYPE_SCALED, "WPTYPE_SCALED", "scaled"},
 	{ WPTYPE_STRETCHED, "WPTYPE_STRETCHED", "stretched"},
+	{ WPTYPE_ZOOM, "WPTYPE_ZOOM", "zoom"},
 	{ WPTYPE_NONE, "WPTYPE_NONE", "none"},
 	{ 0, NULL, NULL }
 };
@@ -383,6 +384,8 @@
 			type =  WPTYPE_SCALED;
 		} else if (!strncmp (string, "stretched", sizeof ("stretched"))) {
 			type =  WPTYPE_STRETCHED;
+		} else if (!strncmp (string, "zoom", sizeof ("zoom"))) {
+			type =  WPTYPE_ZOOM;
 		}
 		g_free (string);
 	}
@@ -432,6 +435,8 @@
 			return "scaled";
 		case WPTYPE_STRETCHED:
 			return "stretched";
+		case WPTYPE_ZOOM:
+			return "zoom";
 		case WPTYPE_NONE:
 			return "none";
 	        case WPTYPE_UNSET:
diff -ur nautilus.orig/libbackground/preferences.h nautilus/libbackground/preferences.h
--- nautilus.orig/libbackground/preferences.h	2002-03-20 03:30:11.000000000 +0000
+++ nautilus/libbackground/preferences.h	2005-11-22 00:25:13.000000000 +0000
@@ -52,7 +52,7 @@
 
 typedef enum _wallpaper_type_t {
 	WPTYPE_TILED = 0, WPTYPE_CENTERED, WPTYPE_SCALED,
-	WPTYPE_STRETCHED, WPTYPE_NONE,
+	WPTYPE_STRETCHED, WPTYPE_ZOOM, WPTYPE_NONE,
 	WPTYPE_UNSET
 } wallpaper_type_t;
 
diff -ur nautilus.orig/libnautilus-private/nautilus-directory-background.c nautilus/libnautilus-private/nautilus-directory-background.c
--- nautilus.orig/libnautilus-private/nautilus-directory-background.c	2005-08-12 19:11:29.000000000 +0100
+++ nautilus/libnautilus-private/nautilus-directory-background.c	2005-11-22 00:25:13.000000000 +0000
@@ -154,6 +154,9 @@
         case WPTYPE_SCALED:
                 *placement = EEL_BACKGROUND_SCALED_ASPECT;
                 break;
+	case WPTYPE_ZOOM:
+		*placement = EEL_BACKGROUND_ZOOM;
+		break;
         }
 	
         end_color     = eel_gdk_rgb_to_color_spec (eel_gdk_color_to_rgb (prefs->color2));
@@ -230,6 +233,9 @@
 			case EEL_BACKGROUND_SCALED_ASPECT:
 				wallpaper_align = WPTYPE_SCALED;
 				break;
+			case EEL_BACKGROUND_ZOOM:
+				wallpaper_align = WPTYPE_ZOOM;
+				break;
 			default:
 				g_assert_not_reached ();
 				wallpaper_align = WPTYPE_TILED;

Attachment: stock_wallpaper-zoom.png
Description: PNG image

diff -ur gnome-user-docs.orig/gnome2-user-guide/C/goscustdesk.xml gnome-user-docs/gnome2-user-guide/C/goscustdesk.xml 
--- gnome-user-docs.orig/gnome2-user-guide/C/goscustdesk.xml.orig	2005-11-22 00:30:26.000000000 +0000
+++ gnome-user-docs/gnome2-user-guide/C/goscustdesk.xml	2005-11-22 00:34:44.000000000 +0000
@@ -169,7 +169,7 @@
                 </listitem>
                 <listitem>
                   <para><guilabel>Fill Screen</guilabel>: Enlarges the image to cover
-the desktop and maintains the relative dimensions of the image.</para>
+the desktop, but without maintaining the relative dimensions of the image.</para>
                 </listitem>
                 <listitem>
                   <para><guilabel>Scaled</guilabel>: Enlarges the image until the
@@ -177,8 +177,12 @@
 image.</para>
                 </listitem>
                 <listitem>
-                  <para><guilabel>Tiled</guilabel>: Enlarges the image until the image
-meets the screen edges, and maintains the relative dimensions of the image.</para>
+                  <para><guilabel>Zoomed</guilabel>: Enlarges the image until the
+image covers the desktop, while maintaining the relative dimensions of the image.</para>
+                </listitem>
+                <listitem>
+                  <para><guilabel>Tiled</guilabel>: Repeats the image from top left
+corner to cover the desktop.</para>
                 </listitem>
               </itemizedlist>
             </entry>

Attachment: signature.asc
Description: This is a digitally signed message part



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