1 | package CFClient::MapWidget; |
1 | package CFClient::MapWidget; |
2 | |
2 | |
3 | use strict; |
3 | use strict; |
|
|
4 | use utf8; |
4 | |
5 | |
5 | use List::Util qw(min max); |
6 | use List::Util qw(min max); |
6 | |
7 | |
7 | use CFClient::OpenGL; |
8 | use CFClient::OpenGL; |
8 | |
9 | |
… | |
… | |
80 | |
81 | |
81 | if (delete $self->{need_update}) { |
82 | if (delete $self->{need_update}) { |
82 | glNewList $self->{list}; |
83 | glNewList $self->{list}; |
83 | |
84 | |
84 | if ($::MAP) { |
85 | if ($::MAP) { |
85 | my $sw = int $::WIDTH / (32 * $::CFG->{map_scale}); |
86 | my $sw = int $::WIDTH / (32 * $::CFG->{map_scale}) + 0.99; |
86 | my $sh = int $::HEIGHT / (32 * $::CFG->{map_scale}); |
87 | my $sh = int $::HEIGHT / (32 * $::CFG->{map_scale}) + 0.99; |
87 | |
88 | |
|
|
89 | glPushMatrix; |
88 | glScale $::CFG->{map_scale}, $::CFG->{map_scale}; |
90 | glScale $::CFG->{map_scale}, $::CFG->{map_scale}; |
89 | |
91 | |
90 | my $sx = $::CFG->{map_shift_x} / $::CFG->{map_scale}; my $sx0 = $sx & 31; $sx = ($sx - $sx0) / 32; |
92 | my $sx = $::CFG->{map_shift_x} / $::CFG->{map_scale}; my $sx0 = $sx & 31; $sx = ($sx - $sx0) / 32; |
91 | my $sy = $::CFG->{map_shift_y} / $::CFG->{map_scale}; my $sy0 = $sy & 31; $sy = ($sy - $sy0) / 32; |
93 | my $sy = $::CFG->{map_shift_y} / $::CFG->{map_scale}; my $sy0 = $sy & 31; $sy = ($sy - $sy0) / 32; |
92 | |
94 | |
… | |
… | |
143 | glEnable GL_BLEND; |
145 | glEnable GL_BLEND; |
144 | glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA; |
146 | glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA; |
145 | glEnable GL_TEXTURE_2D; |
147 | glEnable GL_TEXTURE_2D; |
146 | glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; |
148 | glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; |
147 | |
149 | |
|
|
150 | glPopMatrix; |
|
|
151 | |
148 | $self->{mapmap_texture} = |
152 | $self->{mapmap_texture} = |
149 | new CFClient::Texture |
153 | new CFClient::Texture |
150 | w => $w, |
154 | w => $w, |
151 | h => $h, |
155 | h => $h, |
152 | data => $::MAP->mapmap (- $w * 0.5, - $h * 0.5, $w, $h), |
156 | data => $::MAP->mapmap (- $w * 0.5, - $h * 0.5, $w, $h), |
… | |
… | |
214 | my $mod = $ev->{mod}; |
218 | my $mod = $ev->{mod}; |
215 | my $sym = $ev->{sym}; |
219 | my $sym = $ev->{sym}; |
216 | |
220 | |
217 | if ($sym == CFClient::SDLK_KP5) { |
221 | if ($sym == CFClient::SDLK_KP5) { |
218 | $::CONN->user_send ("stay fire"); |
222 | $::CONN->user_send ("stay fire"); |
|
|
223 | } elsif ($sym == ord ",") { |
|
|
224 | $::CONN->user_send ("take"); |
219 | } elsif ($sym == ord "a") { |
225 | } elsif ($sym == ord "a") { |
220 | $::CONN->user_send ("apply"); |
226 | $::CONN->user_send ("apply"); |
221 | } elsif ($sym == ord "'") { |
227 | } elsif ($sym == ord "'") { |
222 | $self->emit ('activate_console'); |
228 | $self->emit ('activate_console'); |
223 | } elsif ($sym == ord "/") { |
229 | } elsif ($sym == ord "/") { |
… | |
… | |
236 | $self->{command_widget} ||= |
242 | $self->{command_widget} ||= |
237 | new CFClient::MapWidget::Command:: |
243 | new CFClient::MapWidget::Command:: |
238 | command => $self->{command}, |
244 | command => $self->{command}, |
239 | can_focus => 1, |
245 | can_focus => 1, |
240 | connect_execute => sub { |
246 | connect_execute => sub { |
|
|
247 | # todo: support callback instead of user_send |
241 | $::CONN->user_send ($_[1]); |
248 | $::CONN->user_send ($_[1][1]); |
242 | }, |
249 | }, |
243 | connect_close => sub { |
250 | connect_close => sub { |
244 | (delete $self->{command_widget})->hide; |
251 | (delete $self->{command_widget})->hide; |
245 | $self->focus_in; |
252 | $self->focus_in; |
246 | }, |
253 | }, |
247 | ; |
254 | ; |
248 | $self->{command_widget}->key_down ($ev); |
255 | $self->{command_widget}->key_down ($ev); |
|
|
256 | return unless $self->{command_widget}; |
249 | $self->{command_widget}->show; |
257 | $self->{command_widget}->show; |
250 | $self->{command_widget}->focus_in; |
258 | $self->{command_widget}->focus_in; |
251 | } |
259 | } |
252 | } |
260 | } |
253 | |
261 | |
… | |
… | |
264 | $::CONN->user_send ("run_stop"); |
272 | $::CONN->user_send ("run_stop"); |
265 | } |
273 | } |
266 | } |
274 | } |
267 | |
275 | |
268 | sub add_command { |
276 | sub add_command { |
269 | my ($self, $command, $widget, $cb) = @_; |
277 | my ($self, $command, $tooltip, $widget, $cb) = @_; |
270 | |
278 | |
271 | (my $abbrev = $command) =~ s/(\S)[^[:space:]_]*[[:space:]_]+/$1/g; |
279 | (my $abbrev = $command) =~ s/(\S)[^[:space:]_]*[[:space:]_]+/$1/g; |
272 | |
280 | |
273 | push @{$self->{command}}, [$abbrev, $command]; |
281 | push @{$self->{command}}, [$abbrev, $command, $tooltip, $widget, $cb]; |
274 | #warn "$command|$abbrev|$widget\n";#d# |
|
|
275 | } |
282 | } |
276 | |
283 | |
277 | package CFClient::MapWidget::Command; |
284 | package CFClient::MapWidget::Command; |
278 | |
285 | |
279 | use strict; |
286 | use strict; |
… | |
… | |
287 | |
294 | |
288 | my $self = $class->SUPER::new ( |
295 | my $self = $class->SUPER::new ( |
289 | @_, |
296 | @_, |
290 | children => [map |
297 | children => [map |
291 | CFClient::UI::Label->new ( |
298 | CFClient::UI::Label->new ( |
292 | can_hover => 1, |
299 | can_hover => 1, |
|
|
300 | can_events => 1, |
293 | fontsize => $_, |
301 | fontsize => $_, |
294 | ), 1, 1, 0.8, 0.8, 0.8, 0.8, 0.8 |
302 | ), 1, 1, 0.8, 0.8, 0.8, 0.8, 0.8 |
295 | ], |
303 | ], |
296 | ); |
304 | ); |
297 | |
305 | |
298 | $self |
306 | $self |
… | |
… | |
315 | my @found; |
323 | my @found; |
316 | |
324 | |
317 | for (@$command) { |
325 | for (@$command) { |
318 | if ($_->[0] =~ $search_abbrev) { |
326 | if ($_->[0] =~ $search_abbrev) { |
319 | push @found, [$_->[0], $_]; |
327 | push @found, [$_->[0], $_]; |
320 | } elsif ($_[1] =~ $search_full) { |
328 | } elsif ($_->[1] =~ $search_full) { |
321 | push @found, [$_->[1], $_]; |
329 | push @found, [$_->[1], $_]; |
322 | } |
330 | } |
323 | } |
331 | } |
324 | |
332 | |
325 | @found = sort { $a->[0] cmp $b->[0] } @found; |
333 | @found = sort { $a->[0] cmp $b->[0] } @found; |
326 | |
334 | |
327 | $self->{children}[0]->set_text ("$self->{search}_"); |
335 | $self->{children}[0]->set_text ("$self->{search}_"); |
328 | |
336 | |
329 | for (0..5) { |
337 | for (0..5) { |
330 | $self->{children}[$_ + 1]->set_text ($found[$_] ? "$found[$_][0] ($found[$_][1][1])" : ""); |
338 | $self->{children}[$_ + 1]->set_text ($found[$_] ? "$found[$_][0] ($found[$_][1][1])" : ""); |
|
|
339 | $self->{children}[$_ + 1]{tooltip} = ($found[$_] ? $found[$_][1][2] : ""); |
331 | } |
340 | } |
332 | |
341 | |
333 | $self->{select} = $found[0][1][1] |
342 | $self->{select} = $found[0][1] |
334 | if @found; |
343 | if @found; |
335 | |
344 | |
336 | if (@found > 6) { |
345 | if (@found > 6) { |
337 | $self->{children}[6]->set_text ("..."); |
346 | $self->{children}[6]->set_text ("..."); |
338 | } |
347 | } |
… | |
… | |
351 | $self->emit (execute => $self->{select}); |
360 | $self->emit (execute => $self->{select}); |
352 | $self->emit ("close"); |
361 | $self->emit ("close"); |
353 | } |
362 | } |
354 | } elsif ($ev->{sym} == 27) { |
363 | } elsif ($ev->{sym} == 27) { |
355 | $self->emit ("close"); |
364 | $self->emit ("close"); |
|
|
365 | return; |
356 | } elsif ((chr $ev->{unicode}) =~ /^[[:alpha:]]$/) { |
366 | } elsif ((chr $ev->{unicode}) =~ /^[[:alpha:]]$/) { |
357 | $self->{search} .= chr $ev->{unicode}; |
367 | $self->{search} .= chr $ev->{unicode}; |
358 | $self->update_labels; |
368 | $self->update_labels; |
359 | } |
369 | } |
360 | |
370 | |