GTK+ icon themeability, continued



Since I believe Havoc is the only person to ereply to my last post on
the topic, on either gtk-devel or desktop-devel, I am assuming no one
else has an opinion ;-)

I have filed a new bug, 70648, regarding themeing of GTK+ stock icon
sizes.

The bug report includes a patch, and I attach a revised version below.

The main problem with the current RC-file icon theme mechanism is that
it doesn't lend itself to theming of the stock icon size, which is the
most pressing accessibility requirement regarding icons.

The current API allows replacement/respecification of the stock icons on
a per-stock-name, per-size, and per-state basis.  This allows a complete
replacement of the GTK+ stock icons set which certainly would allow any
accessibility needs to be met... HOWEVER...

(1) the only way to change the icon sizes is to replace the icons for
every size and every stock icon name, otherwise the icons will get
resized to the hard-wired "standard" GTK+ icon sizes.

(2) icons must be respecified (as Havoc already noted in reply to my
last email on the topic) as pixmap files; but the stock icon files are
not installed with GTK+, so without installing them this mechanism can't
be used for the default stock icon set.

(3) specifying icon pixmaps for each size requires manually rescaling
most of the GTK+ stock icons and installing the resulting pixmap files;
this also means approximately 300 entries in gtkrc.

(4) if one needs, for instance in a high-contrast theme, light and
dark-background-compatible versions then the number of rc file entries
could exceed 1500.

Ugh.

The attached patch allows theming of the "default sizes" for icons, so
that, for instance, the menu icon size can be set to 24 pixels rather
than the current 16.  This works nicely with the large print theme, but
since gtkiconfactory.c installs a number of the stock icons as
non-resizeable, this breaks for some stock icons.  The patch changes
gtkiconfactory.c to install these icons as resizeable.  

However there is a resulting issue - the rescaling technique can produce
suboptimal looking icons when scaling upwards.  That wouldn't be a
problem for the icons that are only used in one context, such as button
icons, *except* that the existing button icons are actually 20x20
pixmaps, even though the default button icon size is 24x24.  

There are two straightforward solutions to this which would prevent a
visible regression using the default themes (and any cosmetic
imperfections in a large-print theme would possible be bugs but
certainly not regressions since at the moment icon size theming doesn't
really work without this patch).  The solutions:

(a) pad the existing 20x20 GTK+ stock pixmaps to 24x24, so that they are
not rescaled in the default theme even if they are specified as
resizeable;

(b) change the default GTK+ button icon size to 20x20.  This last
solution is simpler but will have a small change in the rendering of
stock icons other than the 20x20 "button only" when they are rendered
onto buttons.  I believe that the only commonly used icons that would
thus be affected would be 
GTK_STOCK_HELP.

Please advise regarding these issues, and advise as to why the default
button icons are actually 20x20 rather than the "specified" 24x24...
perhaps a matter of history?

If changing the hard-wired default size of button icons to 20x20 is
acceptable I can produce a straightforward patch which affects no public
API (other than adding GtkSettings parameters used by the default
theme), causes no API regression other than a tiny change to the size of
GTK_STOCK_HELP, and permits reasonable icon size theming without
creating a new engine or installing all of the stock icons as separate
.png files.  Even the small UI change to GTK_STOCK_HELP can be
circumvented with an entry in the 'default' gtkrc file.

Best regards,

- Bill
Index: gtk/gtkiconfactory.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkiconfactory.c,v
retrieving revision 1.30
diff -u -r1.30 gtkiconfactory.c
--- gtk/gtkiconfactory.c	2002/01/08 00:04:54	1.30
+++ gtk/gtkiconfactory.c	2002/02/06 13:46:59
@@ -446,29 +446,52 @@
   gtk_icon_set_unref (set);
 }
 
+#define ICONS_RESIZEABLE 1
+
 static void
 get_default_icons (GtkIconFactory *factory)
 {
   /* KEEP IN SYNC with gtkstock.c */
 
   add_unsized (factory, stock_missing_image, GTK_STOCK_MISSING_IMAGE);
-  
+
+#if ICONS_RESIZEABLE
+  add_unsized (factory, dialog_error, GTK_STOCK_DIALOG_ERROR);
+  add_unsized (factory, dialog_info, GTK_STOCK_DIALOG_INFO);
+  add_unsized (factory, dialog_question, GTK_STOCK_DIALOG_QUESTION);
+  add_unsized (factory, dialog_warning, GTK_STOCK_DIALOG_WARNING);
+#else
   add_sized (factory, dialog_error, GTK_ICON_SIZE_DIALOG, GTK_STOCK_DIALOG_ERROR);
   add_sized (factory, dialog_info, GTK_ICON_SIZE_DIALOG, GTK_STOCK_DIALOG_INFO);
   add_sized (factory, dialog_question, GTK_ICON_SIZE_DIALOG, GTK_STOCK_DIALOG_QUESTION);
   add_sized (factory, dialog_warning, GTK_ICON_SIZE_DIALOG, GTK_STOCK_DIALOG_WARNING);
+#endif
   
   /* dnd size only */
+#if ICONS_RESIZEABLE
+  add_unsized (factory, stock_new, GTK_STOCK_DND);
+  add_unsized (factory, stock_dnd_multiple, GTK_STOCK_DND_MULTIPLE);
+#else
   add_sized (factory, stock_new, GTK_ICON_SIZE_DND, GTK_STOCK_DND);
   add_sized (factory, stock_dnd_multiple, GTK_ICON_SIZE_DND, GTK_STOCK_DND_MULTIPLE);
-  
+#endif
+
   /* Only have button sizes */
+#if ICONS_RESIZEABLE  
+  add_unsized (factory, stock_button_apply, GTK_STOCK_APPLY);
+  add_unsized (factory, stock_button_cancel, GTK_STOCK_CANCEL);
+  add_unsized (factory, stock_button_no, GTK_STOCK_NO);
+  add_unsized (factory, stock_button_ok, GTK_STOCK_OK);
+  add_unsized (factory, stock_button_yes, GTK_STOCK_YES);
+  
+#else
   add_sized (factory, stock_button_apply, GTK_ICON_SIZE_BUTTON, GTK_STOCK_APPLY);
   add_sized (factory, stock_button_cancel, GTK_ICON_SIZE_BUTTON, GTK_STOCK_CANCEL);
   add_sized (factory, stock_button_no, GTK_ICON_SIZE_BUTTON, GTK_STOCK_NO);
   add_sized (factory, stock_button_ok, GTK_ICON_SIZE_BUTTON, GTK_STOCK_OK);
   add_sized (factory, stock_button_yes, GTK_ICON_SIZE_BUTTON, GTK_STOCK_YES);
-
+#endif
+  
   /* Generic + button sizes */
   add_sized_with_fallback (factory,
                            stock_close,
@@ -588,6 +611,19 @@
     {
 #define NUM_BUILTIN_SIZES 7
       gint i;
+      gint menu_icon_size, button_icon_size,
+	   small_toolbar_icon_size, large_toolbar_icon_size,
+	   dnd_icon_size, dialog_icon_size;
+      GtkSettings *settings = gtk_settings_get_default ();
+      
+      g_object_get (G_OBJECT (settings),
+		    "gtk-icon-menu-size", &menu_icon_size,
+		    "gtk-icon-button-size", &button_icon_size,
+		    "gtk-icon-small-toolbar-size", &small_toolbar_icon_size,
+		    "gtk-icon-large-toolbar-size", &large_toolbar_icon_size,
+		    "gtk-icon-dnd-size", &dnd_icon_size,
+		    "gtk-icon-dialog-size", &dialog_icon_size,
+		    NULL);	      
 
       icon_aliases = g_hash_table_new (g_str_hash, g_str_equal);
       
@@ -608,33 +644,33 @@
       
       icon_sizes[GTK_ICON_SIZE_MENU].size = GTK_ICON_SIZE_MENU;
       icon_sizes[GTK_ICON_SIZE_MENU].name = "gtk-menu";
-      icon_sizes[GTK_ICON_SIZE_MENU].width = 16;
-      icon_sizes[GTK_ICON_SIZE_MENU].height = 16;
+      icon_sizes[GTK_ICON_SIZE_MENU].width = menu_icon_size;
+      icon_sizes[GTK_ICON_SIZE_MENU].height = menu_icon_size;
 
       icon_sizes[GTK_ICON_SIZE_BUTTON].size = GTK_ICON_SIZE_BUTTON;
       icon_sizes[GTK_ICON_SIZE_BUTTON].name = "gtk-button";
-      icon_sizes[GTK_ICON_SIZE_BUTTON].width = 24;
-      icon_sizes[GTK_ICON_SIZE_BUTTON].height = 24;
+      icon_sizes[GTK_ICON_SIZE_BUTTON].width = button_icon_size;
+      icon_sizes[GTK_ICON_SIZE_BUTTON].height = button_icon_size;
 
       icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].size = GTK_ICON_SIZE_SMALL_TOOLBAR;
       icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].name = "gtk-small-toolbar";
-      icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].width = 18;
-      icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].height = 18;
+      icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].width = small_toolbar_icon_size;
+      icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].height = small_toolbar_icon_size;
       
       icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].size = GTK_ICON_SIZE_LARGE_TOOLBAR;
       icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].name = "gtk-large-toolbar";
-      icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].width = 24;
-      icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].height = 24;
+      icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].width = large_toolbar_icon_size;
+      icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].height = large_toolbar_icon_size;
 
       icon_sizes[GTK_ICON_SIZE_DND].size = GTK_ICON_SIZE_DND;
       icon_sizes[GTK_ICON_SIZE_DND].name = "gtk-dnd";
-      icon_sizes[GTK_ICON_SIZE_DND].width = 32;
-      icon_sizes[GTK_ICON_SIZE_DND].height = 32;
+      icon_sizes[GTK_ICON_SIZE_DND].width = dnd_icon_size;
+      icon_sizes[GTK_ICON_SIZE_DND].height = dnd_icon_size;
 
       icon_sizes[GTK_ICON_SIZE_DIALOG].size = GTK_ICON_SIZE_DIALOG;
       icon_sizes[GTK_ICON_SIZE_DIALOG].name = "gtk-dialog";
-      icon_sizes[GTK_ICON_SIZE_DIALOG].width = 48;
-      icon_sizes[GTK_ICON_SIZE_DIALOG].height = 48;
+      icon_sizes[GTK_ICON_SIZE_DIALOG].width = dialog_icon_size;
+      icon_sizes[GTK_ICON_SIZE_DIALOG].height = dialog_icon_size;
 
       g_assert ((GTK_ICON_SIZE_DIALOG + 1) == NUM_BUILTIN_SIZES);
 
Index: gtk/gtksettings.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtksettings.c,v
retrieving revision 1.23
diff -u -r1.23 gtksettings.c
--- gtk/gtksettings.c	2001/12/12 20:26:50	1.23
+++ gtk/gtksettings.c	2002/02/06 13:47:00
@@ -30,7 +30,13 @@
   PROP_THEME_NAME,
   PROP_KEY_THEME_NAME,
   PROP_MENU_BAR_ACCEL,
-  PROP_DND_DRAG_THRESHOLD
+  PROP_DND_DRAG_THRESHOLD,
+  PROP_ICON_MENU_SIZE,
+  PROP_ICON_BUTTON_SIZE,
+  PROP_ICON_SMALL_TOOLBAR_SIZE,
+  PROP_ICON_LARGE_TOOLBAR_SIZE,
+  PROP_ICON_DND_SIZE,
+  PROP_ICON_DIALOG_SIZE
 };
 
 
@@ -208,6 +214,60 @@
                                                                G_PARAM_READWRITE),
 					     NULL);
   g_assert (result == PROP_DND_DRAG_THRESHOLD);
+  
+  result = settings_install_property_parser (class,
+					     g_param_spec_int ("gtk-icon-menu-size",
+							       _("Menu Icon Size"),
+							       _("Size of menu icons, in pixels"),
+							       1, 128, 16,
+                                                               G_PARAM_READWRITE),
+					     NULL);
+  g_assert (result == PROP_ICON_MENU_SIZE);
+  
+  result = settings_install_property_parser (class,
+					     g_param_spec_int ("gtk-icon-button-size",
+							       _("Button Icon Size"),
+							       _("Size of button icons, in pixels"),
+							       1, 128, 20,
+                                                               G_PARAM_READWRITE),
+					     NULL);
+  g_assert (result == PROP_ICON_BUTTON_SIZE);
+
+  result = settings_install_property_parser (class,
+					     g_param_spec_int ("gtk-icon-small-toolbar-size",
+							       _("Small Toolbar Icon Size"),
+							       _("Size of small toolbar icons, in pixels"),
+							       1, 128, 18,
+                                                               G_PARAM_READWRITE),
+					     NULL);
+  g_assert (result == PROP_ICON_SMALL_TOOLBAR_SIZE);
+  
+  result = settings_install_property_parser (class,
+					     g_param_spec_int ("gtk-icon-large-toolbar-size",
+							       _("Large Toolbar Icon Size"),
+							       _("Size of large toolbar icons, in pixels"),
+							       1, 128, 24,
+                                                               G_PARAM_READWRITE),
+					     NULL);
+  g_assert (result == PROP_ICON_LARGE_TOOLBAR_SIZE);
+  
+  result = settings_install_property_parser (class,
+					     g_param_spec_int ("gtk-icon-dnd-size",
+							       _("DnD Icon Size"),
+							       _("Size of drag-and-drop icons, in pixels"),
+							       1, 128, 32,
+                                                               G_PARAM_READWRITE),
+					     NULL);
+  g_assert (result == PROP_ICON_DND_SIZE);
+  
+  result = settings_install_property_parser (class,
+					     g_param_spec_int ("gtk-icon-dialog-size",
+							       _("Dialog Icon Size"),
+							       _("Size of dialog icons, in pixels"),
+							       1, 128, 48,
+                                                               G_PARAM_READWRITE),
+					     NULL);
+  g_assert (result == PROP_ICON_DIALOG_SIZE);
   
 }
 


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