Mikhael Goikhman wrote:

> On 23 Jun 2002 22:30:25 -0600, Steve Talley wrote:
>
> > Mikhael Goikhman wrote:
> >
> > > Another optimization would be to say that size 0 is invalid so it
> > > may be used to switch the feature off. Any of the following 3:
> > >
> > >   Style * IconSize
> > >   Style * IconSize 0 0
> > >   Style * IconSize 0 0, 0 0
> > >
> > > may disable the feature completely. It would be possible to only
> > > partialy disable it (IconSize 0 0, 48 0). This should save another 4
> > > bits and seems more consistent than the logic in the patch that
> > > allows one integer in the pair (I don't think this should be allowed
> > > as ambiguous, use 0 instead).
> >
> > Agreed.  However, I have made -1 the disable/default value, since 0 is
> > a valid maximum dimension.  Consider the setting:
> >
> >     Style * IconSize 64 0
> >
> > This will result in something like the attached zeroheight.jpg
> > (IconGrid is defined) or zeroheight2.jpg (IconGrid not defined),
> > effectively allowing the user to specify that no image is to be shown
> > but still be able size the icon title.
>
> Hmm, ok.
>
> Can IconSize receive 0 arguments (not just 2 or 4) for disabling too?

Oops.  Yes, I have added this feature to the attached patch.

Steve
Index: fvwm/add_window.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/add_window.c,v
retrieving revision 1.295
diff -u -r1.295 add_window.c
--- fvwm/add_window.c   2002/06/17 00:33:06     1.295
+++ fvwm/add_window.c   2002/06/24 15:29:52
@@ -1057,6 +1057,25 @@
        return;
 }
 
+/*
+ * Copy icon size limits from window_style structure to FvwmWindow
+ * structure.
+ */
+void setup_icon_size_limits(FvwmWindow *fw, window_style *pstyle)
+{
+    if (SHAS_ICON_SIZE_LIMITS(&pstyle->flags)) {
+        fw->min_icon_width = SGET_MIN_ICON_WIDTH(*pstyle);
+        fw->min_icon_height = SGET_MIN_ICON_HEIGHT(*pstyle);
+        fw->max_icon_width = SGET_MAX_ICON_WIDTH(*pstyle);
+        fw->max_icon_height = SGET_MAX_ICON_HEIGHT(*pstyle);
+    } else {
+        fw->min_icon_width = MIN_ALLOWABLE_ICON_DIMENSION;
+        fw->min_icon_height = MIN_ALLOWABLE_ICON_DIMENSION;
+        fw->max_icon_width = MAX_ALLOWABLE_ICON_DIMENSION;
+        fw->max_icon_height = MAX_ALLOWABLE_ICON_DIMENSION;
+    }
+}
+
 Bool setup_window_placement(
        FvwmWindow *fw, window_style *pstyle, rectangle *attr_g,
        initial_window_options_type *win_opts)
@@ -2074,6 +2093,9 @@
 
        /****** border width ******/
        XSetWindowBorderWidth(dpy, FW_W(fw), 0);
+
+       /****** icon size limits ******/
+       setup_icon_size_limits(fw, &style);
 
        /***** placement penalities *****/
        setup_placement_penalty(fw, &style);
Index: fvwm/add_window.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/add_window.h,v
retrieving revision 1.26
diff -u -r1.26 add_window.h
--- fvwm/add_window.h   2002/03/24 19:19:24     1.26
+++ fvwm/add_window.h   2002/06/24 15:29:53
@@ -57,6 +57,8 @@
        FvwmWindow *fw);
 void setup_frame_size_limits(
        FvwmWindow *fw, window_style *pstyle);
+void setup_icon_size_limits(
+       FvwmWindow *fw, window_style *pstyle);
 void increase_icon_hint_count(
        FvwmWindow *fw);
 void change_icon(
Index: fvwm/fvwm.1
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/fvwm.1,v
retrieving revision 1.23
diff -u -r1.23 fvwm.1
--- fvwm/fvwm.1 2002/06/21 14:32:34     1.23
+++ fvwm/fvwm.1 2002/06/24 15:30:04
@@ -5333,7 +5333,7 @@
 slashes ('/').  The last style in these groups is the default.
 .IR BorderWidth ", " HandleWidth ,
 .IR NoIcon " / " Icon ", " MiniIcon ,
-.IR IconBox ", " IconGrid ", " IconFill ,
+.IR IconBox ", " IconGrid ", " IconFill ", " IconSize ,
 .IR NoTitle " / " Title ,
 .IR TitleAtBottom " / " TitleAtLeft " / " TitleAtRight " / " TitleAtTop ,
 .IR LeftTitleRotatedCW " / " LeftTitleRotatedCCW,
@@ -5881,8 +5881,9 @@
 values for the icon grid, looking for a free space. The default
 grid is 3 by 3 pixels which gives a tightly packed appearance. To
 get a more regular appearance use a grid larger than your largest
-icon. Currently there is no way to clip an icon to a maximum
-size. An
+icon. Use the
+.I IconSize
+definition to clip an icon to a maximum size. An
 .I IconGrid
 definition must follow the
 .B IconBox
@@ -5913,6 +5914,42 @@
 .EX
 Style * IconBox -80x240-1-1, IconFill b r
 .EE
+.I IconSize
+sets limits on the size of an icon image.  Both user-provided
+and application-provided icon images are affected.
+.EX
+.RI IconSize " [ " width " " height " [ " maxwidth " " maxheight " ] ]"
+.EE
+All arguments are measured in pixels.  When all four arguments are
+passed to
+.I IconSize,
+.I width
+and
+.I height
+represent the minimum size of an icon, and
+.I maxwidth
+and
+.I maxheight
+represent the maximum size of an icon.  Icon images that are smaller
+than the minimum size are padded.  Icon images that are bigger than
+the maximum size are clipped.
+
+If only two arguments are passed to
+.I IconSize,
+.I width
+and
+.I height
+represent the absolute size of an icon.  Icons covered by this style
+will be padded or clipped to achieve the given size.
+
+If no arguments are specified, the default values are used for each
+dimension.  This effectively places no limits on the size of an icon.
+
+The value of "-1" can be used in place of any of the arguments to
+specify the default value for that dimension.
+
+Note that application-provided icon windows are not affected.
+
 .I MiniIcon
 specifies a pixmap to use as the miniature icon for the
 window. This miniature icon can be drawn in a title-bar button
Index: fvwm/fvwm.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/fvwm.h,v
retrieving revision 1.194
diff -u -r1.194 fvwm.h
--- fvwm/fvwm.h 2002/06/17 00:33:06     1.194
+++ fvwm/fvwm.h 2002/06/24 15:30:05
@@ -525,6 +525,7 @@
        unsigned has_handle_width : 1;
        unsigned has_icon : 1;
        unsigned has_icon_boxes : 1;
+       unsigned has_icon_size_limits : 1;
        unsigned has_max_window_size : 1;
        unsigned has_window_shade_steps : 1;
        unsigned has_mini_icon : 1;
@@ -576,6 +577,10 @@
 #ifdef USEDECOR
        char *decor_name;
 #endif
+       unsigned char min_icon_width;
+       unsigned char max_icon_width;
+       unsigned char min_icon_height;
+       unsigned char max_icon_height;
        char *icon_font;
        char *window_font;
        char *fore_color_name;
@@ -764,6 +769,10 @@
 
        int default_layer;
        int layer;
+       unsigned char min_icon_width;
+       unsigned char max_icon_width;
+       unsigned char min_icon_height;
+       unsigned char max_icon_height;
        int max_window_width;
        int max_window_height;
        int shade_anim_steps;
Index: fvwm/icons.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/icons.c,v
retrieving revision 1.181
diff -u -r1.181 icons.c
--- fvwm/icons.c        2002/06/19 14:11:27     1.181
+++ fvwm/icons.c        2002/06/24 15:30:07
@@ -254,6 +254,107 @@
       break;
     }
   }
+
+  /* Resize icon if necessary */
+  if ((IS_ICON_OURS(fw)) &&
+    fw->icon_g.picture_w_g.height > 0 && fw->icon_g.picture_w_g.height > 0)
+  {
+    unsigned int newWidth = fw->icon_g.picture_w_g.width;
+    unsigned int newHeight = fw->icon_g.picture_w_g.height;
+    Boolean resize = False;
+
+    if(newWidth < fw->min_icon_width) {
+      newWidth = fw->min_icon_width;
+      resize = True;
+    } else
+
+    if(newWidth > fw->max_icon_width) {
+      newWidth = fw->max_icon_width;
+      resize = True;
+    }
+
+    if(newHeight < fw->min_icon_height) {
+      newHeight = fw->min_icon_height;
+      resize = True;
+    } else
+
+    if(newHeight > fw->max_icon_height) {
+      newHeight = fw->max_icon_height;
+      resize = True;
+    }
+
+    if(resize) {
+      ICON_DBG((stderr,"ciw: Changing icon (%s) from %dx%d to %dx%d\n",
+        fw->name,
+        fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height,
+        newWidth, newHeight));
+
+      /* Resize the icon Pixmap */
+      SetIconPixmapSize(&(fw->iconPixmap),
+        fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height,
+        fw->iconDepth, newWidth, newHeight,
+        (IS_PIXMAP_OURS(fw)));
+
+      /* Resize the icon mask Pixmap if one was defined */
+      if(fw->icon_maskPixmap) {
+        SetIconPixmapSize(&(fw->icon_maskPixmap),
+          fw->icon_g.picture_w_g.width, fw->icon_g.picture_w_g.height,
+          1, newWidth, newHeight, (IS_PIXMAP_OURS(fw)));
+      }
+
+      /* Set the new dimensions of the icon window */
+      fw->icon_g.picture_w_g.width = newWidth;
+      fw->icon_g.picture_w_g.height = newHeight;
+    }
+  }
+}
+
+/****************************************************************************
+ *
+ * Resizes the given icon Pixmap.
+ *
+ ****************************************************************************/
+static void SetIconPixmapSize(Pixmap *icon,
+    unsigned int width, unsigned int height, unsigned int depth,
+    unsigned int newWidth, unsigned int newHeight,
+    unsigned int freeOldPixmap)
+{
+    Pixmap oldPixmap;
+    GC gc;
+    XGCValues gc_init;
+
+    /* Check for invalid dimensions */
+    if(newWidth == 0 || newHeight == 0) {
+        return;
+    }
+
+    /* Save the existing Pixmap */
+    oldPixmap = *icon;
+
+    /* Create a new Pixmap with the new dimensions */
+    *icon = XCreatePixmap(
+        dpy, oldPixmap, newWidth, newHeight, depth);
+
+    /* Zero out new Pixmap */
+    gc = XCreateGC(dpy, *icon, 0, &gc_init);
+    XSetForeground(dpy, gc, 0);
+    XFillRectangle(dpy, *icon, gc, 0, 0, newWidth, newHeight);
+
+    /*
+     * Copy old Pixmap onto new.  Center horizontally.  Center
+     * vertically if the new height is smaller than the old.
+     * Otherwise, place the icon on the bottom, along the title
+     * bar.
+     */
+    XCopyArea(dpy, oldPixmap, *icon, gc, 0, 0, width, height,
+        (newWidth - width)/2, newHeight > height ?
+            newHeight - height : (newHeight - height)/2);
+
+    XFreeGC(dpy, gc);
+
+    if(freeOldPixmap) {
+        XFreePixmap(dpy, oldPixmap);
+    }
 }
 
 /****************************************************************************
Index: fvwm/icons.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/icons.h,v
retrieving revision 1.10
diff -u -r1.10 icons.h
--- fvwm/icons.h        2002/06/18 10:52:13     1.10
+++ fvwm/icons.h        2002/06/24 15:30:07
@@ -29,6 +29,10 @@
 void ChangeIconPixmap(FvwmWindow *fw);
 void RedoIconName(FvwmWindow *);
 void DrawIconWindow(FvwmWindow *);
+void SetIconPixmapSize(Pixmap *icon,
+    unsigned int width, unsigned int height, unsigned int depth,
+    unsigned int newWidth, unsigned int newHeight,
+    unsigned int freeOldPixmap);
 void CreateIconWindow(FvwmWindow *fw, int def_x, int def_y);
 void Iconify(FvwmWindow *fw, initial_window_options_type *win_opts);
 void DeIconify(FvwmWindow *);
Index: fvwm/style.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/style.c,v
retrieving revision 1.162
diff -u -r1.162 style.c
--- fvwm/style.c        2002/06/18 10:52:14     1.162
+++ fvwm/style.c        2002/06/24 15:30:11
@@ -446,6 +446,13 @@
        {
                SSET_HANDLE_WIDTH(*merged_style, SGET_HANDLE_WIDTH(*add_style));
        }
+       if (add_style->flags.has_icon_size_limits)
+       {
+               SSET_MIN_ICON_WIDTH(*merged_style, 
SGET_MIN_ICON_WIDTH(*add_style));
+               SSET_MIN_ICON_HEIGHT(*merged_style, 
SGET_MIN_ICON_HEIGHT(*add_style));
+               SSET_MAX_ICON_WIDTH(*merged_style, 
SGET_MAX_ICON_WIDTH(*add_style));
+               SSET_MAX_ICON_HEIGHT(*merged_style, 
SGET_MAX_ICON_HEIGHT(*add_style));
+       }
        if (add_style->flags.has_max_window_size)
        {
                SSET_MAX_WINDOW_WIDTH(
@@ -1686,6 +1693,72 @@
          SFSET_HAS_NO_ICON_TITLE(*ptmpstyle, 0);
          SMSET_HAS_NO_ICON_TITLE(*ptmpstyle, 1);
          SCSET_HAS_NO_ICON_TITLE(*ptmpstyle, 1);
+       }
+       else if (StrEquals(token, "IconSize"))
+       {
+         int vals[4];
+      int i;
+         found = True;
+
+         switch(GetIntegerArguments(rest, &rest, vals, 4)) {
+       
+           default:
+             fvwm_msg(ERR, "CMD_Style",
+               "IconSize requires exactly 0, 2 or 4 numerical arguments");
+           break;
+       
+           /* No break is intentional */
+           case 0:
+             /* No arguments results in default values */
+             vals[0] = vals[1] = UNSPECIFIED_ICON_DIMENSION;
+       
+           /* No break is intentional */
+           case 2:
+             /* Max and min values are the same */
+             vals[2] = vals[0];
+             vals[3] = vals[1];
+       
+           case 4:
+       
+             /* Validate values */
+             for(i = 0; i < 4; i++) {
+               int use_default = 0;
+       
+               if( vals[i] < MIN_ALLOWABLE_ICON_DIMENSION ||
+                 vals[i] > MAX_ALLOWABLE_ICON_DIMENSION)
+               {
+                 fvwm_msg(ERR, "CMD_Style",
+                   "IconSize dimension (%d) not in valid range (%d-%d)",
+                   vals[i], MIN_ALLOWABLE_ICON_DIMENSION,
+                   MAX_ALLOWABLE_ICON_DIMENSION);
+
+                 use_default = 1;
+               } else
+
+               /* User requests default value for this dimension */
+               if(vals[i] == UNSPECIFIED_ICON_DIMENSION) {
+                 use_default = 1;
+               }
+
+               if(use_default) {
+                 /* Set default value for this dimension.  The
+                  * first two indexes refer to min values, the
+                  * latter two to max values. */
+                 vals[i] = i < 2 ? MIN_ALLOWABLE_ICON_DIMENSION :
+                   MAX_ALLOWABLE_ICON_DIMENSION;
+               }
+             }
+
+             SSET_MIN_ICON_WIDTH(*ptmpstyle, vals[0]);
+             SSET_MIN_ICON_HEIGHT(*ptmpstyle, vals[1]);
+             SSET_MAX_ICON_WIDTH(*ptmpstyle, vals[2]);
+             SSET_MAX_ICON_HEIGHT(*ptmpstyle, vals[3]);
+
+             ptmpstyle->flags.has_icon_size_limits = 1;
+             ptmpstyle->flag_mask.has_icon_size_limits = 1;
+             ptmpstyle->change_mask.has_icon_size_limits = 1;
+           break;
+         }
        }
        else if (StrEquals(token, "IconBox"))
        {
Index: fvwm/style.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/style.h,v
retrieving revision 1.58
diff -u -r1.58 style.h
--- fvwm/style.h        2002/05/26 21:47:31     1.58
+++ fvwm/style.h        2002/06/24 15:30:12
@@ -27,6 +27,7 @@
 #define SHAS_HANDLE_WIDTH(sf)        ((sf)->has_handle_width)
 #define SHAS_ICON(sf)                ((sf)->has_icon)
 #define SHAS_ICON_BOXES(sf)          ((sf)->has_icon_boxes)
+#define SHAS_ICON_SIZE_LIMITS(sf)     ((sf)->has_icon_size_limits)
 #define SHAS_MAX_WINDOW_SIZE(sf)      ((sf)->has_max_window_size)
 #define SHAS_WINDOW_SHADE_STEPS(sf)   ((sf)->has_window_shade_steps)
 #define SHAS_MINI_ICON(sf)           ((sf)->has_mini_icon)
@@ -528,6 +529,14 @@
 #define SSET_START_PAGE_Y(s,x)       ((s).start_page_y = (x))
 #define SGET_START_SCREEN(s)         ((s).start_screen)
 #define SSET_START_SCREEN(s,x)       ((s).start_screen = (x))
+#define SGET_MIN_ICON_WIDTH(s)        ((s).min_icon_width)
+#define SSET_MIN_ICON_WIDTH(s,x)      ((s).min_icon_width = (x))
+#define SGET_MIN_ICON_HEIGHT(s)       ((s).min_icon_height)
+#define SSET_MIN_ICON_HEIGHT(s,x)     ((s).min_icon_height = (x))
+#define SGET_MAX_ICON_WIDTH(s)        ((s).max_icon_width)
+#define SSET_MAX_ICON_WIDTH(s,x)      ((s).max_icon_width = (x))
+#define SGET_MAX_ICON_HEIGHT(s)       ((s).max_icon_height)
+#define SSET_MAX_ICON_HEIGHT(s,x)     ((s).max_icon_height = (x))
 #define SGET_MAX_WINDOW_WIDTH(s)      ((s).max_window_width)
 #define SSET_MAX_WINDOW_WIDTH(s,x)    ((s).max_window_width = (x))
 #define SGET_MAX_WINDOW_HEIGHT(s)     ((s).max_window_height)
Index: libs/defaults.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/libs/defaults.h,v
retrieving revision 1.49
diff -u -r1.49 defaults.h
--- libs/defaults.h     2002/06/18 10:52:17     1.49
+++ libs/defaults.h     2002/06/24 15:30:13
@@ -152,6 +152,12 @@
 #define DEFAULT_MIN_MAX_WINDOW_HEIGHT   100 /* pixels */
 #define DEFAULT_MAX_MAX_WINDOW_WIDTH   32767 /* pixels */
 #define DEFAULT_MAX_MAX_WINDOW_HEIGHT  32767 /* pixels */
+
+/*** icon geometry ***/
+#define UNSPECIFIED_ICON_DIMENSION        -1
+#define MIN_ALLOWABLE_ICON_DIMENSION       0 /* pixels */
+#define MAX_ALLOWABLE_ICON_DIMENSION     255 /* pixels */
+
 /* this value is used in a bugfix */
 #define WINDOW_FREAKED_OUT_SIZE               65500 /* pixels */
 

Reply via email to