File Coverage

lib/Devel/ebug/Wx/View/Code/STC.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Devel::ebug::Wx::View::Code::STC;
2              
3 1     1   542 use Wx::STC;
  0            
  0            
4              
5             # FIXME split in a fully-fledged view linked to the code display service
6             # and a simple code-edit/display control
7             use strict;
8             use base qw(Wx::StyledTextCtrl Devel::ebug::Wx::View::Base
9             Devel::ebug::Wx::Plugin::Configurable::Base);
10             use Devel::ebug::Wx::Plugin qw(:plugin);
11              
12             __PACKAGE__->mk_accessors( qw(filename line highlighted_line) );
13              
14             use Wx qw(:stc :font);
15             use Wx::Event qw(EVT_CHAR EVT_STC_MARGINCLICK EVT_RIGHT_UP);
16              
17             use constant { CURRENT_LINE => 2,
18             BREAKPOINT => 1,
19             BACKGROUND => 3,
20             };
21              
22             sub tag { 'code_stc' }
23              
24             sub new {
25             my( $class, $parent, $wxebug ) = @_;
26             my $self = $class->SUPER::new( $parent, -1 );
27              
28             $self->filename( '' );
29             $self->line( -1 );
30             $self->highlighted_line( 0 );
31             $self->wxebug( $wxebug );
32              
33             $self->subscribe_ebug( 'file_changed', sub { $self->_show_code( @_ ) } );
34             $self->subscribe_ebug( 'line_changed', sub { $self->_show_line( @_ ) } );
35             $self->subscribe_ebug( 'break_point', sub { $self->_break_point( @_ ) } );
36             $self->subscribe_ebug( 'break_point_delete', sub { $self->_break_point( @_ ) } );
37             $self->subscribe_ebug( 'load_program_state', sub { $self->_change_state( @_ ) } );
38              
39             $self->register_configurable;
40             $self->_setup_stc( $self->get_configuration
41             ( $self->wxebug->service_manager ) );
42              
43             return $self;
44             }
45              
46             sub _change_state {
47             my( $self ) = @_;
48              
49             $self->show_break_point( $_ )
50             foreach $self->ebug->break_points( $self->filename );
51             }
52              
53             sub _break_point {
54             my( $self, $ebug, $event, %params ) = @_;
55              
56             return unless $params{file} eq $self->filename;
57             if( $event eq 'break_point' ) {
58             $self->show_break_point( $params{line} );
59             } elsif( $event eq 'break_point_delete' ) {
60             $self->hide_break_point( $params{line} );
61             }
62             }
63              
64             sub show_break_point {
65             my( $self, $line ) = @_;
66              
67             $self->MarkerAdd( $line - 1, BREAKPOINT );
68             }
69              
70             sub hide_break_point {
71             my( $self, $line ) = @_;
72              
73             $self->MarkerDelete( $line - 1, BREAKPOINT );
74             }
75              
76             sub _show_code {
77             my( $self, $ebug, $event, %params ) = @_;
78              
79             $self->show_code_for_file( $ebug->filename );
80             }
81              
82             sub show_code_for_file {
83             my( $self, $filename ) = @_;
84              
85             $self->SetReadOnly( 0 );
86             $self->SetText( join "\n", $self->ebug->codelines( $filename ) );
87             $self->SetReadOnly( 1 );
88             $self->filename( $filename );
89             $self->show_break_point( $_ )
90             foreach $self->ebug->break_points( $filename );
91             $self->highlighted_line( 0 );
92             }
93              
94             sub _show_line {
95             my( $self, $ebug, $event, %params ) = @_;
96              
97             $self->show_current_line;
98             }
99              
100             sub show_current_line {
101             my( $self ) = @_;
102             my $line = $self->ebug->line;
103              
104             if( $self->filename ne $self->ebug->filename ) {
105             $self->show_code_for_file( $self->ebug->filename );
106             }
107             if( $self->line >= 0 ) {
108             $self->MarkerDelete( $self->line - 1, CURRENT_LINE );
109             }
110             $self->line( $line );
111             $self->MarkerAdd( $line - 1, CURRENT_LINE );
112             $self->EnsureVisibleEnforcePolicy( $line - 1 );
113             }
114              
115             # FIXME split in two methods
116             sub highlight_line {
117             my( $self, $file, $line ) = @_;
118              
119             if( $self->filename ne $file ) {
120             $self->show_code_for_file( $file );
121             }
122             $self->MarkerDelete( $self->highlighted_line - 1, BACKGROUND )
123             if $self->highlighted_line;
124             $self->MarkerAdd( $line - 1, BACKGROUND );
125             $self->EnsureVisibleEnforcePolicy( $line - 1 );
126             $self->highlighted_line( $line );
127             }
128              
129             # FIXME finish moving to configuration
130             sub _setup_stc {
131             my( $self, $configuration ) = @_;
132             my $font = Wx::Font->new( 10, wxTELETYPE, wxNORMAL, wxNORMAL );
133              
134             $self->SetFont( $font );
135             $self->StyleSetFont( wxSTC_STYLE_DEFAULT, $font );
136             $self->StyleClearAll();
137              
138             $self->apply_configuration( $configuration );
139              
140             $self->SetLexer( wxSTC_LEX_PERL );
141              
142             $self->MarkerDefine( CURRENT_LINE, 2, Wx::wxGREEN, Wx::wxNullColour );
143             $self->MarkerDefine( BREAKPOINT , 0, Wx::wxBLUE, Wx::wxNullColour );
144             $self->MarkerDefine( BACKGROUND , 22, Wx::wxNullColour, Wx::Colour->new( 0x90, 0x90, 0x90 ) );
145              
146             $self->SetReadOnly( 1 );
147             $self->SetMarginSensitive( 1, 1 );
148              
149             # FIXME: move to code display service
150             EVT_STC_MARGINCLICK( $self, $self, sub { $self->_set_bp( $_[1] ) } );
151             EVT_CHAR( $self, sub {
152             $self->wxebug->command_manager_service->handle_key( $_[1]->GetKeyCode );
153             } );
154             # FIXME add context menu
155             EVT_RIGHT_UP( $self, sub {
156             warn $_[1]->GetX, ' ', $_[1]->GetY;
157             warn $self->GetMarginWidth( 1 );
158             warn $self->PositionFromPointClose($_[1]->GetX, $_[1]->GetY);
159             } );
160             }
161              
162             sub _has_marker {
163             my( $self, $line, $marker ) = @_;
164              
165             return $self->MarkerGet( $line ) & ( 1 << $marker );
166             }
167              
168             sub _set_bp {
169             my( $self, $e ) = @_;
170             my $stc_line = $self->LineFromPosition( $e->GetPosition );
171             my $has_bp = $self->_has_marker( $stc_line, BREAKPOINT );
172              
173             if( $has_bp ) {
174             $self->ebug->break_point_delete( $self->filename, $stc_line + 1 );
175             } else {
176             $self->ebug->break_point( $self->filename, $stc_line + 1 );
177             }
178             }
179              
180             sub _constant {
181             my( $k ) = @_;
182              
183             no strict 'refs';
184             return &{"Wx::wxSTC_PL_" . uc( $k )}();
185             }
186              
187             no warnings qw(qw);
188             my @style_keys =
189             ( qw(default error commentline pod number word string character
190             punctuation preprocessor operator identifier scalar array regex
191             regsubst)
192             );
193             my @defaults =
194             ( qw(fore:#00007f fore:#ff0000 fore:#007f00 fore:#7f7f7f fore:#007f7f
195             fore:#00007f fore:#ff7f00 fore:#7f007f fore:#000000 fore:#7f7f7f
196             fore:#00007f fore:#00007f fore:#7f007f,bold fore:#4080ff,bold
197             fore:#ff007f fore:#7f7f00)
198             );
199              
200             sub get_configuration_keys {
201             my( $class ) = @_;
202              
203             my @keys = map { key => $style_keys[$_],
204             type => 'string',
205             label => ucfirst( $style_keys[$_] ),
206             default => $defaults[$_],
207             },
208             ( 0 .. $#style_keys );
209             return { label => 'Code display',
210             section => 'code_stc_view',
211             keys => \@keys,
212             };
213             }
214              
215             sub configuration : Configurable {
216             my( $class ) = @_;
217              
218             return { configurable => __PACKAGE__,
219             configurator => 'configuration_simple',
220             };
221             }
222              
223             sub apply_configuration {
224             my( $self, $data ) = @_;
225              
226             foreach my $key ( @{$data->{keys}} ) {
227             $self->StyleSetSpec( _constant( $key->{key} ), $key->{value} );
228             }
229             }
230              
231             1;