ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC/BindingEditor.pm
(Generate patch)

Comparing deliantra/Deliantra-Client/DC/BindingEditor.pm (file contents):
Revision 1.1 by root, Mon Jun 26 21:59:04 2006 UTC vs.
Revision 1.2 by root, Sun Jul 2 18:52:05 2006 UTC

1package CFClient::BindingEditor; 1package CFClient::BindingEditor;
2 2
3use strict;
4
3use CFClient::UI; 5use CFClient::UI;
4 6
5our @ISA = CFClient::UI::FancyFrame::; 7our @ISA = CFClient::UI::FancyFrame::;
8
9my @ALLOWED_MODIFIER_KEYS = (
10 CFClient::SDLK_LSHIFT,
11 CFClient::SDLK_LCTRL ,
12 CFClient::SDLK_LALT ,
13 CFClient::SDLK_LMETA ,
14
15 CFClient::SDLK_RSHIFT,
16 CFClient::SDLK_RCTRL ,
17 CFClient::SDLK_RALT ,
18 CFClient::SDLK_RMETA ,
19);
20
21my %ALLOWED_MODIFIERS = (
22 CFClient::KMOD_LSHIFT => "LSHIFT",
23 CFClient::KMOD_LCTRL => "LCTRL",
24 CFClient::KMOD_LALT => "LALT",
25 CFClient::KMOD_LMETA => "LMETA",
26
27 CFClient::KMOD_RSHIFT => "RSHIFT",
28 CFClient::KMOD_RCTRL => "RCTRL",
29 CFClient::KMOD_RALT => "RALT",
30 CFClient::KMOD_RMETA => "RMETA",
31);
32
33my %DIRECT_BIND_CHARS = map { $_ => 1 } qw/0 1 2 3 4 5 6 7 8 9/;
34my @DIRECT_BIND_KEYS = (
35 CFClient::SDLK_F1,
36 CFClient::SDLK_F2,
37 CFClient::SDLK_F3,
38 CFClient::SDLK_F4,
39 CFClient::SDLK_F5,
40 CFClient::SDLK_F6,
41 CFClient::SDLK_F7,
42 CFClient::SDLK_F8,
43 CFClient::SDLK_F9,
44 CFClient::SDLK_F10,
45 CFClient::SDLK_F11,
46 CFClient::SDLK_F12,
47 CFClient::SDLK_F13,
48 CFClient::SDLK_F14,
49 CFClient::SDLK_F15,
50);
51
52sub keycombo_to_name {
53 my ($mod, $sym) = @_;
54
55 my $mods = join '+',
56 map { $ALLOWED_MODIFIERS{$_} }
57 grep { ($_ + 0) & ($mod + 0) }
58 keys %ALLOWED_MODIFIERS;
59 $mods .= "+" if $mods ne '';
60
61 return $mods . CFClient::SDL_GetKeyName ($sym);
62}
6 63
7sub new { 64sub new {
8 my $class = shift; 65 my $class = shift;
9 66
10 my $self = $class->SUPER::new ( 67 my $self = $class->SUPER::new (
43 $self->ask_for_bind; 100 $self->ask_for_bind;
44 }); 101 });
45 102
46 $vb->add (my $hb = new CFClient::UI::HBox); 103 $vb->add (my $hb = new CFClient::UI::HBox);
47 $hb->add (new CFClient::UI::Button 104 $hb->add (new CFClient::UI::Button
48 text => "ok", 105 text => "OK",
49 expand => 1, 106 expand => 1,
50 tooltip => "This closes the binding editor and saves the binding", 107 tooltip => "This closes the binding editor and saves the binding",
51 on_activate => sub { 108 on_activate => sub {
109 (delete $self->{binder})->destroy if $self->{binder};
52 $self->hide; 110 $self->hide;
53 $self->commit; 111 $self->commit;
112 0
54 }); 113 });
55 114
56 $hb->add (new CFClient::UI::Button 115 $hb->add (new CFClient::UI::Button
57 text => "cancel", 116 text => "Cancel",
58 expand => 1, 117 expand => 1,
59 tooltip => "This closes the binding editor without saving", 118 tooltip => "This closes the binding editor without saving",
60 on_activate => sub { 119 on_activate => sub {
120 (delete $self->{binder})->destroy if $self->{binder};
61 $self->hide; 121 $self->hide;
62 $self->{binding_cancel}->() 122 $self->{binding_cancel}->()
63 if $self->{binding_cancel}; 123 if $self->{binding_cancel};
124 0
64 }); 125 });
65 126
66 $self->update_binding_widgets; 127 $self->update_binding_widgets;
67 128
68 $self 129 $self
80 ::update_bindings (); 141 ::update_bindings ();
81} 142}
82 143
83sub commit { 144sub commit {
84 my ($self) = @_; 145 my ($self) = @_;
146
85 my ($mod, $sym, $cmds) = $self->get_binding; 147 my ($mod, $sym, $cmds) = $self->get_binding;
148
86 if ($sym != 0 && @$cmds > 0) { 149 if ($sym != 0 && @$cmds > 0) {
87 $::STATUSBOX->add ("Bound actions to '".CFClient::Binder::keycombo_to_name ($mod, $sym) 150 $::STATUSBOX->add ("Bound actions to <i>" . keycombo_to_name ($mod, $sym) . "</i>. "
88 ."'. Don't forget 'Save Config'!"); 151 . "Do not forget to 'Save Config'!");
89 $self->{binding_change}->($mod, $sym, $cmds) 152 $self->{binding_change}->($mod, $sym, $cmds)
90 if $self->{binding_change}; 153 if $self->{binding_change};
91 } else { 154 } else {
92 $::STATUSBOX->add ("No action bound, no key or action specified!"); 155 $::STATUSBOX->add ("No action bound, no key or action specified!");
93 $self->{binding_cancel}->() 156 $self->{binding_cancel}->()
114 $rec = $::CONN->stop_record if $::CONN; 177 $rec = $::CONN->stop_record if $::CONN;
115 return unless ref $rec eq 'ARRAY'; 178 return unless ref $rec eq 'ARRAY';
116 $self->set_command_list ($rec); 179 $self->set_command_list ($rec);
117} 180}
118 181
119
120sub ask_for_bind_and_commit {
121 my ($self) = @_;
122 $self->ask_for_bind (1);
123}
124
125sub ask_for_bind { 182sub ask_for_bind {
126 my ($self, $commit, $end_cb) = @_; 183 my ($self, $commit, $end_cb) = @_;
127 184
128 CFClient::Binder::open_binding_dialog (sub { 185 return if $self->{binder};
129 my ($mod, $sym) = @_; 186
130 $self->{binding} = [$mod, $sym]; # XXX: how to stop that memleak? 187 Scalar::Util::weaken $self;
188
189 $self->{binder} = new CFClient::UI::FancyFrame
190 title => "Bind Action",
191 x => "center",
192 y => "center",
193 z => 1000,
194 has_close_button => 1,
195 on_delete => sub {
196 (delete $self->{binder})->destroy;
197 1
198 },
199 ;
200
201 $self->{binder}->add (my $vb = new CFClient::UI::VBox);
202 $vb->add (new CFClient::UI::Label
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."
205 );
206 $vb->add (my $entry = new CFClient::UI::Entry
207 text => "",
208 on_key_down => sub {
209 my ($entry, $ev) = @_;
210
211 my $mod = $ev->{mod};
212 my $sym = $ev->{sym};
213
214 # XXX: This seems a little bit hackisch to me, but I have to ignore them
215 return if grep { $_ == $sym } @ALLOWED_MODIFIER_KEYS;
216
217 if ($mod == CFClient::KMOD_NONE
218 and not $DIRECT_BIND_CHARS{chr ($ev->{unicode})}
219 and not grep { $sym == $_ } @DIRECT_BIND_KEYS)
220 {
221 $::STATUSBOX->add (
222 "Cannot bind key " . CFClient::SDL_GetKeyName ($sym) . " directly without modifier, "
223 . "as those keys are reserved for the command completer."
224 );
225 return;
226 }
227
228 $entry->grab_focus;
229
230 $self->{binding} = [$mod, $sym];
131 $self->update_binding_widgets; 231 $self->update_binding_widgets;
132 $self->commit if $commit; 232 $self->commit if $commit;
133 $end_cb->() if $end_cb; 233 $end_cb->() if $end_cb;
234
235 warn "dexxey $self $self->{binder}\n";#d#
236 (delete $self->{binder})->destroy;
237 1
238 },
239 on_focus_out => sub {
240 # segfaults and worse :()
241 #(delete $self->{binder})->destroy if $self->{binder};
242 1
243 },
134 }); 244 );
245
246 $entry->grab_focus;
247 $self->{binder}->show;
135} 248}
136 249
137# $mod and $sym are the modifiers and key symbol 250# $mod and $sym are the modifiers and key symbol
138# $cmds is a array ref of strings (the commands) 251# $cmds is a array ref of strings (the commands)
139# $cb is the callback that is executed on OK 252# $cb is the callback that is executed on OK
164} 277}
165 278
166sub update_binding_widgets { 279sub update_binding_widgets {
167 my ($self) = @_; 280 my ($self) = @_;
168 my ($mod, $sym, $cmds) = $self->get_binding; 281 my ($mod, $sym, $cmds) = $self->get_binding;
169 $self->{keylbl}->set_text (CFClient::Binder::keycombo_to_name ($mod, $sym)); 282 $self->{keylbl}->set_text (keycombo_to_name ($mod, $sym));
170 $self->set_command_list ($cmds); 283 $self->set_command_list ($cmds);
171} 284}
172 285
173sub get_binding { 286sub get_binding {
174 my ($self) = @_; 287 my ($self) = @_;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines