--- deliantra/Deliantra-Client/DC/Macro.pm 2007/07/21 20:05:37 1.8 +++ deliantra/Deliantra-Client/DC/Macro.pm 2007/08/28 01:23:47 1.9 @@ -2,20 +2,51 @@ use strict; +use List::Util (); use CFPlus::UI; our $REFRESH_MACRO_LIST; +our %DEFAULT_KEYMAP = ( + (map +($_ => "!completer $_"), "a" .. "z"), + "(!)" => "!completer shout ", + "(\")" => "!completer say ", + "(')" => "!completer", + + "LShift-tab" => "!toggle-messagewindow", + "RShift-tab" => "!toggle-messagewindow", + "tab" => "!toggle-playerbook", + "f1" => "!toggle-help", + "f2" => "!toggle-stats", + "f3" => "!toggle-skills", + "f4" => "!toggle-spells", + "f5" => "!toggle-inventory", + "f9" => "!toggle-setup", + (map +("LAlt-$_" => "!switch-tab $_"), 0..9), + (map +("RAlt-$_" => "!switch-tab $_"), 0..9), + "return" => "!activate-chat", + "." => "!repeat-command", + + "," => "take", + "space" => "apply", + "[+]" => "rotateshoottype +", + "[-]" => "rotateshoottype -", +); + # allowed modifiers our %MODIFIER = ( "LShift" => CFPlus::KMOD_LSHIFT, "RShift" => CFPlus::KMOD_RSHIFT, +# "Shift" => CFPlus::KMOD_LSHIFT | CFPlus::KMOD_RSHIFT, "LCtrl" => CFPlus::KMOD_LCTRL, "RCtrl" => CFPlus::KMOD_RCTRL, +# "Ctrl" => CFPlus::KMOD_LCTRL | CFPlus::KMOD_RCTRL, "LAlt" => CFPlus::KMOD_LALT, "RAlt" => CFPlus::KMOD_RALT, +# "Alt" => CFPlus::KMOD_LALT | CFPlus::KMOD_RALT, "LMeta" => CFPlus::KMOD_LMETA, "RMeta" => CFPlus::KMOD_RMETA, +# "Meta" => CFPlus::KMOD_LMETA | CFPlus::KMOD_RMETA, ); # allowed modifiers @@ -42,10 +73,60 @@ CFPlus::SDLK_F15, ); +our %MACRO_FUNCTION = ( + "toggle-messagewindow" => sub { $::MESSAGE_WINDOW->toggle_visibility }, + "toggle-playerbook" => sub { $::PL_WINDOW->toggle_visibility }, + "toggle-help" => sub { $::HELP_WINDOW->toggle_visibility }, + "toggle-stats" => sub { ::toggle_player_page ($::STATS_PAGE) }, + "toggle-skills" => sub { ::toggle_player_page ($::SKILL_PAGE) }, + "toggle-spells" => sub { ::toggle_player_page ($::SPELL_PAGE) }, + "toggle-inventory" => sub { ::toggle_player_page ($::INVENTORY_PAGE) }, + "toggle-pickup" => sub { ::toggle_player_page ($::PICKUP_PAGE) }, + "toggle-setup" => sub { $::SETUP_DIALOG->toggle_visibility }, + "toggle-setup" => sub { $::SETUP_DIALOG->toggle_visibility }, + "switch-tab" => sub { $::MESSAGE_WINDOW->user_switch_to_page (0 + shift) }, + "activate-chat" => sub { $::MESSAGE_WINDOW->activate_current }, + "repeat-command" => sub { + $::CONN->user_send ($::COMPLETER->{last_command}) + if $::CONN && exists $::COMPLETER->{last_command}; + }, + "completer" => sub { + if ($::CONN) { + $::COMPLETER->set_prefix (shift); + $::COMPLETER->show; + } + }, +); + +our $DEFAULT_KEYMAP; + +sub init { + $DEFAULT_KEYMAP ||= do { + my %sym = map +(CFPlus::SDL_GetKeyName $_, $_), CFPlus::SDLK_FIRST .. CFPlus::SDLK_LAST; + my $map; + + while (my ($k, $v) = each %DEFAULT_KEYMAP) { + if ($k =~ /^\((.)\)$/) { + $map->{U}{ord $1} = $v; + } else { + my @mod = split /-/, $k; + my $sym = $sym{pop @mod} + or warn "unknown keysym $k\n"; + + my $mod = 0; $mod |= $MODIFIER{$_} for @mod; + + $map->{K}[CFPlus::popcount $mod]{$mod}{$sym} = $v; + } + } + + %DEFAULT_KEYMAP = (); + $map + }; +} + sub accelkey_to_string($) { join "-", - (grep $_[0][0] & $MODIFIER{$_}, - keys %MODIFIER), + (grep $_[0][0] & $MODIFIER{$_}, keys %MODIFIER), CFPlus::SDL_GetKeyName $_[0][1] } @@ -158,18 +239,66 @@ $window->show; } +sub find_default($) { + my ($ev) = @_; + + if (my $cmd = $DEFAULT_KEYMAP->{U}{$ev->{unicode}}) { + return $cmd; + } + + for my $m (reverse grep $_, @{ $DEFAULT_KEYMAP->{K} }) { + for (keys %$m) { + if ($_ == ($ev->{mod} & $_)) { + if (defined (my $cmd = $m->{$_}{$ev->{sym}})) { + return $cmd; + } + } + } + } + + () +} + # find macro by event -sub match_event($) { +sub find($) { my ($ev) = @_; - grep { - if (my $key = $_->{accelkey}) { - $key->[1] == $ev->{sym} - && $key->[0] == ($ev->{mod} & $MODIFIER_MASK) + # try user-defined macros + if (my @user = + grep { + if (my $key = $_->{accelkey}) { + $key->[1] == $ev->{sym} + && $key->[0] == ($ev->{mod} & $MODIFIER_MASK) + } else { + 0 + } + } @{ $::PROFILE->{macro} || [] } + ) { + return @user; + } + + # now try default keymap + if (defined (my $def = find_default $ev)) { + return { + action => [$def], + }; + } + + () +} + +sub execute { + my ($macro) = @_; + + for (@{ $macro->{action} }) { + if (/^\!(\S+)\s?(.*)$/) { + $MACRO_FUNCTION{$1}->($2) + if exists $MACRO_FUNCTION{$1}; } else { - 0 + $::CONN->send_command ($_) + if $::CONN; } - } @{ $::PROFILE->{macro} || [] } + } } sub keyboard_setup { @@ -383,3 +512,4 @@ }; } +1