Try to make life more bearable in Xaw menus
authorH.G. Muller <h.g.muller@hccnet.nl>
Wed, 20 Feb 2013 20:28:36 +0000 (21:28 +0100)
committerH.G. Muller <h.g.muller@hccnet.nl>
Wed, 20 Feb 2013 20:28:36 +0000 (21:28 +0100)
The alignment still sucks, but not as much as before.

xaw/xoptions.c

index f70e80f..7f73a0b 100644 (file)
@@ -405,14 +405,68 @@ format_accel (char *input)
     key = strdup(input);
   else
     key = strdup(++test); // remove ">"
+  if(strlen(key) == 1) key[0] = ToUpper(key[0]);
 
   output = realloc(output, strlen(output) + strlen(_(key))+2);
-  strncat(output, _(key), strlen(key) +1);
+  strncat(output, _(key), strlen(_(key)) +1);
 
   free(key);
   return output;
 }
 
+int
+pixlen (char *s)
+{
+#if 0
+    int dummy;
+    XCharStruct overall;
+    XTextExtents(messageFontStruct, s, strlen(s), &dummy, &dummy, &dummy, &overall);
+    return overall.width;
+#else
+    float tot = 0;
+    while(*s) switch(*s++) {
+       case '.': tot += 0.45; break;
+       case ' ': tot += 0.55; break;
+       case 'i': tot += 0.45; break;
+       case 'l': tot += 0.45; break;
+       case 'j': tot += 0.45; break;
+       case 'f': tot += 0.45; break;
+       case 'I': tot += 0.45; break;
+       case 't': tot += 0.45; break;
+       case 'k': tot += 0.83; break;
+       case 's': tot += 0.83; break;
+       case 'x': tot += 0.83; break;
+       case 'z': tot += 0.83; break;
+       case 'r': tot += 0.55; break;
+       case 'w': tot += 1.3; break;
+       case 'm': tot += 1.3; break;
+       case 'A': tot += 1.3; break;
+       case 'C': tot += 1.3; break;
+       case 'D': tot += 1.3; break;
+       case 'G': tot += 1.3; break;
+       case 'H': tot += 1.3; break;
+       case 'N': tot += 1.3; break;
+       case 'V': tot += 1.3; break;
+       case 'X': tot += 1.3; break;
+       case 'Y': tot += 1.3; break;
+       case 'Z': tot += 1.3; break;
+       case 'M': tot += 1.6; break;
+       case 'W': tot += 1.6; break;
+       case 'B': tot += 1.1; break;
+       case 'E': tot += 1.1; break;
+       case 'F': tot += 1.1; break;
+       case 'K': tot += 1.1; break;
+       case 'P': tot += 1.1; break;
+       case 'R': tot += 1.1; break;
+       case 'S': tot += 1.1; break;
+       case 'O': tot += 1.4; break;
+       case 'Q': tot += 1.4; break;
+       default:  tot++;
+    }
+    return tot;
+#endif
+}
+
 static Widget
 CreateComboPopup (Widget parent, Option *opt, int n, int fromList, int def)
 {   // fromList determines if the item texts are taken from a list of strings, or from a menu table
@@ -421,16 +475,19 @@ CreateComboPopup (Widget parent, Option *opt, int n, int fromList, int def)
     Arg arg;
     MenuItem *mb = (MenuItem *) opt->choice;
     char **list = (char **) opt->choice;
-    int maxlength=0;
+    int maxlength=0, menuLen[1000];
 
 
     if(list[0] == NULL) return NULL; // avoid empty menus, as they cause crash
     menu = XtCreatePopupShell(opt->name, simpleMenuWidgetClass, parent, NULL, 0);
 
     if(!fromList)
-      for (i=0; mb[i].string; i++)
-       if (maxlength < strlen(_(mb[i].string)) )
-         maxlength = strlen(_(mb[i].string) );
+      for (i=0; mb[i].string; i++) if(mb[i].accel) {
+       int len = pixlen(_(mb[i].string));
+       menuLen[i] = len;
+       if (maxlength < len )
+         maxlength = len;
+      }
 
     for (i=0; 1; i++)
       {
@@ -444,12 +501,13 @@ CreateComboPopup (Widget parent, Option *opt, int n, int fromList, int def)
            char *menuname = opt->min & NO_GETTEXT ? msg : _(msg);
            char *accel = format_accel(mb[i].accel);
            size_t len;
-           int fill = maxlength - strlen(menuname) +2+strlen(accel);
+//         int fill = maxlength - strlen(menuname) +2+strlen(accel);
+           int fill = (maxlength - menuLen[i] + 3)*1.8;
 
-           len = strlen(menuname)+fill+1;
+           len = strlen(menuname)+fill+strlen(accel)+1;
            label = malloc(len);
 
-           snprintf(label,len,"%s%*s",menuname,fill,accel);
+           snprintf(label,len,"%s%*s%s",menuname,fill," ",accel);
            free(accel);
          }
        else