A Perl/Tk NoteBook widget with orientable, dynamically stacking tabs


  

SYNOPSIS

    use Tk::DynaTabFrame;
    $TabbedFrame = $widget->DynaTabFrame
       (
        -font => $font,
        -raisecmd => \&raise_callback,
        -raisecolor => 'green',
        -tabclose => sub { 
                my ($dtf, $caption) = @_; 
                $dtf->delete($caption);
                },
        -tabcolor => 'yellow',
        -tabcurve => 2,
        -tablock => undef,
        -tabpadx => 5,
        -tabpady => 5,
        -tabrotate => 1,
        -tabside => 'nw',
        -textalign => 1,
        [normal frame options...],
       );

Download

Tk-DynaTabFrame-0.23.tar.gz

Screenshots


DESCRIPTION

[ NOTE: This module was based on Tk::TabFrame... but you probably can't tell it anymore ]

A notebook widget with orientable, dynamically rearranging tabs. When the containing window is resized, the tabs will either stack or unstack as needed to fit the enclosing widget's width(height). Likewise, when tabs are added or removed, the tabs will stack/unstack as needed.

Tabs may be placed either on the top (default), bottom, left, or right side of the widget, and may be aligned to either the left (default) or right edge for top or bottom tabs, or to the top or bottom edges for left or right tabs.

Tabs are added at the innermost row adjacent to the tabbed frame at the alignment edge, and automatically become the "raised" tab when added.

Separate -tabcolor and -raisecolor options may be specified for each tab. -tabcolor is used for the tab if it is not the raised tab, or if no -raisecolor is specified. -raisecolor is used when the tab is raised.

A tab can be raised by either clicking on the tab; by using left and right keyboard arrows to traverse the tabbing order; or programmatically via the raise() method.

If -tabrotate is enabled, when a tab in a row other than the innermost frame-adjacent row is raised, all rows are rotated inward, with the current frame-adjacent rows wrapping to the outside, until the raised row becomes the innermost frame adjacent row. Disabling -tabrotate will leave the raised tab in its current location (assuming the containing window has not been resized; see the -tablock option to lock down the tabs on resize events).

A small "close" button can be applied to the tabs via the -tabclose option. By default, clicking the close button will delete the tab and associated frame from the DynaTabFrame. If a coderef is supplied as the -tabclose value, then the coderef will be invoked instead.

Either text or images can be displayed in the tab, using either the -image or -label page options. A future release will permit both in a single tab. If neither is specified, then the page name value will be used.

A "flash" effect may be applied to a tab (i.e., switching between the defined background color and a flash color at a specified interval) using the flash() method. Flashing continues until either the deflash() method is called, the tab is raised manually or programmatically, or the specified flash duration expires.

A "tabtip" (aka balloon or tooltip) may be attached to each tab that is displayed when the mouse hovers over the tab. The number of millseconds between the mouse entering a tab, and the display of the tabtip is determined by the -tiptime option (default 450). The background color of the tabtips can be set by the -tipcolor option (default white). The text of each tabtip can be set, updated, or removed, either in the add() method, or via pageconfigure(), using the -tabtip option. Note that a Tk::Balloon widget is not created for the DynaTabFrame widget until a -tiptime, -tipcolor, or -tabtip is configured.

The widget takes all the options that a Frame does. In addition, it supports the following options:

-font

Font for tab text.

-raisecmd

Code ref invoked on a raise event; passed the caption of the raised page. NOTE:This behavior is different than Tk::Notebook, which passes the widget to the callback.

-raisecolor

Sets the default raisecolor; overridden by add(-raisecolor) option. Default is current widget background color.

-tabclose

Add small close button to each tab; if set to a coderef, the coderef is invoked when the close button is pressed, and is passed both the Tk::DynaTabFrame object, and the caption of the associated tab. If set to a 'true' scalar value, invokes the delete method on the associated tab. Default is no close button. When enabled with -tablock enabled, -tablock is silently ignored.

-tabcolor, -backpagecolor

Sets the default tabcolor; overridden by the add(-tabcolor) option. Default is current widget background color.

-tabcurve

Curve to use for top corners of tabs; set to the number of pixels of spacing between adjoining tab borders. Default 2; rarely needs adjustement.

-tablock

Locks the resize of the tabs; when set to a true value, the tabs will not be rearranged when the enclosing window is resized; default off (ie, tabs are rearranged on resize). Silently ignored when -tabclose is enabled. Note that this options does not effect the tab raise event behavior (tab rows rotate inward). See the -tabrotate option to disable that behavior.

-tabpadx

Padding on left and right of the tab contents

-tabpady

Padding on top and bottom of the tab contents

-tabrotate

When enabled (the default), when a tab is raised in a row other than the innermost, frame-adjacent row, tab rows are rotated inward until the raised tab is frame adjacent. Disabling this option will leave the raised tab's row at its current location until a resize event occurs. (See -tablock to lock down tab locations on resize events).

-tabside

Side of notebook to align tabs; acceptable values:

        'nw' (default) - tabs on top, aligned to the left edge
        'ne' - tabs on top, aligned to the right edge
        'sw' - tabs on bottom, aligned to the left edge
        'se' - tabs on bottom, aligned to the right edge
        'en' - tabs on right, aligned to the top edge
        'es' - tabs on right, aligned to the bottom edge
        'wn' - tabs on left, aligned to the top edge
        'ws' - tabs on left, aligned to the bottom edge
        'n'  - same as 'nw'
        's'  - same as 'sw'
        'e'  - same as 'en'
        'w'  - same as 'wn'
Note: can only be set or changed prior to adding any pages; attempts to change the -tabside after pages have been added will be silently ignored.

-tabscroll (not yet implemented)

When set to a true value, causes tabs to be restricted to a single row, with small arrow buttons placed at either end of the row to permit scrolling the tabs into/out of the window. When a tab is programmatically raised, the tabs will be scrolled until the raised tab is visible.

-textalign

Aligns text to the tab orientation. When enabled (i.e., set to a 'true' scalar, the default), text in tabs is aligned to the tab orientation (i.e., top and bottom tabs have horizontal text, side tabs have vertical text). When disabled (i.e., set to undef or 0), text will be vertical for top and bottom tabs, and horizontal for side tabs.

-tipcolor

Sets the background color of any tabtips (default white). Causes creation of a Tk::Balloon widget if none yet exists.

-tiptime

Sets the integer number of milliseconds to delay between the time the mouse enters a tab and the display of any defined tabtip. Default 450. Causes creation of a Tk::Balloon widget if none yet exists.

Additional cget() -options

-current, -raised

Returns the currently raised frame.

-raised_name

Returns the page name of the currently raised frame

-tabs

Returns a hashref of the tab Button widgets, keyed by the associated caption.

METHODS

The following methods may be used with a DynaTabFrame object in addition to standard methods.

add([ pageName, ] options)

Adds a page with name pageName (if provided) to the notebook. Returns an object of type Frame. If no pageName is supplied, then the -caption option value will be used. If neither is provided, then the name is the string representation of the created page's frame. Recognized options are:

-caption

Specifies the identifying name for the page. Also used for the tab text if no -label or -image is specified. If this option is specified, and the optional pageName argument is specified, pageName overrides this option.

-hidden

When set to a true value, causes the resulting tab to be hidden from view; can later be set to a false value to force the tab to be visible again.

-image

Specifies an image to display on the tab of this page. The image is displayed only if the -label option is not specified.

-label

Specifies the text string to display on the tab of this page.

-raisecmd

Specifies a callback to be called whenever this page is raised by the user. Overrides the widget-level -raisecmd option only for this tab. NOTE: This option's behavior is different from the Tk::Notebook, in that the callback is passed the name of the page, rather than the widget.

-raisecolor

Specifies the raised background color for the tab. Overrides the widget-level -raisecolor option for only this tab.

-tabcolor

Specifies the unraised background color for the tab. Overrides the widget-level -tabcolor/-backpagecolor option for only this tab.

-tabtip

Specifies the text of a tabtip to attach to the created tab. Causes creation of a Tk::Balloon widget if none yet exists.

deflash(pageName)

Turns off flashing for the specified pageName.

delete(pageName)

Deletes the page identified by pageName.

flash(pageName, options)

Flashes the tab for the specified pageName. Flashing continues until either the -duration has expired, the tab is raised (either by clicking the tab, or programmatically), or deflash is called on the page. options include

-color

Color to use for flashing. Flashing alternates between the current -tabcolor (or -raisecolor if the tab is raised), and this color. Default is 'blue'.

-interval

Number of milliseconds between flashes. Default is 300.

-duration

Duration of the flash in milliseconds. Default is 5000 (i.e., 5 secs).

pagecget(pageName, -option)

Returns the current value of the configuration option given by -option in the page given by pageName. -option may be any of the values accepted in the add method, plus the -state option.

pageconfigure(pageName, -option)

Like configure for the page indicated by pageName. -options may be any of the options accepted by the add method, plus the -state option.

Note that configuring the -tabtip option to undef will remove the tabtip from the page.

pages

Returns a list consisting of the names of all currently defined pages, i.e., those created with the add method.

raise(pageName)

Raise the page identified by pageName. Returns the Frame widget of the page.

raised(), current()

Returns the currently raised Frame widget. NOTE: This method behavior differs from the Tk::Notebook method of the same, which returns the page name. Use the raised_name() method to mimic Tk::Notebook behavior.

raised_name()

Returns the page name of the currently raised frame

CAVEATS

Optional horizontal scrolled frames (ie, 'os') seem to cause some race conditions (Config events keep resizing the frame up, then down). Use mandatory scrollbars if you need horizontal scrollbars.

Support for rotated text in left or right side tabs is lacking, due to the lack of a consistent text rotation method in Perl/Tk. While the issue can be alleviated using the -textalign option, another possible solution may be either Tk::Win32RotLabel on Win32 platforms, or Tk::CanvasRottext for *nix platforms. Unfortunately, vertical text is less than aesthetically pleasing, and can consume a rather large vertical area; using images with attached balloons may be a preferable alternative.

As of v. 0.20, better compatibility with Tk::Notebook has been provided. However, DTF is not yet fully backward compatible, as some methods and options of the same name could not be changed from prior versions of DTF in order to preserve backward compatibility.

As of V 0.20, the maximum number of tab rows is 21. This arbitrary limit is imposed due to odd behavior when redrawing the tabs on a resize event. "Pseudo" tabs are used to provide the illusion of tabs embedded into a frame-spanning row. If these pseudotabs are destroyed and recreated during a resize event while the mouse button is still held down on the window resizer, the window will snap back to its original dimensions when the new pseudotabs are place()'d. The only solution seems to be to create a fixed number of pseudotabs at startup, and place() them as needed during the redraw. Eventually, a widget attribute may be added to specify the max number of rows to permit.

-tabclose and -tablock are mutually exclusive; if both are enabled, -tablock will be silently ignored.

Using Tk::Compound objects as tab images appears to cause sizing and layout issues due to the object not reporting its true full layout size; hence, they should be avoided.

TO DO

Canvas based tabs

Currently tabs are drawn as frames with a button (plus optional close button), and the text or image is added to the button. This limits the layout of tabs to square boxes. By converting the ButtonFrame to a Canvas, and just building, binding, and moving objects on the canvas when a redraw occurs, we can have a much more flexible tab layout (image+text, nice curved tabs, etc.).

Configurable -tabclose button

Currently, only a "close" button is implemented with a fixed image. In future, the button image may be configurable, e.g., set to a "minimize" image and set a minimize callback for an MDI-type notebook.

Configurable -tabside

configure(-tabside) should be permitted after pages are added.

Rotated tab text using GD

Newer versions of GD provides better font support, with 90 degree rotation. By using GD to render and rotate the tab text as an image, sideways text can be used in tabs as images.

Single row, scrolled tabs

Support for scrolling tabs, rather than stacking, should be added with small arrow buttons added at either end of the tab row when some tabs exist beyond the beginning/end of the row.

AUTHORS

Dean Arnold <darnold@presicient.com>

Portions of the POD derived from Tk::Notebook.

Initial code derived from Tk::TabFrame, included in Tk-DKW bundle by Damion K. Wilson.

Copyright(c) 2003-2005, Dean Arnold, Presicient Corp., USA. All rights reserved.

Portions Copyright(c) 1998-1999 Damion K. Wilson, all rights reserved.

This code and documentation may be distributed under the same conditions as Perl itself.

HISTORY

May 25, 2005 : Ver. 0.23

- fixed pageconfigure for tabs wo/ close buttons
(thanks to Daniel Wikman for the patch)

May 22, 2005 : Ver. 0.22

- added -hidden page option

- added -tiptime, -tipcolor global attributes

- added -tabtip page option

January 10, 2005 : Ver. 0.20

- added -tabclose

- added -tabside

- added -image attribute to add() to support images in tabs

- added -label attribute to add() to support alternate text in tabs

- fixed -raisecolor behavior to revert color of prior raised tab

- fixed "roaming" tab connector frame

- code mods for performance

- added -tabcolor/-backpagecolor, -raisecolor widget level options

- added -raisecmd attribute to add() to support event callback

- added some Tk::Notebook drop-in compatibility (pagecget(), pageconfigure(), pages(), raised())

- POD enhancements

- added -textalign

- added -tabrotate

- added flash(), deflash()

March 14, 2004 : Ver. 0.07

- added -raisecolor to set the color of a tab when raised

- increased ConfigDebounce width threshold for ptk804.025beta

January 16, 2004 : Ver. 0.06

- fixed programmatic raise

- added (simple) install test

- added programmatic raise button to demo app

- added flash()

January 13, 2004 : Ver. 0.05

- added "pseudo-tabs" to backfill the space between the right side of last tab in a row, and the right side of the enclosing frame

January 6, 2004 : Ver. 0.04

- fixed TabRemove for remove from arbitrary position

- updated demo app to exersize arbitrary position removal

- fixed apparent timing issue with TabRemove and resizing that caused occasional phantom client entries

January 5, 2004 : Ver. 0.03

- added raised_name() method/-raised_name property to return caption of currently raised page

- fixed tab ordering on resize when raised tab gets moved to other than bottom row

December 29, 2003 : Ver. 0.02

- improve raise behavior

- improve tab font behavior (use platform/application default when none specified)

- added tablock option

December 25, 2003 : Ver. 0.01

- Converted from Tk::TabFrame