vptk_w
view release on metacpan or search on metacpan
vptk_w/VPTK_Widget.pm view on Meta::CPAN
Details see in examplary class 'Label'
=cut
package vptk_w::VPTK_Widget;
use strict;
use Exporter 'import';
our @EXPORT = qw(HaveGeometry WidgetIconName AllWidgetsNames EditorProperties DefaultParams TkClassName);
use vptk_w::VPTK_Geometry;
my @widget_types;
BEGIN {
# here we are going to load all sub-classes that placed under this class directory
my ($path) = ($0 =~ m#(.*[/\\])#);
$path = '.' unless $path;
my $package = __PACKAGE__;
$package =~ s#::#/#g;
$package = "$path/$package";
opendir(DIR,$package) || die "$0 dir $package read - $!";
foreach (grep(/\.pm$/,readdir(DIR))) {
require "$package/$_";
s/\.pm$//;
s/^mtk//; # name correction for 'artificial' class names (see constructor comment)
push(@widget_types,$_);
}
closedir DIR;
}
# Public methods wrapping derived classes implementation
sub AllWidgetsNames { return @widget_types }
# Constructor (non-virtual)
# Automatically builds sub-class object with standard content
# Usage:
# my $object = vptk_w::VPTK_Widget->new( subclassname [, args ] );
sub new {
my $class = shift;
my $sub_class = shift;
die "ERROR: missing arg(s) ($class,$sub_class)"
unless $sub_class;
# Re-naming sub-class (dirty trick to overcome M$ Wind0Ze file naming limitation)
# Issue description: like in old DOS times contemporary M$ filesystem does not
# support co-existance of more than one file with same letters set but in
# different lettercase (radiobutton.pm vs Radiobatton.pm)
$sub_class = "mtk$sub_class"
unless (eval $class.'::'.$sub_class."->can('JustDraw')");
$class = $class.'::'.$sub_class;
die "ERROR: missing 1st arg"
unless $class;
my @args = @_;
die "ERROR: wrong parameters number (@args) in ".(caller(0))[3]."\n"
if scalar(@args) % 2;
push (@args,
-instance_data => {-widget_data=>{},-geometry_data=>{}}
);
return bless { @args } => $class;
}
# putter/getter method for '-instance_data' property
# When called without args retrieves object's parameters
sub InstanceData {
my $this = shift;
die "ERROR: wrong this/missing ($this) in ".(caller(0))[3]."\n"
unless ref $this;
if(@_) {
$this->{'-instance_data'} = {@_};
}
else {
return $this->{'-instance_data'};
}
}
sub Draw {
my ($this,$parent) = @_;
die "ERROR: missing or wrong arg(s) (@_)"
unless ref $this && ref $parent;
$this->{'-parent_object'} = $parent;
my @args = %{$this->InstanceData()->{'-widget_data'}};
my $result;
my $scrolled = 0;
if(grep($_ eq '-scrolled',@args)) {
$scrolled = 1;
my %args = @args;
delete $args{'-scrolled'};
@args = %args;
}
if($scrolled) {
$result = $parent->Scrolled($this->PrintTitle()=>@args);
}
else {
$result=$this->JustDraw($parent,@args);
}
if($this->HaveGeometry) {
my $geometry = vptk_w::VPTK_Geometry->new( %{$this->InstanceData()->{'-geometry_data'}} );
$geometry->ApplyGeometry($result);
}
$this->{'-visual_object'} = $result;
return $result;
}
sub DefaultParams { &enquire_from_subclass('DefaultParams' => @_) }
sub HaveGeometry { &enquire_from_subclass('HaveGeometry' => @_) }
sub TkClassName {
return undef
unless grep ($_[0] eq $_,@widget_types);
&enquire_from_subclass('TkClassName' => @_);
}
sub PrintTitle { &enquire_from_subclass('PrintTitle' => @_) }
sub EditorProperties { &enquire_from_subclass('EditorProperties'=> @_) }
sub WidgetIconName { &enquire_from_subclass('AssociatedIcon'=> @_) }
sub enquire_from_subclass {
shift if ref $_[0]; # no 'instance' methods allowed!
my $method = shift || die "missing method name";
my $sub_class = shift || die "missing sub-class argument";
( run in 1.127 second using v1.01-cache-2.11-cpan-800906f7e73 )