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 */