home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  

Book HomeMastering Perl/TkSearch this book

6.3. The Scrollbar Widget

Instead of automatically creating one or more Scrollbars with the Scrolled method, you can use the Scrollbar widget method and perform the configuration yourself. It is better to create and configure your own Scrollbars when you need to do something nonstandard, such as have one Scrollbar scroll two Listboxes. Figure 6-6 shows a Scrollbar widget.

Figure 6-6

Figure 6-6. Scrollbar widget

6.3.1. Creating a Scrollbar Widget

To create the Scrollbar, invoke the Scrollbar method from the parent widget. It returns a reference to the newly created Scrollbar that you can use for configuration:

$scrollbar = $mw->Scrollbar([ options ...])

There are at least two other things you need to do to get a Scrollbar working with another widget. First, create the to-be-scrolled widget and use the Scrollbar with its -xscrollcommand or -yscrollcommand option. Then configure the Scrollbar so that it knows to talk to that widget. Here's an example that creates a Listbox widget (don't worry if you don't quite follow all of this now; we just want to show a complete example before we go on to talk about all the options):

# Create the vertical Scrollbar
$scrollbar = $mw->Scrollbar( );
$lb = $mw->Listbox(-yscrollcommand => ['set' => $scrollbar]);
#Configure the Scrollbar to talk to the Listbox widget
$scrollbar->configure(-command => ['yview' => $lb]);

#Pack the Scrollbar first so that it doesn't disappear when we resize
$scrollbar->pack(-side => 'right', -fill => 'y');
$lb->pack(-side => 'left', -fill => 'both');

Creating the Scrollbar is pretty simple; we want all the default options for it. As we create the Listbox, we have to set up a callback so the Listbox can communicate with the Scrollbar when the contents of the Listbox move around. Our Scrollbar is vertical, so the -yscrollcommand option has the set command and our Scrollbar assigned to it (if it is horizontal, use -xscrollcommand). When the contents of the Listbox are scrolled by the user without using the Scrollbar, the Listbox will alert the Scrollbar by invoking $scrollbar->set(...).

The line $scrollbar->configure(-command => ['yview' => $lb]) does almost the opposite: it configures the Scrollbar to communicate with the Listbox. When the user clicks the Scrollbar, it will invoke $lb->yview(...) to tell the Listbox how to change the view of the contents. Use the y version of the view command, as it's a vertical Scrollbar.

There is more information on the details of yview in Section 6.3.8, "How the Scrollbar Communicates with Other Widgets", later in this chapter. The last two lines in this example pack the Scrollbar and the Listbox in the window so the Scrollbar is the same height and lies to the right of the Listbox.

Always pack your Scrollbars first within the window or Frame. This allows the Scrollbars to remain visible when the user resizes the window smaller. It will then resize the Listbox (or other widget) but leave the Scrollbars visible on the edges of the screen.

Now that we've seen a complete example of how to create a Scrollbar and how to set up the widget it will scroll, we can go over the options with an idea of how they are used.

6.3.2. Scrollbar Options

This list contains the options available with a Scrollbar and their quick definitions. The important options are discussed in more detail later in this chapter.

-activebackground => color
Sets the color the Scrollbar should be when the mouse pointer is over it.

-activerelief => 'flat' | 'groove' | 'raised' | 'ridge' | 'sunken'
Determines how active elements are drawn. The elements in question are arrow1, arrow2, and slider.

-background => color
Sets the background color of the Scrollbar (not the trough color).

-borderwidth => amount
Sets the width of the edges of the Scrollbar and the arrow1, arrow2, and slider elements.

-command => callback
Sets the callback that is invoked when the Scrollbar is clicked.

-cursor => cursorname
Sets the cursor that is displayed when the mouse pointer is over the Scrollbar.

-elementborderwidth => amount
Sets the width of the borders of the arrow1, arrow2, and slider elements.

-highlightbackground => color
Sets the color the highlight rectangle around the Scrollbar widget should be when it does not have the keyboard focus.

-highlightcolor => color
Sets the color the highlight rectangle around the Scrollbar should be when it does have the keyboard focus.

-highlightthickness => amount
Sets the thickness of the highlight rectangle. Default is 2.

-jump => 0 | 1
Indicates whether or not the Scrollbar will jump scroll.

-orient => "horizontal" | "vertical"
Sets the orientation of the Scrollbar.

-relief => 'flat'|'groove'|'raised'|'ridge'|'sunken'|'solid'
Sets the edges of the widget.

-repeatdelay => time
Sets the number of milliseconds required to hold down an arrow before it will auto-repeat. Default is 300 ms.

-repeatinterval => time
Sets the number of milliseconds in between auto-repeats. Default is 100 ms.

-takefocus => 0 | 1 | undef
Controls whether the Scrollbar can obtain the keyboard focus.

-troughcolor => color
Changes the color of the trough (both trough1 and trough2).

-width => amount
Sets the width of the Scrollbar.

6.3.8. How the Scrollbar Communicates with Other Widgets

As described earlier, you use the -command option with the Scrollbar so it knows which widget and method to use when the Scrollbar is clicked. The command should be xview for horizontal Scrollbars and yview for vertical Scrollbars. You can call these methods yourself, but most of the time you won't want to.

Both xview and yview take the same type of arguments. Where the user clicks in the Scrollbar determines the value used, but the value will always be sent as one of the following forms:

This form is used when the user clicks on the slider, moves it around, and drops it again. The argument is a fraction, a real number from 0 to 1 that represents the first part of the data to be shown within the widget. If the user moves the slider all the way to the top or left of the Scrollbar, the very first part of the data in the widget should be seen on the screen. This means the argument should be 0:


If the slider is moved to the center of the Scrollbar, the argument is 0.5:

$widget->xviewScroll(number, "units");
$widget->yviewScroll(number, "units");
This form is used when the user clicks on one of the arrow elements in the Scrollbar. The widget should move its data up/down or left/right unit by unit.

The first argument is the numberof units to scroll by. The value for number can be any number, but it's typically either 1 or -1. A value of 1 means the next unit of data on the bottom or right of the widget becomes visible (scrolling one unit of data off the left or top). A value of -1 means that a previous unit of data will become visible in the top or right of the widget (one unit will scroll off the bottom or right of the widget). For example, every time the user clicks on the down arrow in a vertical Scrollbar associated with a Listbox, a new line shows up at the bottom of the Listbox.

The second argument is the string "units". What a unit is depends on the widget. In a Listbox, a unit would be one line of text. In an Entry widget, it would be one character.

Here are some example calls:

	# User clicked down arrow
	$listbox->yviewScroll(1, "units");

	# User clicked up arrow
	$listbox->yviewScroll(-1, "units");

	# User clicked right arrow
	$entry->xviewScroll(1, "units");
$widget->xviewScroll(number, "page");
$widget->yviewScroll(number, "page");
This form is exactly like our previous one except the last argument is "page" instead of "units". When users click in the trough area of the Scrollbar (between the slider and arrows), they expect to see the data move by an entire page.

The type of page is defined by the widget being scrolled. For example, a Listbox would page up or down by the number of lines shown in the Listbox. It would page right or left by the width of the Listbox.

6.3.10. Defining What We Can See

The set method, which we tell the scrolled widget about when we create it, defines what is visible. In our first example, we created a Listbox and told it to use our Scrollbar and the set method:

$scrollbar = $mw->Scrollbar( );   # Vertical Scrollbar
$lb = $mw->Listbox(-yscrollcommand => ['set' => $scrollbar ]);

When the widget invokes the set command, it sends two fractions (first and last) as the arguments:

$scrollbar->set(first, last);

This will change the position in the data we are seeing. The arguments first and last are real numbers between 0 and 1. They represent the position of the first data item we can see and the position of the last data item we can see, respectively. If we can see all the data in our widget, they would be and 1. The first value gets larger as more data is scrolled off the top, and the last value gets smaller as more data is scrolled off the bottom. You will probably never find a case in which to call set yourself, so just try to get an idea of what it does behind the scenes.

Figure 6-12 shows a hypothetical document that we are viewing with a vertically scrolled widget. The dashed rectangle represents the view of what we can currently see within the widget. When the widget calls set, it determines how far into the document the first viewable item is and sends this as the first argument. In Figure 6-12, this would be 10%, or 0.10. The second argument to set is how far into the document the last viewable item is. In our example, this would be 90%, or 0.90.

Figure 6-12

Figure 6-12. View of data through widget by set method (assumes vertical Scrollbar)

Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.