Subject: FvwmWinList ButtonFrameWidth patch...

From: Jesper James <[email-masked]>
Date: Thu, 17 Dec 1998 15:52:12 +0100 (NFT)

Hi,

I've put in some small changes to the FvwmWinList module, i felt were
useable...

The changes consists of:

A new parameter: 

*FvwmWinListButtonFrameWidth width

this specifies the width of the border around the buttons, ranging from 0
to 5. This allows one to have the more cool one-pixel wide borders around
the buttons like FvwmButtons allows you to have.

Also The TruncateLeft option did only work if you had LeftJustify on,
It now works always. 

Last, i have fiddled with the borders, and margins to align the buttons
better, and have more consistent margins etc..

I have glued in a patch below against the 2.1.5 beta version.

I have tried to test it with a lot of different setups, and the only flaw
i see by now, is that if some buttons don't have pixmaps the texts of
these do not align with the text of the buttons that have pixmaps. An easy
way to fix that though, is to use: 

Style "*" MiniIcon mini.xpm

To have a default (blank) miniicon for all windows...

comments/suggestions welcome...

Best Regards,
Jesper James
[email-masked]

---

*** ../FvwmWinList.old/FvwmWinList.c	Thu Dec 17 13:04:59 1998
--- FvwmWinList.c	Thu Dec 17 14:13:34 1998
***************
*** 110,116 ****
        *ForeColor[MAX_COLOUR_SETS] = { "black" },
        *geometry="";
  char *font_string = "fixed";
! int UseSkipList=0,Anchor=1,UseIconNames=0,LeftJustify=0,TruncateLeft=0,ShowFocus=1;
  
  long CurrentDesk = 0;
  int ShowCurrentDesk = 0;
--- 110,117 ----
        *ForeColor[MAX_COLOUR_SETS] = { "black" },
        *geometry="";
  char *font_string = "fixed";
! int UseSkipList=0,Anchor=1,UseIconNames=0,LeftJustify=0,TruncateLeft=0;
! int ShowFocus=1,ButtonReliefWidth=2;
  
  long CurrentDesk = 0;
  int ShowCurrentDesk = 0;
***************
*** 173,179 ****
  
    InitPictureCMap(dpy, Root);
  
!   InitArray(&buttons,0,0,win_width, fontheight+6);
    InitList(&windows);
  
    fd_width = GetFdWidth();
--- 174,180 ----
  
    InitPictureCMap(dpy, Root);
  
!   InitArray(&buttons,0,0,win_width, fontheight+2, ButtonReliefWidth);
    InitList(&windows);
  
    fd_width = GetFdWidth();
***************
*** 552,557 ****
--- 553,561 ----
                                  Clength+8)==0) MaxWidth=atoi(&tline[Clength+8]);
  	  else if(strncasecmp(tline,CatString3(Module, "DontDepressFocus",""),
  				Clength+16)==0) ShowFocus=0;
+ 	  else if(strncasecmp(tline,CatString3(Module, "ButtonFrameWidth",""),
+ 				Clength+16)==0) ButtonReliefWidth=atoi(&tline[Clength+16]);
+ 	  ButtonReliefWidth=min(max(0,ButtonReliefWidth),5); 
  	}
        GetConfigLine(Fvwm_fd,&tline);
      }
***************
*** 693,699 ****
    }
    new_width=max(new_width, MinWidth);
    new_width=min(new_width, MaxWidth);
!   new_height=(total*(fontheight+6+1));
    if (WindowIsUp && (new_height!=win_height  || new_width!=win_width))
    {
      if (Anchor)
--- 697,703 ----
    }
    new_width=max(new_width, MinWidth);
    new_width=min(new_width, MaxWidth);
!   new_height=(total*(fontheight+2+(2*ButtonReliefWidth)+1));
    if (WindowIsUp && (new_height!=win_height  || new_width!=win_width))
    {
      if (Anchor)
*** ../FvwmWinList.old/FvwmWinList.1	Thu Dec 17 13:04:59 1998
--- FvwmWinList.1	Thu Dec 17 13:57:13 1998
***************
*** 108,113 ****
--- 108,117 ----
  values.  Setting them identically will fix the size of the buttons.
  Setting Max < Min will have unpredictable results.
  
+ .IP "*FvwmWinListBorderReliefWidth \fIwidth\fP"
+ Specify the width of the 3D borders around the buttons in FwvmWinList. Valid values 
+ range from 0 to 5 (included). Other values will be truncated to this range.
+ 
  .IP "*FvwmWinListTruncateLeft"
  If names get truncated because of the setting of \fBFvwmWinListMaxWidth\fP,
  they will normally get truncated on the right, so only the start of the names
***************
*** 144,149 ****
--- 148,154 ----
  *FvwmWinListGeometry -50-85
  *FvwmWinListMinWidth 70
  *FvwmWinListMaxWidth 120
+ *FvwmWinListBorderReliefWidth 
  # I prefer the text centered
  #*FvwmWinListLeftJustify
  # I like it achored
*** ../FvwmWinList.old/ButtonArray.c	Thu Dec 17 13:04:59 1998
--- ButtonArray.c	Thu Dec 17 15:26:57 1998
***************
*** 63,72 ****
      new->p.width = p->width;
      new->p.height = p->height;
      new->p.depth = p->depth;
    }
-   else
- 
-   new->p.picture = 0;
  
    new->up = up;
    new->next = NULL;
--- 63,72 ----
      new->p.width = p->width;
      new->p.height = p->height;
      new->p.depth = p->depth;
+   } else {
+     new->p.picture = 0;
+     new->p.width = 0;
    }
  
    new->up = up;
    new->next = NULL;
***************
*** 78,91 ****
  /******************************************************************************
    InitArray - Initialize the arrary of buttons
  ******************************************************************************/
! void InitArray(ButtonArray *array,int x,int y,int w,int h)
  {
    array->count=0;
    array->head=array->tail=NULL;
    array->x=x;
    array->y=y;
    array->w=w;
!   array->h=h;
  }
  
  /******************************************************************************
--- 78,92 ----
  /******************************************************************************
    InitArray - Initialize the arrary of buttons
  ******************************************************************************/
! void InitArray(ButtonArray *array,int x,int y,int w,int h, int rw)
  {
    array->count=0;
    array->head=array->tail=NULL;
    array->x=x;
    array->y=y;
    array->w=w;
!   array->h=h+2*rw;
!   array->rw=rw;
  }
  
  /******************************************************************************
***************
*** 121,134 ****
    }
    array->count++;
  
! /* in Taskbar this replaces below  ArrangeButtonArray (array);
! */
  
    new->tw=XTextWidth(ButtonFont,title,strlen(title));
    new->truncatewidth=0;
    new->next=NULL;
    new->needsupdate=1;
    new->set=0;
  
    return (array->count-1);
  }
--- 122,135 ----
    }
    array->count++;
  
! /* in Taskbar this replaces below  ArrangeButtonArray (array); */
  
    new->tw=XTextWidth(ButtonFont,title,strlen(title));
    new->truncatewidth=0;
    new->next=NULL;
    new->needsupdate=1;
    new->set=0;
+   new->reliefwidth=array->rw;
  
    return (array->count-1);
  }
***************
*** 282,288 ****
  ******************************************************************************/
  void DoButton(Button *button, int x, int y, int w, int h)
  {
!   int up,Fontheight,newx,set;
    GC topgc;
    GC bottomgc;
    char *string;
--- 283,289 ----
  ******************************************************************************/
  void DoButton(Button *button, int x, int y, int w, int h)
  {
!   int i,up,Fontheight,newx,set,length,adjust;
    GC topgc;
    GC bottomgc;
    char *string;
***************
*** 290,295 ****
--- 291,299 ----
    unsigned long gcm;
    XFontStruct *font;
  
+   /* The margin we want between the relief/text/pixmaps */
+   #define INNER_MARGIN 2
+ 
    up=button->up;
    set=button->set;
    topgc = up ? hilite[set] : shadow[set];
***************
*** 300,317 ****
    gcv.font = font->fid;
    XChangeGC(dpy, graph[set], gcm, &gcv);
  
- 
    Fontheight=ButtonFont->ascent+ButtonFont->descent;
  
!  /*? XClearArea(dpy,win,x,y,w,h,False);*/
!   XFillRectangle(dpy,win,background[set],x,y,w,h+1);
  
    if ((button->p.picture != 0)/* &&
        (w + button->p.width + w3p + 3 > MIN_BUTTON_SIZE)*/) {
  
      gcm = GCClipMask|GCClipXOrigin|GCClipYOrigin;
      gcv.clip_mask = button->p.mask;
!     gcv.clip_x_origin = x + 4;
      gcv.clip_y_origin = y + ((h-button->p.height) >> 1);
      XChangeGC(dpy, hilite[set], gcm, &gcv);
      XCopyArea(dpy, button->p.picture, win, hilite[set], 0, 0,
--- 304,319 ----
    gcv.font = font->fid;
    XChangeGC(dpy, graph[set], gcm, &gcv);
  
    Fontheight=ButtonFont->ascent+ButtonFont->descent;
  
!   XFillRectangle(dpy,win,background[set],x,y,w,h+1); 
  
    if ((button->p.picture != 0)/* &&
        (w + button->p.width + w3p + 3 > MIN_BUTTON_SIZE)*/) {
  
      gcm = GCClipMask|GCClipXOrigin|GCClipYOrigin;
      gcv.clip_mask = button->p.mask;
!     gcv.clip_x_origin = x + 2 + button->reliefwidth;
      gcv.clip_y_origin = y + ((h-button->p.height) >> 1);
      XChangeGC(dpy, hilite[set], gcm, &gcv);
      XCopyArea(dpy, button->p.picture, win, hilite[set], 0, 0,
***************
*** 321,364 ****
      gcv.clip_mask = None;
      XChangeGC(dpy, hilite[set], gcm, &gcv);
  
!     newx = button->p.width+6;
!   }
!   else
!   {
      if (LeftJustify)
!       newx=4;
      else
!       newx=max((w-button->tw)/2,4);
    }
  
    string=button->title;
  
!   if (!LeftJustify) {
!     if (TruncateLeft && (w-button->tw)/2 < 4) {
!       if (button->truncatewidth == w)
! 	string=button->truncate_title;
!       else {
! 	string=button->title;
! 	while(*string && (w-XTextWidth(ButtonFont,string,strlen(string)))/2 < 4)
! 	    string++;
! 	button->truncatewidth = w;
! 	button->truncate_title=string;
!       }
      }
    }
!   XDrawString(dpy,win,graph[set],x+newx,y+3+ButtonFont->ascent,string,strlen(string));
!   button->needsupdate=0;
    
    /* Draw relief last, don't forget that XDrawLine doesn't do the last pixel */
!   XDrawLine(dpy,win,topgc,x,y,x+w-1,y);
!   XDrawLine(dpy,win,topgc,x+1,y+1,x+w-2,y+1);
!   XDrawLine(dpy,win,topgc,x,y+1,x,y+h+1);
!   XDrawLine(dpy,win,topgc,x+1,y+2,x+1,y+h);
!   XDrawLine(dpy,win,bottomgc,x+1,y+h,x+w,y+h);
!   XDrawLine(dpy,win,bottomgc,x+2,y+h-1,x+w-1,y+h-1);
!   XDrawLine(dpy,win,bottomgc,x+w-1,y,x+w-1,y+h);
!   XDrawLine(dpy,win,bottomgc,x+w-2,y+1,x+w-2,y+h-1);
  
  }
  
  /******************************************************************************
--- 323,365 ----
      gcv.clip_mask = None;
      XChangeGC(dpy, hilite[set], gcm, &gcv);
  
!     /* with a picture, there are two margins plus a pixmap to the left of the text */
!     newx = button->p.width+2*INNER_MARGIN;
!   } else {
      if (LeftJustify)
!       newx=INNER_MARGIN;
      else
!       newx=max((w-button->tw)/2, INNER_MARGIN);
    }
  
+   /* check if the string needs to be truncated */
    string=button->title;
+   if (TruncateLeft && (newx + button->tw + 2*button->reliefwidth + INNER_MARGIN) > w) { 
  
!     if (button->truncatewidth == w)
!       string=button->truncate_title;
!     else {
!       while(*string && (newx + XTextWidth(ButtonFont,string,strlen(string)) 
! 			+ 2*button->reliefwidth + INNER_MARGIN) > w)
! 	string++;
!       button->truncatewidth = w;
!       button->truncate_title=string;
      }
    }
!   XDrawString(dpy,win,graph[set],x+newx+button->reliefwidth,y+1+button->reliefwidth
! 	      +ButtonFont->ascent,string,strlen(string));
    
    /* Draw relief last, don't forget that XDrawLine doesn't do the last pixel */
!   for (i=0; i<button->reliefwidth; i++) {
!     XDrawLine(dpy,win,topgc   ,x+i    ,y+i  ,x+w-1-i,y+i);
!     XDrawLine(dpy,win,topgc   ,x+i    ,y+1+i,x+i    ,y+h-i);
!     XDrawLine(dpy,win,bottomgc,x+1+i  ,y+h-i,x+w-i  ,y+h-i);
!     XDrawLine(dpy,win,bottomgc,x+w-1-i,y+1+i,x+w-1-i,y+h-i);
!   }
!   /* Make sure we have a one pixel border to the right too */
!   XDrawLine(dpy,win,background[set],x+w-1-i,y+1+i,x+w-1-i,y+h-i);
  
+   button->needsupdate=0;
  }
  
  /******************************************************************************
*** ../FvwmWinList.old/ButtonArray.h	Thu Dec 17 13:04:59 1998
--- ButtonArray.h	Thu Dec 17 12:32:51 1998
***************
*** 12,25 ****
   *  Things to do:  Convert to C++  (In Progress)
   */
  
  /* Struct definitions */
  typedef struct button
  {
    char *title;
!   char *truncate_title; /* valid only if truncatewidth > 0 */
    int up, needsupdate, tw, set, truncatewidth;
    struct button *next;
    Picture p;
    long desk;
  } Button;
  
--- 12,28 ----
   *  Things to do:  Convert to C++  (In Progress)
   */
  
+ #define MAX_COLOUR_SETS 4
+ 
  /* Struct definitions */
  typedef struct button
  {
    char *title;
!   char *truncate_title;
    int up, needsupdate, tw, set, truncatewidth;
    struct button *next;
    Picture p;
+   int reliefwidth;
    long desk;
  } Button;
  
***************
*** 27,40 ****
  {
    int count;
    Button *head,*tail;
!   int x,y,w,h;
  } ButtonArray;
  
- #define MAX_COLOUR_SETS 4
- 
  /* Function Prototypes */
  Button *ButtonNew(char *title, Picture *p, int up);
! void InitArray(ButtonArray *array,int x,int y,int w,int h);
  void UpdateArray(ButtonArray *array,int x,int y,int w, int h);
  int AddButton(ButtonArray *array, char *title, Picture *p,int up);
  int UpdateButton(ButtonArray *array, int butnum, char *title, int up);
--- 30,41 ----
  {
    int count;
    Button *head,*tail;
!   int x,y,w,h, rw;
  } ButtonArray;
  
  /* Function Prototypes */
  Button *ButtonNew(char *title, Picture *p, int up);
! void InitArray(ButtonArray *array,int x,int y,int w,int h, int rw);
  void UpdateArray(ButtonArray *array,int x,int y,int w, int h);
  int AddButton(ButtonArray *array, char *title, Picture *p,int up);
  int UpdateButton(ButtonArray *array, int butnum, char *title, int up);

--
Visit the official FVWM web page at <URL:http://www.hpc.uh.edu/fvwm/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked].

---

From: Dominik Vogt <[email-masked]>
Date: Thu, 17 Dec 1998 17:36:16 +0100

On Thu, Dec 17, 1998 at 03:52:12PM +0100, [email-masked] wrote:
>...

FYI:

The patch won't be included before the 2.2 release anymore,
but I'll remember it as soon as 2.2 is out.

Bye

Dominik
-- 
Dominik Vogt, Hewlett-Packard GmbH, Dept. BVS
Herrenberger Str.130, 71034 Boeblingen, Germany
phone: 07031/14-4596, fax: 07031/14-3883, [email-masked]
--
Visit the official FVWM web page at <URL:http://www.hpc.uh.edu/fvwm/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked].

---

From: Tim Phipps <[email-masked]>
Date: Thu, 17 Dec 1998 16:44:25 +0000

This looks good, I'll put this in, but a few questions first:

> +                               Clength+16)==0)

> + range from 0 to 5 (included). Other values will be truncated to this range.

I'd prefer to change the man page to match the code (and FvwmButtons terminology).  I can't see
why you'd want to limit the shadow width. Does anything break with borders > 5? If someone
wants a daft number let them have it. (It may not be so daft when I get my 50000x40000 pixel
inflatable LCD display.)

> !   XDrawLine(dpy,win,background[set],x+w-1-i,y+1+i,x+w-1-i,y+h-i);

What does this last line do?

Cheers,
Tim.

---

From: Tim Phipps <[email-masked]>
Date: Thu, 17 Dec 1998 17:03:32 +0000

> This looks good, I'll put this in, but a few questions first:

Got my wires crossed, I'll stash it until after 2.2.

Cheers,
Tim.

---

From: Jesper James <[email-masked]>
Date: Fri, 18 Dec 1998 10:09:27 +0100 (NFT)

> wants a daft number let them have it. (It may not be so daft when I get my 50000x40000 pixel

I should mean that there is a check (and truncating) just below this line,
I thought that this would limit the number of checks that have to be done
later on, to make it stable agains overly huge numbers. But feel free to
remove it, or change it to 20 or something and see if it works...

> What does this last line do?

It draws a one pixel line inside the right relief with the background
color, to cut off any text that extents over buttons limits, to make an
more even inside margin, and so it doesn't look as if the text is going of
the side og the button (even if it does).

I looked at menu.c i fvwm, and it also looks like the two-pixel margins on
this menu also are hardcoded in here, i wonder if something like this
could be useable in this general menu stuff? Maybe i'll take a shot at it.

Best Regards,
Jesper James
[email-masked]

---

From: Tim Phipps <[email-masked]>
Date: Fri, 18 Dec 1998 11:47:11 +0000

> could be useable in this general menu stuff? Maybe i'll take a shot at it.

This would be very useful.  There are umpteen places where buttons are drawn and a library function
would make the look consistent. Just off the top of my head:

typedef struct Button {
  unsigned int width;
  unsigned int height;
  unsigned int padding;
  int frame; (<0 means pressed in like FvwmButtons)
  char *text;
  int hot_key; (which one to underline, -1 means none)
  MyFont *font;
  ColorPair colors;
  something justification; (left, right, centre)
  Bool truncate_left;
#ifdef MINI_ICONS (copied from fvwm.h)
  int mini_icon_width (for lining up text, clip the mini_icon to this)
  char *mini_pixmap_file;
  Picture *mini_icon;
#endif
#ifdef XPM
  Pixmap background;
#endif
} Button;

void EstimateButtonSize(Display, Button *button); /* sets width and height */
void DrawButton(Display, Window, x, y, Button *button);

I stuck the mini_icon_width in so that the text in buttons could be lined up even if the mini_icons
have different widths.

Would this be useful?  There are lots of places that buttons get drawn (menus, titlebar, title
buttons, FvwmWinList, FvwmIconMan, FvwmTaskBar, FvwmForm, FvwmWharf, FvwmButtons).  Is a structure
like the above too much bloat? I'm not intending on programs mallocing one of these per button, more
like just one and change the text pointer before each call to DrawButton.

Cheers,
Tim.