Commits

Herbert Breunung  committed 7315592

centralize dic instance dreation

  • Participants
  • Parent commits 37084d2
  • Branches sp1

Comments (0)

Files changed (11)

File lib/Kephra/API.pm

 use warnings;
 
 use Kephra::API::Command;
-use Kephra::API::Docs;
+use Kephra::API::Doc;
 use Kephra::API::Event;
 use Kephra::API::KeyMap;
 #use Kephra::API::Plugin;
 sub docbar              { Kephra::App::Part::Editor::docbar() }
 sub all_docbars         { Kephra::App::Part::Editor::all_docbars() }
 sub passive_docbars     { Kephra::App::Part::Editor::passive_docbars() }
-sub document            { Kephra::API::Docs::active() }
-sub all_documents       { Kephra::API::Docs::all() }
-sub do_with_all_editors {&Kephra::API::Docs::do_with_all_editors }
-sub editor              { Kephra::API::Docs::active_editor() }
+sub document            { Kephra::API::Doc::active() }
+sub all_documents       { Kephra::API::Doc::all() }
+sub do_with_all_editors {&Kephra::API::Doc::do_with_all_editors }
+sub editor              { Kephra::API::Doc::active_editor() }
 
 sub focus               { Kephra::App::Focus::set(@_) }
 sub focus_back          { Kephra::App::Focus::set_back(@_) }

File lib/Kephra/API/Doc.pm

+use v5.10;
+use strict;
+use warnings;
+use Wx;
+use Kephra::App::Editor;
+use Kephra::App::Panel;
+use Kephra::Document;
+
+package Kephra::API::Doc;
+my %document;                           # keys of subhashes: ID editor panel file
+my $active;
+my $lowest_free_ID = 1;
+my $lowest_free_anon_NR = 1;
+
+use constant DOC_CLASS => 'Kephra::Document';
+use Scalar::Util qw(blessed looks_like_number);
+
+
+sub active        { $active || '' }
+sub active_editor { $active->editor->{Kephra::API::docbar()} if $active }
+sub active_panel  { $active->panel->{Kephra::API::docbar()} if $active }
+sub set_active{
+	my $doc = find( shift );
+	$active = $doc if $doc;
+}
+sub previous      { App::Kephra::Focus::last( DOC_CLASS ) }
+sub all           { values %{$document{'ID'}} }
+
+sub is { return 1 if blessed($_[0]) and $_[0]->isa( DOC_CLASS ); return 0 }
+
+
+sub add {
+	my $doc = shift;
+	Kephra::Log::warning('need a ' . DOC_CLASS . " thats in stash, not $doc!", 1)
+		unless is($doc);
+	$document{'ID'}  {$lowest_free_ID} = $doc;
+	add_instance($doc, $_) for values $doc->panel;
+	if ($doc->file_path) {
+		$document{'file'}{$doc->file_path} = $doc;
+	} else {
+		$doc->anon_NR( $lowest_free_anon_NR++ );
+		$document{'anon'}{$doc->anon_NR} = $doc;
+	}
+	$lowest_free_ID++;
+}
+
+
+sub rename_file {
+	my $doc = find( shift );
+	Kephra::Log::warning('need a ' . DOC_CLASS . " thats in stash, not $doc!", 1)
+		unless is($doc);
+	my $file = $doc->old_file_path;
+	delete $document{'file'}{$file} if $file and $document{'file'}{$file};
+	if ($doc->file_path){
+		$document{'file'}{$doc->file_path} = $doc;
+		unless ($doc->old_file_path) {
+			delete $document{'anon'}{$doc->anon_NR};
+			$doc->anon_NR(0);
+		}
+	} else {
+		if ($doc->old_file_path) {
+			$doc->anon_NR( $lowest_free_anon_NR++ );
+			$document{'anon'}{$doc->anon_NR} = $doc;
+		}
+	}
+}
+
+
+sub remove {
+	my $doc = shift;
+#say "remove $doc ", scalar keys %{$document{'ID'}}, ' ',scalar keys %{$document{'file'}}; 
+	Kephra::Log::warning('need a ' . DOC_CLASS . ' thats in stash, not $doc!', 1)
+		unless is($doc);
+	delete $document{'ID'}{$doc->ID};
+	#remove_instance($doc, $_) for values $doc->panel;
+	delete $document{'file'}{$doc->file_path} if $doc->file_path;
+#say "removed $doc ", scalar keys %{$document{'ID'}}, ' ',scalar keys %{$document{'file'}}; 
+}
+
+
+sub add_instance {
+	my ($doc, $bar) = @_;
+	return Kephra::Log::warning('need as first parameter a'.DOC_CLASS.' thats in stash, not $doc!', 1)
+		unless is($doc);
+	return Kephra::Log::warning("need as second parameter a Kephra::App::Bar::Document instance")
+		unless blessed($bar) eq 'Kephra::App::Bar::Document';
+	$document{'panel'} { $doc->panel->{$bar}  } = $doc;
+	$document{'editor'}{ $doc->editor->{$bar} } = $doc;
+}
+
+
+sub remove_instance {
+	my ($doc, $bar) = @_;
+	return Kephra::Log::warning('need as first parameter a'.DOC_CLASS.' thats in stash, not $doc!', 1)
+		unless is($doc);
+	return Kephra::Log::warning("need as second parameter a Kephra::App::Bar::Document instance")
+		unless blessed($bar) eq 'Kephra::App::Bar::Document';
+	delete $document{'panel'}{ $doc->panel->{$bar} };
+	delete $document{'editor'}{ $doc->editor->{$bar} };
+}
+
+
+sub find {
+	my $any = shift;
+	Kephra::Log::warning("need a parameter!", 1) unless defined $any and $any;
+	return     looks_like_number($any)                                     ? $document{'ID'}    {$any}
+	         : ref($any) eq ''                                             ? $document{'file'}  {$any}
+	         : $any->isa('Kephra::App::Panel')                             ? $document{'panel'} {$any}
+	         : $any->isa('Kephra::App::Editor')                            ? $document{'editor'}{$any}
+	         :($any->isa(DOC_CLASS) and $document{'ID'}{$any->ID} eq $any) ? $any
+	         :                                                               undef;
+}
+
+
+sub file_loaded {
+	my $file_path = shift;
+	#Kephra::Log::warning("needs a file path as input!") unless $file_path and -e $file_path;
+	for my $doc ( all() ) {
+		return 1 if $doc->file_path and $doc->file_path eq $file_path;
+	}
+}
+
+
+sub all_editors { keys %{$document{'editor'}} }
+sub do_with_all_editors {
+}
+
+1;
+

File lib/Kephra/API/Docs.pm

-use v5.10;
-use strict;
-use warnings;
-use Wx;
-use Kephra::App::Editor;
-use Kephra::App::Panel;
-use Kephra::Document;
-
-package Kephra::API::Docs;
-my %document;                           # keys of subhashes: ID editor panel file
-my $active;
-my $lowest_free_ID = 1;
-my $lowest_free_anon_NR = 1;
-
-use constant DOC_CLASS => 'Kephra::Document';
-use Scalar::Util qw(looks_like_number);
-
-
-sub active        { $active || '' }
-sub active_editor { $active->editor->{Kephra::API::docbar()} }
-sub active_panel  { $active->panel->{Kephra::API::docbar()} }
-sub set_active_doc{
-	my $doc = find( shift );
-	$active = $doc if $doc;
-}
-sub previous_doc  { App::Kephra::Focus::last( DOC_CLASS ) }
-sub all           { values %{$document{'ID'}} }
-
-sub is_doc { return 1 if ref $_[0] and $_[0]->isa( DOC_CLASS ); return 0; }
-
-sub add {
-	my $doc = shift;
-	Kephra::Log::warning('need a ' . DOC_CLASS . " thats in stash, not $doc!", 1)
-		unless is_doc($doc);
-	$document{'ID'}  {$lowest_free_ID} = $doc;
-	$document{'panel'}{$_} = $doc for values $doc->panel;
-	$document{'editor'}{$_} = $doc for values $doc->editor;
-	if ($doc->file_path) {
-		$document{'file'}{$doc->file_path} = $doc;
-	} else {
-		$doc->anon_NR( $lowest_free_anon_NR++ );
-		$document{'anon'}{$doc->anon_NR} = $doc;
-	}
-	$lowest_free_ID++;
-}
-
-sub rename_file {
-	my $doc = find( shift );
-	Kephra::Log::warning('need a ' . DOC_CLASS . " thats in stash, not $doc!", 1)
-		unless is_doc($doc);
-	my $file = $doc->old_file_path;
-	delete $document{'file'}{$file} if $file and $document{'file'}{$file};
-	if ($doc->file_path){
-		$document{'file'}{$doc->file_path} = $doc;
-		unless ($doc->old_file_path) {
-			delete $document{'anon'}{$doc->anon_NR};
-			$doc->anon_NR(0);
-		}
-	} else {
-		if ($doc->old_file_path) {
-			$doc->anon_NR( $lowest_free_anon_NR++ );
-			$document{'anon'}{$doc->anon_NR} = $doc;
-		}
-	}
-}
-
-sub remove {
-	my $doc = shift;
-#say "remove $doc ", scalar keys %{$document{'ID'}}, ' ',scalar keys %{$document{'file'}}; 
-	Kephra::Log::warning('need a ' . DOC_CLASS . ' thats in stash, not $doc!', 1)
-		unless is_doc($doc);
-	delete $document{'ID'}{$doc->ID};
-#	delete $document{'panel'}{$_}    for values $doc->panel;
-#	delete $document{'editor'}{$_}   for values $doc->editor;
-	delete $document{'file'}{$doc->file_path} if $doc->file_path;
-#say "removed $doc ", scalar keys %{$document{'ID'}}, ' ',scalar keys %{$document{'file'}}; 
-}
-
-sub find {
-	my $any = shift;
-	Kephra::Log::warning("need a parameter!", 1) unless defined $any and $any;
-	return     looks_like_number($any)                                     ? $document{'ID'}    {$any}
-	         : ref($any) eq ''                                             ? $document{'file'}  {$any}
-	         : $any->isa('Kephra::App::Panel')                             ? $document{'panel'} {$any}
-	         : $any->isa('Kephra::App::Editor')                            ? $document{'editor'}{$any}
-	         :($any->isa(DOC_CLASS) and $document{'ID'}{$any->ID} eq $any) ? $any
-	         :                                                               undef;
-}
-
-sub file_loaded {
-	my $file_path = shift;
-	#Kephra::Log::warning("needs a file path as input!") unless $file_path and -e $file_path;
-	for my $doc ( all() ) {
-		return 1 if $doc->file_path and $doc->file_path eq $file_path;
-	}
-}
-
-sub all_editors { keys %{$document{'editor'}} }
-sub do_with_all_editors {
-}
-
-sub add_bar{}
-sub remove_bar{}
-1;
-

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

 
 	$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_PAGE_CHANGED( $self, -1, sub {
 		my ($bar, $event ) = @_;
 		my $new_page = $bar->GetPage( $event->GetSelection );
-		Kephra::API::Docs::set_active_doc( $new_page );
+		Kephra::API::Doc::set_active( $new_page );
 		Kephra::API::main_window()->refresh_title();
 		Kephra::API::focus( $new_page );
 		$event->Skip;
 	# 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::Docs::find($page);
+	my $doc = Kephra::API::Doc::find($page);
 	Kephra::API::focus ( defined $doc ? $doc->editor->{$self} : $page );
 }
 

File lib/Kephra/App/Editor.pm

 		my ($ed, $event) = @_;
 		my $key = Kephra::API::KeyMap::keycode_from_event($event);
 		#Kephra::API::log("pressed key $key inside the editor");
-		#say $key;
 		if (Kephra::API::KeyMap::keycode_is_registered($key)){
 			my $cmd = Kephra::API::KeyMap::cmd_from_keycode($key);
 			#say $cmd;
 			Kephra::API::Command::run( $cmd );
 		}
 		else {$event->Skip}
-
-		if    ($key ==  0)                     {  }
 		#elsif ($key ==  &Wx::WXK_PAGEUP + 2000){$output_book->AdvanceSelection(0)}
 		#elsif ($key ==  ord('Q')        + 4000){Kephra::API::app()->close_save }
-		else {$event->Skip}
 	});
 	#Wx::Event::EVT_RIGHT_DOWN
 	#Wx::Event::EVT_STC_UPDATEUI

File lib/Kephra/App/Focus.pm

 use strict;
 use warnings;
 use Wx;
-use Kephra::API;
-use Kephra::App::Util;
 
 package Kephra::App::Focus;
 my @focus_stack = ();
 my $max_stack_size = 50;
 
-#Kephra::CommandList::register_cmd({'app-focus-set-back'  =>{sub=>'set_back',label=>'',keys=>''},});
+use Kephra::API;
+use Kephra::App::Util qw(is_widget);
+
+Kephra::API::Command::register({
+ 'app-focus-set-back'  =>{ sub=>'set_back', label=>'',  keys=>'' },
+ 'app-focus-stay'      =>{ sub=>'stay',     label=>'',  keys=>'' },
+});
 
 
 sub get  {                              # give widget in focus or one that was before
 
 sub set  {                              # set focus to another widget
 	my ($widget) = @_;
+	return unless defined $widget;
 	Kephra::Log::note("focus is on :". get()." and will be: $widget");
 	return Kephra::Log::warning( "got no proper widget but $widget", 1 )
-		unless Kephra::App::Util::is_widget($widget);
+		unless is_widget($widget);
 	return if $widget eq get();
 	unshift @focus_stack, $widget;
 	pop @focus_stack while stack_size() > $max_stack_size;
 
 sub stay {                              # reset focus to current (last set) entry
 	my ($widget) = get();
-	Kephra::App::Util::is_widget($widget)
+	is_widget($widget)
 		? Wx::Window::SetFocus( $widget )
 		: Kephra::Log::warning( "no widget to stay focussed on", 1 );
 }

File lib/Kephra/App/Frame.pm

 sub refresh_title {
 	my $self = shift;
 	my $doc = Kephra::API::document();
+	return $self->set_title( $title_end ) unless defined $doc and $doc;
+
 	my $title = $doc->title;
 	$title .= ' ('.$doc->file_path.')' if $doc->file_path;
 	$self->set_title( $title . " - $title_end" );

File lib/Kephra/App/Part/Editor.pm

 
 package Kephra::App::Part::Editor;
 our @ISA = 'Kephra::App::Panel';
-my ($active_bar, @passive_bar, $panel);
+my ($active_bar, @passive_bar, $panel, %splitter);
 use Scalar::Util qw(blessed);
 
 Kephra::API::Command::register({
  'docbar-prev' =>{sub=>'select_docbar_prev', label=>'Prev Docbar',  keys=>'alt+pageup'},
  'docbar-next' =>{sub=>'select_docbar_next', label=>'Next Docbar',  keys=>'alt+pagedown'},
+ 'docbar-del' =>{sub=>'select_docbar_del', label=>'Next Docbar',  keys=>'ctrl+alt+pageup'},
+ 'docbar-add' =>{sub=>'select_docbar_add', label=>'Prev Docbar',  keys=>'ctrl+alt+pagedown'},
 });
 
 
 sub docbar         { $active_bar }
 sub passive_docbars{ @passive_bar}
-sub all_docbars    { ($active_bar, @passive_bar) }
+sub all_docbars    { $active_bar, @passive_bar }
 
 sub new {
 	my( $class, $parent) = @_;
 	my $db  = Kephra::App::Bar::Document->new($self);
 	my $db2 = Kephra::App::Bar::Document->new($self);
 
-	my $splitter = Kephra::App::Splitter->new
+	my $splitter = $splitter{'main'} = Kephra::App::Splitter->new
 		({parent => $self, left => $db, right => $db2, dominant_child => 'left'});
 	$self->append( \$splitter );
 	$splitter->resize('equal');
 
 	$active_bar = $db;
 	@passive_bar = ($db2);
+say $active_bar;
 
 	$self;
 }
 
+sub select_docbar_del {
+	my $docbar_count = scalar @passive_bar + 1;
+	return if $docbar_count < 2;
+	if    ($docbar_count == 4){
+		
+	}
+	elsif ($docbar_count == 3){
+		
+	}
+	elsif ($docbar_count == 2){
+		$splitter{'main'}->set({dominant_child => $active_bar});
+		$splitter{'main'}->unsplit();
+	}
+	$passive_bar[-1]->Destroy();
+	delete $passive_bar[-1];
+}
+sub select_docbar_add {
+	my $docbar_count = scalar @passive_bar + 1;
+	return if $docbar_count > 3;
+	if    ($docbar_count == 3){
+		
+	}
+	elsif ($docbar_count == 2){
+		
+	}
+	elsif ($docbar_count == 1){
+		$passive_bar[0]->Show(1);
+		$splitter{'main'}->resplit();
+	}
+}
+
 sub select_docbar_next {
 	push @passive_bar, $active_bar;
 	$active_bar = shift @passive_bar;
 }
 
 
-sub switch_bar{
-	
-}
-
 sub refresh_doc_label {
 	my $doc = shift // Kephra::API::document();
+	return unless Kephra::API::Doc::is($doc);
 	my $unsaved_mark = '*';
 
 	my $title = $doc->title;

File lib/Kephra/App/Splitter.pm

 		if $self->{'dominant_child'} eq 'left' or $self->{'dominant_child'} eq 'top';
 	$self->{'dominant_child'} = 2
 		if $self->{'dominant_child'} eq 'right' or $self->{'dominant_child'} eq 'bottom';
+	$self->{'dominant_child'} = 1 if $self->{'dominant_child'} eq $self->{'child1'};
+	$self->{'dominant_child'} = 2 if $self->{'dominant_child'} eq $self->{'child2'};
 	$self->{'dominant_child'} = 1 
 		unless $self->{'dominant_child'} eq 1 or $self->{'dominant_child'} eq 2;
 
 	} else { 
 		$self->SplitVertically( $self->{'child1'}, $self->{'child2'}, $self->{'position'} )
 	}
+	$self->UpdateSize;
 }
 
 sub unsplit {
 	my $self = shift;
+	$self->{'position'} = $self->GetSashPosition;
 	$self->Unsplit if $self->IsSplit;
 	return Kephra::Log::error("can't initialize with a not existing child widget")
 		if $self->{'dominant_child'} == 1 and not $self->{'child1'}
 		or $self->{'dominant_child'} == 2 and not $self->{'child2'};
 	$self->Initialize( $self->{'child2'} ) if $self->{'dominant_child'} == 2;
-	$self->UpdateSize;
 	Kephra::App::Focus::stay();
 }
 

File lib/Kephra/Document.pm

 
 package Kephra::Document;
 use Moo; 
+use Scalar::Util qw(blessed);
+
 my $max_title_width = 15;
 
 # export SUB_QUOTE_DEBUG=1
 
 
-has ID     => ( is  => 'rwp' );                             # API::Docs ID
+has ID     => ( is  => 'rwp' );                             # API::Doc ID
 has title  => ( is  => 'rwp' );                             # shown as tab label
 has editor => ( is  => 'ro' );
 has panel  => ( is  => 'ro' );
 		my $self = shift;
 		return if $self->old_file_path and $self->file_path
 				and $self->old_file_path eq $self->file_path;
-		Kephra::API::Docs::rename_file($self) if $self->ID;
+		Kephra::API::Doc::rename_file($self) if $self->ID;
 
 		if ($self->file_path) {
 			my @path_parts = File::Spec->splitpath( $self->file_path );
 
 sub BUILD    {
 	my $self = shift;
-	$self->_set_ID( Kephra::API::Docs::add($self) );
+	$self->_set_ID( Kephra::API::Doc::add($self) );
 	$self->_set_title('<untitled '.$self->anon_NR.'>') unless $self->file_path;
 }
-sub DEMOLISH { Kephra::API::Docs::remove($_[0]); #say "demolish $_[0]"; 
+sub DEMOLISH { Kephra::API::Doc::remove($_[0]); #say "demolish $_[0]"; 
 }
 
+sub add_instance {
+	my ($self, $bar) = @_;
+	return Kephra::Log::warning("need an existing Kephra::App::Bar::Document instance")
+		unless blessed($bar) eq 'Kephra::App::Bar::Document';
+
+	my @editor = values $self->editor;
+	my $panel = $self->panel->{$bar} = Kephra::App::Panel->new( $bar );
+	my $ed = $self->editor->{$bar} = Kephra::App::Editor->new( $panel );
+	$panel->append( \$ed );
+	$ed->SetDocPointer( $editor[0]->GetDocPointer() ) if @editor;
+	Kephra::API::Doc::add_instance($self, $bar);
+}
+
+sub del_instance {
+	my ($self, $bar) = @_;
+	return Kephra::Log::warning("need an existing Kephra::App::Bar::Document instance")
+		unless blessed($bar) eq 'Kephra::App::Bar::Document'
+		and exists $self->panel->{$bar};
+	Kephra::API::Doc::remove_instance($self, $bar);
+	$bar->remove_page( $self->panel->{$bar} );
+	delete $self->panel->{$bar};
+	delete $self->editor->{$bar};
+}
 sub raise { Kephra::API::focus( shift->panel ) }
 sub insert_before_caret {}
 sub insert_after_caret {}

File lib/edpart.pl

 
 	Kephra::File::new();
 	Kephra::API::focus( Kephra::API::editor() );
+say Kephra::API::editor();
+#say Kephra::API::editor()->GetParent->GetParent;
 
 	$win->Center();
 	$win->Show(1);