X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xaw%2Fxoptions.c;h=91baa04df6b9088f7a5b55dc892e02fe2898047c;hb=c37d45adc7d98a702a7459ccdc0ac23df01a476e;hp=5db8614c6edcb24c97650b1f55842ddb23b3de76;hpb=e5876bb39d5f30d92865ff5f37b0b60f15e4fa87;p=xboard.git diff --git a/xaw/xoptions.c b/xaw/xoptions.c index 5db8614..91baa04 100644 --- a/xaw/xoptions.c +++ b/xaw/xoptions.c @@ -1,7 +1,7 @@ /* * xoptions.c -- Move list window, part of X front end for XBoard * - * Copyright 2000, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. + * Copyright 2000, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc. * ------------------------------------------------------------------------ * * GNU XBoard is free software: you can redistribute it and/or modify @@ -201,7 +201,8 @@ LoadListBox (Option *opt, char *emptyText, int n1, int n2) { static char *dummyList[2]; dummyList[0] = emptyText; // empty listboxes tend to crash X, so display user-supplied warning string instead - XawListChange(opt->handle, *(char*)opt->target ? opt->target : dummyList, 0, 0, True); + XawListChange(opt->handle, *(char**)opt->target ? opt->target : dummyList, 0, 0, True); +//printf("listbox data = %x\n", opt->target); } int @@ -373,6 +374,100 @@ CreateMenuItem (Widget menu, char *msg, XtCallbackProc CB, int n) return entry; } +char * +format_accel (char *input) +{ + char *output; + char *key,*test; + + output = strdup(""); + + if( strstr(input, "") ) + { + output = realloc(output, strlen(output) + strlen(_("Ctrl"))+2); + strncat(output, _("Ctrl"), strlen(_("Ctrl")) +1); + strncat(output, "+", 1); + }; + if( strstr(input, "") ) + { + output = realloc(output, strlen(output) + strlen(_("Alt"))+2); + strncat(output, _("Alt"), strlen(_("Alt")) +1); + strncat(output, "+", 1); + }; + if( strstr(input, "") ) + { + output = realloc(output, strlen(output) + strlen(_("Shift"))+2); + strncat(output, _("Shift"), strlen(_("Shift")) +1); + strncat(output, "+", 1); + }; + + test = strrchr(input, '>'); + if ( test==NULL ) + 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); + + 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 @@ -381,20 +476,51 @@ 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, 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(mb[i].accel) { + int len = pixlen(_(mb[i].string)); + menuLen[i] = len; + if (maxlength < len ) + maxlength = len; + } + for (i=0; 1; i++) { char *msg = fromList ? list[i] : mb[i].string; + char *label=NULL; + if(!msg) break; - entry = CreateMenuItem(menu, opt->min & NO_GETTEXT ? msg : _(msg), (XtCallbackProc) ComboSelect, (n<<16)+i); + + if(!fromList && mb[i].accel) + { + 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 - menuLen[i] + 3)*1.8; + + len = strlen(menuname)+fill+strlen(accel)+1; + label = malloc(len); + + snprintf(label,len,"%s%*s%s",menuname,fill," ",accel); + free(accel); + } + else + label = strdup(opt->min & NO_GETTEXT ? msg : _(msg)); + + entry = CreateMenuItem(menu, label, (XtCallbackProc) ComboSelect, (n<<16)+i); if(!fromList) mb[i].handle = (void*) entry; // save item ID, for enabling / checkmarking if(i==def) { XtSetArg(arg, XtNpopupOnEntry, entry); XtSetValues(menu, &arg, 1); } + free(label); } return menu; } @@ -582,8 +708,15 @@ GraphEventProc(Widget widget, caddr_t client_data, XEvent *event) // to give drawing routines opportunity to use it before first expose event // (which are only processed when main gets to the event loop, so after all init!) // so only change when size is no longer good + cairo_t *cr; if(graph->choice) cairo_surface_destroy((cairo_surface_t *) graph->choice); graph->choice = (char**) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); + // paint white, to prevent weirdness when people maximize window and drag pieces over space next to board + cr = cairo_create ((cairo_surface_t *) graph->choice); + cairo_rectangle (cr, 0, 0, w, h); + cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); + cairo_fill(cr); + cairo_destroy (cr); break; } w = ((XExposeEvent*)event)->width; @@ -855,6 +988,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent } else texts[h] = dialog = NULL; // kludge to position from left margin w = option[i].type == Spin || option[i].type == Fractional ? 70 : option[i].max ? option[i].max : 205; if(option[i].type == FileName || option[i].type == PathName) w -= 55; + if(squareSize > 33) w += (squareSize - 33)/2; j = SetPositionAndSize(args, dialog, last, 1 /* border */, w /* w */, option[i].type == TextBox ? option[i].value : 0 /* h */, 0x91 /* chain full width */); if(option[i].type == TextBox) { // decorations for multi-line text-edits @@ -953,8 +1087,8 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent option[i].max /* w */, shrink ? textHeight : 0 /* h */, option[i].min & 0xE | chain /* chain */); XtSetArg(args[j], XtNlabel, _(option[i].name)); j++; if(option[i].textValue) { // special for buttons of New Variant dialog - XtSetArg(args[j], XtNsensitive, appData.noChessProgram || option[i].value < 0 - || strstr(first.variants, VariantName(option[i].value))); j++; + XtSetArg(args[j], XtNsensitive, option[i].value >= 0 && (appData.noChessProgram + || strstr(first.variants, VariantName(option[i].value)))); j++; XtSetArg(args[j], XtNborderWidth, (gameInfo.variant == option[i].value)+1); j++; } option[i].handle = (void*) @@ -1158,13 +1292,17 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent shellUp[dlgNr]++; // count rather than flag previous = NULL; if(textField) SetFocus(textField, popup, (XEvent*) NULL, False); - if(dlgNr && wp[dlgNr] && wp[dlgNr]->width > 0) { // if persistent window-info available, reposition + if(dlgNr && wp[dlgNr]) { // if persistent window-info available, reposition j = 0; - XtSetArg(args[j], XtNheight, (Dimension) (wp[dlgNr]->height)); j++; - XtSetArg(args[j], XtNwidth, (Dimension) (wp[dlgNr]->width)); j++; - XtSetArg(args[j], XtNx, (Position) (wp[dlgNr]->x)); j++; - XtSetArg(args[j], XtNy, (Position) (wp[dlgNr]->y)); j++; - XtSetValues(popup, args, j); + if(wp[dlgNr]->width > 0 && wp[dlgNr]->height > 0) { + XtSetArg(args[j], XtNheight, (Dimension) (wp[dlgNr]->height)); j++; + XtSetArg(args[j], XtNwidth, (Dimension) (wp[dlgNr]->width)); j++; + } + if(wp[dlgNr]->x > 0 && wp[dlgNr]->y > 0) { + XtSetArg(args[j], XtNx, (Position) (wp[dlgNr]->x)); j++; + XtSetArg(args[j], XtNy, (Position) (wp[dlgNr]->y)); j++; + } + if(j) XtSetValues(popup, args, j); } RaiseWindow(dlgNr); return 1; // tells caller he must do initialization (e.g. add specific event handlers)