Source

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

Herbert Breunung ac839f5 
Herbert Breunung 0e4eeff 

Herbert Breunung 441ba84 
Herbert Breunung 0929a31 
Herbert Breunung 0e4eeff 


Herbert Breunung 36adcac 

Herbert Breunung 26b29b9 
Herbert Breunung 0e4eeff 
Herbert Breunung 320b6b3 
Herbert Breunung 95c7b31 

Herbert Breunung 36adcac 

Herbert Breunung 0af3d4a 

Herbert Breunung 36adcac 

Herbert Breunung 5bb19d7 


Herbert Breunung 0e4eeff 
Herbert Breunung e2c90af 
Herbert Breunung 36adcac 
Herbert Breunung e2c90af 


Herbert Breunung 8a74257 
Herbert Breunung 36adcac 

Herbert Breunung 7315592 

Herbert Breunung 36adcac 
Herbert Breunung e8de99d 
Herbert Breunung 2d42ab2 


Herbert Breunung 7315592 






Herbert Breunung 36adcac 
Herbert Breunung 2d42ab2 
Herbert Breunung 36adcac 
Herbert Breunung e2c90af 
Herbert Breunung 36adcac 

Herbert Breunung e2c90af 

Herbert Breunung 36adcac 




Herbert Breunung e2c90af 

Herbert Breunung 36adcac 

Herbert Breunung 7315592 
Herbert Breunung bd47e49 
Herbert Breunung 36adcac 
Herbert Breunung dfbe38b 
Herbert Breunung e2c90af 
Herbert Breunung dfbe38b 
Herbert Breunung 36adcac 
Herbert Breunung dfbe38b 


Herbert Breunung 3a54b2a 
Herbert Breunung 29977f3 
Herbert Breunung 2d42ab2 
Herbert Breunung 29977f3 
Herbert Breunung 2d42ab2 
Herbert Breunung 36adcac 

Herbert Breunung 2d42ab2 

Herbert Breunung 441ba84 
Herbert Breunung 2d42ab2 
Herbert Breunung 441ba84 
Herbert Breunung 0e4eeff 

Herbert Breunung 36adcac 
Herbert Breunung e2c90af 
Herbert Breunung 36adcac 

Herbert Breunung d7153be 
Herbert Breunung effa397 
Herbert Breunung 36adcac 

Herbert Breunung f00cf47 



Herbert Breunung 36adcac 
Herbert Breunung ed39599 
Herbert Breunung 36adcac 

Herbert Breunung b9cfdfa 
Herbert Breunung 36adcac 

Herbert Breunung e2c90af 
Herbert Breunung 6e6c0ab 
Herbert Breunung f00cf47 


Herbert Breunung 2d42ab2 
Herbert Breunung 36adcac 
Herbert Breunung 0e4eeff 

Herbert Breunung 2d42ab2 
Herbert Breunung 36adcac 

Herbert Breunung fce2a88 
Herbert Breunung 36adcac 
Herbert Breunung f00cf47 

Herbert Breunung 2d42ab2 
Herbert Breunung fce2a88 
Herbert Breunung f00cf47 

Herbert Breunung 2d42ab2 

Herbert Breunung 36adcac 

Herbert Breunung 2d42ab2 
Herbert Breunung f00cf47 
Herbert Breunung 2d42ab2 


Herbert Breunung f00cf47 
Herbert Breunung 2d42ab2 

Herbert Breunung 36adcac 
Herbert Breunung 2d42ab2 


Herbert Breunung 36adcac 

Herbert Breunung f00cf47 
Herbert Breunung 2d42ab2 

Herbert Breunung 36adcac 
Herbert Breunung 2d42ab2 





Herbert Breunung f00cf47 
Herbert Breunung 2d42ab2 

Herbert Breunung f00cf47 
Herbert Breunung 2d42ab2 
Herbert Breunung 36adcac 
Herbert Breunung 2d42ab2 





Herbert Breunung f00cf47 


Herbert Breunung 36adcac 
Herbert Breunung 2d42ab2 

Herbert Breunung 36adcac 
Herbert Breunung 2d42ab2 
Herbert Breunung f00cf47 

Herbert Breunung d7153be 
Herbert Breunung 2d42ab2 
Herbert Breunung 36adcac 
Herbert Breunung 2d42ab2 
Herbert Breunung f00cf47 

Herbert Breunung d7153be 

Herbert Breunung f00cf47 
Herbert Breunung d7153be 
Herbert Breunung f00cf47 
Herbert Breunung d7153be 
Herbert Breunung f00cf47 
Herbert Breunung d7153be 
Herbert Breunung f00cf47 
Herbert Breunung 2d42ab2 

Herbert Breunung 36adcac 
Herbert Breunung 2d42ab2 
Herbert Breunung cd3dce8 
Herbert Breunung 2d42ab2 
Herbert Breunung 36adcac 
Herbert Breunung 2d42ab2 
Herbert Breunung cd3dce8 
Herbert Breunung d7153be 
Herbert Breunung cd3dce8 

Herbert Breunung d7153be 
Herbert Breunung 36adcac 






Herbert Breunung d7153be 
Herbert Breunung f00cf47 

Herbert Breunung d7153be 
Herbert Breunung 36adcac 
Herbert Breunung d7153be 
Herbert Breunung f00cf47 

Herbert Breunung 2d42ab2 

Herbert Breunung 36adcac 





Herbert Breunung 26b29b9 

Herbert Breunung 7315592 
Herbert Breunung 26b29b9 
Herbert Breunung c50f082 

Herbert Breunung 36adcac 


Herbert Breunung f00cf47 
Herbert Breunung 2655cce 
Herbert Breunung ac839f5 





Herbert Breunung 2d42ab2 
Herbert Breunung 3a54b2a 
Herbert Breunung cd3dce8 
Herbert Breunung 36adcac 
use v5.12;
use warnings;
use Wx;
use Wx::AUI;
use Kephra::API;

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=>'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'},
});


sub new {
	my( $class, $parent) = @_;
	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 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 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 ($bar, $event ) = @_;
		$bar->{'DND_page_nr'} = $event->GetSelection;
	});
	Wx::Event::EVT_AUINOTEBOOK_END_DRAG($self, -1, sub {
		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 ($bar, $event ) = @_;
		my $new_page = $bar->GetPage( $event->GetSelection );
		Kephra::API::Doc::set_active( $new_page );
		Kephra::API::main_window()->refresh_title();
		Kephra::API::focus( $new_page );
		$event->Skip;
	});
	Wx::Event::EVT_AUINOTEBOOK_PAGE_CLOSE( $self, -1, sub {
		my ($bar, $event ) = @_; 
		$event->Veto;
		Kephra::File::close_active();
	});
	# keep focus on editor even when klicking on tab bar
	#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 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_CHANGED( $self, -1, sub {});
	Wx::Event::EVT_AUINOTEBOOK_PAGE_CLOSE  ( $self, -1, sub {});
}


sub add_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;

	$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 = 0                          unless defined $set_active;

	$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();

	$self;
}

sub remove_page {
	my ($self, $page) = @_;
	my $internal_position = $self->GetPageIndex( $page );

	$self->RemovePage( $internal_position );
	my $visual_position = $self->{'internal_page_order'}[$internal_position];
	my $visual = $self->{'visual_page_order'};
	splice @$visual, $visual_position, 1;
	for (@$visual) {$_-- if $_ >= $internal_position}
	$self->{'visual_page_order'} = $visual;
	$self->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 [];
	my $internal;
	$internal->[ $visual->[$_] ] = $_ for 0 .. @$visual-1;
	$self->{'internal_page_order'} = $internal;
}

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 $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
	my ($self, $from, $to ) = @_;
	my $max = $self->GetPageCount - 1;
	return if $from < 0 or $from > $max;
	return if $to < 0 or $to > $max;
	return if $from == $to;

	my $pos = $self->{'visual_page_order'}[ $from ];
	my $page = $self->GetPage( $pos );
	my $label = $self->GetPageText( $pos );
	my $visual = $self->{'visual_page_order'};

	$self->unmount_events();
	$self->RemovePage( $pos );
	$self->InsertPage( $to, $page, $label);
	my $removed = splice @$visual, $from, 1;
	if ($from < $to) { for (@$visual) {$_-- if $_ > $removed and $_ <= $to} }
	else             { for (@$visual) {$_++ if $_ < $removed and $_ >= $to} }
	splice @$visual, $to, 0, $to;
	$self->{'visual_page_order'} = $visual;
	$self->refresh_internal_page_order();
	$self->SetSelection( $self->{'visual_page_order'}[$to] );
	$self->mount_events();
}

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     {
	my ($self) = @_;
	$self->move_page_visually( 
		$self->active_visual_pos, $self->next_page_pos_rot_right( $self->GetSelection )
	);
}
sub move_page_leftmost  { 
	my ($self) = @_;
	$self->move_page_visually( $self->active_visual_pos, $self->leftmost_page_pos );
}
sub move_page_rightmost { 
	my ($self) = @_;
	$self->move_page_visually( $self->active_visual_pos, $self->rightmost_page_pos );
}

sub select_page_left    { 
	my ($self) = @_;
	$self->raise_page( $self->next_page_pos_rot_left( $self->GetSelection ) );
}
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 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{
	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, $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::focus ( defined $doc ? $doc->editor->{$self} : $page );
}


sub active_title { $_[0]->GetPageText( $_[0]->GetSelection ) }

sub set_page_title {
	my ($self, $label, $page) = @_;
	$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 );
}


1;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.