1 | package CFClient::BindingEditor; |
1 | package CFPlus::BindingEditor; |
2 | |
2 | |
3 | use strict; |
3 | use strict; |
4 | |
4 | |
5 | use CFClient::UI; |
5 | use CFPlus::UI; |
6 | |
6 | |
7 | our @ISA = CFClient::UI::FancyFrame::; |
7 | our @ISA = CFPlus::UI::FancyFrame::; |
8 | |
8 | |
9 | my @ALLOWED_MODIFIER_KEYS = ( |
9 | my @ALLOWED_MODIFIER_KEYS = ( |
10 | CFClient::SDLK_LSHIFT, |
10 | CFPlus::SDLK_LSHIFT, |
11 | CFClient::SDLK_LCTRL , |
11 | CFPlus::SDLK_LCTRL , |
12 | CFClient::SDLK_LALT , |
12 | CFPlus::SDLK_LALT , |
13 | CFClient::SDLK_LMETA , |
13 | CFPlus::SDLK_LMETA , |
14 | |
14 | |
15 | CFClient::SDLK_RSHIFT, |
15 | CFPlus::SDLK_RSHIFT, |
16 | CFClient::SDLK_RCTRL , |
16 | CFPlus::SDLK_RCTRL , |
17 | CFClient::SDLK_RALT , |
17 | CFPlus::SDLK_RALT , |
18 | CFClient::SDLK_RMETA , |
18 | CFPlus::SDLK_RMETA , |
19 | ); |
19 | ); |
20 | |
20 | |
21 | my %ALLOWED_MODIFIERS = ( |
21 | my %ALLOWED_MODIFIERS = ( |
22 | CFClient::KMOD_LSHIFT => "LSHIFT", |
22 | CFPlus::KMOD_LSHIFT => "LSHIFT", |
23 | CFClient::KMOD_LCTRL => "LCTRL", |
23 | CFPlus::KMOD_LCTRL => "LCTRL", |
24 | CFClient::KMOD_LALT => "LALT", |
24 | CFPlus::KMOD_LALT => "LALT", |
25 | CFClient::KMOD_LMETA => "LMETA", |
25 | CFPlus::KMOD_LMETA => "LMETA", |
26 | |
26 | |
27 | CFClient::KMOD_RSHIFT => "RSHIFT", |
27 | CFPlus::KMOD_RSHIFT => "RSHIFT", |
28 | CFClient::KMOD_RCTRL => "RCTRL", |
28 | CFPlus::KMOD_RCTRL => "RCTRL", |
29 | CFClient::KMOD_RALT => "RALT", |
29 | CFPlus::KMOD_RALT => "RALT", |
30 | CFClient::KMOD_RMETA => "RMETA", |
30 | CFPlus::KMOD_RMETA => "RMETA", |
31 | ); |
31 | ); |
32 | |
32 | |
33 | my %DIRECT_BIND_CHARS = map { $_ => 1 } qw/0 1 2 3 4 5 6 7 8 9/; |
33 | my %DIRECT_BIND_CHARS = map { $_ => 1 } qw/0 1 2 3 4 5 6 7 8 9/; |
34 | my @DIRECT_BIND_KEYS = ( |
34 | my @DIRECT_BIND_KEYS = ( |
35 | CFClient::SDLK_F1, |
35 | CFPlus::SDLK_F1, |
36 | CFClient::SDLK_F2, |
36 | CFPlus::SDLK_F2, |
37 | CFClient::SDLK_F3, |
37 | CFPlus::SDLK_F3, |
38 | CFClient::SDLK_F4, |
38 | CFPlus::SDLK_F4, |
39 | CFClient::SDLK_F5, |
39 | CFPlus::SDLK_F5, |
40 | CFClient::SDLK_F6, |
40 | CFPlus::SDLK_F6, |
41 | CFClient::SDLK_F7, |
41 | CFPlus::SDLK_F7, |
42 | CFClient::SDLK_F8, |
42 | CFPlus::SDLK_F8, |
43 | CFClient::SDLK_F9, |
43 | CFPlus::SDLK_F9, |
44 | CFClient::SDLK_F10, |
44 | CFPlus::SDLK_F10, |
45 | CFClient::SDLK_F11, |
45 | CFPlus::SDLK_F11, |
46 | CFClient::SDLK_F12, |
46 | CFPlus::SDLK_F12, |
47 | CFClient::SDLK_F13, |
47 | CFPlus::SDLK_F13, |
48 | CFClient::SDLK_F14, |
48 | CFPlus::SDLK_F14, |
49 | CFClient::SDLK_F15, |
49 | CFPlus::SDLK_F15, |
50 | ); |
50 | ); |
51 | |
51 | |
52 | sub keycombo_to_name { |
52 | sub keycombo_to_name { |
53 | my ($mod, $sym) = @_; |
53 | my ($mod, $sym) = @_; |
54 | |
54 | |
… | |
… | |
56 | map { $ALLOWED_MODIFIERS{$_} } |
56 | map { $ALLOWED_MODIFIERS{$_} } |
57 | grep { ($_ + 0) & ($mod + 0) } |
57 | grep { ($_ + 0) & ($mod + 0) } |
58 | keys %ALLOWED_MODIFIERS; |
58 | keys %ALLOWED_MODIFIERS; |
59 | $mods .= "+" if $mods ne ''; |
59 | $mods .= "+" if $mods ne ''; |
60 | |
60 | |
61 | return $mods . CFClient::SDL_GetKeyName ($sym); |
61 | return $mods . CFPlus::SDL_GetKeyName ($sym); |
62 | } |
62 | } |
63 | |
63 | |
64 | sub new { |
64 | sub new { |
65 | my $class = shift; |
65 | my $class = shift; |
66 | |
66 | |
… | |
… | |
69 | commands => [], |
69 | commands => [], |
70 | title => "Macro/Keybinding Recorder", |
70 | title => "Macro/Keybinding Recorder", |
71 | @_ |
71 | @_ |
72 | ); |
72 | ); |
73 | |
73 | |
74 | $self->add (my $vb = new CFClient::UI::VBox); |
74 | $self->add (my $vb = new CFPlus::UI::VBox); |
75 | |
75 | |
76 | $vb->add ($self->{rec_btn} = new CFClient::UI::Button |
76 | $vb->add ($self->{rec_btn} = new CFPlus::UI::Button |
77 | text => "start recording", |
77 | text => "start recording", |
78 | tooltip => "Start/Stops recording of actions." |
78 | tooltip => "Start/Stops recording of actions." |
79 | ."All subsequent actions after the recording started will be captured." |
79 | ."All subsequent actions after the recording started will be captured." |
80 | ."The actions are displayed after the record was stopped." |
80 | ."The actions are displayed after the record was stopped." |
81 | ."To bind the action you have to click on the 'Bind' button", |
81 | ."To bind the action you have to click on the 'Bind' button", |
… | |
… | |
85 | } else { |
85 | } else { |
86 | $self->stop; |
86 | $self->stop; |
87 | } |
87 | } |
88 | }); |
88 | }); |
89 | |
89 | |
90 | $vb->add (new CFClient::UI::Label text => "Actions:"); |
90 | $vb->add (new CFPlus::UI::Label text => "Actions:"); |
91 | $vb->add ($self->{cmdbox} = new CFClient::UI::VBox); |
91 | $vb->add ($self->{cmdbox} = new CFPlus::UI::VBox); |
92 | |
92 | |
93 | $vb->add (new CFClient::UI::Label text => "Bound to: "); |
93 | $vb->add (new CFPlus::UI::Label text => "Bound to: "); |
94 | $vb->add (my $hb = new CFClient::UI::HBox); |
94 | $vb->add (my $hb = new CFPlus::UI::HBox); |
95 | $hb->add ($self->{keylbl} = new CFClient::UI::Label expand => 1); |
95 | $hb->add ($self->{keylbl} = new CFPlus::UI::Label expand => 1); |
96 | $hb->add (new CFClient::UI::Button |
96 | $hb->add (new CFPlus::UI::Button |
97 | text => "bind", |
97 | text => "bind", |
98 | tooltip => "This opens a query where you have to press the key combination to bind the recorded actions", |
98 | tooltip => "This opens a query where you have to press the key combination to bind the recorded actions", |
99 | on_activate => sub { |
99 | on_activate => sub { |
100 | $self->ask_for_bind; |
100 | $self->ask_for_bind; |
101 | }); |
101 | }); |
102 | |
102 | |
103 | $vb->add (my $hb = new CFClient::UI::HBox); |
103 | $vb->add (my $hb = new CFPlus::UI::HBox); |
104 | $hb->add (new CFClient::UI::Button |
104 | $hb->add (new CFPlus::UI::Button |
105 | text => "OK", |
105 | text => "OK", |
106 | expand => 1, |
106 | expand => 1, |
107 | tooltip => "This closes the binding editor and saves the binding", |
107 | tooltip => "This closes the binding editor and saves the binding", |
108 | on_activate => sub { |
108 | on_activate => sub { |
109 | (delete $self->{binder})->destroy if $self->{binder}; |
109 | (delete $self->{binder})->destroy if $self->{binder}; |
110 | $self->hide; |
110 | $self->hide; |
111 | $self->commit; |
111 | $self->commit; |
112 | 0 |
112 | 0 |
113 | }); |
113 | }); |
114 | |
114 | |
115 | $hb->add (new CFClient::UI::Button |
115 | $hb->add (new CFPlus::UI::Button |
116 | text => "Cancel", |
116 | text => "Cancel", |
117 | expand => 1, |
117 | expand => 1, |
118 | tooltip => "This closes the binding editor without saving", |
118 | tooltip => "This closes the binding editor without saving", |
119 | on_activate => sub { |
119 | on_activate => sub { |
120 | (delete $self->{binder})->destroy if $self->{binder}; |
120 | (delete $self->{binder})->destroy if $self->{binder}; |
… | |
… | |
184 | |
184 | |
185 | return if $self->{binder}; |
185 | return if $self->{binder}; |
186 | |
186 | |
187 | Scalar::Util::weaken $self; |
187 | Scalar::Util::weaken $self; |
188 | |
188 | |
189 | $self->{binder} = new CFClient::UI::FancyFrame |
189 | $self->{binder} = new CFPlus::UI::FancyFrame |
190 | title => "Bind Action", |
190 | title => "Bind Action", |
191 | x => "center", |
191 | x => "center", |
192 | y => "center", |
192 | y => "center", |
193 | z => 1000, |
193 | z => 1000, |
194 | has_close_button => 1, |
194 | has_close_button => 1, |
… | |
… | |
196 | (delete $self->{binder})->destroy; |
196 | (delete $self->{binder})->destroy; |
197 | 1 |
197 | 1 |
198 | }, |
198 | }, |
199 | ; |
199 | ; |
200 | |
200 | |
201 | $self->{binder}->add (my $vb = new CFClient::UI::VBox); |
201 | $self->{binder}->add (my $vb = new CFPlus::UI::VBox); |
202 | $vb->add (new CFClient::UI::Label |
202 | $vb->add (new CFPlus::UI::Label |
203 | text => "Press a modifier (CTRL, ALT and/or SHIFT) and a key." |
203 | text => "Press a modifier (CTRL, ALT and/or SHIFT) and a key." |
204 | . "You can only bind 0-9 and F1-F15 without modifiers." |
204 | . "You can only bind 0-9 and F1-F15 without modifiers." |
205 | ); |
205 | ); |
206 | $vb->add (my $entry = new CFClient::UI::Entry |
206 | $vb->add (my $entry = new CFPlus::UI::Entry |
207 | text => "", |
207 | text => "", |
208 | on_key_down => sub { |
208 | on_key_down => sub { |
209 | my ($entry, $ev) = @_; |
209 | my ($entry, $ev) = @_; |
210 | |
210 | |
211 | my $mod = $ev->{mod}; |
211 | my $mod = $ev->{mod}; |
212 | my $sym = $ev->{sym}; |
212 | my $sym = $ev->{sym}; |
213 | |
213 | |
214 | # XXX: This seems a little bit hackisch to me, but I have to ignore them |
214 | # XXX: This seems a little bit hackisch to me, but I have to ignore them |
215 | return if grep { $_ == $sym } @ALLOWED_MODIFIER_KEYS; |
215 | return if grep { $_ == $sym } @ALLOWED_MODIFIER_KEYS; |
216 | |
216 | |
217 | if ($mod == CFClient::KMOD_NONE |
217 | if ($mod == CFPlus::KMOD_NONE |
218 | and not $DIRECT_BIND_CHARS{chr ($ev->{unicode})} |
218 | and not $DIRECT_BIND_CHARS{chr ($ev->{unicode})} |
219 | and not grep { $sym == $_ } @DIRECT_BIND_KEYS) |
219 | and not grep { $sym == $_ } @DIRECT_BIND_KEYS) |
220 | { |
220 | { |
221 | $::STATUSBOX->add ( |
221 | $::STATUSBOX->add ( |
222 | "Cannot bind key " . CFClient::SDL_GetKeyName ($sym) . " directly without modifier, " |
222 | "Cannot bind key " . CFPlus::SDL_GetKeyName ($sym) . " directly without modifier, " |
223 | . "as those keys are reserved for the command completer." |
223 | . "as those keys are reserved for the command completer." |
224 | ); |
224 | ); |
225 | return; |
225 | return; |
226 | } |
226 | } |
227 | |
227 | |
… | |
… | |
303 | $self->{commands} = $cmds; |
303 | $self->{commands} = $cmds; |
304 | |
304 | |
305 | my $idx = 0; |
305 | my $idx = 0; |
306 | |
306 | |
307 | for (@$cmds) { |
307 | for (@$cmds) { |
308 | $self->{cmdbox}->add (my $hb = new CFClient::UI::HBox); |
308 | $self->{cmdbox}->add (my $hb = new CFPlus::UI::HBox); |
309 | |
309 | |
310 | my $i = $idx; |
310 | my $i = $idx; |
311 | $hb->add (new CFClient::UI::Label text => $_); |
311 | $hb->add (new CFPlus::UI::Label text => $_); |
312 | $hb->add (new CFClient::UI::Button |
312 | $hb->add (new CFPlus::UI::Button |
313 | text => "delete", |
313 | text => "delete", |
314 | tooltip => "Deletes the action from the record", |
314 | tooltip => "Deletes the action from the record", |
315 | on_activate => sub { |
315 | on_activate => sub { |
316 | $self->{cmdbox}->remove ($hb); |
316 | $self->{cmdbox}->remove ($hb); |
317 | $cmds->[$i] = undef; |
317 | $cmds->[$i] = undef; |