Prima

 view release on metacpan or  search on metacpan

examples/dock.pl  view on Meta::CPAN

=pod

=head1 NAME

examples/dock.pl - Docking widgets

=head1 FEATURES

This is the demonstration of Prima::Dock and Prima::DockManager
modules. The window created is docking client, and it's able
to accept toolbars and panels, and toolbars in turn accept buttons.
buttons are very samplish; there are two panels, Edit and Banner,
that are docked in different ways.
Note the following unevident features:

=over 4

=item popup on the border of the window ( and the Customize command there)

=item dragging of buttons on the window and the extreior

=item dragging panels and toolbar to the exterior

=item storing of the geometry in the ~/.demo_dock file

=back

=cut

use strict;
use warnings;

use Prima;
use Prima::Application;
use Prima::Edit;
use Prima::Buttons;
use Prima::DockManager;
use Prima::Utils;

package dmfp;
use constant Edit       => 0x100000;
use constant Vertical   => 0x200000;
use constant Horizontal => 0x400000;

# This is the main window. it's responsible for
# command handling and bar visiblity;
# NB - bars are not owned by this window when undocked.

package Prima::Dock::BasicWindow;
use vars qw(@ISA);
@ISA = qw(Prima::Window);

sub profile_default
{
	my $def = $_[0]-> SUPER::profile_default;
	my %prf = (
		instance => undef,
	);
	@$def{keys %prf} = values %prf;
	return $def;
}

sub init
{
	my  $self = shift;
	my %profile = $self-> SUPER::init( @_);
	$self-> $_($profile{$_}) for qw(instance);
	$self-> {toolBarPopup} = $self-> insert( Popup =>
		autoPopup  => 0,
		items      => $self-> make_popupitems(),
	);
	$self-> {mainDock} = $self-> insert( FourPartDocker =>
		rect        => [ 0, 0, $self-> size],
		fingerprint => dmfp::Tools|dmfp::Toolbar|dmfp::Edit|dmfp::Horizontal|dmfp::Vertical,
		dockup      => $self-> instance,
		dockerCommonProfile => {
			hasPocket => 0,
			onPopup => sub { # all dockers would render this popup
				my ( $me, $btn, $x, $y) = @_;
				( $x, $y) = $self-> screen_to_client( $me-> client_to_screen($x, $y));
				$self-> {toolBarPopup}-> popup( $x, $y);
				$me-> clear_event;
			}
		},
		dockerProfileClient => { # allow docking only to Edit
			fingerprint => dmfp::Edit,
		},
		dockerProfileLeft   => { fingerprint => dmfp::Vertical|dmfp::Tools|dmfp::Toolbar },
		dockerProfileRight  => { fingerprint => dmfp::Vertical|dmfp::Tools|dmfp::Toolbar },
		dockerProfileTop    => { fingerprint => dmfp::Horizontal|dmfp::Tools|dmfp::Toolbar },
		dockerProfileBottom => { fingerprint => dmfp::Horizontal|dmfp::Tools|dmfp::Toolbar },
	);
	$self-> instance-> add_notification( 'ToolbarChange', \&on_toolbarchange, $self);
	$self-> instance-> add_notification( 'PanelChange',   \&on_toolbarchange, $self);
	$self-> instance-> add_notification( 'Command',   \&on_command, $self);
	return %profile;
}

sub make_popupitems
{
	my $items = $_[0]-> instance-> toolbar_menuitems( \&Menu_Check_Toolbars);
	# actually DockManager doesn't care if panel CLSID and toolbar name intermix.
	# this is the demonstration of resolving that clash
	$$_[0] .= ',toolbar' for @$items;
	push ( @$items, []);
	push ( @$items, @{$_[0]-> instance-> panel_menuitems( \&Menu_Check_Panels)});
	push ( @$items, []);
	push ( @$items, ['customize' => "~Customize..." => q(open_dockmanaging)]);
	return $items;
}


sub Menu_Check_Toolbars
{
	my ( $self, $var) = @_;
	my $toolname = $var;
	$toolname =~ s/\,toolbar$//;
	$self-> instance-> toolbar_visible(
		$self-> instance-> toolbar_by_name($toolname),
		$self-> {toolBarPopup}-> toggle( $var)
	);
}

sub Menu_Check_Panels
{
	my ( $self, $var) = @_;
	$self-> instance-> panel_visible(
		$var, $self-> {toolBarPopup}-> toggle( $var));
}

sub instance
{
	return $_[0]-> {instance} unless $#_;
	$_[0]-> {instance} = $_[1];
}


sub on_toolbarchange
{
	$_[0]-> {toolBarPopup}-> items( $_[0]-> make_popupitems());
}

sub on_command
{
	my ( $self, $instance, $command) = @_;
	$command =~ s/\://g;
	my $x = $self-> can( $command);
	return unless $x;
	$x-> ( $self);
}

# we'll take our actions we need to reflect the state.
sub open_dockmanaging
{
	my $self = $_[0];
	my $i = $self-> instance;
	return if $i-> interactiveDrag;
	my $wpanel = Prima::Window-> create(
		name => 'Customize tools',
		size => [ 400, 200],
		onClose => sub {
			$self-> {toolBarPopup}-> customize-> enabled(1);
			$i-> interactiveDrag(0);
		},
	);
	$i-> create_manager( $wpanel,  dockerProfile => {
		hint => 'Drag here unneeded buttons',
	});
	$i-> interactiveDrag(1);
	$self-> {toolBarPopup}-> customize-> enabled(0);
}

sub get_docks
{
	my $self = $_[0];
	my @docks = ( $self-> {mainDock});
	my $sid = $self-> {mainDock}-> open_session({
		self => $self-> {mainDock},
		sizes => [[0,0]],
		sizeable => [1,1],
	});
	if ( $sid) {
		while ( 1) {
			my $x = $self-> {mainDock}-> next_docker( $sid);
			last unless $x;
			next if $x-> isa(q(Prima::DockManager::LaunchPad));
			push ( @docks, $x);
		}
		$self-> {mainDock}-> close_session( $sid);
	}
	return @docks;
}

sub init_read
{
	my ( $self, $fd) = @_;
	my $last = undef;
	my @docks = $self-> get_docks;
	my $state;
	my %docks = map { my $x = $_-> name; $x =~ s/(\W)/\%sprintf("%02x",$1)/; $x => $_} @docks;

examples/dock.pl  view on Meta::CPAN

	},
	profile => {
		vScroll => 1,
		text    => '',
	},
});
$i-> register_panel( 'Banner' => {
	class => 'Banner',
	text  => 'Banner window',
	dockerProfile => {
		fingerprint => dmfp::Horizontal,
		size => [ 200, 30]
	},
});


my $resFile = Prima::Utils::path('demo_dock');

# after all that, creating window ( the window itself is of small importance...)

my $ww = Prima::Dock::BasicWindow -> create(
	instance => $i,
	onClose => sub {
		if ( open F, "> $resFile") {
			$_[0]-> init_write( *F);
			close F;
		} else {
			warn "Cannot open $resFile:$!\n";
		};
	},
	onDestroy => sub {
		$::application-> destroy;
	},
	size      => [ 400, 400],
	text       => 'Docking example',
	onActivate    => sub { $i-> activate; },
	onWindowState => sub { $i-> windowState( $_[1]); },
);


# opening predefined bars
if ( open F, $resFile) {
	$ww-> init_read(*F);
	close F;
} else {
	$i-> predefined_panels( "Edit" => $ww-> {mainDock}-> ClientDocker);
}

$i-> predefined_toolbars( {
	name => "File",
	list => ["File::Open", "File::Close"],
	dock => $ww-> {mainDock}-> TopDocker,
	origin => [ 0, 0],
}, {
	name => "Edit",
	list => [ "Edit::OK", "Edit::Cancel", ],
	dock => $ww-> {mainDock}-> TopDocker,
	origin => [ 0, 0],
});

#$ww-> open_dockmanaging; # uncomment this for Customize window popup immediately

run Prima;

1;



( run in 0.521 second using v1.01-cache-2.11-cpan-364913b4093 )