diff options
-rw-r--r-- | doc/listbox.n | 7 | ||||
-rw-r--r-- | generic/tkListbox.c | 108 | ||||
-rw-r--r-- | library/demos/states.tcl | 9 | ||||
-rw-r--r-- | macosx/tkMacOSXDefault.h | 1 | ||||
-rw-r--r-- | tests/listbox.test | 2 | ||||
-rw-r--r--[-rwxr-xr-x] | tests/winDialog.test | 0 | ||||
-rw-r--r-- | unix/tkUnixDefault.h | 1 | ||||
-rw-r--r-- | win/tkWinDefault.h | 1 |
8 files changed, 121 insertions, 8 deletions
diff --git a/doc/listbox.n b/doc/listbox.n index 9f34b5e..0f263b4 100644 --- a/doc/listbox.n +++ b/doc/listbox.n @@ -17,9 +17,10 @@ listbox \- Create and manipulate 'listbox' item list widgets \-background \-borderwidth \-cursor \-disabledforeground \-exportselection \-font \-foreground \-highlightbackground \-highlightcolor -\-highlightthickness \-relief \-selectbackground -\-selectborderwidth \-selectforeground \-setgrid -\-takefocus \-xscrollcommand \-yscrollcommand +\-highlightthickness \-justify \-relief +\-selectbackground \-selectborderwidth \-selectforeground +\-setgrid \-takefocus \-xscrollcommand +\-yscrollcommand .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-activestyle activeStyle ActiveStyle diff --git a/generic/tkListbox.c b/generic/tkListbox.c index 1843bbb..f16218b 100644 --- a/generic/tkListbox.c +++ b/generic/tkListbox.c @@ -165,6 +165,8 @@ typedef struct { Pixmap gray; /* Pixmap for displaying disabled text. */ int flags; /* Various flag bits: see below for * definitions. */ + Tk_Justify justify; /* Justification */ + int oldMaxOffset; /* Used in scrolling for right/center justification */ } Listbox; /* @@ -308,6 +310,8 @@ static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_STRING, "-listvariable", "listVariable", "Variable", DEF_LISTBOX_LIST_VARIABLE, -1, Tk_Offset(Listbox, listVarName), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", + DEF_LISTBOX_JUSTIFY, -1, Tk_Offset(Listbox, justify), 0, 0, 0}, {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0} }; @@ -436,6 +440,7 @@ static char * ListboxListVarProc(ClientData clientData, const char *name2, int flags); static void MigrateHashEntries(Tcl_HashTable *table, int first, int last, int offset); +static int GetMaxOffset(Listbox *listPtr); /* * The structure below defines button class behavior by means of procedures @@ -546,6 +551,8 @@ Tk_ListboxObjCmd( listPtr->cursor = None; listPtr->state = STATE_NORMAL; listPtr->gray = None; + listPtr->justify = TK_JUSTIFY_LEFT; + listPtr->oldMaxOffset = 0; /* * Keep a hold of the associated tkwin until we destroy the listbox, @@ -572,6 +579,13 @@ Tk_ListboxObjCmd( return TCL_ERROR; } + if (listPtr->justify == TK_JUSTIFY_RIGHT) { + listPtr->xOffset = GetMaxOffset(listPtr); + } else if (listPtr->justify == TK_JUSTIFY_CENTER) { + listPtr->xOffset = GetMaxOffset(listPtr) / 2; + listPtr->xOffset -= listPtr->xOffset % listPtr->xScrollUnit; + } + Tcl_SetObjResult(interp, TkNewWindowObj(listPtr->tkwin)); return TCL_OK; } @@ -1111,7 +1125,7 @@ ListboxBboxSubCmd( Tk_GetFontMetrics(listPtr->tkfont, &fm); pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen); - x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset; + x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset; y = ((index - listPtr->topIndex)*listPtr->lineHeight) + listPtr->inset + listPtr->selBorderWidth; results[0] = Tcl_NewIntObj(x); @@ -1838,6 +1852,7 @@ DisplayListbox( * or right edge of the listbox is * off-screen. */ Pixmap pixmap; + int totalLength, height; listPtr->flags &= ~REDRAW_PENDING; if (listPtr->flags & LISTBOX_DELETED) { @@ -2056,12 +2071,22 @@ DisplayListbox( /* * Draw the actual text of this item. */ + Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement); + stringRep = Tcl_GetStringFromObj(curElement, &stringLen); + Tk_ComputeTextLayout(listPtr->tkfont, + stringRep, stringLen, 0, + listPtr->justify, TK_IGNORE_NEWLINES, &totalLength, &height); Tk_GetFontMetrics(listPtr->tkfont, &fm); y += fm.ascent + listPtr->selBorderWidth; - x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset; - Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement); - stringRep = Tcl_GetStringFromObj(curElement, &stringLen); + + if (listPtr->justify == TK_JUSTIFY_LEFT) { + x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset; + } else if (listPtr->justify == TK_JUSTIFY_RIGHT) { + x = width - totalLength - listPtr->inset - listPtr->selBorderWidth - listPtr->xOffset + GetMaxOffset(listPtr) - 1; + } else { + x = (width + GetMaxOffset(listPtr))/2 - totalLength/2 - listPtr->xOffset; + } Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont, stringRep, stringLen, x, y); @@ -2582,6 +2607,7 @@ ListboxEventProc( ClientData clientData, /* Information about window. */ XEvent *eventPtr) /* Information about event. */ { + int tmpOffset, tmpOffset2, maxOffset; Listbox *listPtr = clientData; if (eventPtr->type == Expose) { @@ -2613,6 +2639,53 @@ ListboxEventProc( } listPtr->flags |= UPDATE_V_SCROLLBAR|UPDATE_H_SCROLLBAR; ChangeListboxView(listPtr, listPtr->topIndex); + if (listPtr->justify == TK_JUSTIFY_RIGHT) { + maxOffset = GetMaxOffset(listPtr); + if (maxOffset != listPtr->oldMaxOffset && listPtr->oldMaxOffset > 0) { // window has shrunk + if (maxOffset > listPtr->oldMaxOffset) { + tmpOffset = maxOffset - listPtr->oldMaxOffset; + } else { + tmpOffset = listPtr->oldMaxOffset - maxOffset; + } + tmpOffset -= tmpOffset % listPtr->xScrollUnit; + if ((tmpOffset + listPtr->xOffset) > maxOffset) { + tmpOffset = maxOffset - listPtr->xOffset; + } + if (tmpOffset < 0) { + tmpOffset = 0; + } + listPtr->xOffset += tmpOffset; + } else { + listPtr->xOffset = maxOffset; + } + listPtr->oldMaxOffset = maxOffset; + } else if (listPtr->justify == TK_JUSTIFY_CENTER) { + maxOffset = GetMaxOffset(listPtr); + if (maxOffset != listPtr->oldMaxOffset && listPtr->oldMaxOffset > 0) { // window has shrunk + tmpOffset2 = maxOffset / 2; + if (maxOffset > listPtr->oldMaxOffset) { + tmpOffset = maxOffset/2 - listPtr->oldMaxOffset/2; + } else { + tmpOffset = listPtr->oldMaxOffset/2 - maxOffset/2; + } + tmpOffset -= tmpOffset % listPtr->xScrollUnit; + if ((tmpOffset + listPtr->xOffset) > maxOffset) { + tmpOffset = maxOffset - listPtr->xOffset; + } + if (tmpOffset < 0) { + tmpOffset = 0; + } + if (listPtr->xOffset < tmpOffset2) { + listPtr->xOffset += tmpOffset; + } else { + listPtr->xOffset -= tmpOffset; + } + } else { + listPtr->xOffset = maxOffset/2; + listPtr->xOffset -= listPtr->xOffset % listPtr->xScrollUnit; + } + listPtr->oldMaxOffset = maxOffset; + } ChangeListboxOffset(listPtr, listPtr->xOffset); /* @@ -3584,6 +3657,33 @@ MigrateHashEntries( } /* + *---------------------------------------------------------------------- + * + * GetMaxOffset -- + * + * Passing in a listbox pointer, returns the maximum offset for the box + * + * Results: + * Listbox's maxOffset + * + * Side effects: + * None + * + *---------------------------------------------------------------------- +*/ +static int GetMaxOffset(register Listbox *listPtr) +{ + int maxOffset; + + maxOffset = listPtr->maxWidth - (Tk_Width(listPtr->tkwin) - 2*listPtr->inset - 2*listPtr->selBorderWidth) + listPtr->xScrollUnit - 1; + if (maxOffset < 0) { + maxOffset = 0; + } + maxOffset -= maxOffset % listPtr->xScrollUnit; + + return maxOffset; +} +/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/library/demos/states.tcl b/library/demos/states.tcl index 92b1f1e..41ce0bf 100644 --- a/library/demos/states.tcl +++ b/library/demos/states.tcl @@ -19,6 +19,15 @@ positionWindow $w 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." pack $w.msg -side top +foreach c {Left Center Right} { + set lower [string tolower $c] + radiobutton $w.$lower -text $c -variable just \ + -relief flat -value $lower -anchor w \ + -command "$w.frame.list configure -justify \$just" \ + -tristatevalue "multi" + pack $w.$lower -side left -pady 2 -fill x +} + ## See Code / Dismiss buttons set btns [addSeeDismiss $w.buttons $w] pack $btns -side bottom -fill x diff --git a/macosx/tkMacOSXDefault.h b/macosx/tkMacOSXDefault.h index 528ea10..dc73188 100644 --- a/macosx/tkMacOSXDefault.h +++ b/macosx/tkMacOSXDefault.h @@ -262,6 +262,7 @@ #define DEF_LISTBOX_RELIEF "solid" #define DEF_LISTBOX_SCROLL_COMMAND "" #define DEF_LISTBOX_LIST_VARIABLE "" +#define DEF_LISTBOX_JUSTIFY "left" #define DEF_LISTBOX_SELECT_COLOR SELECT_BG #define DEF_LISTBOX_SELECT_MONO BLACK #define DEF_LISTBOX_SELECT_BD "0" diff --git a/tests/listbox.test b/tests/listbox.test index f50267e..0519e93 100644 --- a/tests/listbox.test +++ b/tests/listbox.test @@ -455,7 +455,7 @@ test listbox-3.22 {ListboxWidgetCmd procedure, "cget" option} -body { } -result {0} test listbox-3.23 {ListboxWidgetCmd procedure, "configure" option} -body { llength [.l configure] -} -result {27} +} -result {28} test listbox-3.24 {ListboxWidgetCmd procedure, "configure" option} -body { .l configure -gorp } -returnCodes error -result {unknown option "-gorp"} diff --git a/tests/winDialog.test b/tests/winDialog.test index c8c36bf..c8c36bf 100755..100644 --- a/tests/winDialog.test +++ b/tests/winDialog.test diff --git a/unix/tkUnixDefault.h b/unix/tkUnixDefault.h index d214aa5..ac7bc4d 100644 --- a/unix/tkUnixDefault.h +++ b/unix/tkUnixDefault.h @@ -224,6 +224,7 @@ #define DEF_LISTBOX_RELIEF "sunken" #define DEF_LISTBOX_SCROLL_COMMAND "" #define DEF_LISTBOX_LIST_VARIABLE "" +#define DEF_LISTBOX_JUSTIFY "left" #define DEF_LISTBOX_SELECT_COLOR SELECT_BG #define DEF_LISTBOX_SELECT_MONO BLACK #define DEF_LISTBOX_SELECT_BD "0" diff --git a/win/tkWinDefault.h b/win/tkWinDefault.h index c52cc4d..29fe4ee 100644 --- a/win/tkWinDefault.h +++ b/win/tkWinDefault.h @@ -227,6 +227,7 @@ #define DEF_LISTBOX_RELIEF "sunken" #define DEF_LISTBOX_SCROLL_COMMAND "" #define DEF_LISTBOX_LIST_VARIABLE "" +#define DEF_LISTBOX_JUSTIFY "left" #define DEF_LISTBOX_SELECT_COLOR SELECT_BG #define DEF_LISTBOX_SELECT_MONO BLACK #define DEF_LISTBOX_SELECT_BD "0" |