Skip to content

Commit

Permalink
ADDED: accept multiple escape keys
Browse files Browse the repository at this point in the history
  • Loading branch information
nkh committed Nov 26, 2023
1 parent 4d7ab29 commit c431260
Show file tree
Hide file tree
Showing 13 changed files with 298 additions and 225 deletions.
1 change: 1 addition & 0 deletions Build.PL
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ lib/App/Asciio/Actions/Mouse.pm
lib/App/Asciio/Actions/Multiwirl.pm
lib/App/Asciio/Actions/Presentation.pm
lib/App/Asciio/Actions/Ruler.pm
lib/App/Asciio/Actions/Selection.pm
lib/App/Asciio/Actions/Shapes.pm
lib/App/Asciio/Actions/Unsorted.pm
lib/App/Asciio/Actions/ZBuffer.pm
Expand Down
1 change: 1 addition & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ lib/App/Asciio/Actions/Mouse.pm
lib/App/Asciio/Actions/Multiwirl.pm
lib/App/Asciio/Actions/Presentation.pm
lib/App/Asciio/Actions/Ruler.pm
lib/App/Asciio/Actions/Selection.pm
lib/App/Asciio/Actions/Shapes.pm
lib/App/Asciio/Actions/Unsorted.pm
lib/App/Asciio/Actions/ZBuffer.pm
Expand Down
33 changes: 16 additions & 17 deletions documentation/mdbook_asciio/src/for_developers/bindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,26 @@ Goals when adding bindings:

- sort by name or key if possible

## Binding Groups

```perl

'Cross element Insert leader' =>
'<< selection leader >>' =>
{
SHORTCUTS => '000-x',
SHORTCUTS => '000-r', # also accepts multiple entries in an array ref
ENTER_GROUP => \&App::Asciio::Actions::Selection::selection_enter,
ESCAPE_KEYS => [ '000-r', '000-Escape' ], # also accepts single entry

# ESCAPE_KEYS need to be define of group will catch input untill an action is selected

'Add cross angled arrow' => ['A'],
'Add cross arrow' => ['a'],
'Add cross box' => ['b'],
'Add cross exec box' => ['e'],

'Select cross elements' => ['c'],
'Select cross filler elements' => ['f'],
'Select normal elements' => ['C'],
'Select normal filler elements' => ['F'],

'Add cross unicode line 2' => ['i'],
'Add cross unicode line 3' => ['I'],
'Change to cross elements' => ['s'],
'Change to normal elements' => ['S'],
# same keys as the ESCAPE_KEYS, will be called on exit
'Selection escape' => [ '000-r', \&App::Asciio::Actions::Selection::selection_escape ],
'Selection escape2' => [ '000-Escape', \&App::Asciio::Actions::Selection::selection_escape ],

# simple action
'select flip mode' => [ '000-f', \&App::Asciio::Actions::Selection::selection_mode_flip ],

# handle mouse movement
'select motion' => [ '000-motion_notify', \&App::Asciio::Actions::Selection::select_elements ],
},
```

Expand Down
115 changes: 35 additions & 80 deletions lib/App/Asciio/Actions.pm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use strict ; use warnings ;

use Encode ;
use List::Util qw(max) ;
use List::MoreUtils qw(any) ;

#------------------------------------------------------------------------------------------------------

Expand All @@ -16,30 +17,19 @@ sub use_action_group
{
my ($self, $action) = @_ ; ;

$self->{CURRENT_ACTIONS} = $self->{ACTIONS} ;
$self->run_actions($action) ;
$self->{CROSS_ACTION_GROUP}++ ;
$self->{CURRENT_ACTIONS} = $self->{ACTIONS}{$action} ;
}

sub create_binding_completions
sub show_binding_completions
{
my ($self, $keep_visible) = @_ ;

if($self->{USE_BINDINGS_COMPLETION})
{
my $binding_max_length =
max map { length }
grep {
$_ ne 'IS_GROUP'
&& $_ ne 'ENTER_GROUP'
&& $_ ne 'ESCAPE_KEY'
&& $_ ne 'NAME'
&& $_ ne 'SHORTCUTS'
&& $_ ne 'ORIGIN'
&& $_ ne 'CODE'
}
keys $self->{CURRENT_ACTIONS}->%* ;

my %reserved = map { $_ => 1 } qw(IS_GROUP ENTER_GROUP ESCAPE_KEYS NAME SHORTCUTS ORIGIN CODE) ;

my $binding_max_length = max map { length } grep { ! exists $reserved{$_} } keys $self->{CURRENT_ACTIONS}->%* ;

my $max_length = 0 ;

$self->{BINDINGS_COMPLETION} =
Expand All @@ -52,20 +42,10 @@ if($self->{USE_BINDINGS_COMPLETION})
$max_length = $length if $length > $max_length ;
$completion ;
}
sort grep {
$_ ne 'IS_GROUP'
&& $_ ne 'ENTER_GROUP'
&& $_ ne 'ESCAPE_KEY'
&& $_ ne 'NAME'
&& $_ ne 'SHORTCUTS'
&& $_ ne 'ORIGIN'
&& $_ ne 'CODE'
}
keys $self->{CURRENT_ACTIONS}->%*
sort grep { ! exists $reserved{$_} } keys $self->{CURRENT_ACTIONS}->%*
] ;

$self->{BINDINGS_COMPLETION_LENGTH} = $max_length ;

$self->update_display() ;
}
else
Expand Down Expand Up @@ -101,41 +81,29 @@ for my $action (@actions)
$modifiers //= '000-' ;

next if $action_key eq 'Shift_R' || $action_key eq 'Shift_L' || $action_key eq 'Alt_R' || $action_key eq 'Alt_L' ;
# C00-Shift_R
# C00-Shift_L
# C00-Alt_L
# C00-Alt_L
# CA0-Shift_R
# C00-Shift_L
# C0S-Shift_R
# 0A0-Shift_R
# 0A0-Shift_L

my $action = encode('utf8', $action) ;

if(exists $self->{CURRENT_ACTIONS}{$action})
{
my $is_group = $self->{CURRENT_ACTIONS}{$action}{IS_GROUP} ;
my $in_capture = defined $self->{CURRENT_ACTIONS}{ESCAPE_KEY} ;

my $group_tag = $is_group ? defined $self->{CURRENT_ACTIONS}{$action}{ESCAPE_KEY}
? "[c] "
: "[g] "
: '' ;

my $capture_tag = $in_capture ? "[$self->{CURRENT_ACTIONS}{NAME}] " : '' ;
my $action_is_group = $self->{CURRENT_ACTIONS}{$action}{IS_GROUP} ;
my $action_capture = defined $self->{CURRENT_ACTIONS}{$action}{ESCAPE_KEYS} && $self->{CURRENT_ACTIONS}{$action}{ESCAPE_KEYS}->@* ;
my $action_group_tag = $action_is_group ? ($action_capture ? "[ge] " : "[g] ") : '' ;

$self->{ACTION_VERBOSE}->
(
sprintf
(
"%-30s %-30s [%s]",
"${modifiers}$action_key $group_tag$capture_tag",
"${modifiers}$action_key $action_group_tag",
$self->{CURRENT_ACTIONS}{$action}{NAME},
$self->{CURRENT_ACTIONS}{$action}{ORIGIN}
)
) if $self->{ACTION_VERBOSE} && $self->{CURRENT_ACTIONS}{$action}{NAME} ne 'Mouse motion' ;

# Note: action sub is what changes $self->{CURRENT_ACTIONS} to a new action group
my $start_actions = $self->{CURRENT_ACTIONS} ;

if(defined $self->{CURRENT_ACTIONS}{$action}{ARGUMENTS})
{
push @results,
Expand All @@ -150,20 +118,14 @@ for my $action (@actions)
}
else
{
push @results,
[
$self->{CURRENT_ACTIONS}{$action}{CODE}->($self, @arguments)
] ;
push @results, [ $self->{CURRENT_ACTIONS}{$action}{CODE}->($self, @arguments) ] ;
}

$is_group += $self->{CROSS_ACTION_GROUP} // 0 ;
delete $self->{CROSS_ACTION_GROUP} ;

$self->{CURRENT_ACTIONS} = $self->{ACTIONS} unless $is_group || $in_capture ;

if ($is_group)
if($start_actions != $self->{CURRENT_ACTIONS})
{
$self->create_binding_completions() ;
# entered new group
$self->{CURRENT_ACTIONS}{ENTER_GROUP}->($self) if defined $self->{CURRENT_ACTIONS}{ENTER_GROUP} ;
$self->show_binding_completions() ;
}
else
{
Expand All @@ -174,49 +136,42 @@ for my $action (@actions)
}

delete $self->{KEEP_BINDINGS_COMPLETION} ;
}

if($is_group && defined $self->{CURRENT_ACTIONS}{ENTER_GROUP})
{
$self->{CURRENT_ACTIONS}{ENTER_GROUP}->($self) ;
}

if(defined $self->{CURRENT_ACTIONS}{ESCAPE_KEY})
{
my $escape_key = "escape key: $self->{CURRENT_ACTIONS}{ESCAPE_KEY}" ;

if($action eq $self->{CURRENT_ACTIONS}{ESCAPE_KEY})
if(defined $self->{CURRENT_ACTIONS}{ESCAPE_KEYS} && any { $_ eq $action } $self->{CURRENT_ACTIONS}{ESCAPE_KEYS}->@*)
{
$self->{ACTION_VERBOSE}->("\e[33m[$self->{CURRENT_ACTIONS}{NAME}] leaving\e[m") if $self->{ACTION_VERBOSE} ;
$self->{CURRENT_ACTIONS} = $self->{ACTIONS} ;
}
else
{
my $in_capture = defined $self->{CURRENT_ACTIONS}{ESCAPE_KEYS} && $self->{CURRENT_ACTIONS}{ESCAPE_KEYS}->@* ;
$self->{CURRENT_ACTIONS} = $self->{ACTIONS} unless $in_capture ;
}
}
}
else
{
if(defined $self->{CURRENT_ACTIONS}{ESCAPE_KEY})
if(defined $self->{CURRENT_ACTIONS}{ESCAPE_KEYS} && $self->{CURRENT_ACTIONS}{ESCAPE_KEYS}->@*)
{
my $escape_key = "escape key: $self->{CURRENT_ACTIONS}{ESCAPE_KEY}" ;

if($action eq $self->{CURRENT_ACTIONS}{ESCAPE_KEY})
if(any { $_ eq $action } $self->{CURRENT_ACTIONS}{ESCAPE_KEYS}->@*)
{
$self->{ACTION_VERBOSE}->("\e[33m[$self->{CURRENT_ACTIONS}{NAME}] leaving\e[m") if $self->{ACTION_VERBOSE} ;
$self->{CURRENT_ACTIONS} = $self->{ACTIONS} ;
}
else
{
my $escape_key = "escape keys: " . join (', ', $self->{CURRENT_ACTIONS}{ESCAPE_KEYS}->@*) ;
$self->{ACTION_VERBOSE}->("\e[31m$action, [$self->{CURRENT_ACTIONS}{NAME}], $escape_key\e[m") if $self->{ACTION_VERBOSE} ;
}
}
else
{
$self->{ACTION_VERBOSE}->(sprintf "\e[31m%-30s\e[m", "$action") if $self->{ACTION_VERBOSE} ;
$self->{CURRENT_ACTIONS} = $self->{ACTIONS} ;

}

$self->update_display() ;
delete $self->{BINDINGS_COMPLETION} ;
$self->update_display() ;
}
}

Expand Down Expand Up @@ -257,11 +212,11 @@ for my $action (@actions)
push @results,
[
$current_actions_by_name->{$action}{CODE}->
(
$self,
$self->{CURRENT_ACTIONS}{$action}{ARGUMENTS},
@arguments
)
(
$self,
$self->{CURRENT_ACTIONS}{$action}{ARGUMENTS},
@arguments
)
] ;
}
else
Expand Down
65 changes: 37 additions & 28 deletions lib/App/Asciio/Actions/Elements.pm
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ unless (defined $file_name)
if(defined $file_name && $file_name ne '')
{
# check path

system "asciio '$file_name' &" ;
}

Expand Down Expand Up @@ -181,23 +180,28 @@ my @headless_arrows =
sub add_line
{
my ($self, $line_type) = @_;

$self->create_undo_snapshot();

$self->deselect_all_elements() ;

my $arrow_type = $headless_arrows[$line_type] ;

my $my_line_obj = new App::Asciio::stripes::section_wirl_arrow
({
POINTS => [[5, 0, 'right']],
DIRECTION => 'left',
ALLOW_DIAGONAL_LINES => 0,
EDITABLE => 1,
RESIZABLE => 1,
ARROW_TYPE => $arrow_type,
});
my $line = new App::Asciio::stripes::section_wirl_arrow
({
POINTS => [[5, 0, 'right']],
DIRECTION => 'left',
ALLOW_DIAGONAL_LINES => 0,
EDITABLE => 1,
RESIZABLE => 1,
ARROW_TYPE => $arrow_type,
});

$line->{NAME} = 'line';

$my_line_obj->{NAME} = 'line';
$self->add_element_at($line, $self->{MOUSE_X}, $self->{MOUSE_Y});

$self->add_element_at($my_line_obj, $self->{MOUSE_X}, $self->{MOUSE_Y});
$self->select_elements(1, $line);

$self->update_display();
}
Expand All @@ -207,26 +211,31 @@ $self->update_display();
sub add_non_connecting_line
{
my ($self, $line_type) = @_;

$self->create_undo_snapshot();

$self->deselect_all_elements() ;

my $arrow_type = $headless_arrows[$line_type] ;

my $my_line_obj = new App::Asciio::stripes::section_wirl_arrow
({
POINTS => [[2, 0, 'right']],
DIRECTION => 'left',
ALLOW_DIAGONAL_LINES => 0,
EDITABLE => 1,
RESIZABLE => 1,
ARROW_TYPE => $arrow_type,
});

$my_line_obj->{NAME} = 'line';
$my_line_obj->enable_autoconnect(0);
$my_line_obj->allow_connection('start', 0);
$my_line_obj->allow_connection('end', 0);

$self->add_element_at($my_line_obj, $self->{MOUSE_X}, $self->{MOUSE_Y});
my $line = new App::Asciio::stripes::section_wirl_arrow
({
POINTS => [[2, 0, 'right']],
DIRECTION => 'left',
ALLOW_DIAGONAL_LINES => 0,
EDITABLE => 1,
RESIZABLE => 1,
ARROW_TYPE => $arrow_type,
});

$line->{NAME} = 'line';
$line->enable_autoconnect(0);
$line->allow_connection('start', 0);
$line->allow_connection('end', 0);

$self->add_element_at($line, $self->{MOUSE_X}, $self->{MOUSE_Y});

$self->select_elements(1, $line);

$self->update_display();
}
Expand Down
Loading

0 comments on commit c431260

Please sign in to comment.