home *** CD-ROM | disk | FTP | other *** search
- # $Id: NoteBook.pm,v 1.3 1997/02/08 19:11:39 rsi Exp $
- #
- # Implementation of NoteBook widget.
- # Derived from NoteBook.tcl in Tix 4.0
-
- # Contributed by Rajappa Iyer <rsi@earthling.net>
- # Hack by Nick for 'menu' traversal.
-
- package Tk::NoteBook;
-
- use Tk qw(Ev);
-
- use Carp;
- require Tk::Frame;
- require Tk::NBFrame;
- require Tk::VStack;
-
- Tk::Widget->Construct("NoteBook");
-
- @Tk::NoteBook::ISA = qw(Tk::VStack);
-
- sub TraverseToNoteBook;
-
- sub ClassInit {
- my ($class,$mw) = @_;
- if (0) {
- # class binding does not work right due to extra level of
- # widget hierachy
- $mw->bind($class,"<ButtonPress-1>", ['MouseDown',Ev('x'),Ev('y')]);
- $mw->bind($class,"<ButtonRelease-1>", ['MouseUp',Ev('x'),Ev('y')]);
-
- $mw->bind($class,"<B1-Motion>", ['MouseDown',Ev('x'),Ev('y')]);
- $mw->bind($class,"<Left>", ['FocusNext','prev']);
- $mw->bind($class,"<Right>", ['FocusNext','next']);
-
- $mw->bind($class,"<Return>", 'SetFocusByKey');
- $mw->bind($class,"<space>", 'SetFocusByKey');
- }
- return $class;
- }
-
- sub Populate {
- my ($cw, $args) = @_;
-
- $cw->SUPER::Populate($args);
- $cw->{"pad-x1"} = 0;
- $cw->{"pad-x2"} = 0;
- $cw->{"pad-y1"} = 20;
- $cw->{"pad-y2"} = 0;
-
- my $f = $cw->Component("NBFrame" => "nbframe");
-
- if (1) {
- # Should be class bindings
- $f->bind("<ButtonPress-1>", sub {
- $cw->MouseDown($f->XEvent->x, $f->XEvent->y);
- });
- $f->bind("<ButtonRelease-1>", sub {
- $cw->MouseUp($f->XEvent->x, $f->XEvent->y);
- });
- $f->bind("<B1-Motion>", sub {
- $cw->MouseDown($f->XEvent->x, $f->XEvent->y);
- });
- $f->bind("<Left>", sub {$cw->FocusNext("prev");});
- $f->bind("<Right>", sub {$cw->FocusNext("next");});
- $f->bind("<Return>", sub {$cw->SetFocusByKey;});
- $f->bind("<space>", sub {$cw->SetFocusByKey;});
- }
-
- $f->configure(-slave => 1, -takefocus => 1, -relief => "raised");
- $cw->{"top"} = $f;
- $cw->ConfigSpecs(-takefocus => ["SELF", "takeFocus", "TakeFocus", 0],
- "DEFAULT" => [$f]);
- }
-
- #---------------------------
- # Public methods
- #---------------------------
- sub add {
- my ($w, $child, %args) = @_;
- my $c = $w->SUPER::add($child, %args);
- delete $args{-createcmd};
- delete $args{-raisecmd};
- if (keys %args) {
- $w->{"top"}->add($child, %args);
- }
- return $c;
- }
-
- sub raise {
- my ($w, $child) = @_;
- $w->SUPER::raise($child);
- if ($w->{"top"}->pagecget($child, -state) eq "normal") {
- $w->{"top"}->activate($child);
- $w->{"top"}->focus($child);
- }
- }
-
- sub delete {
- my ($w, $child) = @_;
- $w->SUPER::delete($child);
- if (defined $w->{"top"}->{$child}) {
- $w->{"top"}->delete($child);
- }
- $w->Subwidget ( 'nbframe' )->delete ( $child );
- }
-
- #---------------------------------------
- # Private methods
- #---------------------------------------
- sub Resize {
- my ($w) = @_;
-
- my ($tW, $tH) = split(" ", $w->{"top"}->geometryinfo);
- $w->{"pad-x1"} = 2;
- $w->{"pad-x2"} = 2;
- $w->{"pad-y1"} = $tH + (defined $w->{"-ipadx"} ? $w->{"-ipadx"} : 0) + 1;
- $w->{"pad-y2"} = 2;
- $w->{"minW"} = $tW;
- $w->{"minH"} = $tH;
- $w->SUPER::Resize;
- }
-
- sub MouseDown {
- my ($w, $x, $y) = @_;
- my $name = $w->{"top"}->identify($x, $y);
- $w->{"top"}->focus($name);
- $w->{"down"} = $name;
- }
-
- sub MouseUp {
- my ($w, $x, $y) = @_;
- my $name = $w->{"top"}->identify($x, $y);
- if ((defined $name) &&
- ($name eq $w->{"down"}) &&
- ($w->{"top"}->pagecget($name, -state) eq "normal")) {
- $w->{"top"}->activate($name);
- $w->SUPER::raise($name);
- } else {
- $w->{"top"}->focus($name);
- }
- }
-
- sub FocusNext {
- my ($w, $dir) = @_;
- my $name;
-
- if (not defined $w->{"top"}->info("focus")) {
- $name = $w->{"top"}->info("active");
- $w->{"top"}->focus($name);
- } else {
- $name = $w->{"top"}->info("focus" . $dir);
- $w->{"top"}->focus($name);
- }
- }
-
- sub SetFocusByKey {
- my ($w) = @_;
-
- my $name = $w->{"top"}->info("focus");
- if (defined $name) {
- if ($w->{"top"}->pagecget($name, -state) eq "normal") {
- $w->raise($name);
- $w->{"top"}->activate($name);
- }
- }
- }
-
- sub NoteBookFind {
- my ($w, $char) = @_;
-
- foreach $page (@{$w->{"windows"}}) {
- $i = $w->{"top"}->pagecget($page, -underline);
- $c = substr($page, $i, 1);
- if ($char =~ /$c/) {
- if ($w->{"top"}->pagecget($page, -state) ne "disabled") {
- return $page;
- }
- }
- }
- return undef;
- }
-
- # This is called by TraveseToMenu when an <Alt-Keypress> occurs
- # See the code in Tk.pm
- sub FindMenu {
- my ($w, $char) = @_;
-
- foreach $page (@{$w->{"windows"}}) {
- $i = $w->{"top"}->pagecget($page, -underline);
- my $l = $w->{"top"}->pagecget($page, -label);
- next if (not defined $l);
- $c = substr($l, $i, 1);
- if ($char =~ /$c/i) {
- if ($w->{"top"}->pagecget($page, -state) ne "disabled") {
- $w->{"keypage"} = $page;
- return $w;
- }
- }
- }
- return undef;
- }
-
- #
- # This is called to post the supposed 'menu'
- # when we have returned ourselves as a 'menu' matching
- # and <Alt-KeyPress>, See the code in Tk.pm
- #
- sub PostFirst {
- my ($w) = @_;
- my $page = delete $w->{"keypage"};
- if (defined $page) {
- $w->raise($page);
- }
- }
-
- 1;
-
- __END__
-
- =head1 NAME
-
- Tk::NoteBook - display several windows in limited space with notebook metaphor.
-
- =head1 SYNOPSIS
-
- use Tk::NoteBook;
- ...
- $w = $frame->NoteBook();
- $page1 = $w->add("page1", options);
- $page2 = $w->add("page2", options);
- ...
-
- =head1 DESCRIPTION
-
- The NoteBook widget provides a notebook metaphor to display several
- windows in limited space. The notebook is divided into a stack of pages
- of which only one is displayed at any time. The other pages can be
- selected by means of choosing the visual "tabs" at the top of the
- widget. Additionally, the <Tab> key may be used to traverse the pages.
- If B<-underline> is used, Alt- bindings will also work.
-
- The widget takes all the options that a Frame does. In addition,
- it supports the following options:
-
- =over 4
-
- =item B<-dynamicgeometry>
-
- If set to false (default and recommended), the size of the NoteBook
- will match the size of the largest page. Otherwise the size will
- match the size of the current page causing the NoteBook to change
- size when different pages of different sizes are selected.
-
- =item B<-ipadx>
-
- The amount of internal horizontal padding around the pages.
-
- =item B<-ipady>
-
- The amount of internal vertical padding around the pages.
-
- =back
-
- =head1 METHODS
-
- The following methods may be used with a NoteBook object in addition
- to standard methods.
-
- =over 4
-
- =item B<add(>I<page>, I<options>B<)>
-
- Adds a page with name I<page> to the notebook. Returns an object
- of type B<Frame>. The recognized I<options> are:
-
- =over 4
-
- =item B<-anchor>
-
- Specifies how the information in a tab is to be displayed. Must be
- one of B<n>, B<ne>, B<e>, B<se>, B<s>, B<sw>, B<w>, B<nw> or
- B<center>.
-
- =item B<-bitmap>
-
- Specifies a bitmap to display on the tab of this page. The bitmap
- is displayed only if none of the B<-label> or B<-image> options
- are specified.
-
- =item B<-image>
-
- Specifies an image to display on the tab of this page. The image
- is displayed only if the B<-label> option is not specified.
-
- =item B<-label>
-
- Specifies the text string to display on the tab of this page.
-
- =item B<-justify>
-
- When there are multiple lines of text displayed in a tab, this
- option determines the justification of the lines.
-
- =item B<-createcmd>
-
- Specifies a Perl command to be called the first time the page is
- shown on the screen. This option can be used to delay the creation
- of the contents of a page until necessary. It can be useful in
- situations where there are a large number of pages in a NoteBook
- widget; with B<-createcmd> you do not have to make the user wait
- until all pages are constructed before displaying the first page.
-
- =item B<-raisecmd>
-
- Specifies a Perl command to be called whenever this page is raised
- by the user.
-
- =item B<-state>
-
- Specifies whether this page can be raised by the user. Must be
- either B<normal> or B<disabled>.
-
- =item B<-underline>
-
- Specifies the integer index of a character to underline in the
- tab. This option is used by the default bindings to implement
- keyboard traversal for menu buttons and menu entries. 0
- corresponds to the first character of text displayed on the
- widget, 1 to the next character and so on.
-
- =item B<-wraplength>
-
- This option specifies the maximum line length of the label string
- on this tab. If the line length of the label string exceeds this
- length, then it is wrapped onto the next line so that no line is
- longer than the specified length. The value may be specified in
- any standard forms for screen distances. If this value is less
- than or equal to 0, then no wrapping is done: lines will break
- only at newline characters in the text.
-
- =back
-
- =item B<delete(>I<page>B<)>
-
- Deletes the page identified by I<page>.
-
- =item B<pagecget(>I<page>, I<option>B<)>
-
- Returns the current value of the configuration otion given by
- I<option> in the page given by I<page>. I<Option> may have any of
- the values accepted in the B<add> method.
-
- =item B<pageconfigure(>I<page>, I<options>B<)>
-
- Like configure for the page indicated by I<page>. I<Options> may
- be any of the options accepted by the B<add> method.
-
- =item B<raise(>I<page>B<)>
-
- Raise the page identified by I<page>.
-
- =item B<raised()>
-
- Returns the name of the currently raised page.
-
- =back
-
- =head1 AUTHOR
-
- B<Rajappa Iyer> rsi@earthling.net
-
- This code and documentation was derived from NoteBook.tcl in
- Tix4.0 written by Ioi Lam. It may be distributed under the same
- conditions as Perl itself.
-
- =cut
-