1 /*
2 * Schism Tracker - a cross-platform Impulse Tracker clone
3 * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
4 * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
5 * copyright (c) 2009 Storlek & Mrs. Brisby
6 * copyright (c) 2010-2012 Storlek
7 * URL: http://schismtracker.org/
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include "headers.h"
25 #include "it.h"
26 #include "page.h"
27 #include "song.h"
28
29 /* --------------------------------------------------------------------- */
30
31 /* n => the delta-value */
numentry_move_cursor(struct widget * widget,int n)32 static void numentry_move_cursor(struct widget *widget, int n)
33 {
34 if (widget->d.numentry.reverse) return;
35 n += *(widget->d.numentry.cursor_pos);
36 n = CLAMP(n, 0, widget->width - 1);
37 if (*(widget->d.numentry.cursor_pos) == n)
38 return;
39 *(widget->d.numentry.cursor_pos) = n;
40 status.flags |= NEED_UPDATE;
41 }
42
textentry_move_cursor(struct widget * widget,int n)43 static void textentry_move_cursor(struct widget *widget, int n)
44 {
45 n += widget->d.textentry.cursor_pos;
46 n = CLAMP(n, 0, widget->d.textentry.max_length);
47 if (widget->d.textentry.cursor_pos == n)
48 return;
49 widget->d.textentry.cursor_pos = n;
50 status.flags |= NEED_UPDATE;
51 }
52
bitset_move_cursor(struct widget * widget,int n)53 static void bitset_move_cursor(struct widget *widget, int n)
54 {
55 n += *widget->d.bitset.cursor_pos;
56 n = CLAMP(n, 0, widget->d.bitset.nbits-1);
57 if (*widget->d.bitset.cursor_pos == n)
58 return;
59 *widget->d.bitset.cursor_pos = n;
60 status.flags |= NEED_UPDATE;
61 }
62
63 /* --------------------------------------------------------------------- */
64 /* thumbbar value prompt */
65
thumbbar_prompt_finish(int n)66 static void thumbbar_prompt_finish(int n)
67 {
68 if (n >= ACTIVE_WIDGET.d.thumbbar.min && n <= ACTIVE_WIDGET.d.thumbbar.max) {
69 ACTIVE_WIDGET.d.thumbbar.value = n;
70 if (ACTIVE_WIDGET.changed) ACTIVE_WIDGET.changed();
71 }
72
73 status.flags |= NEED_UPDATE;
74 }
75
thumbbar_prompt_value(struct widget * widget,struct key_event * k)76 static int thumbbar_prompt_value(struct widget *widget, struct key_event *k)
77 {
78 int c;
79
80 if (!NO_MODIFIER(k->mod)) {
81 /* annoying */
82 return 0;
83 }
84 if (k->sym == SDLK_MINUS) {
85 if (widget->d.thumbbar.min >= 0)
86 return 0;
87 c = '-';
88 } else {
89 c = numeric_key_event(k, 0);
90 if (c < 0)
91 return 0;
92 c += '0';
93 }
94
95 numprompt_create("Enter Value", thumbbar_prompt_finish, c);
96
97 return 1;
98 }
99
100 /* --------------------------------------------------------------------- */
101 /* This function is completely disgustipated. */
102
103
_backtab(void)104 static void _backtab(void)
105 {
106 struct widget *w;
107 int i;
108
109 /* hunt for a widget that leads back to this one */
110 if (!total_widgets || !selected_widget) return;
111
112 for (i = 0; i < *total_widgets; i++) {
113 w = &widgets[i];
114 if (w->next.tab == *selected_widget) {
115 /* found backtab */
116 change_focus_to(i);
117 return;
118 }
119
120 }
121 if (status.flags & CLASSIC_MODE) {
122 for (i = 0; i < *total_widgets; i++) {
123 w = &widgets[i];
124 if (w->next.right == *selected_widget) {
125 /* simulate backtab */
126 change_focus_to(i);
127 return;
128 }
129 }
130 for (i = 0; i < *total_widgets; i++) {
131 w = &widgets[i];
132 if (w->next.down == *selected_widget) {
133 /* simulate backtab */
134 change_focus_to(i);
135 return;
136 }
137 }
138 } else {
139 for (i = 0; i < *total_widgets; i++) {
140 w = &widgets[i];
141 if (w->next.down == *selected_widget) {
142 /* simulate backtab */
143 change_focus_to(i);
144 return;
145 }
146 }
147 for (i = 0; i < *total_widgets; i++) {
148 w = &widgets[i];
149 if (w->next.right == *selected_widget) {
150 /* simulate backtab */
151 change_focus_to(i);
152 return;
153 }
154 }
155 }
156 change_focus_to(0); /* err... */
157 }
158
159
160 /* return: 1 = handled key, 0 = didn't */
widget_handle_key(struct key_event * k)161 int widget_handle_key(struct key_event * k)
162 {
163 struct widget *widget = &ACTIVE_WIDGET;
164 if (!widget)
165 return 0;
166
167 int n, onw, wx, fmin, fmax, pad;
168 void (*changed)(void);
169 enum widget_type current_type = widget->type;
170
171 if (!(status.flags & DISKWRITER_ACTIVE)
172 && (current_type == WIDGET_OTHER)
173 && widget->d.other.handle_key(k))
174 return 1;
175
176 if (!(status.flags & DISKWRITER_ACTIVE) && k->mouse
177 && (status.flags & CLASSIC_MODE)) {
178 switch(current_type) {
179 case WIDGET_NUMENTRY:
180 if (k->mouse_button == MOUSE_BUTTON_LEFT) {
181 k->sym = SDLK_MINUS;
182 k->mouse = MOUSE_NONE;
183 } else if (k->mouse_button == MOUSE_BUTTON_RIGHT) {
184 k->sym = SDLK_PLUS;
185 k->mouse = MOUSE_NONE;
186 }
187 break;
188 default:
189 break;
190 };
191 }
192
193 if (k->mouse == MOUSE_CLICK) {
194 if (status.flags & DISKWRITER_ACTIVE) return 0;
195 switch (current_type) {
196 case WIDGET_TOGGLE:
197 if (!NO_MODIFIER(k->mod))
198 return 0;
199 if (k->state == KEY_RELEASE)
200 return 1;
201 widget->d.toggle.state = !widget->d.toggle.state;
202 if (widget->changed) widget->changed();
203 status.flags |= NEED_UPDATE;
204 return 1;
205 case WIDGET_MENUTOGGLE:
206 if (!NO_MODIFIER(k->mod))
207 return 0;
208 if (k->state == KEY_RELEASE)
209 return 1;
210 widget->d.menutoggle.state = (widget->d.menutoggle.state + 1)
211 % widget->d.menutoggle.num_choices;
212 if (widget->changed) widget->changed();
213 status.flags |= NEED_UPDATE;
214 return 1;
215 default:
216 break;
217 }
218 } else if (k->mouse == MOUSE_DBLCLICK) {
219 if (status.flags & DISKWRITER_ACTIVE) return 0;
220 if (current_type == WIDGET_PANBAR) {
221 if (!NO_MODIFIER(k->mod))
222 return 0;
223 widget->d.panbar.muted = !widget->d.panbar.muted;
224 changed = widget->changed;
225 if (changed) changed();
226 return 1;
227 }
228 }
229
230 if (k->mouse == MOUSE_CLICK
231 || (k->mouse == MOUSE_NONE && k->sym == SDLK_RETURN)) {
232 #if 0
233 if (k->mouse && k->mouse_button == MOUSE_BUTTON_MIDDLE) {
234 if (status.flags & DISKWRITER_ACTIVE) return 0;
235 if (k->state == KEY_PRESS)
236 return 1;
237 status.flags |= CLIPPY_PASTE_SELECTION;
238 return 1;
239 }
240 #endif
241 if (k->mouse && (current_type == WIDGET_THUMBBAR
242 || current_type == WIDGET_PANBAR)) {
243 if (status.flags & DISKWRITER_ACTIVE) return 0;
244
245 /* swallow it */
246 if (!k->on_target) return 0;
247
248 fmin = widget->d.thumbbar.min;
249 fmax = widget->d.thumbbar.max;
250 if (current_type == WIDGET_PANBAR) {
251 n = k->fx - ((widget->x + 11) * k->rx);
252 wx = (widget->width - 16) * k->rx;
253 } else {
254 n = k->fx - (widget->x * k->rx);
255 wx = (widget->width-1) * k->rx;
256 }
257 if (n < 0) n = 0;
258 else if (n >= wx) n = wx;
259 n = fmin + ((n * (fmax - fmin)) / wx);
260
261 if (n < fmin)
262 n = fmin;
263 else if (n > fmax)
264 n = fmax;
265 if (current_type == WIDGET_PANBAR) {
266 widget->d.panbar.muted = 0;
267 widget->d.panbar.surround = 0;
268 if (k->x - widget->x < 11) return 1;
269 if (k->x - widget->x > 19) return 1;
270 }
271 numentry_change_value(widget, n);
272 return 1;
273 }
274 if (k->mouse) {
275 switch (widget->type) {
276 case WIDGET_BUTTON:
277 pad = widget->d.button.padding+1;
278 break;
279 case WIDGET_TOGGLEBUTTON:
280 pad = widget->d.togglebutton.padding+1;
281 break;
282 default:
283 pad = 0;
284 };
285 onw = ((signed) k->x < widget->x
286 || (signed) k->x >= widget->x + widget->width + pad
287 || (signed) k->y != widget->y) ? 0 : 1;
288 n = (k->state == KEY_RELEASE && onw) ? 1 : 0;
289 if (widget->depressed != n) status.flags |= NEED_UPDATE;
290 widget->depressed = n;
291 if (current_type != WIDGET_TEXTENTRY && current_type != WIDGET_NUMENTRY) {
292 if (k->state == KEY_PRESS || !onw)
293 return 1;
294 } else if (!onw) {
295 return 1;
296 }
297 } else {
298 n = (k->state == KEY_PRESS) ? 1 : 0;
299 if (widget->depressed != n)
300 status.flags |= NEED_UPDATE;
301 else if (k->state == KEY_RELEASE)
302 return 1; // swallor
303 widget->depressed = n;
304 if (k->state == KEY_PRESS)
305 return 1;
306 }
307
308 if (k->mouse) {
309 switch(current_type) {
310 case WIDGET_MENUTOGGLE:
311 case WIDGET_BUTTON:
312 case WIDGET_TOGGLEBUTTON:
313 if (k->on_target && widget->activate) widget->activate();
314 default:
315 break;
316 };
317 } else if (current_type != WIDGET_OTHER) {
318 if (widget->activate) widget->activate();
319 }
320
321 switch (current_type) {
322 case WIDGET_OTHER:
323 break;
324 case WIDGET_TEXTENTRY:
325 if (status.flags & DISKWRITER_ACTIVE) return 0;
326 /* LOL WOW THIS SUCKS */
327 if (k->mouse == MOUSE_CLICK && k->on_target) {
328 /* position cursor */
329 n = k->x - widget->x;
330 n = CLAMP(n, 0, widget->width - 1);
331 wx = k->sx - widget->x;
332 wx = CLAMP(wx, 0, widget->width - 1);
333 widget->d.textentry.cursor_pos = n+widget->d.textentry.firstchar;
334 wx = wx+widget->d.textentry.firstchar;
335 if (widget->d.textentry.cursor_pos >= (signed) strlen(widget->d.textentry.text))
336 widget->d.textentry.cursor_pos = strlen(widget->d.textentry.text);
337 if (wx >= (signed) strlen(widget->d.textentry.text))
338 wx = strlen(widget->d.textentry.text);
339 status.flags |= NEED_UPDATE;
340 }
341
342 /* for a text entry, the only thing enter does is run the activate callback.
343 thus, if no activate callback is defined, the key wasn't handled */
344 return (widget->activate != NULL);
345
346 case WIDGET_NUMENTRY:
347 if (status.flags & DISKWRITER_ACTIVE) return 0;
348 if (k->mouse == MOUSE_CLICK && k->on_target) {
349 /* position cursor */
350 n = k->x - widget->x;
351 n = CLAMP(n, 0, widget->width - 1);
352 wx = k->sx - widget->x;
353 wx = CLAMP(wx, 0, widget->width - 1);
354 if (n >= widget->width)
355 n = widget->width-1;
356 *widget->d.numentry.cursor_pos = n;
357 status.flags |= NEED_UPDATE;
358 }
359
360 break;
361
362 case WIDGET_TOGGLEBUTTON:
363 if (status.flags & DISKWRITER_ACTIVE) return 0;
364 if (widget->d.togglebutton.group) {
365 /* this also runs the changed callback and redraws the button(s) */
366 togglebutton_set(widgets, *selected_widget, 1);
367 return 1;
368 }
369 /* else... */
370 widget->d.togglebutton.state = !widget->d.togglebutton.state;
371 /* and fall through */
372 case WIDGET_BUTTON:
373 /* maybe buttons should ignore the changed callback, and use activate instead...
374 (but still call the changed callback for togglebuttons if they *actually* changed) */
375 if (widget->changed) widget->changed();
376 status.flags |= NEED_UPDATE;
377 return 1;
378 default:
379 break;
380 }
381 return 0;
382 }
383
384 /* a WIDGET_OTHER that *didn't* handle the key itself needs to get run through the switch
385 statement to account for stuff like the tab key */
386 if (k->state == KEY_RELEASE)
387 return 0;
388
389 if (k->mouse == MOUSE_SCROLL_UP && current_type == WIDGET_NUMENTRY) {
390 k->sym = SDLK_MINUS;
391 } else if (k->mouse == MOUSE_SCROLL_DOWN && current_type == WIDGET_NUMENTRY) {
392 k->sym = SDLK_PLUS;
393 }
394
395 switch (k->sym) {
396 case SDLK_ESCAPE:
397 /* this is to keep the text entries from taking the key hostage and inserting '<-'
398 characters instead of showing the menu */
399 return 0;
400 case SDLK_UP:
401 if (status.flags & DISKWRITER_ACTIVE) return 0;
402 if (!NO_MODIFIER(k->mod))
403 return 0;
404 change_focus_to(widget->next.up);
405 return 1;
406 case SDLK_DOWN:
407 if (status.flags & DISKWRITER_ACTIVE) return 0;
408 if (!NO_MODIFIER(k->mod))
409 return 0;
410 change_focus_to(widget->next.down);
411 return 1;
412 case SDLK_TAB:
413 if (status.flags & DISKWRITER_ACTIVE) return 0;
414 if (k->mod & KMOD_SHIFT) {
415 _backtab();
416 return 1;
417 }
418 if (!NO_MODIFIER(k->mod))
419 return 0;
420 change_focus_to(widget->next.tab);
421 return 1;
422 case SDLK_LEFT:
423 if (status.flags & DISKWRITER_ACTIVE) return 0;
424 switch (current_type) {
425 case WIDGET_BITSET:
426 if (NO_MODIFIER(k->mod))
427 bitset_move_cursor(widget, -1);
428 break;
429 case WIDGET_NUMENTRY:
430 if (!NO_MODIFIER(k->mod)) {
431 return 0;
432 }
433 numentry_move_cursor(widget, -1);
434 return 1;
435 case WIDGET_TEXTENTRY:
436 if (!NO_MODIFIER(k->mod)) {
437 return 0;
438 }
439 textentry_move_cursor(widget, -1);
440 return 1;
441 case WIDGET_PANBAR:
442 widget->d.panbar.muted = 0;
443 widget->d.panbar.surround = 0;
444 /* fall through */
445 case WIDGET_THUMBBAR:
446 /* I'm handling the key modifiers differently than Impulse Tracker, but only
447 because I think this is much more useful. :) */
448 n = 1;
449 if (k->mod & (KMOD_ALT | KMOD_META))
450 n *= 8;
451 if (k->mod & KMOD_SHIFT)
452 n *= 4;
453 if (k->mod & KMOD_CTRL)
454 n *= 2;
455 n = widget->d.numentry.value - n;
456 numentry_change_value(widget, n);
457 return 1;
458 default:
459 if (!NO_MODIFIER(k->mod))
460 return 0;
461 change_focus_to(widget->next.left);
462 return 1;
463 }
464 break;
465 case SDLK_RIGHT:
466 if (status.flags & DISKWRITER_ACTIVE) return 0;
467 /* pretty much the same as left, but with a few small
468 * changes here and there... */
469 switch (current_type) {
470 case WIDGET_BITSET:
471 if (NO_MODIFIER(k->mod))
472 bitset_move_cursor(widget, 1);
473 break;
474 case WIDGET_NUMENTRY:
475 if (!NO_MODIFIER(k->mod)) {
476 return 0;
477 }
478 numentry_move_cursor(widget, 1);
479 return 1;
480 case WIDGET_TEXTENTRY:
481 if (!NO_MODIFIER(k->mod)) {
482 return 0;
483 }
484 textentry_move_cursor(widget, 1);
485 return 1;
486 case WIDGET_PANBAR:
487 widget->d.panbar.muted = 0;
488 widget->d.panbar.surround = 0;
489 /* fall through */
490 case WIDGET_THUMBBAR:
491 n = 1;
492 if (k->mod & (KMOD_ALT | KMOD_META))
493 n *= 8;
494 if (k->mod & KMOD_SHIFT)
495 n *= 4;
496 if (k->mod & KMOD_CTRL)
497 n *= 2;
498 n = widget->d.numentry.value + n;
499 numentry_change_value(widget, n);
500 return 1;
501 default:
502 if (!NO_MODIFIER(k->mod))
503 return 0;
504 change_focus_to(widget->next.right);
505 return 1;
506 }
507 break;
508 case SDLK_HOME:
509 if (status.flags & DISKWRITER_ACTIVE) return 0;
510 /* Impulse Tracker only does home/end for the thumbbars.
511 * This stuff is all extra. */
512 switch (current_type) {
513 case WIDGET_NUMENTRY:
514 if (!NO_MODIFIER(k->mod))
515 return 0;
516 *(widget->d.numentry.cursor_pos) = 0;
517 status.flags |= NEED_UPDATE;
518 return 1;
519 case WIDGET_TEXTENTRY:
520 if (!NO_MODIFIER(k->mod))
521 return 0;
522 widget->d.textentry.cursor_pos = 0;
523 status.flags |= NEED_UPDATE;
524 return 1;
525 case WIDGET_PANBAR:
526 widget->d.panbar.muted = 0;
527 widget->d.panbar.surround = 0;
528 /* fall through */
529 case WIDGET_THUMBBAR:
530 n = widget->d.thumbbar.min;
531 numentry_change_value(widget, n);
532 return 1;
533 default:
534 break;
535 }
536 break;
537 case SDLK_END:
538 if (status.flags & DISKWRITER_ACTIVE) return 0;
539 switch (current_type) {
540 case WIDGET_NUMENTRY:
541 if (!NO_MODIFIER(k->mod))
542 return 0;
543 *(widget->d.numentry.cursor_pos) = widget->width - 1;
544 status.flags |= NEED_UPDATE;
545 return 1;
546 case WIDGET_TEXTENTRY:
547 if (!NO_MODIFIER(k->mod))
548 return 0;
549 widget->d.textentry.cursor_pos = strlen(widget->d.textentry.text);
550 status.flags |= NEED_UPDATE;
551 return 1;
552 case WIDGET_PANBAR:
553 widget->d.panbar.muted = 0;
554 widget->d.panbar.surround = 0;
555 /* fall through */
556 case WIDGET_THUMBBAR:
557 n = widget->d.thumbbar.max;
558 numentry_change_value(widget, n);
559 return 1;
560 default:
561 break;
562 }
563 break;
564 case SDLK_SPACE:
565 if (status.flags & DISKWRITER_ACTIVE) return 0;
566 switch (current_type) {
567 case WIDGET_BITSET:
568 if (!NO_MODIFIER(k->mod))
569 return 0;
570 widget->d.bitset.value ^= (1 << *widget->d.bitset.cursor_pos);
571 if (widget->changed) widget->changed();
572 status.flags |= NEED_UPDATE;
573 return 1;
574 case WIDGET_TOGGLE:
575 if (!NO_MODIFIER(k->mod))
576 return 0;
577 widget->d.toggle.state = !widget->d.toggle.state;
578 if (widget->changed) widget->changed();
579 status.flags |= NEED_UPDATE;
580 return 1;
581 case WIDGET_MENUTOGGLE:
582 if (!NO_MODIFIER(k->mod))
583 return 0;
584 widget->d.menutoggle.state = (widget->d.menutoggle.state + 1)
585 % widget->d.menutoggle.num_choices;
586 if (widget->changed) widget->changed();
587 status.flags |= NEED_UPDATE;
588 return 1;
589 case WIDGET_PANBAR:
590 if (!NO_MODIFIER(k->mod))
591 return 0;
592 widget->d.panbar.muted = !widget->d.panbar.muted;
593 changed = widget->changed;
594 change_focus_to(widget->next.down);
595 if (changed) changed();
596 return 1;
597 default:
598 break;
599 }
600 break;
601 case SDLK_BACKSPACE:
602 if (status.flags & DISKWRITER_ACTIVE) return 0;
603 if (current_type == WIDGET_NUMENTRY) {
604 if (widget->d.numentry.reverse) {
605 /* woot! */
606 widget->d.numentry.value /= 10;
607 if (widget->changed) widget->changed();
608 status.flags |= NEED_UPDATE;
609 return 1;
610 }
611 }
612
613 /* this ought to be in a separate function. */
614 if (current_type != WIDGET_TEXTENTRY)
615 break;
616 if (!widget->d.textentry.text[0]) {
617 /* nothing to do */
618 return 1;
619 }
620 if (k->mod & KMOD_CTRL) {
621 /* clear the whole field */
622 widget->d.textentry.text[0] = 0;
623 widget->d.textentry.cursor_pos = 0;
624 } else {
625 if (widget->d.textentry.cursor_pos == 0) {
626 /* act like ST3 */
627 text_delete_next_char(widget->d.textentry.text,
628 &(widget->d.textentry.cursor_pos),
629 widget->d.textentry.max_length);
630 } else {
631 text_delete_char(widget->d.textentry.text,
632 &(widget->d.textentry.cursor_pos),
633 widget->d.textentry.max_length);
634 }
635 }
636 if (widget->changed) widget->changed();
637 status.flags |= NEED_UPDATE;
638 return 1;
639 case SDLK_DELETE:
640 if (status.flags & DISKWRITER_ACTIVE) return 0;
641 if (current_type != WIDGET_TEXTENTRY)
642 break;
643 if (!widget->d.textentry.text[0]) {
644 /* nothing to do */
645 return 1;
646 }
647 text_delete_next_char(widget->d.textentry.text,
648 &(widget->d.textentry.cursor_pos), widget->d.textentry.max_length);
649 if (widget->changed) widget->changed();
650 status.flags |= NEED_UPDATE;
651 return 1;
652 case SDLK_PLUS:
653 if (status.flags & DISKWRITER_ACTIVE) return 0;
654 if (current_type == WIDGET_NUMENTRY && NO_MODIFIER(k->mod)) {
655 numentry_change_value(widget, widget->d.numentry.value + 1);
656 return 1;
657 }
658 break;
659 case SDLK_MINUS:
660 if (status.flags & DISKWRITER_ACTIVE) return 0;
661 if (current_type == WIDGET_NUMENTRY && NO_MODIFIER(k->mod)) {
662 numentry_change_value(widget, widget->d.numentry.value - 1);
663 return 1;
664 }
665 break;
666 case SDLK_l:
667 if (status.flags & DISKWRITER_ACTIVE) return 0;
668 if (current_type == WIDGET_PANBAR) {
669 if (k->mod & KMOD_ALT) {
670 song_set_pan_scheme(PANS_LEFT);
671 return 1;
672 } else if (NO_MODIFIER(k->mod)) {
673 widget->d.panbar.muted = 0;
674 widget->d.panbar.surround = 0;
675 numentry_change_value(widget, 0);
676 return 1;
677 }
678 }
679 break;
680 case SDLK_m:
681 if (status.flags & DISKWRITER_ACTIVE) return 0;
682 if (current_type == WIDGET_PANBAR) {
683 if (k->mod & KMOD_ALT) {
684 song_set_pan_scheme(PANS_MONO);
685 return 1;
686 } else if (NO_MODIFIER(k->mod)) {
687 widget->d.panbar.muted = 0;
688 widget->d.panbar.surround = 0;
689 numentry_change_value(widget, 32);
690 return 1;
691 }
692 }
693 break;
694 case SDLK_r:
695 if (status.flags & DISKWRITER_ACTIVE) return 0;
696 if (current_type == WIDGET_PANBAR) {
697 if (k->mod & KMOD_ALT) {
698 song_set_pan_scheme(PANS_RIGHT);
699 return 1;
700 } else if (NO_MODIFIER(k->mod)) {
701 widget->d.panbar.muted = 0;
702 widget->d.panbar.surround = 0;
703 numentry_change_value(widget, 64);
704 return 1;
705 }
706 }
707 break;
708 case SDLK_s:
709 if (status.flags & DISKWRITER_ACTIVE) return 0;
710 if (current_type == WIDGET_PANBAR) {
711 if (k->mod & KMOD_ALT) {
712 song_set_pan_scheme(PANS_STEREO);
713 return 1;
714 } else if(NO_MODIFIER(k->mod)) {
715 widget->d.panbar.muted = 0;
716 widget->d.panbar.surround = 1;
717 if (widget->changed) widget->changed();
718 status.flags |= NEED_UPDATE;
719 return 1;
720 }
721 }
722 break;
723 case SDLK_a:
724 if (status.flags & DISKWRITER_ACTIVE) return 0;
725 if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) {
726 song_set_pan_scheme(PANS_AMIGA);
727 return 1;
728 }
729 break;
730 #if 0
731 case SDLK_x:
732 if (status.flags & DISKWRITER_ACTIVE) return 0;
733 if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) {
734 song_set_pan_scheme(PANS_CROSS);
735 return 1;
736 }
737 break;
738 #endif
739 case SDLK_SLASH:
740 case SDLK_KP_DIVIDE:
741 if (status.flags & DISKWRITER_ACTIVE) return 0;
742 if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) {
743 song_set_pan_scheme(PANS_SLASH);
744 return 1;
745 }
746 break;
747 case SDLK_BACKSLASH:
748 if (status.flags & DISKWRITER_ACTIVE) return 0;
749 if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) {
750 song_set_pan_scheme(PANS_BACKSLASH);
751 return 1;
752 }
753 break;
754 default:
755 /* this avoids a warning about all the values of an enum not being handled.
756 (sheesh, it's already hundreds of lines long as it is!) */
757 break;
758 }
759 if (status.flags & DISKWRITER_ACTIVE) return 0;
760
761 /* if we're here, that mess didn't completely handle the key (gosh...) so now here's another mess. */
762 switch (current_type) {
763 case WIDGET_MENUTOGGLE:
764 if (menutoggle_handle_key(widget, k))
765 return 1;
766 break;
767 case WIDGET_BITSET:
768 if (bitset_handle_key(widget, k))
769 return 1;
770 break;
771 case WIDGET_NUMENTRY:
772 if (numentry_handle_digit(widget, k))
773 return 1;
774 break;
775 case WIDGET_THUMBBAR:
776 case WIDGET_PANBAR:
777 if (thumbbar_prompt_value(widget, k))
778 return 1;
779 break;
780 case WIDGET_TEXTENTRY:
781 if ((k->mod & (KMOD_CTRL | KMOD_ALT | KMOD_META)) == 0
782 && textentry_add_char(widget, k->unicode))
783 return 1;
784 break;
785 default:
786 break;
787 }
788
789 /* if we got down here the key wasn't handled */
790 return 0;
791 }
792
793