Since it has been years since I saw a NeXT box, can you elaborate on
what a "NeXT-style" scrollbar was?
--
Jeff Hobbs The Tcl Guy
Senior Developer http://www.ActiveState.com/
Tcl Support and Productivity Solutions
> > Can anyone point me to a NeXT-style scrollbar widget, for the TK 8.0.3
> > release or later?
>
> Since it has been years since I saw a NeXT box, can you elaborate on
> what a "NeXT-style" scrollbar was?
Both scrollbar buttons placed at the bottom (for a vertical bar) or at the left
for a horizontal bar. This is good because it makes mousing easier: you don't
have to move the mouse as much to simply move up and down.
Here is the URL for an picture:
Or you just buy a mouse with a scroll-wheel. It's amazing how fast that
becomes adictive. :-)
--
Darren New
San Diego, CA, USA (PST). Cryptokeys on demand.
Remember, drive defensively if you drink.
One thing I remember about them is that they had the
up/down (left/right) arrows at the same end of the scrollbar,
and if both scrollbars were present all four scrollbuttons
were in the same corner. So you could scroll in all four
directions without having to move the mouse all the way
across the window.
This layout is so amazingly useful I wonder why it hasn't been
copied in more toolkits.
--Joe English
I agree.
I've even gone as far as making all my tcl apps use shift-mouse wheel
to scroll horizontally.
Keith
I am another addict of the mousewheel (one of the reasons laptops are
more of a pain to use now), but one thing that people often forget in
Tk is that it has default B2 pan bindings. The mousewheel is B2 on
Windows, so if you press it and move up/down or left/right in a widget
that takes scrollbars, it will move the view for you.
--
Jeff Hobbs The Tcl Guy
Senior Developer http://www.ActiveState.com/
Tcl Support and Productivity Solutions
Join us in Sept. for Tcl'2002: http://www.tcl.tk/community/tcl2002/
Ah, I've seen that before. This would be easy to either modify in
the Unix Tk core or to simulate as an alternative widget, but on
Windows, the native scrollbar is used (so you always get what MS
wants). Same with Mac.
--
Jeff Hobbs The Tcl Guy
Senior Developer http://www.ActiveState.com/
Tcl Support and Productivity Solutions
> > > > Can anyone point me to a NeXT-style scrollbar widget, for the TK 8.0.3
> > > > release or later?
> > >
> > > Since it has been years since I saw a NeXT box, can you elaborate on
> > > what a "NeXT-style" scrollbar was?
> >
> > Both scrollbar buttons placed at the bottom (for a vertical bar) or at the left
> > for a horizontal bar. This is good because it makes mousing easier: you don't
> > have to move the mouse as much to simply move up and down.
>
> Ah, I've seen that before. This would be easy to either modify in
> the Unix Tk core or to simulate as an alternative widget, but on
> Windows, the native scrollbar is used (so you always get what MS
> wants). Same with Mac.
Yeah, I looked and I think changing the TkpScrollbarPosition and
TkpScrollbar display routines would be enough. I was just hoping somebody
else had already made the changes. I haven't played with TCL/TK in a
very long time.
Oh! ... I thought that only worked for text widgets. Good to know.
L
--
Laurent Duperval <mailto:laurent....@masq.ca>
HUBBARD'S LAW
Don't take life too seriously; you won't get out of it alive.
I'm not looking at the code right now, but it is just about moving
the top/left triangle next to the bottom/right right, so it is just
an adjustment of where that triangle and the bar are drawn. The
dimensions for them should always be the same.
IIRC, MacOS allowed the user to choose if the arrow buttons were
at either end or both together. I could see the reason of co-location
for less mousing, but in practice I found it counter-intuitive is actual use
going to the bottom of the scrollbar to scroll up - and since the mouse wheel
was invented I became way hooked on it
Bruce
> Tommy Reynolds wrote:
> ...
> > Yeah, I looked and I think changing the TkpScrollbarPosition and
> > TkpScrollbar display routines would be enough. I was just hoping somebody
> > else had already made the changes. I haven't played with TCL/TK in a
> > very long time.
>
> I'm not looking at the code right now, but it is just about moving
> the top/left triangle next to the bottom/right right, so it is just
> an adjustment of where that triangle and the bar are drawn. The
> dimensions for them should always be the same.
>
I've made some patches that work for me under Linux. It adds a "-nextstyle"
boolean to the "scrollbar" widget. I've placed a line (marked by "FIXME") in
the TkpConfigureScrollbar() routine that forces the NeXT-style scrollbar.
Have fun.
----------------------------------- cut -------------------------------
Index: tk/generic/tkScrollbar.c
===================================================================
RCS file: /cvs/src/src/tk/generic/tkScrollbar.c,v
retrieving revision 1.1.1.1
diff -u -w -p -b -r1.1.1.1 tkScrollbar.c
--- tk/generic/tkScrollbar.c 7 Feb 2000 00:19:29 -0000 1.1.1.1
+++ tk/generic/tkScrollbar.c 11 Apr 2002 20:40:03 -0000
@@ -61,6 +61,8 @@ Tk_ConfigSpec tkpScrollbarConfigSpecs[]
{TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
"HighlightThickness",
DEF_SCROLLBAR_HIGHLIGHT_WIDTH, Tk_Offset(TkScrollbar, highlightWidth), 0},
+ {TK_CONFIG_BOOLEAN, "-nextstyle", "nextstyle", "NeXTStyle",
+ DEF_SCROLLBAR_JUMP, Tk_Offset(TkScrollbar, style), 0},
{TK_CONFIG_BOOLEAN, "-jump", "jump", "Jump",
DEF_SCROLLBAR_JUMP, Tk_Offset(TkScrollbar, jump), 0},
{TK_CONFIG_UID, "-orient", "orient", "Orient",
Index: tk/generic/tkScrollbar.h
===================================================================
RCS file: /cvs/src/src/tk/generic/tkScrollbar.h,v
retrieving revision 1.1.1.1
diff -u -w -p -b -r1.1.1.1 tkScrollbar.h
--- tk/generic/tkScrollbar.h 7 Feb 2000 00:19:29 -0000 1.1.1.1
+++ tk/generic/tkScrollbar.h 11 Apr 2002 20:40:03 -0000
@@ -43,6 +43,7 @@ typedef struct TkScrollbar {
* "horizontal"). */
int vertical; /* Non-zero means vertical orientation
* requested, zero means horizontal. */
+ int style; /* 0:native, 1:NeXT */
int width; /* Desired narrow dimension of scrollbar,
* in pixels. */
char *command; /* Command prefix to use when invoking
Index: tk/unix/tkUnixScrlbr.c
===================================================================
RCS file: /cvs/src/src/tk/unix/tkUnixScrlbr.c,v
retrieving revision 1.1.1.1
diff -u -w -p -b -r1.1.1.1 tkUnixScrlbr.c
--- tk/unix/tkUnixScrlbr.c 7 Feb 2000 00:19:30 -0000 1.1.1.1
+++ tk/unix/tkUnixScrlbr.c 11 Apr 2002 20:40:04 -0000
@@ -101,6 +101,7 @@ TkpDisplayScrollbar(clientData)
Tk_3DBorder border;
int relief, width, elementBorderWidth;
Pixmap pixmap;
+ int length;
if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
goto done;
@@ -108,8 +109,10 @@ TkpDisplayScrollbar(clientData)
if (scrollPtr->vertical) {
width = Tk_Width(tkwin) - 2*scrollPtr->inset;
+ length = Tk_Height( tkwin );
} else {
width = Tk_Height(tkwin) - 2*scrollPtr->inset;
+ length = Tk_Width( tkwin );
}
elementBorderWidth = scrollPtr->elementBorderWidth;
if (elementBorderWidth < 0) {
@@ -164,24 +167,43 @@ TkpDisplayScrollbar(clientData)
relief = TK_RELIEF_RAISED;
}
if (scrollPtr->vertical) {
+ if( scrollPtr->style == 0 ) {
points[0].x = scrollPtr->inset - 1;
points[0].y = scrollPtr->arrowLength + scrollPtr->inset - 1;
points[1].x = width + scrollPtr->inset;
points[1].y = points[0].y;
points[2].x = width/2 + scrollPtr->inset;
points[2].y = scrollPtr->inset - 1;
- Tk_Fill3DPolygon(tkwin, pixmap, border, points, 3,
- elementBorderWidth, relief);
} else {
+ points[0].x = width/2 + scrollPtr->inset + 1;
+ points[0].y = length -
+ (scrollPtr->arrowLength + scrollPtr->inset - 1)*2;
+ points[1].x = scrollPtr->inset;
+ points[1].y = points[0].y + scrollPtr->arrowLength;
+ points[2].x = width + scrollPtr->inset;
+ points[2].y = points[1].y;
+ }
+ } else {
+ if( scrollPtr->style == 0 ) {
points[0].x = scrollPtr->arrowLength + scrollPtr->inset - 1;
points[0].y = scrollPtr->inset - 1;
points[1].x = scrollPtr->inset;
points[1].y = width/2 + scrollPtr->inset;
points[2].x = points[0].x;
points[2].y = width + scrollPtr->inset;
- Tk_Fill3DPolygon(tkwin, pixmap, border, points, 3,
- elementBorderWidth, relief);
+ } else {
+ points[0].x = length -
+ (scrollPtr->arrowLength + scrollPtr->inset - 1)*2;
+ points[0].y = width/2 + scrollPtr->inset;
+ points[1].x = points[0].x + scrollPtr->arrowLength;
+ points[1].y = points[0].y + (width/2) + 1;
+ points[2].x = points[1].x;
+ points[2].y = points[1].y - width;
}
+ }
+ Tk_Fill3DPolygon(tkwin, pixmap, border,
+ points, 3, elementBorderWidth, relief);
+ /* FIXME */
/*
* Display the bottom or right arrow.
@@ -196,6 +218,7 @@ TkpDisplayScrollbar(clientData)
relief = TK_RELIEF_RAISED;
}
if (scrollPtr->vertical) {
+ if( scrollPtr->style == 0 ) {
points[0].x = scrollPtr->inset;
points[0].y = Tk_Height(tkwin) - scrollPtr->arrowLength
- scrollPtr->inset + 1;
@@ -203,8 +226,24 @@ TkpDisplayScrollbar(clientData)
points[1].y = Tk_Height(tkwin) - scrollPtr->inset;
points[2].x = width + scrollPtr->inset;
points[2].y = points[0].y;
- Tk_Fill3DPolygon(tkwin, pixmap, border,
- points, 3, elementBorderWidth, relief);
+ } else {
+ points[0].x = scrollPtr->inset;
+ points[0].y = Tk_Height(tkwin) - scrollPtr->arrowLength
+ - scrollPtr->inset + 1;
+ points[1].x = width/2 + scrollPtr->inset;
+ points[1].y = Tk_Height(tkwin) - scrollPtr->inset;
+ points[2].x = width + scrollPtr->inset;
+ points[2].y = points[0].y;
+ }
+ } else {
+ if( scrollPtr->style == 0 ) {
+ points[0].x = Tk_Width(tkwin) - scrollPtr->arrowLength
+ - scrollPtr->inset + 1;
+ points[0].y = scrollPtr->inset - 1;
+ points[1].x = points[0].x;
+ points[1].y = width + scrollPtr->inset;
+ points[2].x = Tk_Width(tkwin) - scrollPtr->inset;
+ points[2].y = width/2 + scrollPtr->inset;
} else {
points[0].x = Tk_Width(tkwin) - scrollPtr->arrowLength
- scrollPtr->inset + 1;
@@ -213,9 +252,10 @@ TkpDisplayScrollbar(clientData)
points[1].y = width + scrollPtr->inset;
points[2].x = Tk_Width(tkwin) - scrollPtr->inset;
points[2].y = width/2 + scrollPtr->inset;
+ }
+ }
Tk_Fill3DPolygon(tkwin, pixmap, border,
points, 3, elementBorderWidth, relief);
- }
/*
* Display the slider.
@@ -230,15 +270,29 @@ TkpDisplayScrollbar(clientData)
relief = TK_RELIEF_RAISED;
}
if (scrollPtr->vertical) {
- Tk_Fill3DRectangle(tkwin, pixmap, border,
- scrollPtr->inset, scrollPtr->sliderFirst,
- width, scrollPtr->sliderLast - scrollPtr->sliderFirst,
- elementBorderWidth, relief);
- } else {
- Tk_Fill3DRectangle(tkwin, pixmap, border,
- scrollPtr->sliderFirst, scrollPtr->inset,
- scrollPtr->sliderLast - scrollPtr->sliderFirst, width,
- elementBorderWidth, relief);
+ Tk_Fill3DRectangle(
+ tkwin,
+ pixmap,
+ border,
+ scrollPtr->inset,
+ scrollPtr->sliderFirst,
+ width,
+ scrollPtr->sliderLast - scrollPtr->sliderFirst,
+ elementBorderWidth,
+ relief
+ );
+ } else {
+ Tk_Fill3DRectangle(
+ tkwin,
+ pixmap,
+ border,
+ scrollPtr->sliderFirst,
+ scrollPtr->inset,
+ scrollPtr->sliderLast - scrollPtr->sliderFirst,
+ width,
+ elementBorderWidth,
+ relief
+ );
}
/*
@@ -315,8 +369,13 @@ TkpComputeScrollbarGeometry(scrollPtr)
if (scrollPtr->sliderLast > fieldLength) {
scrollPtr->sliderLast = fieldLength;
}
+ if( scrollPtr->style == 0 ) {
scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset;
scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset;
+ } else {
+ scrollPtr->sliderFirst += scrollPtr->inset;
+ scrollPtr->sliderLast += scrollPtr->inset;
+ }
/*
* Register the desired geometry for the window (leave enough space
@@ -396,6 +455,8 @@ TkpConfigureScrollbar(scrollPtr)
GC new;
UnixScrollbar *unixScrollPtr = (UnixScrollbar *) scrollPtr;
+ scrollPtr->style = 1; /* FIXME: force NeXT style scrollbars */
+
Tk_SetBackgroundFromBorder(scrollPtr->tkwin, scrollPtr->bgBorder);
gcValues.foreground = scrollPtr->troughColorPtr->pixel;
@@ -438,6 +499,7 @@ TkpScrollbarPosition(scrollPtr, x, y)
* window. */
{
int length, width, tmp;
+ int point;
if (scrollPtr->vertical) {
length = Tk_Height(scrollPtr->tkwin);
@@ -460,17 +522,23 @@ TkpScrollbarPosition(scrollPtr, x, y)
* TkpDisplayScrollbar. Be sure to keep the two consistent.
*/
- if (y < (scrollPtr->inset + scrollPtr->arrowLength)) {
- return TOP_ARROW;
- }
- if (y < scrollPtr->sliderFirst) {
- return TOP_GAP;
- }
- if (y < scrollPtr->sliderLast) {
- return SLIDER;
+ point = length - scrollPtr->inset;
+ /* */
+ if( y >= (point - scrollPtr->arrowLength) ) {
+ return( BOTTOM_ARROW );
+ }
+ point -= scrollPtr->arrowLength;
+ /* */
+ if( y >= (point - scrollPtr->arrowLength) ) {
+ return( TOP_ARROW );
+ }
+ point -= scrollPtr->arrowLength;
+ /* */
+ if( y >= (scrollPtr->sliderLast) ) {
+ return( BOTTOM_GAP );
}
- if (y >= (length - (scrollPtr->arrowLength + scrollPtr->inset))) {
- return BOTTOM_ARROW;
+ if( y >= (scrollPtr->sliderFirst) ) {
+ return( SLIDER );
}
- return BOTTOM_GAP;
+ return( TOP_GAP );
}
This would be a good thing to post to the SF patch db so it doesn't
get lost.
--
Jeff Hobbs The Tcl Guy
Senior Developer http://www.ActiveState.com/
Tcl Support and Productivity Solutions