Source

Kephra / lib / Kephra / App / Bar / Document.pm

Diff from to

lib/Kephra/App/Bar/Document.pm

-use v5.10;
-use strict;
+use v5.12;
 use warnings;
 use Wx;
 use Wx::AUI;
 use Kephra::API;
-use Kephra::App::Panel;
-use Kephra::App::Util;
+use Kephra::API::Command;
 
 package Kephra::App::Bar::Document;
 our @ISA = 'Wx::AuiNotebook';
+our $_ref;
+
+use Scalar::Util qw(blessed looks_like_number);
+
 
 Kephra::API::Command::register({
  'docbar-select-left'     =>{sub=>'$docbar->select_page_left',     label=>'Previous Tab',  keys=>'ctrl+pageup'},
  'docbar-select-right'    =>{sub=>'$docbar->select_page_right',    label=>'Next Tab',      keys=>'ctrl+pagedown'},
- 'docbar-select-leftmost' =>{sub=>'$docbar->select_page_leftmost', label=>'First Tab',     keys=>'ctrl+shift+pageup'},
- 'docbar-select-rightmost'=>{sub=>'$docbar->select_page_rightmost',label=>'Last Tab',      keys=>'ctrl+shift+pagedown'},
- 'docbar-move-left'       =>{sub=>'$docbar->move_page_left',       label=>'Move Left',     keys=>'alt+pageup'},
- 'docbar-move-right'      =>{sub=>'$docbar->move_page_right',      label=>'Move Right',    keys=>'alt+pagedown'},
- 'docbar-move-leftmost'   =>{sub=>'$docbar->move_page_leftmost',   label=>'Move Leftmost', keys=>'alt+shift+pageup'},
- 'docbar-move-rightmost'  =>{sub=>'$docbar->move_page_rightmost',  label=>'Move Rightmost',keys=>'alt+shift+pagedown'},
+ #'docbar-select-leftmost'=>{sub=>'$docbar->select_page_leftmost', label=>'First Tab',     keys=>'ctrl+shift+pageup'},
+ #'docbar-select-rightmost'=>{sub=>'$docbar->select_page_rightmost',label=>'Last Tab',      keys=>'ctrl+shift+pagedown'},
+ 'docbar-move-left'       =>{sub=>'$docbar->move_page_left',       label=>'Move Left',     keys=>'ctrl+shift+pageup'},
+ 'docbar-move-right'      =>{sub=>'$docbar->move_page_right',      label=>'Move Right',    keys=>'ctrl+shift+pagedown'},
+ #'docbar-move-leftmost'   =>{sub=>'$docbar->move_page_leftmost',   label=>'Move Leftmost', keys=>'alt+shift+pageup'},
+ #'docbar-move-rightmost'  =>{sub=>'$docbar->move_page_rightmost',  label=>'Move Rightmost',keys=>'alt+shift+pagedown'},
 });
 
 
-my ($is_panel, $is_widget) = Kephra::App::Util::get(qw/is_panel is_widget/);
-
 sub new {
 	my( $class, $parent) = @_;
-	my $self = $class->SUPER::new( $parent, -1, [-1,-1], [-1,-1],
+	my $self = $_ref = $class->SUPER::new( $parent, -1, [-1,-1], [-1,-1],
 		&Wx::wxAUI_NB_TOP | &Wx::wxAUI_NB_TAB_MOVE | &Wx::wxAUI_NB_WINDOWLIST_BUTTON |
 		&Wx::wxAUI_NB_SCROLL_BUTTONS | &Wx::wxAUI_NB_CLOSE_ON_ACTIVE_TAB
 	);
 
-	$self->{'visual_page_order'} = [];   # visual order of internal indexes : vis -> int
-	$self->{'internal_page_order'} = []; # internal order of visual indexes : int -> vis
-	$self->activate_events();
+	$self->{'visual_page_order'} = [];   # visual order of internal pos : vis -> int
+	$self->{'internal_page_order'} = []; # internal order of visual pos : int -> vis
+
+	$_->add_instance($self) for Kephra::API::all_documents();
+	$self->mount_events();
 
 	return $self;
 }
 
-sub activate_events {
+sub Destroy {
 	my ($self) = @_;
+	$_->del_instance($self) for Kephra::API::all_documents();
+	$self->SUPER::Destroy( );
+	1;
+}
+
+sub mount_events {
+	my ($self) = @_;
+	#Wx::Event::EVT_SET_FOCUS ($self,  sub { print "focus--\n";$_[1]->Skip });
 	Wx::Event::EVT_AUINOTEBOOK_BEGIN_DRAG( $self, -1, sub {
-		my ($nb, $event ) = @_;
-		$self->{'DND_page_nr'} = $event->GetSelection;
+		my ($bar, $event ) = @_;
+		$bar->{'DND_page_nr'} = $event->GetSelection;
 	});
 	Wx::Event::EVT_AUINOTEBOOK_END_DRAG($self, -1, sub {
-		my ($nb, $event ) = @_;
-		return unless defined $self->{'DND_page_nr'};
-		$nb->move_page_index_visually($self->{'DND_page_nr'}, $event->GetSelection);
-		$self->{'DND_page_nr'} = undef;
+		my ($bar, $event ) = @_;
+		return unless defined $bar->{'DND_page_nr'};
+		$bar->move_page_position_visually($bar->{'DND_page_nr'}, $event->GetSelection);
+		$bar->{'DND_page_nr'} = undef;
+		Kephra::App::Focus::stay();
 	});
 	Wx::Event::EVT_AUINOTEBOOK_PAGE_CHANGED( $self, -1, sub {
-		my ($nb, $event ) = @_;
-		my $new_page = $nb->GetPage( $event->GetSelection );
-		Kephra::API::Doc::set_active_doc( $new_page );
+		my ($bar, $event ) = @_;
+		my $new_page = $bar->GetPage( $event->GetSelection );
+		Kephra::API::Doc::set_active( $new_page );
 		Kephra::API::main_window()->refresh_title();
-		Wx::Window::SetFocus( $new_page );
+		Kephra::API::focus( $new_page );
 		$event->Skip;
 	});
 	Wx::Event::EVT_AUINOTEBOOK_PAGE_CLOSE( $self, -1, sub {
-		my ($nb, $event ) = @_; 
+		my ($bar, $event ) = @_; 
 		$event->Veto;
 		Kephra::File::close_active();
 	});
-	#Wx::Event::EVT_AUINOTEBOOK_PAGE_CHANGED(
-	#);
 	# keep focus on editor even when klicking on tab bar
-	#Wx::Event::EVT_LEFT_DOWN($self, sub { Kephra::API::active_editor()->focus; print "--"; });
+	#Wx::Event::EVT_LEFT_DOWN( $self, sub { Kephra::API::active_editor()->focus; print "--down"; });
 	#$self->Connect( -1, -1, &Wx::wxEVT_SET_FOCUS, sub {  print "--"; } )
+	#Wx::Event::EVT_SET_FOCUS( $self, sub { my ($bar, $event ) = @_; $event->Skip; say "--bar"; });
 }
-sub silence_events {
+
+sub unmount_events {
 	my ($self) = @_;
 	Wx::Event::EVT_AUINOTEBOOK_BEGIN_DRAG( $self, -1, sub {});
 	Wx::Event::EVT_AUINOTEBOOK_END_DRAG  ( $self, -1, sub {});
 	Wx::Event::EVT_AUINOTEBOOK_PAGE_CLOSE  ( $self, -1, sub {});
 }
 
+
 sub add_page {
-	my ($self, $new_page, $label, $position) = @_;
-	return unless $new_page and ($is_panel->($new_page) or $is_widget->($new_page));
+	my ($self, $new_page, $position, $title, $set_active) = @_;
+	return Kephra::Log::warning( "got no panel", 1 ) until Kephra::App::Util::is_panel($new_page);
 	my $active_pos = $self->GetSelection;
 
-	$label    = ''                           unless defined $label;
-	$position = 'right'                      if $position eq 'default' or $position == -1;
+	$title    = ''                           unless defined $title;
+	$position = 'right'                      if $position eq 'default' or $position eq -1;
 	$position = $self->rightmost_page_pos+1  if $position eq 'rightmost';
 	$position = $active_pos + 1              if $position eq 'right';
 	$position = $active_pos                  if $position eq 'left';
 	$position = $self->leftmost_page_pos     if $position eq 'leftmost';
-	#$set_active = 1                          unless defined $set_active;
+	$set_active = 0                          unless defined $set_active;
 
-	# put panel under a none-panel
-	unless ($new_page->isa('Kephra::App::Panel')) {
-		my $widget = $new_page;
-		$new_page = Kephra::App::Panel->new( $self, \$widget);# if ($position == 0 or $label);
-		# document property: panel the editor sits on has to be set before EVT_AUINOTEBOOK_PAGE_CHANGED
-		Kephra::DocumentStash::doc_by_ed( $widget )->panel( $new_page ) if $widget->isa('Kephra::Editor'); # and ($position == 0 or $label);
-	}
-	else { $new_page->Reparent( $self ) }
-
-	$self->InsertPage( $position, $new_page, '');# if $position == 0 or $label; # last parameter sets new pace as active
-	$self->set_page_title( $label, $new_page );
+	$new_page->Reparent($self);
+	$self->InsertPage( $position, $new_page, $title, $set_active);
+	#$self->set_page_title( $title, $new_page );
+	Kephra::API::focus($new_page) if $set_active;
+	Kephra::API::main_window()->refresh_title() if $set_active;
 
 	# inserting new index to position translators
 	for   (@{$self->{'visual_page_order'}}){ $_++ if $_ >= $position }
 	splice @{$self->{'visual_page_order'}},  $position, 0, $position;
 	$self->refresh_internal_page_order();
 
-	return $new_page;
+	$self;
 }
 
 sub remove_page {
-	my ($self, $internal_position) = @_;
+	my ($self, $page) = @_;
+	my $internal_position = $self->GetPageIndex( $page );
 
-	$self->DeletePage( $internal_position );
+	$self->RemovePage( $internal_position );
 	my $visual_position = $self->{'internal_page_order'}[$internal_position];
 	my $visual = $self->{'visual_page_order'};
 	splice @$visual, $visual_position, 1;
 	$self->refresh_internal_page_order;
 }
 
-sub refresh_internal_page_order {
+
+sub refresh_internal_page_order {       # sync visual_page_order index with internal_page_order after each change
 	my ($self) = @_;
 	my $visual = $self->{'visual_page_order'};
 	return unless ref $visual eq ref [];
 	$self->{'internal_page_order'} = $internal;
 }
 
-sub move_page_index_visually { # for dnd only
+sub move_page_position_visually {          # for dnd only
 	my ($self, $from, $to ) = @_;
 	return unless $from >= 0 and $from < $self->GetPageCount;
 	return unless $to >= 0 and $to < $self->GetPageCount;
-	my $index = splice @{$self->{'visual_page_order'}}, $from, 1;
-	splice @{$self->{'visual_page_order'}}, $to, 0, $index;
+	my $position = splice @{$self->{'visual_page_order'}}, $from, 1;
+	splice @{$self->{'visual_page_order'}}, $to, 0, $position;
 	$self->refresh_internal_page_order();
 }
 
-sub move_page_visually { # for movements by keyboard
+sub move_page_visually  {               # for movements by keyboard
 	my ($self, $from, $to ) = @_;
 	my $max = $self->GetPageCount - 1;
 	return if $from < 0 or $from > $max;
 	my $label = $self->GetPageText( $pos );
 	my $visual = $self->{'visual_page_order'};
 
-	$self->silence_events();
+	$self->unmount_events();
 	$self->RemovePage( $pos );
 	$self->InsertPage( $to, $page, $label);
 	my $removed = splice @$visual, $from, 1;
 	$self->{'visual_page_order'} = $visual;
 	$self->refresh_internal_page_order();
 	$self->SetSelection( $self->{'visual_page_order'}[$to] );
-	$self->activate_events();
+	$self->mount_events();
 }
 
-sub move_page_left  { 
+sub move_page_left      {
 	my ($self) = @_;
 	$self->move_page_visually ( 
 		$self->active_visual_pos, $self->next_page_pos_rot_left( $self->GetSelection )
 	);
 }
-sub move_page_right { 
+sub move_page_right     {
 	my ($self) = @_;
 	$self->move_page_visually( 
 		$self->active_visual_pos, $self->next_page_pos_rot_right( $self->GetSelection )
 	$self->move_page_visually( $self->active_visual_pos, $self->rightmost_page_pos );
 }
 
-sub select_page_left  { 
+sub select_page_left    { 
 	my ($self) = @_;
 	$self->raise_page( $self->next_page_pos_rot_left( $self->GetSelection ) );
 }
-sub select_page_right { 
+sub select_page_right   { 
 	my ($self) = @_;
 	$self->raise_page( $self->next_page_pos_rot_right( $self->GetSelection ) );
 }
 sub select_page_leftmost  { $_[0]->raise_page( $_[0]->leftmost_page_pos ) }
 sub select_page_rightmost { $_[0]->raise_page( $_[0]->rightmost_page_pos ) }
 
-sub leftmost_page_pos { 0 }
-sub rightmost_page_pos { $_[0]->GetPageCount-1 }
-sub active_visual_pos { $_[0]->{'internal_page_order'}[ $_[0]->GetSelection ] }
-sub next_page_pos_rot_left {
+sub active_visual_pos     { $_[0]->{'internal_page_order'}[ $_[0]->GetSelection ] }
+sub leftmost_page_pos     { 0 }
+sub rightmost_page_pos    { $_[0]->GetPageCount-1 }
+sub valid_page_pos        { 
+	1 if $_[1] >= $_[0]->leftmost_page_pos and $_[1]<= $_[0]->rightmost_page_pos
+}
+sub next_page_pos_rot_left{
 	my ($self) = @_; # take in position of internal order
 	my $pos = $self->{'internal_page_order'}[ $_[1] ];
 	$self->{'visual_page_order'}[$pos == 0 ? $self->rightmost_page_pos : $pos-1]
 }
-sub next_page_pos_rot_right {
+sub next_page_pos_rot_right{
 	my ($self) = @_; # take in position of internal order
 	my $pos = $self->{'internal_page_order'}[ $_[1] ];
 	$self->{'visual_page_order'}[$pos == $self->rightmost_page_pos ? 0 : $pos+1]
 }
 
-sub raise_page {
-	my ($self, $iop) = @_; # can be Index Or Page (panel reference)
-	my $index = int $iop eq $iop ? $iop : $self->GetPageIndex($iop);
-	return if $index < 0 or $index > $self->rightmost_page_pos;
-	$self->SetSelection( $index );
-	my $page = $self->GetPage($index);
-	#print $page->GetChildren,"||\n";
-	Kephra::App::Focus::set($page);
+
+sub raise_page    {
+	my ($self, $pop) = @_; # can be Position Or Page (panel reference)
+	my $position = int $pop eq $pop ? $pop : $self->GetPageIndex($pop);
+	return unless $self->valid_page_pos( $position );
+	# if just selecting the currrent, only tab drives focus nuts
+	$self->SetSelection( $position ) unless $position == $self->GetSelection;
+	my $page = $self->GetPage($position);
+	my $doc = Kephra::API::Doc::find($page);
+	Kephra::API::Doc::set_active( $doc );
+	Kephra::API::focus ( defined $doc ? $doc->editor->{$self} : $page );
+	Kephra::API::main_window()->refresh_title();
+
 }
 
+
+sub active_title { $_[0]->GetPageText( $_[0]->GetSelection ) }
+
 sub set_page_title {
 	my ($self, $label, $page) = @_;
-	return if ref $page and $page ne ref $page and $page->isa(' Wx::Window');
-	my $position = $page ? $self->GetPageIndex($page) : $self->GetSelection;
-	return unless $position >= 0;
-	$label = '<untitled>' unless $label;
-	my $max_width = 15;
-	if ( length($label) > $max_width and $max_width > 7 ) {
-		$label = substr( $label, 0, $max_width - 2 ) . '..';
-	}
+	$page = $self->GetSelection unless defined $page;
+	return Kephra::Log::warning("need a Kephra::App::Panel or valid position number") 
+		unless (looks_like_number($page) and $self->valid_page_pos($page))
+		or (blessed($page) and $page->isa('Kephra::App::Panel'));
+	my $found = $self->GetPageIndex($page);
+	my $position = $found eq &Wx::wxNOT_FOUND ? $page : $found;
 	$self->SetPageText( $position, $label );
 }
 
-sub refresh_page_title {
-	my $self = shift;
-	my $doc = shift // Kephra::API::document();
-	my $unsaved_mark = '*';
-	my $position = $self->GetSelection;
-	my $label = $self->GetPageText( $position);
-	chop $label if substr($label,-1) eq $unsaved_mark;
-	$label .= $unsaved_mark if $doc->editor->GetModify;
-	$self->SetPageText($position, $label);
-}
 
-1;
-
+1;