The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
# twind.pl

use Plot;
use subs qw/twind_create_plot twind_delete_plot twind_restore_bg/;
use vars qw/$TOP/;

sub twind {

    # Create a top-level window with a text widget that demonstrates the
    # use of embedded windows in Text widgets.

    my($demo) = @_;
    $TOP = $MW->WidgetDemo(
        -name     => $demo,
        -text     => '',
        -title    => 'Text Demonstration - Embedded Windows',
        -iconname => 'twind',
    );

    # By default, when you create a Scrolled instance of a Perl/Tk widget
    # the scrollbars are always displayed; that is, they are required.  But
    # you can have optional scrollbars as well, specified via the -scrollbars
    # specifier.  So, assume scrollbars can be postioned 'nsew' (north, south
    # east or west), or 'se' for southeast, etcetera.  You specify 'required'
    # or 'optional' using an 'r' or 'o' character, respectively, preceeding
    # the scrollbar position.  So the following Scrolled widget has an
    # optional scrollbar at the bottom of the text widget and a required
    # scrollbar positioned to the right.
    #
    # Optional scrollbars are only displayed if they are required, so, the
    # the southern scrollbar is displayed IFF -wrap => none.

    my $t = $TOP->Scrolled(qw/Text -setgrid true -width 70 -height 35
        -wrap word -highlightthickness 0 -borderwidth 0 -scrollbars osre
	-font/ => $FONT)->pack;

    $t->tag(qw/configure center -justify center	-spacing1 5m -spacing3 5m/);
    $t->tag(qw/configure buttons -lmargin1 1c -lmargin2 1c -rmargin 1c
	    -spacing1 3m -spacing2 0 -spacing3 0/);

    my $t_on = $t->Button(
        -text => 'Turn On',
        -command => [$t => qw/configure -wrap none/],
        -cursor => 'top_left_arrow',
    );
    my $t_off = $t->Button(
        -text => 'Turn Off',
        -command => [$t => qw/configure -wrap word/],
	-cursor => 'top_left_arrow',
    );

    my $t_click = $t->Button(
        -text    => 'Click Here',
	-command => [\&twind_create_plot, $t],
	-cursor  => 'top_left_arrow',
    );
    my $t_delete = $t->Button(
        -text    => 'Delete',
	-command => [\&twind_delete_plot, $t],
	-cursor  => 'top_left_arrow',
    );

    $t->insert('end', "A text widget can contain other widgets embedded ");
    $t->insert('end', "in it.  These are called ");
    $t->insert('end', "\"embedded windows\"");
    $t->insert('end', ", and they can consist of arbitrary widgets.  ");
    $t->insert('end', "For example, here are two embedded button ");
    $t->insert('end', "widgets.  You can click on the first button to ");
    $t->window('create', 'end', -window => $t_on);
    $t->insert('end', " horizontal scrolling, which also turns off ");
    $t->insert('end', "word wrapping.  Or, you can click on the second ");
    $t->insert('end', "button to\n");
    $t->window('create', 'end', -window => $t_off);
    $t->insert('end', " horizontal scrolling and turn back on word ");
    $t->insert('end', "wrapping.\n\n");

    $t->insert('end', "Or, here is another example.  If you ");
    $t->window('create', 'end', -window => $t_click);
    $t->insert('end', " a canvas displaying an x-y plot will appear ");
    $t->insert('end', "right here.");
    $t->mark('set', 'plot', 'insert');
    $t->mark('gravity', 'plot', 'left');
    $t->insert('end', "  You can drag the data points around with the ");
    $t->insert('end', "mouse, or you can click here to ");
    $t->window('create', 'end', -window => $t_delete);
    $t->insert('end', " the plot again.\n\n");

    $t->insert('end', "You may also find it useful to put embedded windows");
    $t->insert('end', " in a text without any actual text.  In this case ");
    $t->insert('end', "the text widget acts like a geometry manager.  For ");
    $t->insert('end', "example, here is a collection of buttons laid out ");
    $t->insert('end', "neatly into rows by the text widget.  These buttons");
    $t->insert('end', " can be used to change the background color of the ");
    $t->insert('end', "text widget (\"Default\" restores the color to ");
    $t->insert('end', "its default).  If you click on the button labeled ");
    $t->insert('end', "\"Short\", it changes to a longer string so that ");
    $t->insert('end', "you can see how the text widget automatically ");
    $t->insert('end', "changes the layout.  Click on the button again ");
    $t->insert('end', "to restore the short string.\n");

    my $t_default = $t->Button(
        -text => 'Default',
	-command => [\&twind_restore_bg, $t],
	-cursor  => 'top_left_arrow',
    );
    $t->window('create', 'end', -window => $t_default, -padx => 3);
    my $embToggle = 'Short';
    my $t_toggle = $t->Checkbutton(
        -textvariable => \$embToggle,
        -indicatoron  => 0,
        -variable     => \$embToggle,
        -onvalue      => 'A much longer string',
        -offvalue     => 'Short',
        -cursor       => 'top_left_arrow',
    );
    $t->window('create', 'end', -window => $t_toggle,
			     -padx => 3, -pady => 2);
    my($i, $color) = (1, '');
    foreach $color (qw(AntiqueWhite3 Bisque1 Bisque2 Bisque3 Bisque4
		       SlateBlue3 RoyalBlue1 SteelBlue2 DeepSkyBlue3
		       LightBlue1 DarkSlateGray1 Aquamarine2 DarkSeaGreen2
		       SeaGreen1 Yellow1 IndianRed1 IndianRed2 Tan1 Tan4)) {
	my $col = $t->Button(
            -text   => "$color",
	    -cursor => 'top_left_arrow',
        );
        $col->configure(-command => sub {
	    $t->configure(-background => $color);
	});
        $t->window('create', 'end', -window => $col,
	             -padx => 3, -pady => 2);
        $i++;
    }
    $t->tag('add', 'buttons', $t_default, 'end');

} # end twind

sub twind_create_plot {

    # We are required to create a new Plot object everytime since embedded
    # widgets are destroyed when their tag is deleted. (Too bad.)

    my($text) = @_;

    if (not Exists($twind::plot)) {
        $twind::plot = $text->Plot(
	    -title_color        => 'Brown',
            -inactive_highlight => 'Skyblue2',
            -active_highlight   => 'red',
        );

        while ($text->get('plot') =~ / |\t|\n/) {
            $text->delete('plot');
	}
	$text->insert('plot', "\n");
	$text->window('create', 'plot', -window => $twind::plot);
	$text->tag('add', 'center', 'plot');
	$text->insert('plot', "\n");
    } # ifend

} # end twind_create_plot

sub twind_delete_plot {

    my($text) = @_;

    if (Exists($twind::plot)) {
	$text->delete($twind::plot);
	while ($text->get('plot') =~ / |\t|\n/) {
	    $text->delete('plot');
	}
	$text->insert('plot', '  ');
    }

} # end twind_delete_plot

sub twind_restore_bg {

    my($text) = @_;

    $text->configure(-background =>
		     ($text->Subwidget('text')->configure(-background))[3]);

} # end twind_restore_bg

1;