Source

Kephra / lib / Kephra / App / Panel / IOUnit.pm

use strict;
use warnings;
use Wx::AUI;
use Wx::Perl::ProcessStream;
use Kephra::API;

package Kephra::App::Panel::IOUnit;
our @ISA = 'Wx::Panel';
our $_ref;

Kephra::CommandList::register_cmd_namespace('iounit');
Kephra::CommandList::register_cmd({'+-focus'=>{sub=>'focus_on_input', label => ' ', keys => 'esc'},});
Kephra::KeyMap::register_map({'iounit'=>{'esc' => 1, 'window-fullscreen-toggle' => '' } });


sub new {
	my( $class, $parent) = @_;
	my $self = $_ref = $class->SUPER::new($parent, -1);
	$self->{'input'} = my $input = Wx::TextCtrl->new
		($self, -1, '', [-1,-1], [-1, -1], &Wx::wxTE_PROCESS_ENTER );
	$self->{'output_book'} = my $output_book = Wx::Notebook->new (
		$self, -1, [-1,-1], [-1, -1], &Wx::wxNB_TOP
	);
	$self->{'output_slots'} = {};
	$self->{'master_slot_name'} = 'all';
	$self->{'active_slot_name'} = 'drum';
	$self->{'process'} = '';

	$self->create_slot($_) for ($self->{'master_slot_name'}, qw/drum perl shell output log warn/);
	$self->raise_slot( $self->{'active_slot_name'} );

	Wx::Event::EVT_SET_FOCUS($output_book, sub {$self->focus_on_input} );
	Wx::Event::EVT_NOTEBOOK_PAGE_CHANGED( $output_book, -1, sub {
		my ($nb, $event ) = @_;
		$self->{'active_slot_name'} = $nb->GetPageText( $event->GetSelection );
	});
	Wx::Event::EVT_TEXT_ENTER($input, -1, sub {
		my ($input, $event ) = @_;
		my $cmd = $input->GetValue;
		$input->Clear;
		my $active_name = $self->{'active_slot_name'};
		return unless $active_name eq 'drum'
				   or $active_name eq 'perl'
				   or $active_name eq 'shell'
				   or $active_name eq 'output';
		$self->output_line('log',"$active_name command $cmd");
		my $outxt = $self->{'output_slots'}{ $active_name };
		if    ($active_name eq 'drum')  { 
		}
		elsif ($active_name eq 'perl')  { 
			$self->output_line ('perl',  $cmd . ' => "' . eval($cmd) . '"' );
		}
		elsif ($active_name eq 'shell') { 
			$self->{'process'} = Wx::Perl::ProcessStream->OpenProcess
				(qq~bash "$cmd"~ , __PACKAGE__, $self->{'output_slots'}{'shell'});
		}
	});
	Wx::Perl::ProcessStream::EVT_WXP_PROCESS_STREAM_STDOUT(
		$self->{'output_slots'}{'shell'}, sub {
			my ($txt, $event) = @_;
			$event->Skip(1);
			$self->output_line('shell', $event->GetLine );
	} );

	Wx::Event::EVT_KEY_DOWN ($input, sub {
		my ($input, $event) = @_;
		my $key = Kephra::KeyMap::code_from_event($event);
		Kephra::API::log("pressed key $key inside the IOUnit");

		my $slot = $self->{'output_slots'}{ $self->{'active_slot_name'} };

		if    ($key ==  0)                     {  }
		elsif ($key ==  &Wx::WXK_UP     + 2000){
		#$txt->MoveUp(1,0);
		#print $txt->HitTest([12,5]),"\n";
		#$txt->SetCaretPosition(  ); 
		#$txt->ScrollIntoView( $txt->HitTest([12,5])-1, &Wx::WXK_UP);
			$slot->PageUp( 1, &Wx::WXK_UP);
			$slot->ShowPosition( $slot->GetCaretPosition )
		}
		elsif ($key ==  &Wx::WXK_UP     + 3000){$slot->ShowPosition(0)}
		elsif ($key ==  &Wx::WXK_DOWN   + 2000){$slot->PageDown(1,0) }
		elsif ($key ==  &Wx::WXK_DOWN   + 3000){$slot->ShowPosition($slot->GetLastPosition-1) }
		elsif ($key ==  &Wx::WXK_PAGEUP + 2000){$output_book->AdvanceSelection(0)}
		#elsif ($key ==  &Wx::WXK_PAGEUP + 3000){Kephra::App::Panel::Editor::select_tab_leftmost()  }
		#elsif ($key ==  &Wx::WXK_PAGEUP + 4000){Kephra::App::Panel::Editor::move_tab_left()  }
		#elsif ($key ==  &Wx::WXK_PAGEUP + 5000){Kephra::App::Panel::Editor::move_tab_leftmost()  }
		elsif ($key ==  &Wx::WXK_PAGEDOWN+2000){$output_book->AdvanceSelection(1)}
		#elsif ($key ==  &Wx::WXK_PAGEDOWN+3000){Kephra::App::Panel::Editor::select_tab_rightmost()}
		#elsif ($key ==  &Wx::WXK_PAGEDOWN+4000){Kephra::App::Panel::Editor::move_tab_right()}
		#elsif ($key ==  &Wx::WXK_PAGEDOWN+5000){Kephra::App::Panel::Editor::move_tab_rightmost()}
		elsif ($key ==  &Wx::WXK_F2)           {Kephra::App::Panel::FileBrowser::focus() } 
		elsif ($key ==  &Wx::WXK_F11)          {Kephra::API::main_window()->toggle_fullscreen() } 
		elsif ($key ==  &Wx::WXK_ESCAPE)       {Kephra::API::editor()->focus() } 
		elsif ($key ==  &Wx::WXK_TAB    + 2000){Kephra::API::editor()->focus() } # SHIFT LOCK
		elsif ($key ==  ord('Q')        + 2000){Kephra::File::close_active() }
		elsif ($key ==  ord('Q')        + 4000){Kephra::API::app()->close_save }
		else {$event->Skip}
	});

	my $sizer = Wx::BoxSizer->new( &Wx::wxVERTICAL );
	$sizer->Add( $output_book, 1, &Wx::wxGROW);
	$sizer->Add( $input,  0, &Wx::wxGROW);
	$self->SetSizer( $sizer );

	return $self;
}

sub create_slot {
	my ($self, $slot_name) = @_;
	die __PACKAGE__ . "::create_slot: wanted to creat already existing output slot"
		if exists $self->{'output_slots'}{ $slot_name };
	my $slot = $self->{'output_slots'}{ $slot_name } = Wx::RichTextCtrl->new(
		$self->{'output_book'}, -1, '', [-1,-1], [-1,-1],
		&Wx::wxTE_MULTILINE | &Wx::wxTE_READONLY
	);
	# put new pages on second last pos, because all is on last
	my $pos = $self->{'output_book'}->GetPageCount;
	$pos-- if $pos;
	$self->{'output_book'}->InsertPage ( $pos, $slot, $slot_name, 0 );
	Wx::Event::EVT_SET_FOCUS($slot, sub { $self->focus_on_input });
}

sub output {
	my ($self, $slot_name, $msg, $raise) = @_;
	return unless defined $self->{'output_slots'}{ $slot_name };
	my $slot = $self->{'output_slots'}{ $slot_name };
	my $stamped_msg = Kephra::Log::timestamp() . ' ' . $msg;
	if ($slot_name eq 'log') {
		$slot->AppendText("\n") if $slot->GetValue;
		$slot->AppendText($stamped_msg);
	}
	else                     { $slot->AppendText($msg) }
	$slot->ShowPosition( $slot->GetCaretPosition );
	unless ($slot_name eq $self->{'master_slot_name'}) {
		my $masterslot =  $self->{'output_slots'}{ $self->{'master_slot_name'} };
		$masterslot->AppendText("\n") if $masterslot->GetValue;
		$masterslot->AppendText("<$slot_name> $stamped_msg");
		$masterslot->ShowPosition( $masterslot->GetCaretPosition);
	}
	$self->raise_slot($slot_name) if $raise;
}
sub output_string { $_[0]->output(@_) }
sub output_line {
	my $self = shift;
	my ($slot_name, $msg) = @_;
	return unless defined $self->{'output_slots'}{ $slot_name };
	my $slot = $self->{'output_slots'}{ $slot_name };
	my ($x, $y) = $slot->GetLastPosition;
	$slot->AppendText("\n")
		if ($slot_name ne 'log' and $slot_name ne $self->{'master_slot_name'})
		and $slot->GetValue     and $x > 0;
	$self->output(@_);
}
sub output_on_clear_and_raised {
	my ($self, $slot_name, $msg) = @_;
	return unless defined $self->{'output_slots'}{ $slot_name };
	$self->raise_slot($slot_name);
	$self->{'output_slots'}{ $slot_name }->Clear;
	$self->output(@_);
}

sub raise_slot {
	my ($self, $slot_name) = @_;
	return unless defined $self->{'output_slots'}{ $slot_name };
	my $nb = $self->{'output_book'};
	my $page = $self->{'output_slots'}{ $slot_name };
	for (0 .. $nb->GetPageCount-1) {
		$nb->ChangeSelection( $_ ),last if $nb->GetPage($_) eq $page;
	}
	Kephra::API::focus_back();
}
sub focus_on_input { Kephra::API::focus( $_ref->{'input'} ) }

sub get_line  {}
sub get_click {}

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.