Padre::Wx::Dialog::Wizard::Select - the wizard selection page


Padre documentation Contained in the Padre distribution.

Index


Code Index:

NAME

Top

Padre::Wx::Dialog::Wizard::Select - the wizard selection page

DESCRIPTION

Top

This prepares the required page UI that the wizard will include in its UI and has the page flow information for the next and previous pages.

AUTHOR

Top

Ahmad M. Zawawi <ahmad.zawawi at gmail.com>

COPYRIGHT & LICENSE

Top


Padre documentation Contained in the Padre distribution.

package Padre::Wx::Dialog::Wizard::Select;

use 5.008;
use strict;
use warnings;
use Padre::Wx                     ();
use Padre::Wx::TreeCtrl           ();
use Padre::Wx::Dialog::WizardPage ();

our $VERSION = '0.86';
our @ISA     = qw(Padre::Wx::Dialog::WizardPage);

# Initialize the page
sub init {
	my $self = shift;

	$self->name( Wx::gettext("Select a Wizard") );
	$self->title( Wx::gettext("Wizard Selector") );
}

# Add controls to page
sub add_controls {
	my $self = shift;

	# Filter label
	my $filter_label = Wx::StaticText->new( $self, -1, Wx::gettext('&Filter:') );

	# Filter text field
	$self->{filter} = Wx::TextCtrl->new( $self, -1, '' );

	# Filtered list
	$self->{tree} = Padre::Wx::TreeCtrl->new(
		$self,
		-1,
		Wx::wxDefaultPosition,
		Wx::wxDefaultSize,
		Wx::wxTR_HIDE_ROOT | Wx::wxTR_SINGLE | Wx::wxTR_FULL_ROW_HIGHLIGHT | Wx::wxTR_HAS_BUTTONS
			| Wx::wxTR_LINES_AT_ROOT
	);

	# Filter sizer
	my $filter_sizer = Wx::BoxSizer->new(Wx::wxHORIZONTAL);
	$filter_sizer->Add( $filter_label,   0, Wx::wxALIGN_CENTER_VERTICAL, 5 );
	$filter_sizer->Add( $self->{filter}, 1, Wx::wxALIGN_CENTER_VERTICAL, 5 );

	# Main vertical sizer
	my $sizer = Wx::BoxSizer->new(Wx::wxVERTICAL);
	$sizer->Add( $filter_sizer, 0, Wx::wxALL | Wx::wxEXPAND, 5 );
	$sizer->Add( $self->{tree}, 1, Wx::wxALL | Wx::wxEXPAND, 3 );

	$self->SetSizer($sizer);
	$self->Fit;
}

# Adds the events
sub add_events {
	my $self = shift;

	# Set focus when Keypad Down or page down keys are pressed
	Wx::Event::EVT_CHAR(
		$self->{filter},
		sub {
			$self->_on_char( $_[1] );
		}
	);

	# Update filter search results on each text change
	Wx::Event::EVT_TEXT(
		$self,
		$self->{filter},
		sub {
			shift->_update_tree;
		}
	);

	# Open a wizard when a wizard is activated (i.e. clicked)
	Wx::Event::EVT_TREE_ITEM_ACTIVATED(
		$self,
		$self->{tree},
		sub {
			shift->_on_tree_item_activated(@_);
		}
	);

	# Update status text when a wizard is selected
	Wx::Event::EVT_TREE_SEL_CHANGED(
		$self,
		$self->{tree},
		sub {
			shift->_on_tree_selection_changed(@_);
		}
	);

}

# Private method to handle on character pressed event
sub _on_char {
	my $self  = shift;
	my $event = shift;
	my $code  = $event->GetKeyCode;

	$self->{tree}->SetFocus
		if ( $code == Wx::WXK_DOWN )
		or ( $code == Wx::WXK_NUMPAD_PAGEDOWN )
		or ( $code == Wx::WXK_PAGEDOWN );

	$event->Skip(1);
}

# Private method to handle tree item activation (i.e. clicking)
sub _on_tree_item_activated {
	my ( $self, $event ) = @_;
}

# Private method to handle tree selection change
sub _on_tree_selection_changed {
	my ( $self, $event ) = @_;

	my $tree_item_id = $event->GetItem;
	my $wizard       = $self->{tree}->GetPlData($tree_item_id);
	if ($wizard) {
		my $class = $wizard->class;
		eval "require $class";
		if ($@) {
			$self->next_wizard(undef);
			$self->status( sprintf( Wx::gettext("Error while loading %s"), $class ) );
		} else {
			$self->next_wizard($wizard);
			$self->status( $wizard ? $wizard->comment : '' );
		}
	} else {
		$self->next_wizard(undef);
		$self->status('');
	}
	$self->refresh();
}

# Private method to update the tree by using the filter
sub _update_tree {
	my $self   = shift;
	my $filter = quotemeta $self->{filter}->GetValue;

	# Clear list
	my $tree = $self->{tree};
	$tree->DeleteAllItems;

	# Collect available wizard categories
	my $wizards_by_category = {};
	for my $wizard ( values %{ $self->ide->wizards } ) {
		my $category = $wizard->category;

		# Add the wizard the list of wizards in that category
		my $wizards = $wizards_by_category->{$category} || [];
		push @$wizards, $wizard;
		$wizards_by_category->{$category} = $wizards;
	}

	# Add items to the wizard selection tree
	my $filter_not_empty = $filter ne '';
	my $root = $tree->AddRoot('Root');
	my $perl_5_category_item;
	for my $category ( sort keys %$wizards_by_category ) {
		my $category_item;
		my $unmatched_category = $category !~ /$filter/i;
		for my $wizard ( @{ $wizards_by_category->{$category} } ) {
			my $label = $wizard->label;

			#Remove the first 2-digits sorting numbers from the name
			$label =~ s/^\d\d//;

			# Ignore adding the wizard if it has an unmatched category and
			# does not match the filter regex
			next if $unmatched_category and $label !~ /$filter/i;

			# Add a category if it doesnt exist and append the wizard to the end of it
			$category_item = $tree->AppendItem( $root, $category ) unless $category_item;
			my $item = $tree->AppendItem( $category_item, $label );
			$tree->SetPlData( $item, $wizard );
		}

		# Expand the defined category only if it the 'Perl 5' category
		# OR if it has children and the filter is not empty
		$tree->Expand($category_item)
			if defined($category_item)
				and ( $category eq 'Perl 5'
					or ( $filter_not_empty && $tree->ItemHasChildren($category_item) ) );
	}
}

# Shows the page
sub show {
	my $self = shift;

	# Set focus on the filter text field
	$self->{filter}->SetFocus;

	# Update the tree
	$self->_update_tree;
}

1;


__END__

# Copyright 2008-2011 The Padre development team as listed in Padre.pm.
# LICENSE
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl 5 itself.