/usr/local/CPAN/PPresenter/PPresenter/Viewport/Control.pm
# Copyright (C) 2000-2002, Free Software Foundation FSF.
# PPresenter::Viewport::Control
#
# A special version of a viewport: a viewport with controls.
#
package PPresenter::Viewport::Control;
use strict;
use PPresenter::Viewport;
use base 'PPresenter::Viewport';
use PPresenter::Viewport::SlideButtonBar;
use PPresenter::Viewport::ProgressBar;
use PPresenter::Viewport::Neighbours;
use PPresenter::Viewport::BackgroundMenu;
use PPresenter::Viewport::SlideControl;
use PPresenter::Viewport::TagControl;
use PPresenter::Viewport::Phases;
use constant ObjDefaults =>
{ -showSlideNotes => 0
, -includeControls => 0
, -resizable => undef
, -progressColors => [ 'white', 0.5, 'yellow', 0.7, 'green', 0.9,
'orange', 1.1, 'red' ]
# Settings of progress-bar.
, -showProgressBar => 1
, -progressLineWidth => 2
, -progressBackground => 'black'
, -slideButtonBackground => 'green'
# Settings of progress-control.
, -showSlideButtons => 1
# Settings of neighbour slide-names.
, -showNeighbours => 1
, -neighbourNameColor => 'yellow'
, -neighbourNameSize => '10p' # pixels.
# Settings of phase progression display.
, -showPhases => 1
, -phaseSymbol => 'image pinkball.gif'
, -phaseLocation => 'ne'
, -phaseDirection => 'vertical'
};
sub InitObject(@)
{ my $viewport = shift;
$viewport->{-resizable} = $viewport->{-showSlideNotes}
unless defined $viewport->{-resizable};
$viewport->SUPER::InitObject(@_);
die "Progress color-list for progress shall have odd length.\n"
unless (@{$viewport->{-progressColors}} & 1) == 1;
$viewport;
}
sub createControl()
{ my $viewport = shift;
my ($show,$screen) = @$viewport{'show', 'screen'};
my $has_popup = not $viewport->{-includeControls};
my $where = $has_popup
? MainWindow->new(-screen => $viewport->{-display})
: ($viewport->{controlframe} = $screen->Frame);
@$viewport{ qw/progressbar slidebar neighbours menu
slidecontrol tagcontrol phases/ } =
( PPresenter::Viewport::ProgressBar->new($show, $viewport)
, PPresenter::Viewport::SlideButtonBar->new($show, $viewport)
, PPresenter::Viewport::Neighbours->new($show, $viewport)
, PPresenter::Viewport::BackgroundMenu->new($show, $viewport,
$viewport->{screen}, $has_popup)
, PPresenter::Viewport::SlideControl->new($show, $viewport, $where)
, PPresenter::Viewport::TagControl->new($show, $viewport, $where)
, PPresenter::Viewport::Phases->new($show, $viewport)
);
if($has_popup)
{ $where->withdraw;
$viewport->make_popup($show, $where,
$viewport->{slidecontrol}, $viewport->{tagcontrol});
$viewport->{controlpopup} = $where;
}
else
{ # These two are grouped into a separate frame which is repacked
# when needed. The controls do not need to be repacked ever.
$viewport->getSlideControl->pack(-fill => 'both', -anchor => 'n');
$viewport->getTagControl->pack(-fill => 'both', -anchor => 'n');
}
$viewport->packViewport;
}
sub getProgressBar() {shift->{progressbar}->getBar}
sub getSlideBar() {shift->{slidebar}->getBar}
sub getNeighbours() {shift->{neighbours}->getBar}
sub getSlideControl() {shift->{slidecontrol}->getControl}
sub getTagControl() {shift->{tagcontrol}->getControl}
sub setPhase($$)
{ my $viewport = shift;
$viewport->{phases}->setPhase($viewport->{-showPhases} ? (@_) : (0,0));
}
sub remove_controls()
{ my $viewport = shift;
$viewport->{-showPhases} = 0;
$viewport->{-showProgressBar} = 0;
$viewport->{-showSlideButtons} = 0;
$viewport->{-showNeighbours} = 0;
$viewport->packViewport;
}
sub add_controls()
{ my $viewport = shift;
$viewport->{-showPhases} = 1;
$viewport->{-showProgressBar} = 1;
$viewport->{-showSlideButtons} = 1;
$viewport->{-showNeighbours} = 1;
$viewport->packViewport;
}
sub showControls($)
{ my ($viewport, $do_show) = @_;
$do_show ? $viewport->add_controls : $viewport->remove_controls;
$viewport;
}
sub busy($)
{ my ($viewport, $on) = @_;
$on ? $viewport->{screen}->Busy : $viewport->{screen}->Unbusy;
$viewport;
}
sub packViewport()
{ my $viewport = shift;
# Take all widgets from the viewport.
my $screen = $viewport->{screen};
my @components = $screen->packSlaves;
@components && map {$_->packForget} @components;
# Create a normal viewport.
# Put on the viewport what we need now.
$viewport->getProgressBar->pack(-side => 'bottom', -fill => 'x')
if $viewport->{-showProgressBar};
$viewport->getSlideBar->pack(-side => 'bottom', -fill => 'x')
if $viewport->{-showSlideButtons};
$viewport->getNeighbours->pack(-side => 'bottom', -fill => 'x')
if $viewport->{-showNeighbours};
$viewport->{controlframe}->pack(-side => 'right', -fill => 'y' )
if exists $viewport->{controlframe};
$viewport->{playfield}->pack(-side => 'left', -fill =>'both', -expand=>1);
$viewport->{show}->showSlide('THIS'); # Recompute: often resize needed.
$viewport;
}
sub hasControl() { 1 } # yes.
sub clockTic($$)
{ my ($viewport, $interval, $current_slide) = @_;
$viewport->{slidecontrol}->clockTic($interval, $current_slide);
$viewport->{progressbar}->clockTic($interval);
}
sub update($$)
{ my ($viewport, $show, $slide) = @_;
# Update neighbours.
my ($back,$forward) = ($show->previousSelected, $show->nextSelected);
my $left = defined $back ? "$back" : '';
my $right = defined $forward ? "$forward" : '';
$viewport->{neighbours}->update($left, "$slide", $right);
$viewport->{slidebar}->update($slide);
$viewport->{progressbar}
->expectedArrival($viewport->{slidebar}->endOfSlide);
$viewport;
}
sub slideSelectionChanged()
{ my $viewport = shift;
$viewport->{slidebar}->reconstruct;
$viewport->{slidecontrol}->selectionChanged;
$viewport->{tagcontrol}->selectionChanged;
$viewport;
}
sub make_popup($$$$)
{ my ($viewport, $show, $w, $slidecontrol, $tagcontrol) = @_;
$w->withdraw;
$w->iconname('Control');
my $f = $w->Frame;
$f->Button
( -text => "Dismiss"
, -underline => 0
, -command => sub {$w->withdraw}
)->pack(-side => 'left', -padx=>3,-pady=>3, -fill => 'both');
$w->bind("<Key-d>", sub {$w->withdraw});
$f->Checkbutton
( -text => 'Halt'
, -underline => 0
, -variable => \$show->{-halted}
, -command => sub {$show->setRunning}
, -relief => 'raised'
)->pack(-side => 'left', -padx=>3,-pady=>3, -fill => 'both');
$w->bind("<Key-g>", sub {$show->setRunning(1)} );
$w->bind("<Key-h>", sub {$show->setRunning(0)} );
$slidecontrol->getControl->grid($tagcontrol->getControl, -sticky => 'n');
$f->grid('-', -pady => 5, -padx => 5);
$w->bind("<Key-n>", sub {$show->showSlide('NEXT_SELECTED');} );
$w->bind("<Key-N>", sub {$show->showSlide('NEXT');} );
$w->bind("<Key-p>", sub {$show->showSlide('PREVIOUS');} );
$w->Advertise(slides => $slidecontrol);
$w->Advertise(tags => $tagcontrol);
}
sub showControl()
{ shift->{controlpopup}->Popup(-popover => 'cursor')
}
1;