summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhobbs <hobbs>2002-06-21 02:38:54 (GMT)
committerhobbs <hobbs>2002-06-21 02:38:54 (GMT)
commit093ba20aa9429d1193d14f69c01efa197fb23b02 (patch)
tree614fdb1ec8759677a120bdac4fb4edd69daa4b17
parentee7d851982f1cba4efafa2b2246864b17c11bad6 (diff)
downloadtk-093ba20aa9429d1193d14f69c01efa197fb23b02.zip
tk-093ba20aa9429d1193d14f69c01efa197fb23b02.tar.gz
tk-093ba20aa9429d1193d14f69c01efa197fb23b02.tar.bz2
* doc/listbox.n:
* generic/tkListbox.c (DisplayListbox): * mac/tkMacDefault.h: TIP #94 implementation adding -activestyle * tests/listbox.test: option to the listbox. This adds the ability * unix/tkUnixDefault.h: to have listboxes look native on Windows, and * win/tkWinDefault.h: "nicer" elsewhere using the 'dotbox' style.
-rw-r--r--doc/listbox.n35
-rw-r--r--generic/tkListbox.c136
-rw-r--r--mac/tkMacDefault.h3
-rw-r--r--tests/listbox.test21
-rw-r--r--unix/tkUnixDefault.h3
-rw-r--r--win/tkWinDefault.h3
6 files changed, 155 insertions, 46 deletions
diff --git a/doc/listbox.n b/doc/listbox.n
index cd1067c..7326497 100644
--- a/doc/listbox.n
+++ b/doc/listbox.n
@@ -5,10 +5,10 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-'\" RCS: @(#) $Id: listbox.n,v 1.8 2000/08/25 06:58:32 ericm Exp $
+'\" RCS: @(#) $Id: listbox.n,v 1.9 2002/06/21 02:38:54 hobbs Exp $
'\"
.so man.macros
-.TH listbox n 8.0 Tk "Tk Built-In Commands"
+.TH listbox n 8.4 Tk "Tk Built-In Commands"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -16,15 +16,24 @@ listbox \- Create and manipulate listbox widgets
.SH SYNOPSIS
\fBlistbox\fR \fIpathName \fR?\fIoptions\fR?
.SO
-\-background \-height \-selectforeground
-\-borderwidth \-highlightbackground \-setgrid
-\-cursor \-highlightcolor \-state
-\-disabledforeground \-highlightthickness \-takefocus
-\-exportselection \-relief \-width
-\-font \-selectbackground \-xscrollcommand
-\-foreground \-selectborderwidth \-yscrollcommand
+\-activestyle \-height \-selectforeground
+\-background \-highlightbackground \-setgrid
+\-borderwidth \-highlightcolor \-state
+\-cursor \-highlightthickness \-takefocus
+\-disabledforeground \-relief \-width
+\-exportselection \-selectbackground \-xscrollcommand
+\-font \-selectborderwidth \-yscrollcommand
+\-foreground
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
+.VS 8.4
+.OP \-activestyle activeStyle ActiveStyle
+Specifies the style in which to draw the active element. This must be
+one of \fBdotbox\fR (show a focus ring around the active element),
+\fBnone\fR (nospecial indication of active element) or
+\fBunderline\fR (underline the active element).
+The default is \fBunderline\fR.
+.VS 8.4
.OP \-height height Height
Specifies the desired height for the window, in lines.
If zero or less, then the desired height for the window is made just
@@ -100,8 +109,8 @@ to the first element in the listbox.
.TP 12
\fBactive\fR
Indicates the element that has the location cursor. This element
-will be displayed with an underline when the listbox has the
-keyboard focus, and it is specified with the \fBactivate\fR
+will be displayed as specified by \fB\-activestyle\fR when the listbox
+has the keyboard focus, and it is specified with the \fBactivate\fR
widget command.
.TP 12
\fBanchor\fR
@@ -145,8 +154,8 @@ Sets the active element to the one indicated by \fIindex\fR.
If \fIindex\fR is outside the range of elements in the listbox
then the closest element is activated.
.VE
-The active element is drawn with an underline when the widget
-has the input focus, and its index may be retrieved with the
+The active element is drawn as specified by \fB\-activestyle\fR when the
+widget has the input focus, and its index may be retrieved with the
index \fBactive\fR.
.TP
\fIpathName \fBbbox\fR \fIindex\fR
diff --git a/generic/tkListbox.c b/generic/tkListbox.c
index e6483fd..03d130d 100644
--- a/generic/tkListbox.c
+++ b/generic/tkListbox.c
@@ -11,13 +11,17 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkListbox.c,v 1.26 2002/03/20 22:55:16 dgp Exp $
+ * RCS: @(#) $Id: tkListbox.c,v 1.27 2002/06/21 02:38:54 hobbs Exp $
*/
#include "tkPort.h"
#include "default.h"
#include "tkInt.h"
+#ifdef WIN32
+#include "tkWinInt.h"
+#endif
+
typedef struct {
Tk_OptionTable listboxOptionTable; /* Table defining configuration options
* available for the listbox */
@@ -128,6 +132,8 @@ typedef struct {
int active; /* Index of "active" element (the one that
* has been selected by keyboard traversal).
* -1 means none. */
+ int activeStyle; /* style in which to draw the active element.
+ * One of: underline, none, dotbox */
/*
* Information for scanning:
@@ -210,11 +216,22 @@ static char *stateStrings[] = {
"disabled", "normal", (char *) NULL
};
+enum activeStyle {
+ ACTIVE_STYLE_DOTBOX, ACTIVE_STYLE_NONE, ACTIVE_STYLE_UNDERLINE
+};
+
+static char *activeStyleStrings[] = {
+ "dotbox", "none", "underline", (char *) NULL
+};
+
/*
* The optionSpecs table defines the valid configuration options for the
* listbox widget
*/
static Tk_OptionSpec optionSpecs[] = {
+ {TK_OPTION_STRING_TABLE, "-activestyle", "activeStyle", "ActiveStyle",
+ DEF_LISTBOX_ACTIVE_STYLE, -1, Tk_Offset(Listbox, activeStyle),
+ 0, (ClientData) activeStyleStrings, 0},
{TK_OPTION_BORDER, "-background", "background", "Background",
DEF_LISTBOX_BG_COLOR, -1, Tk_Offset(Listbox, normalBorder),
0, (ClientData) DEF_LISTBOX_BG_MONO, 0},
@@ -294,26 +311,26 @@ static Tk_OptionSpec optionSpecs[] = {
*/
static Tk_OptionSpec itemAttrOptionSpecs[] = {
{TK_OPTION_BORDER, "-background", "background", "Background",
- (char *)NULL, -1, Tk_Offset(ItemAttr, border),
- TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
+ (char *)NULL, -1, Tk_Offset(ItemAttr, border),
+ TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
(ClientData) DEF_LISTBOX_BG_MONO, 0},
{TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-background", 0},
+ (char *) NULL, 0, -1, 0, (ClientData) "-background", 0},
{TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL,
- (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0},
+ (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0},
{TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
- (char *) NULL, -1, Tk_Offset(ItemAttr, fgColor),
- TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
+ (char *) NULL, -1, Tk_Offset(ItemAttr, fgColor),
+ TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
{TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
- (char *) NULL, -1, Tk_Offset(ItemAttr, selBorder),
- TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
+ (char *) NULL, -1, Tk_Offset(ItemAttr, selBorder),
+ TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
(ClientData) DEF_LISTBOX_SELECT_MONO, 0},
{TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
- (char *) NULL, -1, Tk_Offset(ItemAttr, selFgColor),
- TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
+ (char *) NULL, -1, Tk_Offset(ItemAttr, selFgColor),
+ TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
(ClientData) DEF_LISTBOX_SELECT_FG_MONO, 0},
{TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, -1, 0, 0, 0}
+ (char *) NULL, 0, -1, 0, 0, 0}
};
/*
@@ -323,17 +340,17 @@ static Tk_OptionSpec itemAttrOptionSpecs[] = {
*/
static CONST char *commandNames[] = {
"activate", "bbox", "cget", "configure", "curselection", "delete", "get",
- "index", "insert", "itemcget", "itemconfigure", "nearest", "scan",
- "see", "selection", "size", "xview", "yview",
+ "index", "insert", "itemcget", "itemconfigure", "nearest", "scan",
+ "see", "selection", "size", "xview", "yview",
(char *) NULL
};
enum command {
COMMAND_ACTIVATE, COMMAND_BBOX, COMMAND_CGET, COMMAND_CONFIGURE,
- COMMAND_CURSELECTION, COMMAND_DELETE, COMMAND_GET, COMMAND_INDEX,
- COMMAND_INSERT, COMMAND_ITEMCGET, COMMAND_ITEMCONFIGURE,
- COMMAND_NEAREST, COMMAND_SCAN, COMMAND_SEE, COMMAND_SELECTION,
- COMMAND_SIZE, COMMAND_XVIEW, COMMAND_YVIEW
+ COMMAND_CURSELECTION, COMMAND_DELETE, COMMAND_GET, COMMAND_INDEX,
+ COMMAND_INSERT, COMMAND_ITEMCGET, COMMAND_ITEMCONFIGURE,
+ COMMAND_NEAREST, COMMAND_SCAN, COMMAND_SEE, COMMAND_SELECTION,
+ COMMAND_SIZE, COMMAND_XVIEW, COMMAND_YVIEW
};
static CONST char *selCommandNames[] = {
@@ -1796,7 +1813,7 @@ DisplayListbox(clientData)
register Listbox *listPtr = (Listbox *) clientData;
register Tk_Window tkwin = listPtr->tkwin;
GC gc;
- int i, limit, x, y, width, prevSelected;
+ int i, limit, x, y, width, prevSelected, freeGC;
Tk_FontMetrics fm;
Tcl_Obj *curElement;
Tcl_HashEntry *entry;
@@ -1873,6 +1890,7 @@ DisplayListbox(clientData)
y = ((i - listPtr->topIndex) * listPtr->lineHeight)
+ listPtr->inset;
gc = listPtr->textGC;
+ freeGC = 0;
/*
* Lookup this item in the item attributes table, to see if it has
* special foreground/background colors
@@ -1908,27 +1926,29 @@ DisplayListbox(clientData)
if (attrs->selFgColor != NULL) {
gcValues.foreground = attrs->selFgColor->pixel;
gc = Tk_GetGC(listPtr->tkwin, mask, &gcValues);
+ freeGC = 1;
}
}
-
+
Tk_Fill3DRectangle(tkwin, pixmap, selectedBg, x, y,
width, listPtr->lineHeight, 0, TK_RELIEF_FLAT);
/*
* Draw beveled edges around the selection, if there are
- * visible edges next to this element. Special considerations:
+ * visible edges next to this element. Special considerations:
+ *
* 1. The left and right bevels may not be visible if
- * horizontal scrolling is enabled (the "left" and "right"
+ * horizontal scrolling is enabled (the "left" & "right"
* variables are zero to indicate that the corresponding
* bevel is visible).
* 2. Top and bottom bevels are only drawn if this is the
* first or last seleted item.
- * 3. If the left or right bevel isn't visible, then the "left"
- * and "right" variables, computed above, have non-zero
+ * 3. If the left or right bevel isn't visible, then the
+ * "left" & "right" vars, computed above, have non-zero
* values that extend the top and bottom bevels so that
* the mitered corners are off-screen.
*/
-
+
/* Draw left bevel */
if (left == 0) {
Tk_3DVerticalBevel(tkwin, pixmap, selectedBg,
@@ -1990,11 +2010,13 @@ DisplayListbox(clientData)
&& attrs->fgColor != NULL) {
gcValues.foreground = attrs->fgColor->pixel;
gc = Tk_GetGC(listPtr->tkwin, mask, &gcValues);
+ freeGC = 1;
}
}
prevSelected = 0;
}
}
+
/* Draw the actual text of this item */
Tk_GetFontMetrics(listPtr->tkfont, &fm);
y += fm.ascent + listPtr->selBorderWidth;
@@ -2004,10 +2026,68 @@ DisplayListbox(clientData)
Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont,
stringRep, stringLen, x, y);
- /* If this is the active element, underline it. */
+ /* If this is the active element, apply the activestyle to it. */
if ((i == listPtr->active) && (listPtr->flags & GOT_FOCUS)) {
- Tk_UnderlineChars(listPtr->display, pixmap, gc, listPtr->tkfont,
- stringRep, x, y, 0, stringLen);
+ if (listPtr->activeStyle == ACTIVE_STYLE_UNDERLINE) {
+ /* Underline the text. */
+ Tk_UnderlineChars(listPtr->display, pixmap, gc,
+ listPtr->tkfont, stringRep, x, y, 0, stringLen);
+ } else if (listPtr->activeStyle == ACTIVE_STYLE_DOTBOX) {
+#ifdef WIN32
+ /*
+ * This provides for exact default look and feel on Windows.
+ */
+ TkWinDCState state;
+ HDC dc;
+ RECT rect;
+
+ dc = TkWinGetDrawableDC(listPtr->display, pixmap, &state);
+ rect.left = listPtr->inset;
+ rect.top = ((i - listPtr->topIndex) * listPtr->lineHeight)
+ + listPtr->inset;
+ rect.right = rect.left + width;
+ rect.bottom = rect.top + listPtr->lineHeight;
+ DrawFocusRect(dc, &rect);
+ TkWinReleaseDrawableDC(pixmap, dc, &state);
+#else
+ /*
+ * Draw a dotted box around the text.
+ */
+ x = listPtr->inset;
+ y = ((i - listPtr->topIndex) * listPtr->lineHeight)
+ + listPtr->inset;
+ width = Tk_Width(tkwin) - 2*listPtr->inset - 1;
+
+ gcValues.line_style = LineOnOffDash;
+ gcValues.line_width = listPtr->selBorderWidth;
+ if (gcValues.line_width <= 0) {
+ gcValues.line_width = 1;
+ }
+ gcValues.dash_offset = 0;
+ gcValues.dashes = 1;
+ /*
+ * You would think the XSetDashes was necessary, but it
+ * appears that the default dotting for just saying we
+ * want dashes appears to work correctly.
+ static char dashList[] = { 1 };
+ static int dashLen = sizeof(dashList);
+ XSetDashes(listPtr->display, gc, 0, dashList, dashLen);
+ */
+ mask = GCLineWidth | GCLineStyle | GCDashList | GCDashOffset;
+ XChangeGC(listPtr->display, gc, mask, &gcValues);
+ XDrawRectangle(listPtr->display, pixmap, gc, x, y,
+ (unsigned) width, (unsigned) listPtr->lineHeight - 1);
+ if (!freeGC) {
+ /* Don't bother changing if it is about to be freed. */
+ gcValues.line_style = LineSolid;
+ XChangeGC(listPtr->display, gc, GCLineStyle, &gcValues);
+ }
+#endif
+ }
+ }
+
+ if (freeGC) {
+ Tk_FreeGC(listPtr->display, gc);
}
}
diff --git a/mac/tkMacDefault.h b/mac/tkMacDefault.h
index 48eff70..fd55d68 100644
--- a/mac/tkMacDefault.h
+++ b/mac/tkMacDefault.h
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacDefault.h,v 1.14 2002/02/22 21:07:05 hobbs Exp $
+ * RCS: @(#) $Id: tkMacDefault.h,v 1.15 2002/06/21 02:38:54 hobbs Exp $
*/
#ifndef _TKMACDEFAULT
@@ -213,6 +213,7 @@
* Defaults for listboxes:
*/
+#define DEF_LISTBOX_ACTIVE_STYLE "underline"
#define DEF_LISTBOX_BG_COLOR NORMAL_BG
#define DEF_LISTBOX_BG_MONO WHITE
#define DEF_LISTBOX_BORDER_WIDTH "1"
diff --git a/tests/listbox.test b/tests/listbox.test
index 0033ee4..0b1b7a0 100644
--- a/tests/listbox.test
+++ b/tests/listbox.test
@@ -6,7 +6,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: listbox.test,v 1.17 2002/02/26 01:07:29 hobbs Exp $
+# RCS: @(#) $Id: listbox.test,v 1.18 2002/06/21 02:38:54 hobbs Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
source [file join [pwd] [file dirname [info script]] defs.tcl]
@@ -73,6 +73,7 @@ resetGridInfo
set i 1
foreach test {
+ {-activestyle under underline foo {bad activestyle "foo": must be dotbox, none, or underline}}
{-background #ff0000 #ff0000 non-existent
{unknown color name "non-existent"}}
{-bd 4 4 badValue {bad screen distance "badValue"}}
@@ -241,7 +242,7 @@ test listbox-3.22 {ListboxWidgetCmd procedure, "cget" option} {
} {0}
test listbox-3.23 {ListboxWidgetCmd procedure, "configure" option} {
llength [.l configure]
-} {26}
+} {27}
test listbox-3.24 {ListboxWidgetCmd procedure, "configure" option} {
list [catch {.l configure -gorp} msg] $msg
} {1 {unknown option "-gorp"}}
@@ -2117,6 +2118,22 @@ test listbox-27.1 {widget deletion while active} {
winfo exists .l
} 0
+test listbox-28.1 {listbox -activestyle} {
+ catch {destroy .l}
+ listbox .l -activ non
+ .l cget -activestyle
+} none
+test listbox-28.2 {listbox -activestyle} {
+ catch {destroy .l}
+ listbox .l
+ .l cget -activestyle
+} underline
+test listbox-28.3 {listbox -activestyle} {
+ catch {destroy .l}
+ listbox .l -activestyle dot
+ .l cget -activestyle
+} dotbox
+
resetGridInfo
eval destroy [winfo children .]
option clear
diff --git a/unix/tkUnixDefault.h b/unix/tkUnixDefault.h
index d5503c0..d0afe39 100644
--- a/unix/tkUnixDefault.h
+++ b/unix/tkUnixDefault.h
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkUnixDefault.h,v 1.14 2002/02/22 21:07:05 hobbs Exp $
+ * RCS: @(#) $Id: tkUnixDefault.h,v 1.15 2002/06/21 02:38:54 hobbs Exp $
*/
#ifndef _TKUNIXDEFAULT
@@ -208,6 +208,7 @@
* Defaults for listboxes:
*/
+#define DEF_LISTBOX_ACTIVE_STYLE "underline"
#define DEF_LISTBOX_BG_COLOR NORMAL_BG
#define DEF_LISTBOX_BG_MONO WHITE
#define DEF_LISTBOX_BORDER_WIDTH "2"
diff --git a/win/tkWinDefault.h b/win/tkWinDefault.h
index 4a5b59d..e9f999b 100644
--- a/win/tkWinDefault.h
+++ b/win/tkWinDefault.h
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinDefault.h,v 1.14 2002/02/22 21:07:05 hobbs Exp $
+ * RCS: @(#) $Id: tkWinDefault.h,v 1.15 2002/06/21 02:38:54 hobbs Exp $
*/
#ifndef _TKWINDEFAULT
@@ -213,6 +213,7 @@
* Defaults for listboxes:
*/
+#define DEF_LISTBOX_ACTIVE_STYLE "underline"
#define DEF_LISTBOX_BG_COLOR "SystemWindow"
#define DEF_LISTBOX_BG_MONO WHITE
#define DEF_LISTBOX_BORDER_WIDTH "2"