Tk Source Code

Changes On Branch tip-441
Login
Bounty program for improvements to Tcl and certain Tcl packages.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch tip-441 Excluding Merge-Ins

This is equivalent to a diff from 6543f30d to 9a244ba8

2016-01-22
09:21
Implement TIP #441: Add -justify Configuration Option to the listbox Widget check-in: 12499582 user: jan.nijtmans tags: trunk
2016-01-20
22:03
Fixed bug [9e606527af] - && instead of & used in generic/tkOption.c check-in: 36728caf user: fvogel tags: trunk
21:17
Patch [960391] from Erik Leunissen (rebased to latest trunk) to improve listbox performance when selecting items in extended mode. Closed-Leaf check-in: 7144449a user: fvogel tags: bug-960391ffff
2016-01-18
18:45
Removed unfinished test case committed by error in the previous commit. Closed-Leaf check-in: 9a244ba8 user: fvogel tags: tip-441
18:43
Reverted [5f396dacdc]. check-in: d1731afd user: fvogel tags: tip-441
2016-01-16
15:22
Rebased to latest trunk check-in: 83dfa2db user: fvogel tags: tip-441
15:21
Fixed bug [639558ac83] - Lots of listbox tests fail on Linux check-in: 6543f30d user: fvogel tags: trunk
2016-01-13
17:56
TIP #438 (Ensure Line Metrics are Up-to-Date) accepted by vote check-in: 15b7aa7e user: fvogel tags: trunk

Changes to doc/listbox.n.

    13     13   listbox \- Create and manipulate 'listbox' item list widgets
    14     14   .SH SYNOPSIS
    15     15   \fBlistbox\fR \fIpathName \fR?\fIoptions\fR?
    16     16   .SO
    17     17   \-background	\-borderwidth	\-cursor
    18     18   \-disabledforeground	\-exportselection	\-font
    19     19   \-foreground	\-highlightbackground	\-highlightcolor
    20         -\-highlightthickness	\-relief	\-selectbackground
    21         -\-selectborderwidth	\-selectforeground	\-setgrid
    22         -\-takefocus	\-xscrollcommand	\-yscrollcommand
           20  +\-highlightthickness	\-justify	\-relief
           21  +\-selectbackground	\-selectborderwidth	\-selectforeground
           22  +\-setgrid	\-takefocus	\-xscrollcommand
           23  +\-yscrollcommand
    23     24   .SE
    24     25   .SH "WIDGET-SPECIFIC OPTIONS"
    25     26   .OP \-activestyle activeStyle ActiveStyle
    26     27   Specifies the style in which to draw the active element.  This must be
    27     28   one of \fBdotbox\fR (show a focus ring around the active element),
    28     29   \fBnone\fR (no special indication of active element) or
    29     30   \fBunderline\fR (underline the active element).

Changes to generic/tkListbox.c.

    86     86       GC selTextGC;		/* For drawing selected text. */
    87     87       int width;			/* Desired width of window, in characters. */
    88     88       int height;			/* Desired height of window, in lines. */
    89     89       int lineHeight;		/* Number of pixels allocated for each line in
    90     90   				 * display. */
    91     91       int topIndex;		/* Index of top-most element visible in
    92     92   				 * window. */
    93         -    int fullLines;		/* Number of lines that fit are completely
           93  +    int fullLines;		/* Number of lines that are completely
    94     94   				 * visible in window. There may be one
    95     95   				 * additional line at the bottom that is
    96     96   				 * partially visible. */
    97     97       int partialLine;		/* 0 means that the window holds exactly
    98     98   				 * fullLines lines. 1 means that there is one
    99     99   				 * additional line that is partially
   100         -				 * visble. */
          100  +				 * visible. */
   101    101       int setGrid;		/* Non-zero means pass gridding information to
   102    102   				 * window manager. */
   103    103   
   104    104       /*
   105    105        * Information to support horizontal scrolling:
   106    106        */
   107    107   
................................................................................
   110    110       int xScrollUnit;		/* Number of pixels in one "unit" for
   111    111   				 * horizontal scrolling (window scrolls
   112    112   				 * horizontally in increments of this size).
   113    113   				 * This is an average character size. */
   114    114       int xOffset;		/* The left edge of each string in the listbox
   115    115   				 * is offset to the left by this many pixels
   116    116   				 * (0 means no offset, positive means there is
   117         -				 * an offset). */
          117  +				 * an offset). This is x scrolling information
          118  +                                 * is not linked to justification. */
   118    119   
   119    120       /*
   120    121        * Information about what's selected or active, if any.
   121    122        */
   122    123   
   123    124       Tk_Uid selectMode;		/* Selection style: single, browse, multiple,
   124    125   				 * or extended. This value isn't used in C
................................................................................
   127    128       int selectAnchor;		/* Fixed end of selection (i.e. element at
   128    129   				 * which selection was started.) */
   129    130       int exportSelection;	/* Non-zero means tie internal listbox to X
   130    131   				 * selection. */
   131    132       int active;			/* Index of "active" element (the one that has
   132    133   				 * been selected by keyboard traversal). -1
   133    134   				 * means none. */
   134         -    int activeStyle;		/* style in which to draw the active element.
          135  +    int activeStyle;		/* Style in which to draw the active element.
   135    136   				 * One of: underline, none, dotbox */
   136    137   
   137    138       /*
   138    139        * Information for scanning:
   139    140        */
   140    141   
   141    142       int scanMarkX;		/* X-position at which scan started (e.g.
................................................................................
   161    162       char *xScrollCmd;		/* Command prefix for communicating with
   162    163   				 * horizontal scrollbar. NULL means no command
   163    164   				 * to issue. Malloc'ed. */
   164    165       int state;			/* Listbox state. */
   165    166       Pixmap gray;		/* Pixmap for displaying disabled text. */
   166    167       int flags;			/* Various flag bits: see below for
   167    168   				 * definitions. */
          169  +    Tk_Justify justify;         /* Justification. */
   168    170   } Listbox;
   169    171   
   170    172   /*
   171    173    * How to encode the keys for the hash tables used to store what items are
   172    174    * selected and what the attributes are.
   173    175    */
   174    176   
................................................................................
   193    195    *				already been queued to redraw this window.
   194    196    * UPDATE_V_SCROLLBAR:		Non-zero means vertical scrollbar needs to be
   195    197    *				updated.
   196    198    * UPDATE_H_SCROLLBAR:		Non-zero means horizontal scrollbar needs to
   197    199    *				be updated.
   198    200    * GOT_FOCUS:			Non-zero means this widget currently has the
   199    201    *				input focus.
   200         - * MAXWIDTH_IS_STALE:		Stored maxWidth may be out-of-date
          202  + * MAXWIDTH_IS_STALE:		Stored maxWidth may be out-of-date.
   201    203    * LISTBOX_DELETED:		This listbox has been effectively destroyed.
   202    204    */
   203    205   
   204    206   #define REDRAW_PENDING		1
   205    207   #define UPDATE_V_SCROLLBAR	2
   206    208   #define UPDATE_H_SCROLLBAR	4
   207    209   #define GOT_FOCUS		8
................................................................................
   271    273   	 Tk_Offset(Listbox, highlightBgColorPtr), 0, 0, 0},
   272    274       {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
   273    275   	 DEF_LISTBOX_HIGHLIGHT, -1, Tk_Offset(Listbox, highlightColorPtr),
   274    276   	 0, 0, 0},
   275    277       {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
   276    278   	 "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, -1,
   277    279   	 Tk_Offset(Listbox, highlightWidth), 0, 0, 0},
          280  +    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
          281  +	DEF_LISTBOX_JUSTIFY, -1, Tk_Offset(Listbox, justify), 0, 0, 0},
   278    282       {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
   279    283   	 DEF_LISTBOX_RELIEF, -1, Tk_Offset(Listbox, relief), 0, 0, 0},
   280    284       {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
   281    285   	 DEF_LISTBOX_SELECT_COLOR, -1, Tk_Offset(Listbox, selBorder),
   282    286   	 0, DEF_LISTBOX_SELECT_MONO, 0},
   283    287       {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
   284    288   	 "BorderWidth", DEF_LISTBOX_SELECT_BD, -1,
................................................................................
   309    313   	 DEF_LISTBOX_LIST_VARIABLE, -1, Tk_Offset(Listbox, listVarName),
   310    314   	 TK_OPTION_NULL_OK, 0, 0},
   311    315       {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
   312    316   };
   313    317   
   314    318   /*
   315    319    * The itemAttrOptionSpecs table defines the valid configuration options for
   316         - * listbox items
          320  + * listbox items.
   317    321    */
   318    322   
   319    323   static const Tk_OptionSpec itemAttrOptionSpecs[] = {
   320    324       {TK_OPTION_BORDER, "-background", "background", "Background",
   321    325        NULL, -1, Tk_Offset(ItemAttr, border),
   322    326        TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
   323    327        DEF_LISTBOX_BG_MONO, 0},
................................................................................
   336    340        NULL, -1, Tk_Offset(ItemAttr, selFgColor),
   337    341        TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
   338    342        DEF_LISTBOX_SELECT_FG_MONO, 0},
   339    343       {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
   340    344   };
   341    345   
   342    346   /*
   343         - * The following tables define the listbox widget commands (and sub- commands)
          347  + * The following tables define the listbox widget commands (and sub-commands)
   344    348    * and map the indexes into the string tables into enumerated types used to
   345    349    * dispatch the listbox widget command.
   346    350    */
   347    351   
   348    352   static const char *const commandNames[] = {
   349    353       "activate", "bbox", "cget", "configure", "curselection", "delete", "get",
   350    354       "index", "insert", "itemcget", "itemconfigure", "nearest", "scan",
................................................................................
   432    436   static void		ListboxWorldChanged(ClientData instanceData);
   433    437   static int		NearestListboxElement(Listbox *listPtr, int y);
   434    438   static char *		ListboxListVarProc(ClientData clientData,
   435    439   			    Tcl_Interp *interp, const char *name1,
   436    440   			    const char *name2, int flags);
   437    441   static void		MigrateHashEntries(Tcl_HashTable *table,
   438    442   			    int first, int last, int offset);
          443  +static int		GetMaxOffset(Listbox *listPtr);
   439    444   
   440    445   /*
   441    446    * The structure below defines button class behavior by means of procedures
   442    447    * that can be invoked from generic window code.
   443    448    */
   444    449   
   445    450   static const Tk_ClassProcs listboxClass = {
................................................................................
   542    547       listPtr->selTextGC		 = None;
   543    548       listPtr->fullLines		 = 1;
   544    549       listPtr->xScrollUnit	 = 1;
   545    550       listPtr->exportSelection	 = 1;
   546    551       listPtr->cursor		 = None;
   547    552       listPtr->state		 = STATE_NORMAL;
   548    553       listPtr->gray		 = None;
          554  +    listPtr->justify             = TK_JUSTIFY_LEFT;
   549    555   
   550    556       /*
   551    557        * Keep a hold of the associated tkwin until we destroy the listbox,
   552    558        * otherwise Tk might free it while we still need it.
   553    559        */
   554    560   
   555    561       Tcl_Preserve(listPtr->tkwin);
................................................................................
   609    615       if (objc < 2) {
   610    616   	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
   611    617   	return TCL_ERROR;
   612    618       }
   613    619   
   614    620       /*
   615    621        * Parse the command by looking up the second argument in the list of
   616         -     * valid subcommand names
          622  +     * valid subcommand names.
   617    623        */
   618    624   
   619    625       result = Tcl_GetIndexFromObj(interp, objv[1], commandNames,
   620    626   	    "option", 0, &cmdIndex);
   621    627       if (result != TCL_OK) {
   622    628   	return result;
   623    629       }
................................................................................
  1072   1078   
  1073   1079   static int
  1074   1080   ListboxBboxSubCmd(
  1075   1081       Tcl_Interp *interp,		/* Pointer to the calling Tcl interpreter */
  1076   1082       Listbox *listPtr,		/* Information about the listbox */
  1077   1083       int index)			/* Index of the element to get bbox info on */
  1078   1084   {
         1085  +    register Tk_Window tkwin = listPtr->tkwin;
  1079   1086       int lastVisibleIndex;
  1080   1087   
  1081   1088       /*
  1082   1089        * Determine the index of the last visible item in the listbox.
  1083   1090        */
  1084   1091   
  1085   1092       lastVisibleIndex = listPtr->topIndex + listPtr->fullLines
................................................................................
  1107   1114   	    return result;
  1108   1115   	}
  1109   1116   
  1110   1117   	stringRep = Tcl_GetStringFromObj(el, &stringLen);
  1111   1118   	Tk_GetFontMetrics(listPtr->tkfont, &fm);
  1112   1119   	pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);
  1113   1120   
  1114         -	x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset;
         1121  +        if (listPtr->justify == TK_JUSTIFY_LEFT) {
         1122  +            x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset;
         1123  +        } else if (listPtr->justify == TK_JUSTIFY_RIGHT) {
         1124  +            x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth)
         1125  +                    - pixelWidth - listPtr->xOffset + GetMaxOffset(listPtr);
         1126  +        } else {
         1127  +            x = (Tk_Width(tkwin) - pixelWidth)/2
         1128  +                    - listPtr->xOffset + GetMaxOffset(listPtr)/2;
         1129  +        }
  1115   1130   	y = ((index - listPtr->topIndex)*listPtr->lineHeight)
  1116   1131   		+ listPtr->inset + listPtr->selBorderWidth;
  1117   1132   	results[0] = Tcl_NewIntObj(x);
  1118   1133   	results[1] = Tcl_NewIntObj(y);
  1119   1134   	results[2] = Tcl_NewIntObj(pixelWidth);
  1120   1135   	results[3] = Tcl_NewIntObj(fm.linespace);
  1121   1136   	Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
................................................................................
  1833   1848       Tk_3DBorder selectedBg;
  1834   1849       XGCValues gcValues;
  1835   1850       unsigned long mask;
  1836   1851       int left, right;		/* Non-zero values here indicate that the left
  1837   1852   				 * or right edge of the listbox is
  1838   1853   				 * off-screen. */
  1839   1854       Pixmap pixmap;
         1855  +    int textWidth;
  1840   1856   
  1841   1857       listPtr->flags &= ~REDRAW_PENDING;
  1842   1858       if (listPtr->flags & LISTBOX_DELETED) {
  1843   1859   	return;
  1844   1860       }
  1845   1861   
  1846   1862       if (listPtr->flags & MAXWIDTH_IS_STALE) {
................................................................................
  2012   2028   			    width+left+right, listPtr->selBorderWidth, 0, 0, 0,
  2013   2029   			    TK_RELIEF_RAISED);
  2014   2030   		}
  2015   2031   		prevSelected = 1;
  2016   2032   	    } else {
  2017   2033   		/*
  2018   2034   		 * If there is an item attributes record for this item, draw
  2019         -		 * the background box and set the foreground color accordingly
         2035  +		 * the background box and set the foreground color accordingly.
  2020   2036   		 */
  2021   2037   
  2022   2038   		if (entry != NULL) {
  2023   2039   		    attrs = Tcl_GetHashValue(entry);
  2024   2040   		    gcValues.foreground = listPtr->fgColorPtr->pixel;
  2025   2041   		    gcValues.font = Tk_FontId(listPtr->tkfont);
  2026   2042   		    gcValues.graphics_exposures = False;
................................................................................
  2052   2068   	    }
  2053   2069   	}
  2054   2070   
  2055   2071   	/*
  2056   2072   	 * Draw the actual text of this item.
  2057   2073   	 */
  2058   2074   
         2075  +        Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement);
         2076  +        stringRep = Tcl_GetStringFromObj(curElement, &stringLen);
         2077  +        textWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);
         2078  +
  2059   2079   	Tk_GetFontMetrics(listPtr->tkfont, &fm);
  2060   2080   	y += fm.ascent + listPtr->selBorderWidth;
  2061         -	x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset;
  2062         -	Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement);
  2063         -	stringRep = Tcl_GetStringFromObj(curElement, &stringLen);
  2064         -	Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont,
         2081  +
         2082  +        if (listPtr->justify == TK_JUSTIFY_LEFT) {
         2083  +            x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset;
         2084  +        } else if (listPtr->justify == TK_JUSTIFY_RIGHT) {
         2085  +            x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth)
         2086  +                    - textWidth - listPtr->xOffset + GetMaxOffset(listPtr);
         2087  +        } else {
         2088  +            x = (Tk_Width(tkwin) - textWidth)/2
         2089  +                    - listPtr->xOffset + GetMaxOffset(listPtr)/2;
         2090  +        }
         2091  +
         2092  +        Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont,
  2065   2093   		stringRep, stringLen, x, y);
  2066   2094   
  2067   2095   	/*
  2068   2096   	 * If this is the active element, apply the activestyle to it.
  2069   2097   	 */
  2070   2098   
  2071   2099   	if ((i == listPtr->active) && (listPtr->flags & GOT_FOCUS)) {
................................................................................
  2454   2482   	    ckfree(Tcl_GetHashValue(entry));
  2455   2483   	    Tcl_DeleteHashEntry(entry);
  2456   2484   	}
  2457   2485   
  2458   2486   	/*
  2459   2487   	 * Check width of the element. We only have to check if widthChanged
  2460   2488   	 * has not already been set to 1, because we only need one maxWidth
  2461         -	 * element to disappear for us to have to recompute the width
         2489  +	 * element to disappear for us to have to recompute the width.
  2462   2490   	 */
  2463   2491   
  2464   2492   	if (widthChanged == 0) {
  2465   2493   	    Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &element);
  2466   2494   	    stringRep = Tcl_GetStringFromObj(element, &length);
  2467   2495   	    pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
  2468   2496   	    if (pixelWidth == listPtr->maxWidth) {
................................................................................
  2731   2759   
  2732   2760       /*
  2733   2761        * The index didn't match any of the named indices; maybe it's an @x,y
  2734   2762        */
  2735   2763   
  2736   2764       stringRep = Tcl_GetString(indexObj);
  2737   2765       if (stringRep[0] == '@') {
  2738         -	/* @x,y index */
         2766  +
         2767  +        /*
         2768  +         * @x,y index
         2769  +         */
         2770  +
  2739   2771   	int y;
  2740   2772   	const char *start;
  2741   2773   	char *end;
  2742   2774   
  2743   2775   	start = stringRep + 1;
  2744   2776   	y = strtol(start, &end, 0);
  2745   2777   	if ((start == end) || (*end != ',')) {
................................................................................
  2840   2872        * it off to an even multiple of xScrollUnit.
  2841   2873        *
  2842   2874        * Add half a scroll unit to do entry/text-like synchronization. [Bug
  2843   2875        * #225025]
  2844   2876        */
  2845   2877   
  2846   2878       offset += listPtr->xScrollUnit / 2;
  2847         -    maxOffset = listPtr->maxWidth - (Tk_Width(listPtr->tkwin) -
  2848         -	    2*listPtr->inset - 2*listPtr->selBorderWidth)
  2849         -	    + listPtr->xScrollUnit - 1;
         2879  +    maxOffset = GetMaxOffset(listPtr);
  2850   2880       if (offset > maxOffset) {
  2851   2881   	offset = maxOffset;
  2852   2882       }
  2853   2883       if (offset < 0) {
  2854   2884   	offset = 0;
  2855   2885       }
  2856   2886       offset -= offset % listPtr->xScrollUnit;
................................................................................
  2883   2913       register Listbox *listPtr,	/* Information about widget. */
  2884   2914       int x,			/* X-coordinate to use for scan operation. */
  2885   2915       int y)			/* Y-coordinate to use for scan operation. */
  2886   2916   {
  2887   2917       int newTopIndex, newOffset, maxIndex, maxOffset;
  2888   2918   
  2889   2919       maxIndex = listPtr->nElements - listPtr->fullLines;
  2890         -    maxOffset = listPtr->maxWidth + (listPtr->xScrollUnit - 1)
  2891         -	    - (Tk_Width(listPtr->tkwin) - 2*listPtr->inset
  2892         -	    - 2*listPtr->selBorderWidth - listPtr->xScrollUnit);
         2920  +    maxOffset = GetMaxOffset(listPtr);
  2893   2921   
  2894   2922       /*
  2895   2923        * Compute new top line for screen by amplifying the difference between
  2896   2924        * the current position and the place where the scan started (the "mark"
  2897   2925        * position). If we run off the top or bottom of the list, then reset the
  2898   2926        * mark point so that the current position continues to correspond to the
  2899   2927        * edge of the window. This means that the picture will start dragging as
................................................................................
  3461   3489   	 */
  3462   3490   
  3463   3491   	Tcl_DecrRefCount(oldListObj);
  3464   3492       }
  3465   3493   
  3466   3494       /*
  3467   3495        * If the list length has decreased, then we should clean up selection and
  3468         -     * attributes information for elements past the end of the new list
         3496  +     * attributes information for elements past the end of the new list.
  3469   3497        */
  3470   3498   
  3471   3499       oldLength = listPtr->nElements;
  3472   3500       Tcl_ListObjLength(listPtr->interp, listPtr->listObj, &listPtr->nElements);
  3473   3501       if (listPtr->nElements < oldLength) {
  3474   3502   	for (i = listPtr->nElements; i < oldLength; i++) {
  3475   3503   	    /*
................................................................................
  3578   3606   		Tcl_SetHashValue(entry, clientData);
  3579   3607   	    }
  3580   3608   	}
  3581   3609       }
  3582   3610       return;
  3583   3611   }
  3584   3612   
         3613  +/*
         3614  + *----------------------------------------------------------------------
         3615  + *
         3616  + * GetMaxOffset --
         3617  + *
         3618  + *	Passing in a listbox pointer, returns the maximum offset for the box,
         3619  + *	i.e. the maximum possible horizontal scrolling value (in pixels).
         3620  + *
         3621  + * Results:
         3622  + *	Listbox's maxOffset.
         3623  + *
         3624  + * Side effects:
         3625  + *	None.
         3626  + *
         3627  + *----------------------------------------------------------------------
         3628  +*/
         3629  +static int GetMaxOffset(
         3630  +    register Listbox *listPtr)
         3631  +{
         3632  +    int maxOffset;
         3633  +
         3634  +    maxOffset = listPtr->maxWidth -
         3635  +            (Tk_Width(listPtr->tkwin) - 2*listPtr->inset -
         3636  +            2*listPtr->selBorderWidth) + listPtr->xScrollUnit - 1;
         3637  +    if (maxOffset < 0) {
         3638  +
         3639  +        /*
         3640  +         * Listbox is larger in width than its largest width item.
         3641  +         */
         3642  +
         3643  +        maxOffset = 0;
         3644  +    }
         3645  +    maxOffset -= maxOffset % listPtr->xScrollUnit;
         3646  +
         3647  +    return maxOffset;
         3648  +}
  3585   3649   /*
  3586   3650    * Local Variables:
  3587   3651    * mode: c
  3588   3652    * c-basic-offset: 4
  3589   3653    * fill-column: 78
  3590   3654    * End:
  3591   3655    */

Changes to library/demos/states.tcl.

    14     14   toplevel $w
    15     15   wm title $w "Listbox Demonstration (50 states)"
    16     16   wm iconname $w "states"
    17     17   positionWindow $w
    18     18   
    19     19   label $w.msg -font $font -wraplength 4i -justify left -text "A listbox containing the 50 states is displayed below, along with a scrollbar.  You can scan the list either using the scrollbar or by scanning.  To scan, press button 2 in the widget and drag up or down."
    20     20   pack $w.msg -side top
           21  +
           22  +labelframe $w.justif -text Justification
           23  +foreach c {Left Center Right} {
           24  +    set lower [string tolower $c]
           25  +    radiobutton $w.justif.$lower -text $c -variable just \
           26  +        -relief flat -value $lower -anchor w \
           27  +        -command "$w.frame.list configure -justify \$just" \
           28  +        -tristatevalue "multi"
           29  +    pack $w.justif.$lower -side left -pady 2 -fill x
           30  +}
           31  +pack $w.justif
    21     32   
    22     33   ## See Code / Dismiss buttons
    23     34   set btns [addSeeDismiss $w.buttons $w]
    24     35   pack $btns -side bottom -fill x
    25     36   
    26     37   frame $w.frame -borderwidth .5c
    27     38   pack $w.frame -side top -expand yes -fill y

Changes to macosx/tkMacOSXDefault.h.

   255    255   #define DEF_LISTBOX_EXPORT_SELECTION	"1"
   256    256   #define DEF_LISTBOX_FONT		"TkTextFont"
   257    257   #define DEF_LISTBOX_FG			BLACK
   258    258   #define DEF_LISTBOX_HEIGHT		"10"
   259    259   #define DEF_LISTBOX_HIGHLIGHT_BG	NORMAL_BG
   260    260   #define DEF_LISTBOX_HIGHLIGHT		BLACK
   261    261   #define DEF_LISTBOX_HIGHLIGHT_WIDTH	"0"
          262  +#define DEF_LISTBOX_JUSTIFY		"left"
   262    263   #define DEF_LISTBOX_RELIEF		"solid"
   263    264   #define DEF_LISTBOX_SCROLL_COMMAND	""
   264    265   #define DEF_LISTBOX_LIST_VARIABLE	""
   265    266   #define DEF_LISTBOX_SELECT_COLOR	SELECT_BG
   266    267   #define DEF_LISTBOX_SELECT_MONO		BLACK
   267    268   #define DEF_LISTBOX_SELECT_BD		"0"
   268    269   #define DEF_LISTBOX_SELECT_FG_COLOR	SELECT_FG

Changes to tests/listbox.test.

   200    200   } -returnCodes error -result {bad screen distance "bogus"}
   201    201   test listbox-1.31 {configuration options} -body {
   202    202       .l configure -highlightthickness -2
   203    203       list [lindex [.l configure -highlightthickness] 4] [.l cget -highlightthickness]
   204    204   } -cleanup {
   205    205       .l configure -highlightthickness [lindex [.l configure -highlightthickness] 3]
   206    206   } -result {0 0}
          207  +test listbox-1.32.1 {configuration options} -setup {
          208  +    set res {}
          209  +} -body {
          210  +    .l configure -justify left
          211  +    set res [list [lindex [.l configure -justify] 4] [.l cget -justify]]
          212  +    .l configure -justify center
          213  +    lappend res [lindex [.l configure -justify] 4] [.l cget -justify]
          214  +    .l configure -justify right
          215  +    lappend res [lindex [.l configure -justify] 4] [.l cget -justify]
          216  +} -cleanup {
          217  +    .l configure -justify [lindex [.l configure -justify] 3]
          218  +} -result {left left center center right right}
          219  +test listbox-1.32.2 {configuration options} -body {
          220  +    .l configure -justify bogus
          221  +} -returnCodes error -result {bad justification "bogus": must be left, right, or center}
   207    222   test listbox-1.33 {configuration options} -body {
   208    223       .l configure -relief groove
   209    224       list [lindex [.l configure -relief] 4] [.l cget -relief]
   210    225   } -cleanup {
   211    226       .l configure -relief [lindex [.l configure -relief] 3]
   212    227   } -result {groove groove}
   213    228   test listbox-1.34 {configuration options} -body {
................................................................................
   438    453   } -result {-72 39 393 14}
   439    454   test listbox-3.18 {ListboxWidgetCmd procedure, "bbox" option, partial last line} -constraints {
   440    455   	fonts
   441    456   } -body {
   442    457       mkPartial
   443    458       list [.partial.l bbox 3] [.partial.l bbox 4]
   444    459   } -result {{5 56 24 14} {5 73 23 14}}
          460  +test listbox-3.18a {ListboxWidgetCmd procedure, "bbox" option, justified} -constraints {
          461  +	fonts
          462  +} -setup {
          463  +    destroy .top.l .top
          464  +    unset -nocomplain res
          465  +} -body {
          466  +    toplevel .top
          467  +    listbox .top.l -justify left
          468  +    .top.l insert end Item1 LongerItem2 MuchLongerItem3
          469  +    pack .top.l
          470  +    update
          471  +    lappend res [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2]
          472  +    .top.l configure -justify center
          473  +    lappend res [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2]
          474  +    .top.l configure -justify right
          475  +    lappend res [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2]
          476  +} -cleanup {
          477  +    destroy .top.l .top
          478  +    unset -nocomplain res
          479  +} -result [list \
          480  +    {5 5 34 14} {5 22 74 14} {5 39 106 14}     \
          481  +    {58 5 34 14} {38 22 74 14} {22 39 106 14}  \
          482  +    {111 5 34 14} {71 22 74 14} {39 39 106 14} \
          483  +]
          484  +test listbox-3.18b {ListboxWidgetCmd procedure, "bbox" option, justified, non-default borderwidth} -setup {
          485  +    destroy .top.l .top
          486  +    unset -nocomplain lres res
          487  +} -body {
          488  +    # This test checks whether all "x" values from bbox for different size
          489  +    # items with different justification settings are all positive or zero
          490  +    # This checks a bit the calculation of this x value with non-default
          491  +    # borders widths of the listbox
          492  +    toplevel .top
          493  +    listbox .top.l -justify left -borderwidth 17 -highlightthickness 19 -selectborderwidth 22
          494  +    .top.l insert end Item1 LongerItem2 MuchLongerItem3
          495  +    .top.l selection set 1
          496  +    pack .top.l
          497  +    update
          498  +    lappend lres [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2]
          499  +    .top.l configure -justify center
          500  +    lappend lres [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2]
          501  +    .top.l configure -justify right
          502  +    lappend lres [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2]
          503  +    set res 1
          504  +    for {set i 0} {$i < [llength $lres]} {incr i 4} {
          505  +        set res [expr {$res * [expr {[lindex $lres $i] >= 0}] }]
          506  +    }
          507  +    set res
          508  +} -cleanup {
          509  +    destroy .top.l .top
          510  +    unset -nocomplain lres res
          511  +} -result {1}
   445    512   test listbox-3.19 {ListboxWidgetCmd procedure, "cget" option} -body {
   446    513       .l cget
   447    514   } -returnCodes error -result {wrong # args: should be ".l cget option"}
   448    515   test listbox-3.20 {ListboxWidgetCmd procedure, "cget" option} -body {
   449    516       .l cget a b
   450    517   } -returnCodes error -result {wrong # args: should be ".l cget option"}
   451    518   test listbox-3.21 {ListboxWidgetCmd procedure, "cget" option} -body {
................................................................................
   452    519       .l cget -gorp
   453    520   } -returnCodes error -result {unknown option "-gorp"}
   454    521   test listbox-3.22 {ListboxWidgetCmd procedure, "cget" option} -body {
   455    522       .l cget -setgrid
   456    523   } -result {0}
   457    524   test listbox-3.23 {ListboxWidgetCmd procedure, "configure" option} -body {
   458    525       llength [.l configure]
   459         -} -result {27}
          526  +} -result {28}
   460    527   test listbox-3.24 {ListboxWidgetCmd procedure, "configure" option} -body {
   461    528       .l configure -gorp
   462    529   } -returnCodes error -result {unknown option "-gorp"}
   463    530   test listbox-3.25 {ListboxWidgetCmd procedure, "configure" option} -body {
   464    531       .l configure -setgrid
   465    532   } -result {-setgrid setGrid SetGrid 0 0}
   466    533   test listbox-3.26 {ListboxWidgetCmd procedure, "configure" option} -body {

Changes to unix/tkUnixDefault.h.

   217    217   #define DEF_LISTBOX_EXPORT_SELECTION	"1"
   218    218   #define DEF_LISTBOX_FONT		"TkDefaultFont"
   219    219   #define DEF_LISTBOX_FG			BLACK
   220    220   #define DEF_LISTBOX_HEIGHT		"10"
   221    221   #define DEF_LISTBOX_HIGHLIGHT_BG	NORMAL_BG
   222    222   #define DEF_LISTBOX_HIGHLIGHT		BLACK
   223    223   #define DEF_LISTBOX_HIGHLIGHT_WIDTH	"1"
          224  +#define DEF_LISTBOX_JUSTIFY		"left"
   224    225   #define DEF_LISTBOX_RELIEF		"sunken"
   225    226   #define DEF_LISTBOX_SCROLL_COMMAND	""
   226    227   #define DEF_LISTBOX_LIST_VARIABLE	""
   227    228   #define DEF_LISTBOX_SELECT_COLOR	SELECT_BG
   228    229   #define DEF_LISTBOX_SELECT_MONO		BLACK
   229    230   #define DEF_LISTBOX_SELECT_BD		"0"
   230    231   #define DEF_LISTBOX_SELECT_FG_COLOR	BLACK

Changes to win/tkWinDefault.h.

   220    220   #define DEF_LISTBOX_EXPORT_SELECTION	"1"
   221    221   #define DEF_LISTBOX_FONT		"TkDefaultFont"
   222    222   #define DEF_LISTBOX_FG			NORMAL_FG
   223    223   #define DEF_LISTBOX_HEIGHT		"10"
   224    224   #define DEF_LISTBOX_HIGHLIGHT_BG	NORMAL_BG
   225    225   #define DEF_LISTBOX_HIGHLIGHT		HIGHLIGHT
   226    226   #define DEF_LISTBOX_HIGHLIGHT_WIDTH	"1"
          227  +#define DEF_LISTBOX_JUSTIFY		"left"
   227    228   #define DEF_LISTBOX_RELIEF		"sunken"
   228    229   #define DEF_LISTBOX_SCROLL_COMMAND	""
   229    230   #define DEF_LISTBOX_LIST_VARIABLE	""
   230    231   #define DEF_LISTBOX_SELECT_COLOR	SELECT_BG
   231    232   #define DEF_LISTBOX_SELECT_MONO		BLACK
   232    233   #define DEF_LISTBOX_SELECT_BD		"0"
   233    234   #define DEF_LISTBOX_SELECT_FG_COLOR	SELECT_FG