App-Music-ChordPro
view release on metacpan or search on metacpan
lib/ChordPro/Wx/Editor.pm view on Meta::CPAN
#! perl
use v5.26;
use feature 'signatures';
no warnings 'experimental::signatures';
use utf8;
use Wx ':everything';
package ChordPro::Wx::Editor;
use ChordPro::Wx::Config;
use ChordPro::Wx::Utils;
sub new( $class, $parent, $id ) {
my $widget;
$::options->{stc} //= 1;
if ( $::options->{stc} && eval { require Wx::STC; 1 } ) {
# if ( $::options->{stc} && eval { require Wx::Scintilla; 1 } ) {
$widget = Wx::StyledTextCtrl->new($parent);
# $widget = Wx::Scintilla::TextCtrl->new($parent);
$state{have_stc} = 1;
return bless $widget => 'ChordPro::Wx::STCEditor';
}
# Emergency fallback.
$state{have_stc} = 0;
ChordPro::Wx::TextEditor->new($parent);
}
package ChordPro::Wx::STCEditor;
use parent qw( -norequire Wx::StyledTextCtrl );
#use parent qw( -norequire Wx::Scintilla::TextCtrl );
use Wx ':everything';
use ChordPro::Wx::Config;
use ChordPro::Wx::Utils;
sub refresh( $self, $prefs = undef ) {
my $stc = $self;
$prefs //= \%preferences;
# RTI loading is currently too slow.
# $state{rti} = ChordPro::runtime_info();
$state{rti}->{directive_abbrevs} = ChordPro::Song::_directive_abbrevs();
$stc->SetLexer(wxSTC_LEX_CONTAINER);
$stc->SetKeyWords(0,
[qw( album arranger artist capo chord chorus
column_break columns comment comment_box
comment_italic composer copyright define
diagrams duration end_of_bridge end_of_chorus
end_of_grid end_of_tab end_of_verse grid
highlight image key lyricist meta new_page
new_physical_page new_song no_grid pagesize
pagetype sorttitle start_of_bridge
start_of_chorus start_of_grid start_of_tab
start_of_verse subtitle tempo time title
titles transpose year )
]);
Wx::Event::EVT_STC_STYLENEEDED( $stc, wxID_ANY,
sub { OnStyleNeeded($self, $_[1]) } );
Wx::Event::EVT_STC_CHANGE( $stc, wxID_ANY,
sub { OnChanged($self, $_[1]) } );
$self->SetModEventMask(0x01|0x02|0x10);
my $theme = $state{editortheme};
my $c = $prefs->{editcolour}{$theme};
my $fg = Wx::Colour->new($c->{fg});
my $bg = Wx::Colour->new($c->{bg});
$stc->SetBackgroundColour($bg);
$stc->SetCaretForeground($fg);
$stc->StyleSetForeground( wxSTC_STYLE_DEFAULT, $fg );
$stc->StyleSetBackground( wxSTC_STYLE_DEFAULT, $bg );
$stc->StyleClearAll;
# 0 - basic
$stc->StyleSetForeground( 0, $fg );
$stc->StyleSetBackground( 0, $bg );
# 1 - comments (grey)
$stc->StyleSetForeground( 1, Wx::Colour->new($c->{s1}) );
$stc->StyleSetBackground( 1, $bg );
# 2 - Keywords (grey)
$stc->StyleSetForeground( 2, Wx::Colour->new($c->{s2}) );
$stc->StyleSetBackground( 2, $bg );
# 3 - Brackets (grey)
$stc->StyleSetForeground( 3, Wx::Colour->new($c->{s3}) );
$stc->StyleSetBackground( 3, $bg );
# 4 - Chords (red)
$stc->StyleSetForeground( 4, Wx::Colour->new($c->{s4}) );
$stc->StyleSetBackground( 4, $bg );
# 5 - Directives (blue, same as status label colour)
$stc->StyleSetForeground( 5, Wx::Colour->new($c->{s5}) );
$stc->StyleSetBackground( 5, $bg );
# 6 - Directive arguments (orange, same as toolbar icon colour)
$stc->StyleSetForeground( 6, Wx::Colour->new($c->{s6}) );
$stc->StyleSetBackground( 6, $bg );
# 7 - Errors
$stc->StyleSetForeground( 7, $fg );
$stc->StyleSetBackground( 7, wxRED );
# For linenumbers.
$stc->StyleSetForeground( wxSTC_STYLE_LINENUMBER,
Wx::Colour->new( $c->{numfg} ) );
$stc->StyleSetBackground( wxSTC_STYLE_LINENUMBER,
Wx::Colour->new( $c->{numbg} ) );
# For annotations.
$self->{astyle} //= 1 + wxSTC_STYLE_LASTPREDEFINED;
$stc->StyleSetBackground( $self->{astyle}, Wx::Colour->new($c->{annbg}) );
$stc->StyleSetForeground( $self->{astyle}, Wx::Colour->new($c->{annfg}) );
$stc->SetFont( Wx::Font->new($prefs->{editfont}) );
# Wrapping.
if ( $prefs->{editorwrap} ) {
$stc->SetWrapMode(3); # wxSTC_WRAP_WHITESPACE );
$stc->SetWrapStartIndent( $prefs->{editorwrapindent} );
}
else {
$stc->SetWrapMode(0); # wxSTC_WRAP_NONE );
}
$self->style_text;
# Expert...
$stc->SetViewEOL( $state{vieweol} );
$stc->SetViewWhiteSpace( $state{viewws} );
$stc->SetViewLineNumbers(1);
# Free Ctrl-Shift-U for iBus input (doesn't work).
# $stc->CmdKeyClear( ord('U'), 3 ); # Ctrl-Shift-U
}
sub SetViewLineNumbers( $self, $b ) {
$self->SetMarginWidth( 0, $b ? 40 : 0 ); # TODO length
if ( $self->can("SetMarginBackground") ) { # wxPerl 3.005
$self->SetMarginType( 1, wxSTC_MARGIN_SYMBOL|wxSTC_MARGIN_COLOUR );
$self->SetMarginWidth( 1, 3 );
my $theme = $state{editortheme};
my $c = $preferences{editcolour}{$theme};
my $bg = Wx::Colour->new($c->{bg});
$self->SetMarginBackground( 1, $bg );
}
else {
$self->SetMarginWidth( 1, 0 );
}
}
sub style_text( $self ) {
my $stc = $self;
# Scintilla uses byte indices.
require Encode;
my $text = Encode::encode_utf8($stc->GetText);
my $style = sub {
my ( $re, @styles ) = @_;
pos($text) = 0;
while ( $text =~ m/$re/g ) {
my @s = @styles;
die("!!! ", scalar(@{^CAPTURE}), ' ', scalar(@s)) unless @s == @{^CAPTURE};
my $end = pos($text);
my $start = $end - length($&);
my $group = 0;
while ( $start < $end ) {
my $l = length(${^CAPTURE[$group++]});
if ( $Wx::VERSION < 3.006 ) {
$stc->StartStyling( $start, 0 );
}
else {
$stc->StartStyling( $start );
}
$stc->SetStyling( $l, shift(@s) );
$start += $l;
}
}
};
lib/ChordPro/Wx/Editor.pm view on Meta::CPAN
sub SetModified( $self, $mod ) {
if ( $mod ) {
$self->{_modified} = 1;
}
else {
$self->DiscardEdits;
}
}
sub SetFont( $self, $font ) {
die("XXX\n") unless $font->IsOk;
$self->StyleSetFont( $_, $font ) for 0..7;
$self->{font} = $font;
}
sub GetFont( $self ) {
$self->{font} // $self->StyleGetFont(0);
}
sub OSXDisableAllSmartSubstitutions( $self ) {
}
sub OnStyleNeeded( $self, $event ) { # scintilla
$self->style_text;
}
sub OnChanged( $self, $event ) { # scintilla
$state{editchanged}++;
}
sub Replace( $self, $from=-1, $to=-1, $text="" ) {
# We will only call this to replace the selection.
$self->ReplaceSelection($text);
}
# STC::Remove is missing...
sub Remove( $self, $from=-1, $to=-1 ) {
$self->Replace( $from, $to, "" );
}
################ Methods ################
package ChordPro::Wx::TextEditor;
use parent qw( -norequire Wx::TextCtrl );
use Wx ':everything';
use ChordPro::Files;
use ChordPro::Wx::Config;
use ChordPro::Wx::Utils;
sub new( $class, $parent, $id=undef ) {
my $self = $class->SUPER::new( $parent, wxID_ANY, "",
wxDefaultPosition, wxDefaultSize,
wxHSCROLL|wxTE_MULTILINE );
return $self;
}
sub refresh( $self, $prefs = undef ) {
my $ctrl = $self;
$prefs //= \%preferences;
my $mod = $self->IsModified;
# TextCtrl only supports background colour and font.
my $theme = $prefs->{editortheme};
my $c = $prefs->{editcolour}{$theme};
my $bgcol = Wx::Colour->new( $c->{bg} );
my $fgcol = Wx::Colour->new( $c->{fg} );
$ctrl->SetBackgroundColour($bgcol);
$ctrl->SetStyle( 0, $ctrl->GetLastPosition,
Wx::TextAttr->new( $fgcol, $bgcol ) );
$ctrl->SetFont( Wx::Font->new($prefs->{editfont}) );
$ctrl->SetModified($mod);
}
sub AddText( $self, $text ) {
$self->WriteText($text);
}
sub GetLineCount( $self ) {
$self->GetNumberOfLines;
}
sub GetSelectedText( $self ) {
$self->GetStringSelection;
}
sub GetText( $self ) {
$self->GetValue;
}
sub SetText( $self, $text ) {
$self->SetValue($text);
}
sub SetColour( $self, $colour ) {
$self->SetStyle( 0, $self->GetLastPosition,
Wx::TextAttr->new( Wx::Colour->new($colour) ) );
}
sub SetViewLineNumbers( $self, $b ) {
}
sub EmptyUndoBuffer($self) {
}
sub OSXDisableAllSmartSubstitutions( $self ) {
return unless is_macos;
$self->SUPER::OSXDisableAllSmartSubstitutions;
}
################
1;
( run in 1.140 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )