1. Herbert Breunung
  2. Kephra

Commits

Herbert Breunung  committed 5cdeb2a

this is the real one

  • Participants
  • Parent commits c61832e
  • Branches default

Comments (0)

Files changed (1)

File lib/Kephra/App/Sizer.pm

View file
  • Ignore whitespace
 use strict;
 use warnings;
+use Scalar::Util qw(blessed looks_like_number);
 use Kephra::API;
+use Kephra::App::Util;
+
 
 
 package Kephra::App::Sizer;
 
 
 sub new {
-	my ($class, $orient, $children) = @_;
+	my ($class) = shift;
+	my ($orient) = shift;
 
 	if  (substr($orient, 0, 1) eq 'h') { $orient = &Wx::wxHORIZONTAL }
 	elsif (substr($orient, 0, 1) eq 'v') { $orient = &Wx::wxVERTICAL }
-	else  {
-		return Kephra::Log::error("need orientation as first parameter, not $orient", 1);
-	}
+	else {return Kephra::Log::error("need orientation as first parameter, not $orient", 1) }
 
 	my $self = $class->SUPER::new( $orient );
 	$self->{'orient'} = $orient;
+	$self->{'children'} = [];
+	$self->append(@_);
+	$self;
+}
 
-	$self->{'children'} = [];
-	if (defined $children and $children){
-		if (ref $children eq 'ARRAY') {for (@$children) { $self->append($_) }}
-		else                          {                   $self->append($children)}
+
+# syntax sugar for insert method, unless insert can take list of child items
+# all these methods are ment to be chained, thatswhy the $self at the end
+sub before {
+	my ($self) = shift;
+	my ($mark_child) = shift;
+	my $pos = $self->get_position($mark_child);
+	return Kephra::Log::error("bookmark child $mark_child not found", 1) unless $pos > -1;
+	$self->insert($pos, 0, @_);
+}
+sub after {
+	my ($self) = shift;
+	my ($mark_child) = shift;
+	my $pos = $self->get_position($mark_child);
+	return Kephra::Log::error("bookmark child $mark_child not found", 1) unless $pos > -1;
+	$self->insert($pos+1, 0, @_);
+}
+sub prepend         { my ($self) = shift; $self->insert(  0, 0, @_ ); $self }
+sub append          { my ($self) = shift; $self->insert( -1, 0, @_ ); $self }
+sub append_expanded { my ($self) = shift; $self->insert( -1, 1, @_ ); $self }
+sub insert          {
+	my ($self) = shift;
+	my ($position) = shift;
+	my ($proportion) = shift;
+	for (@_) {
+		$self->_insert( $self->_build_item($position, $proportion, $_) );
+		$position++ unless $position == -1;
 	}
 	$self;
 }
 
-#sub prepend {
-	#my ($self, @widgets) = @_;
-	#$self->_insert({widget => $_, position => 0}) for @widgets;
-#}
-#sub append {
-	#my ($self, @widgets) = @_;
-	#$self->_insert({widget => $_, 
-	                #position => $self->{'sizer'}->GetChildren || 0}) for @widgets;
-#}
-#sub append_expanded {
-	#my ($self, @widgets) = @_;
-	#$self->_insert({
-		#widget => $_, 
-		#position => $self->{'sizer'}->GetChildren || 0, 
-		#proportion => 1                               }) for @widgets;
-#}
-#sub insert {
-	#my ($self, $widget, $position ) = @_;
-	#$self->_insert({widget => $widget, position => $position}) if ref $widget;
-#}
-#
-#sub _insert { # only one item
-	#my ($self, $item) = @_;
-	#return Kephra::Log::error('got hash as item def') unless ref $item eq 'HASH';
-	#return Kephra::Log::error('got no proper widget, but '.$item->{'widget'})
-		#unless $is_widget->( $item->{'widget'} )
-		#or $is_widget->( ${$item->{'widget'}} );
-	# ref to widget ref can signal to expand that widget
-	#if (ref $item->{'widget'} eq 'REF'){
-		#$item->{'widget'} = ${ $item->{'widget'} };
-		#$item->{'proportion'} = 1;
-	#}
-	#my %presets = (
-		#position => $self->{'sizer'}->GetChildren || 0,
-		#proportion => 0,
-		#style => &Wx::wxGROW,
-		#border => 0,
-	#);
-	#for (qw/position proportion style border/)
-		#{ $item->{$_} = $presets{$_} unless exists $item->{$_} }
-#
-	#splice @{$self->{'widgets'}}, $item->{'position'}, 0, $item->{'widget'};
-	#$self->{'sizer'}->Insert(
-		#$item->{'position'}, $item->{'widget'}, $item->{'proportion'},
-		#$item->{'style'},    $item->{'border'}
-	#);
-	#$item->{'position'};
-#}
+# accepted items : 
+# - arrayref: sizer with crossing orientation holding the list of items in the array
+# - widget: add widget without proportion
+# - widgetref: add with proportion
+# - int: spacer
+# - intref: stretchspacer
+sub _build_item {
+	my ($self, $position, $proportion, $child) = @_;
+	my $refcount;
+	while (ref $child eq 'REF'){ $refcount++; $child = $$child; }
 
-#sub remove {}
-#sub detach {}
-#sub show {
-	#my ($self, $widget) = @_;
-	#$self->{'sizer'}->Show($widget, 1);
-#}
-sub hide {
-	my ($self, $widget) = @_;
-	$self->Hide($widget);
-	$self->Layout;
+	if (ref $child eq 'ARRAY'){
+		my $child_orient = 
+			$refcount % 2                          ? $self->{'orient'} 
+		  : $self->{'orient'} == &Wx::wxHORIZONTAL ? &Wx::wxVERTICAL
+		  :                                          &Wx::wxHORIZONTAL;
+		my @subsizer_children = @$child;
+		$child = __PACKAGE__->new( $child_orient, @subsizer_children );
+	}
+
+	my %item;
+	if (defined blessed($child)){
+		return Kephra::Log::error("got no proper widget, but $child", 2)
+			unless $is_widget->($child) or ref $child eq __PACKAGE__;
+		$item{'child'} = $child;
+	}
+	elsif (looks_like_number($child) and int $child == $child){
+		return Kephra::Log::error("got no proper widget, but $child", 2)
+			unless $is_widget->($child) or ref $child eq __PACKAGE__;
+		$item{'child'} = 'space';
+	}
+	# already assembled 
+	elsif (ref $child eq 'HASH'){ %item = %$child }
+	else { return Kephra::Log::error("got no proper widget, but $child", 2) }
+
+	$item{'position'} = $position;
+	$item{'proportion'} = $proportion if $proportion;
+	$item{'proportion'} += $refcount if $refcount;
+
+	my %presets = (
+		position => -1, proportion => 0, style => &Wx::wxGROW, border => 0,
+	);
+	# fill with default settings (presets)
+	for (qw/position proportion style border/)
+		{ $item{$_} = $presets{$_} unless exists $item{$_} }
+	$item{position} = $self->GetChildren || 0 if $item{position} == -1;
+
+
+	return \%item;
 }
 
-sub all_widgets { shift->{'widgets'} }
-#sub get {                                            # child with that number
-	#my ($self, $nr) = @_;
-	#$self->{'widgets'}[$nr]
-#}
+sub _insert { # only one item
+	my ($self, $item) = @_;
+	return Kephra::Log::error('got hash as item def') unless ref $item eq 'HASH';
+
+	if ($item->{'child'} eq 'space'){
+		if ($item->{'proportion'}){
+			$self->InsertStretchSpacer( $item->{'position'},  $item->{'proportion'} )
+		} else {
+			$self->InsertSpacer(        $item->{'position'},  $item->{'border'} )
+		}
+	} else {
+		splice @{$self->{'children'}}, $item->{'position'}, 0, $item->{'child'};
+		$self->Insert(
+			$item->{'position'},  $item->{'child'},  $item->{'proportion'},
+			$item->{'style'},     $item->{'border'}
+		);
+	}
+	$item->{'position'};
+}
+
+sub show      {_relayout( sub { $_[0]->Show(   $_[1], 1) }, @_) }
+sub hide      {_relayout( sub { $_[0]->Hide(   $_[1] )   }, @_) }
+sub detach    {_relayout( sub { $_[0]->Detach( $_[1] )   }, @_) }
+sub remove    {_relayout( sub { $_[0]->Remove( $_[1] )   }, @_) } # del spacer & sizer
+sub _relayout {
+	my ($self, $child, $call) = @_;
+	return Kephra::Log::error('need a coderef, not $call', 2) unless ref $call eq 'CODE';
+	$call->($self, $child);
+	$self->Layout;
+	$self;
+}
+
+
+# getter
+sub get_position {                                          # number of that child
+	my ($self, $child) = @_;
+	my $pos = 0;
+	for ($self->GetChildren){
+		return $pos if defined $_->GetWindow and $_->GetWindow eq $child;
+		$pos++;
+	}
+	return -1;
+}
+sub is_child     { $_[0]->get_position( $_[1] ) > -1 ? 1 : 0 }
+sub get_child    { $_[0]->GetItem($_[1])->GetWindow }       # child with that number
+sub get_children { shift->{'children'}   }
 
 1;
-__END__
-
-=pod
-
-add:
- - widget: add widget without proportion
- - widgetref: add with proportion
- - int: spacer
- - intref: stretchspacer
-